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 }