github.com/sagernet/quic-go@v0.43.1-beta.1/internal/handshake_ech/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  }