log tokens in NEW_TOKEN frames, Retry packets and Initial packets

This commit is contained in:
Marten Seemann 2020-11-06 14:57:29 +07:00
parent b623a10b54
commit b83e156e9f
7 changed files with 83 additions and 12 deletions

View file

@ -130,8 +130,7 @@ func marshalCryptoFrame(enc *gojay.Encoder, f *logging.CryptoFrame) {
func marshalNewTokenFrame(enc *gojay.Encoder, f *logging.NewTokenFrame) {
enc.StringKey("frame_type", "new_token")
enc.IntKey("length", len(f.Token))
enc.StringKey("token", fmt.Sprintf("%x", f.Token))
enc.ObjectKey("token", &token{Raw: f.Token})
}
func marshalStreamFrame(enc *gojay.Encoder, f *logging.StreamFrame) {

View file

@ -149,8 +149,7 @@ var _ = Describe("Frames", func() {
},
map[string]interface{}{
"frame_type": "new_token",
"length": 4,
"token": "deadbeef",
"token": map[string]interface{}{"data": "deadbeef"},
},
)
})

View file

@ -1,6 +1,8 @@
package qlog
import (
"fmt"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/wire"
"github.com/lucas-clemente/quic-go/logging"
@ -25,10 +27,22 @@ func getPacketTypeFromEncryptionLevel(encLevel protocol.EncryptionLevel) packetT
return packetType(t)
}
type token struct {
Raw []byte
}
var _ gojay.MarshalerJSONObject = &token{}
func (t token) IsNil() bool { return false }
func (t token) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("data", fmt.Sprintf("%x", t.Raw))
}
// PacketHeader is a QUIC packet header.
type packetHeader struct {
PacketType logging.PacketType
KeyPhaseBit logging.KeyPhaseBit
PacketNumber logging.PacketNumber
PayloadLength logging.ByteCount
// Size of the QUIC packet (QUIC header + payload).
@ -39,17 +53,21 @@ type packetHeader struct {
SrcConnectionID logging.ConnectionID
DestConnectionID logging.ConnectionID
KeyPhaseBit logging.KeyPhaseBit
Token *token
}
func transformHeader(hdr *wire.Header) *packetHeader {
return &packetHeader{
h := &packetHeader{
PacketType: logging.PacketTypeFromHeader(hdr),
PayloadLength: hdr.Length,
SrcConnectionID: hdr.SrcConnectionID,
DestConnectionID: hdr.DestConnectionID,
Version: hdr.Version,
}
if len(hdr.Token) > 0 {
h.Token = &token{Raw: hdr.Token}
}
return h
}
func transformExtendedHeader(hdr *wire.ExtendedHeader) *packetHeader {
@ -82,4 +100,7 @@ func (h packetHeader) MarshalJSONObject(enc *gojay.Encoder) {
if h.KeyPhaseBit == logging.KeyPhaseZero || h.KeyPhaseBit == logging.KeyPhaseOne {
enc.StringKey("key_phase_bit", h.KeyPhaseBit.String())
}
if h.Token != nil {
enc.ObjectKey("token", h.Token)
}
}

View file

@ -69,6 +69,52 @@ var _ = Describe("Packet Header", func() {
)
})
It("marshals an Initial with a token", func() {
check(
&wire.ExtendedHeader{
PacketNumber: 4242,
Header: wire.Header{
IsLongHeader: true,
Type: protocol.PacketTypeInitial,
Length: 123,
Version: protocol.VersionNumber(0xdecafbad),
Token: []byte{0xde, 0xad, 0xbe, 0xef},
},
},
map[string]interface{}{
"packet_type": "initial",
"packet_number": 4242,
"payload_length": 123,
"dcil": 0,
"scil": 0,
"version": "decafbad",
"token": map[string]interface{}{"data": "deadbeef"},
},
)
})
It("marshals a Retry packet", func() {
check(
&wire.ExtendedHeader{
Header: wire.Header{
IsLongHeader: true,
Type: protocol.PacketTypeRetry,
SrcConnectionID: protocol.ConnectionID{0x11, 0x22, 0x33, 0x44},
Version: protocol.VersionNumber(0xdecafbad),
Token: []byte{0xde, 0xad, 0xbe, 0xef},
},
},
map[string]interface{}{
"packet_type": "retry",
"dcil": 0,
"scil": 4,
"scid": "11223344",
"token": map[string]interface{}{"data": "deadbeef"},
"version": "decafbad",
},
)
})
It("marshals a packet with packet number 0", func() {
check(
&wire.ExtendedHeader{

View file

@ -33,12 +33,10 @@ func checkEncoding(data []byte, expected map[string]interface{}) {
ExpectWithOffset(1, m).To(HaveLen(len(expected)))
for key, value := range expected {
switch v := value.(type) {
case string:
case bool, string, map[string]interface{}:
ExpectWithOffset(1, m).To(HaveKeyWithValue(key, v))
case int:
ExpectWithOffset(1, m).To(HaveKeyWithValue(key, float64(v)))
case bool:
ExpectWithOffset(1, m).To(HaveKeyWithValue(key, v))
case [][]float64: // used in the ACK frame
ExpectWithOffset(1, m).To(HaveKey(key))
for i, l := range v {

View file

@ -357,6 +357,7 @@ var _ = Describe("Tracing", func() {
Type: protocol.PacketTypeInitial,
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
SrcConnectionID: protocol.ConnectionID{4, 3, 2, 1},
Token: []byte{0xde, 0xad, 0xbe, 0xef},
Version: protocol.VersionTLS,
},
PacketNumber: 1337,
@ -377,6 +378,9 @@ var _ = Describe("Tracing", func() {
Expect(hdr).To(HaveKeyWithValue("packet_size", float64(789)))
Expect(hdr).To(HaveKeyWithValue("packet_number", float64(1337)))
Expect(hdr).To(HaveKeyWithValue("scid", "04030201"))
Expect(hdr).To(HaveKey("token"))
token := hdr["token"].(map[string]interface{})
Expect(token).To(HaveKeyWithValue("data", "deadbeef"))
Expect(ev).To(HaveKey("frames"))
Expect(ev["frames"].([]interface{})).To(HaveLen(2))
})
@ -388,6 +392,7 @@ var _ = Describe("Tracing", func() {
Type: protocol.PacketTypeRetry,
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
SrcConnectionID: protocol.ConnectionID{4, 3, 2, 1},
Token: []byte{0xde, 0xad, 0xbe, 0xef},
Version: protocol.VersionTLS,
},
)
@ -396,12 +401,15 @@ var _ = Describe("Tracing", func() {
Expect(entry.Name).To(Equal("transport:packet_received"))
ev := entry.Event
Expect(ev).To(HaveKey("header"))
header := ev["header"]
header := ev["header"].(map[string]interface{})
Expect(header).To(HaveKeyWithValue("packet_type", "retry"))
Expect(header).ToNot(HaveKey("packet_number"))
Expect(header).To(HaveKey("version"))
Expect(header).To(HaveKey("dcid"))
Expect(header).To(HaveKey("scid"))
Expect(header).To(HaveKey("token"))
token := header["token"].(map[string]interface{})
Expect(token).To(HaveKeyWithValue("data", "deadbeef"))
Expect(ev).ToNot(HaveKey("frames"))
})

View file

@ -3,7 +3,7 @@ package qlog
import (
"go/ast"
"go/parser"
"go/token"
gotoken "go/token"
"path"
"runtime"
"strconv"
@ -96,7 +96,7 @@ var _ = Describe("Types", func() {
panic("Failed to get current frame")
}
filename := path.Join(path.Dir(thisfile), "../internal/qerr/error_codes.go")
fileAst, err := parser.ParseFile(token.NewFileSet(), filename, nil, 0)
fileAst, err := parser.ParseFile(gotoken.NewFileSet(), filename, nil, 0)
Expect(err).NotTo(HaveOccurred())
constSpecs := fileAst.Decls[2].(*ast.GenDecl).Specs
Expect(len(constSpecs)).To(BeNumerically(">", 4)) // at time of writing