File: session_ticket.go

package info (click to toggle)
golang-github-lucas-clemente-quic-go 0.50.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,496 kB
  • sloc: sh: 54; makefile: 7
file content (72 lines) | stat: -rw-r--r-- 1,760 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package handshake

import (
	"bytes"
	"errors"
	"fmt"
	"time"

	"github.com/quic-go/quic-go/internal/wire"
	"github.com/quic-go/quic-go/quicvarint"
)

const sessionTicketRevision = 4

type sessionTicket struct {
	Parameters *wire.TransportParameters
	RTT        time.Duration // to be encoded in mus
}

func (t *sessionTicket) Marshal() []byte {
	b := make([]byte, 0, 256)
	b = quicvarint.Append(b, sessionTicketRevision)
	b = quicvarint.Append(b, uint64(t.RTT.Microseconds()))
	if t.Parameters == nil {
		return b
	}
	return t.Parameters.MarshalForSessionTicket(b)
}

func (t *sessionTicket) Unmarshal(b []byte, using0RTT bool) error {
	rev, l, err := quicvarint.Parse(b)
	if err != nil {
		return errors.New("failed to read session ticket revision")
	}
	b = b[l:]
	if rev != sessionTicketRevision {
		return fmt.Errorf("unknown session ticket revision: %d", rev)
	}
	rtt, l, err := quicvarint.Parse(b)
	if err != nil {
		return errors.New("failed to read RTT")
	}
	b = b[l:]
	if using0RTT {
		var tp wire.TransportParameters
		if err := tp.UnmarshalFromSessionTicket(b); err != nil {
			return fmt.Errorf("unmarshaling transport parameters from session ticket failed: %s", err.Error())
		}
		t.Parameters = &tp
	} else if len(b) > 0 {
		return fmt.Errorf("the session ticket has more bytes than expected")
	}
	t.RTT = time.Duration(rtt) * time.Microsecond
	return nil
}

const extraPrefix = "quic-go1"

func addSessionStateExtraPrefix(b []byte) []byte {
	return append([]byte(extraPrefix), b...)
}

func findSessionStateExtraData(extras [][]byte) []byte {
	prefix := []byte(extraPrefix)
	for _, extra := range extras {
		if len(extra) < len(prefix) || !bytes.Equal(prefix, extra[:len(prefix)]) {
			continue
		}
		return extra[len(prefix):]
	}
	return nil
}