github.com/sagernet/quic-go@v0.43.1-beta.1/internal/handshake/session_ticket.go (about) 1 package handshake 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "time" 8 9 "github.com/sagernet/quic-go/internal/wire" 10 "github.com/sagernet/quic-go/quicvarint" 11 ) 12 13 const sessionTicketRevision = 4 14 15 type sessionTicket struct { 16 Parameters *wire.TransportParameters 17 RTT time.Duration // to be encoded in mus 18 } 19 20 func (t *sessionTicket) Marshal() []byte { 21 b := make([]byte, 0, 256) 22 b = quicvarint.Append(b, sessionTicketRevision) 23 b = quicvarint.Append(b, uint64(t.RTT.Microseconds())) 24 if t.Parameters == nil { 25 return b 26 } 27 return t.Parameters.MarshalForSessionTicket(b) 28 } 29 30 func (t *sessionTicket) Unmarshal(b []byte, using0RTT bool) error { 31 r := bytes.NewReader(b) 32 rev, err := quicvarint.Read(r) 33 if err != nil { 34 return errors.New("failed to read session ticket revision") 35 } 36 if rev != sessionTicketRevision { 37 return fmt.Errorf("unknown session ticket revision: %d", rev) 38 } 39 rtt, err := quicvarint.Read(r) 40 if err != nil { 41 return errors.New("failed to read RTT") 42 } 43 if using0RTT { 44 var tp wire.TransportParameters 45 if err := tp.UnmarshalFromSessionTicket(r); err != nil { 46 return fmt.Errorf("unmarshaling transport parameters from session ticket failed: %s", err.Error()) 47 } 48 t.Parameters = &tp 49 } else if r.Len() > 0 { 50 return fmt.Errorf("the session ticket has more bytes than expected") 51 } 52 t.RTT = time.Duration(rtt) * time.Microsecond 53 return nil 54 }