github.com/sagernet/quic-go@v0.43.1-beta.1/qlog/packet_header.go (about)

     1  package qlog
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/francoispqt/gojay"
     7  	"github.com/sagernet/quic-go/internal/protocol"
     8  	"github.com/sagernet/quic-go/logging"
     9  )
    10  
    11  func getPacketTypeFromEncryptionLevel(encLevel protocol.EncryptionLevel) logging.PacketType {
    12  	switch encLevel {
    13  	case protocol.EncryptionInitial:
    14  		return logging.PacketTypeInitial
    15  	case protocol.EncryptionHandshake:
    16  		return logging.PacketTypeHandshake
    17  	case protocol.Encryption0RTT:
    18  		return logging.PacketType0RTT
    19  	case protocol.Encryption1RTT:
    20  		return logging.PacketType1RTT
    21  	default:
    22  		panic("unknown encryption level")
    23  	}
    24  }
    25  
    26  type token struct {
    27  	Raw []byte
    28  }
    29  
    30  var _ gojay.MarshalerJSONObject = &token{}
    31  
    32  func (t token) IsNil() bool { return false }
    33  func (t token) MarshalJSONObject(enc *gojay.Encoder) {
    34  	enc.StringKey("data", fmt.Sprintf("%x", t.Raw))
    35  }
    36  
    37  // PacketHeader is a QUIC packet header.
    38  // TODO: make this a long header
    39  type packetHeader struct {
    40  	PacketType logging.PacketType
    41  
    42  	KeyPhaseBit  logging.KeyPhaseBit
    43  	PacketNumber logging.PacketNumber
    44  
    45  	Version          logging.VersionNumber
    46  	SrcConnectionID  logging.ConnectionID
    47  	DestConnectionID logging.ConnectionID
    48  
    49  	Token *token
    50  }
    51  
    52  func transformHeader(hdr *logging.Header) *packetHeader {
    53  	h := &packetHeader{
    54  		PacketType:       logging.PacketTypeFromHeader(hdr),
    55  		SrcConnectionID:  hdr.SrcConnectionID,
    56  		DestConnectionID: hdr.DestConnectionID,
    57  		Version:          hdr.Version,
    58  	}
    59  	if len(hdr.Token) > 0 {
    60  		h.Token = &token{Raw: hdr.Token}
    61  	}
    62  	return h
    63  }
    64  
    65  func transformLongHeader(hdr *logging.ExtendedHeader) *packetHeader {
    66  	h := transformHeader(&hdr.Header)
    67  	h.PacketNumber = hdr.PacketNumber
    68  	h.KeyPhaseBit = hdr.KeyPhase
    69  	return h
    70  }
    71  
    72  func (h packetHeader) MarshalJSONObject(enc *gojay.Encoder) {
    73  	enc.StringKey("packet_type", packetType(h.PacketType).String())
    74  	if h.PacketType != logging.PacketTypeRetry {
    75  		enc.Int64Key("packet_number", int64(h.PacketNumber))
    76  	}
    77  	if h.Version != 0 {
    78  		enc.StringKey("version", versionNumber(h.Version).String())
    79  	}
    80  	if h.PacketType != logging.PacketType1RTT {
    81  		enc.IntKey("scil", h.SrcConnectionID.Len())
    82  		if h.SrcConnectionID.Len() > 0 {
    83  			enc.StringKey("scid", h.SrcConnectionID.String())
    84  		}
    85  	}
    86  	enc.IntKey("dcil", h.DestConnectionID.Len())
    87  	if h.DestConnectionID.Len() > 0 {
    88  		enc.StringKey("dcid", h.DestConnectionID.String())
    89  	}
    90  	if h.KeyPhaseBit == logging.KeyPhaseZero || h.KeyPhaseBit == logging.KeyPhaseOne {
    91  		enc.StringKey("key_phase_bit", h.KeyPhaseBit.String())
    92  	}
    93  	if h.Token != nil {
    94  		enc.ObjectKey("token", h.Token)
    95  	}
    96  }
    97  
    98  type packetHeaderVersionNegotiation struct {
    99  	SrcConnectionID  logging.ArbitraryLenConnectionID
   100  	DestConnectionID logging.ArbitraryLenConnectionID
   101  }
   102  
   103  func (h packetHeaderVersionNegotiation) IsNil() bool { return false }
   104  func (h packetHeaderVersionNegotiation) MarshalJSONObject(enc *gojay.Encoder) {
   105  	enc.StringKey("packet_type", "version_negotiation")
   106  	enc.IntKey("scil", h.SrcConnectionID.Len())
   107  	enc.StringKey("scid", h.SrcConnectionID.String())
   108  	enc.IntKey("dcil", h.DestConnectionID.Len())
   109  	enc.StringKey("dcid", h.DestConnectionID.String())
   110  }
   111  
   112  // a minimal header that only outputs the packet type, and potentially a packet number
   113  type packetHeaderWithType struct {
   114  	PacketType   logging.PacketType
   115  	PacketNumber logging.PacketNumber
   116  }
   117  
   118  func (h packetHeaderWithType) IsNil() bool { return false }
   119  func (h packetHeaderWithType) MarshalJSONObject(enc *gojay.Encoder) {
   120  	enc.StringKey("packet_type", packetType(h.PacketType).String())
   121  	if h.PacketNumber != protocol.InvalidPacketNumber {
   122  		enc.Int64Key("packet_number", int64(h.PacketNumber))
   123  	}
   124  }
   125  
   126  // a minimal header that only outputs the packet type
   127  type packetHeaderWithTypeAndPacketNumber struct {
   128  	PacketType   logging.PacketType
   129  	PacketNumber logging.PacketNumber
   130  }
   131  
   132  func (h packetHeaderWithTypeAndPacketNumber) IsNil() bool { return false }
   133  func (h packetHeaderWithTypeAndPacketNumber) MarshalJSONObject(enc *gojay.Encoder) {
   134  	enc.StringKey("packet_type", packetType(h.PacketType).String())
   135  	enc.Int64Key("packet_number", int64(h.PacketNumber))
   136  }
   137  
   138  type shortHeader struct {
   139  	DestConnectionID logging.ConnectionID
   140  	PacketNumber     logging.PacketNumber
   141  	KeyPhaseBit      logging.KeyPhaseBit
   142  }
   143  
   144  func transformShortHeader(hdr *logging.ShortHeader) *shortHeader {
   145  	return &shortHeader{
   146  		DestConnectionID: hdr.DestConnectionID,
   147  		PacketNumber:     hdr.PacketNumber,
   148  		KeyPhaseBit:      hdr.KeyPhase,
   149  	}
   150  }
   151  
   152  func (h shortHeader) IsNil() bool { return false }
   153  func (h shortHeader) MarshalJSONObject(enc *gojay.Encoder) {
   154  	enc.StringKey("packet_type", packetType(logging.PacketType1RTT).String())
   155  	if h.DestConnectionID.Len() > 0 {
   156  		enc.StringKey("dcid", h.DestConnectionID.String())
   157  	}
   158  	enc.Int64Key("packet_number", int64(h.PacketNumber))
   159  	enc.StringKey("key_phase_bit", h.KeyPhaseBit.String())
   160  }