github.com/quic-go/quic-go@v0.44.0/internal/handshake/session_ticket.go (about)

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