mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
implement the new header format
Currently, we're only sending and accepting packets with matching source and destination connection IDs.
This commit is contained in:
parent
1a035a265c
commit
52d31dd7ef
19 changed files with 527 additions and 344 deletions
|
@ -304,11 +304,16 @@ func (c *client) handlePacket(remoteAddr net.Addr, packet []byte) {
|
|||
}
|
||||
hdr.Raw = packet[:len(packet)-r.Len()]
|
||||
|
||||
if hdr.IsLongHeader && !hdr.DestConnectionID.Equal(hdr.SrcConnectionID) {
|
||||
c.logger.Errorf("receiving packets with different destination and source connection IDs not supported")
|
||||
}
|
||||
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
|
||||
// reject packets with the wrong connection ID
|
||||
if !hdr.OmitConnectionID && !hdr.ConnectionID.Equal(c.connectionID) {
|
||||
// TODO(#1003): add support for server-chosen connection IDs
|
||||
if !hdr.OmitConnectionID && !hdr.DestConnectionID.Equal(c.connectionID) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -316,7 +321,7 @@ func (c *client) handlePacket(remoteAddr net.Addr, packet []byte) {
|
|||
cr := c.conn.RemoteAddr()
|
||||
// check if the remote address and the connection ID match
|
||||
// otherwise this might be an attacker trying to inject a PUBLIC_RESET to kill the connection
|
||||
if cr.Network() != remoteAddr.Network() || cr.String() != remoteAddr.String() || !hdr.ConnectionID.Equal(c.connectionID) {
|
||||
if cr.Network() != remoteAddr.Network() || cr.String() != remoteAddr.String() || !hdr.DestConnectionID.Equal(c.connectionID) {
|
||||
c.logger.Infof("Received a spoofed Public Reset. Ignoring.")
|
||||
return
|
||||
}
|
||||
|
|
|
@ -34,9 +34,10 @@ var _ = Describe("Client", func() {
|
|||
acceptClientVersionPacket := func(connID protocol.ConnectionID) []byte {
|
||||
b := &bytes.Buffer{}
|
||||
err := (&wire.Header{
|
||||
ConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: 1,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: 1,
|
||||
}).Write(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
return b.Bytes()
|
||||
|
@ -293,9 +294,10 @@ var _ = Describe("Client", func() {
|
|||
|
||||
It("recognizes that a packet without VersionFlag means that the server accepted the suggested version", func() {
|
||||
ph := wire.Header{
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
ConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
}
|
||||
b := &bytes.Buffer{}
|
||||
err := ph.Write(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||
|
@ -460,9 +462,10 @@ var _ = Describe("Client", func() {
|
|||
connID2 := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7}
|
||||
Expect(connID).ToNot(Equal(connID2))
|
||||
(&wire.Header{
|
||||
ConnectionID: connID2,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: 1,
|
||||
DestConnectionID: connID2,
|
||||
SrcConnectionID: connID2,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: 1,
|
||||
}).Write(buf, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||
cl.handlePacket(addr, buf.Bytes())
|
||||
Expect(sess.packetCount).To(BeZero())
|
||||
|
@ -589,9 +592,10 @@ var _ = Describe("Client", func() {
|
|||
Context("handling packets", func() {
|
||||
It("handles packets", func() {
|
||||
ph := wire.Header{
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
ConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
}
|
||||
b := &bytes.Buffer{}
|
||||
err := ph.Write(b, protocol.PerspectiveServer, cl.version)
|
||||
|
|
|
@ -25,7 +25,8 @@ var _ = Describe("QUIC Proxy", func() {
|
|||
hdr := wire.Header{
|
||||
PacketNumber: p,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
ConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0, 0, 0x13, 0x37},
|
||||
DestConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0, 0, 0x13, 0x37},
|
||||
SrcConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0, 0, 0x13, 0x37},
|
||||
OmitConnectionID: false,
|
||||
}
|
||||
hdr.Write(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||
|
|
|
@ -10,12 +10,16 @@ import (
|
|||
// Header is the header of a QUIC packet.
|
||||
// It contains fields that are only needed for the gQUIC Public Header and the IETF draft Header.
|
||||
type Header struct {
|
||||
Raw []byte
|
||||
ConnectionID protocol.ConnectionID
|
||||
Raw []byte
|
||||
|
||||
Version protocol.VersionNumber
|
||||
|
||||
DestConnectionID protocol.ConnectionID
|
||||
SrcConnectionID protocol.ConnectionID
|
||||
OmitConnectionID bool
|
||||
PacketNumberLen protocol.PacketNumberLen
|
||||
PacketNumber protocol.PacketNumber
|
||||
Version protocol.VersionNumber // VersionNumber sent by the client
|
||||
|
||||
PacketNumberLen protocol.PacketNumberLen
|
||||
PacketNumber protocol.PacketNumber
|
||||
|
||||
IsVersionNegotiation bool
|
||||
SupportedVersions []protocol.VersionNumber // Version Number sent in a Version Negotiation Packet by the server
|
||||
|
|
|
@ -23,11 +23,12 @@ var _ = Describe("Header", func() {
|
|||
buf := &bytes.Buffer{}
|
||||
// use a Short Header, which isn't distinguishable from the gQUIC Public Header when looking at the type byte
|
||||
err := (&Header{
|
||||
IsLongHeader: false,
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
KeyPhase: 1,
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
IsLongHeader: false,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
KeyPhase: 1,
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
}).writeHeader(buf)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
hdr, err := ParseHeaderSentByClient(bytes.NewReader(buf.Bytes()))
|
||||
|
@ -40,11 +41,12 @@ var _ = Describe("Header", func() {
|
|||
It("parses an IETF draft header, when the version is not known, but it has Long Header format", func() {
|
||||
buf := &bytes.Buffer{}
|
||||
err := (&Header{
|
||||
IsLongHeader: true,
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
Type: protocol.PacketType0RTT,
|
||||
PacketNumber: 0x42,
|
||||
Version: 0x1234,
|
||||
IsLongHeader: true,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
Type: protocol.PacketType0RTT,
|
||||
PacketNumber: 0x42,
|
||||
Version: 0x1234,
|
||||
}).writeHeader(buf)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
hdr, err := ParseHeaderSentByClient(bytes.NewReader(buf.Bytes()))
|
||||
|
@ -59,10 +61,11 @@ var _ = Describe("Header", func() {
|
|||
// make sure this packet could be mistaken for a Version Negotiation Packet, if we only look at the 0x1 bit
|
||||
buf := &bytes.Buffer{}
|
||||
err := (&Header{
|
||||
IsLongHeader: false,
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
PacketNumber: 0x42,
|
||||
IsLongHeader: false,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
PacketNumber: 0x42,
|
||||
}).writeHeader(buf)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
hdr, err := ParseHeaderSentByServer(bytes.NewReader(buf.Bytes()), versionIETFHeader)
|
||||
|
@ -74,16 +77,18 @@ var _ = Describe("Header", func() {
|
|||
connID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
buf := &bytes.Buffer{}
|
||||
err := (&Header{
|
||||
VersionFlag: true,
|
||||
Version: versionPublicHeader,
|
||||
ConnectionID: connID,
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
VersionFlag: true,
|
||||
Version: versionPublicHeader,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
}).writePublicHeader(buf, protocol.PerspectiveClient, versionPublicHeader)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
hdr, err := ParseHeaderSentByClient(bytes.NewReader(buf.Bytes()))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.ConnectionID).To(Equal(connID))
|
||||
Expect(hdr.DestConnectionID).To(Equal(connID))
|
||||
Expect(hdr.SrcConnectionID).To(Equal(connID))
|
||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0x1337)))
|
||||
Expect(hdr.Version).To(Equal(versionPublicHeader))
|
||||
Expect(hdr.isPublicHeader).To(BeTrue())
|
||||
|
@ -93,7 +98,8 @@ var _ = Describe("Header", func() {
|
|||
connID := protocol.ConnectionID{8, 7, 6, 5, 4, 3, 2, 1}
|
||||
buf := &bytes.Buffer{}
|
||||
err := (&Header{
|
||||
ConnectionID: connID,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
DiversificationNonce: bytes.Repeat([]byte{'f'}, 32),
|
||||
|
@ -101,7 +107,8 @@ var _ = Describe("Header", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
hdr, err := ParseHeaderSentByServer(bytes.NewReader(buf.Bytes()), versionPublicHeader)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.ConnectionID).To(Equal(connID))
|
||||
Expect(hdr.DestConnectionID).To(Equal(connID))
|
||||
Expect(hdr.SrcConnectionID).To(Equal(connID))
|
||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0x1337)))
|
||||
Expect(hdr.DiversificationNonce).To(HaveLen(32))
|
||||
Expect(hdr.isPublicHeader).To(BeTrue())
|
||||
|
@ -110,11 +117,12 @@ var _ = Describe("Header", func() {
|
|||
It("errors when parsing the gQUIC header fails", func() {
|
||||
buf := &bytes.Buffer{}
|
||||
err := (&Header{
|
||||
VersionFlag: true,
|
||||
Version: versionPublicHeader,
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
VersionFlag: true,
|
||||
Version: versionPublicHeader,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
}).writePublicHeader(buf, protocol.PerspectiveClient, versionPublicHeader)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = ParseHeaderSentByClient(bytes.NewReader(buf.Bytes()[0:12]))
|
||||
|
@ -135,7 +143,8 @@ var _ = Describe("Header", func() {
|
|||
hdr, err := ParseHeaderSentByServer(bytes.NewReader(data), protocol.VersionUnknown)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.isPublicHeader).To(BeTrue())
|
||||
Expect(hdr.ConnectionID).To(Equal(connID))
|
||||
Expect(hdr.DestConnectionID).To(Equal(connID))
|
||||
Expect(hdr.SrcConnectionID).To(Equal(connID))
|
||||
// in addition to the versions, the supported versions might contain a reserved version number
|
||||
for _, version := range versions {
|
||||
Expect(hdr.SupportedVersions).To(ContainElement(version))
|
||||
|
@ -143,14 +152,17 @@ var _ = Describe("Header", func() {
|
|||
})
|
||||
|
||||
It("parses an IETF draft style Version Negotiation Packet", func() {
|
||||
connID := protocol.ConnectionID{1, 3, 3, 7, 1, 3, 3, 7}
|
||||
destConnID := protocol.ConnectionID{1, 3, 3, 7, 1, 3, 3, 7}
|
||||
srcConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
versions := []protocol.VersionNumber{0x13, 0x37}
|
||||
data := ComposeVersionNegotiation(connID, versions)
|
||||
data, err := ComposeVersionNegotiation(destConnID, srcConnID, versions)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
hdr, err := ParseHeaderSentByServer(bytes.NewReader(data), protocol.VersionUnknown)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.isPublicHeader).To(BeFalse())
|
||||
Expect(hdr.IsVersionNegotiation).To(BeTrue())
|
||||
Expect(hdr.ConnectionID).To(Equal(connID))
|
||||
Expect(hdr.DestConnectionID).To(Equal(destConnID))
|
||||
Expect(hdr.SrcConnectionID).To(Equal(srcConnID))
|
||||
Expect(hdr.Version).To(BeZero())
|
||||
// in addition to the versions, the supported versions might contain a reserved version number
|
||||
for _, version := range versions {
|
||||
|
@ -163,9 +175,10 @@ var _ = Describe("Header", func() {
|
|||
It("writes a gQUIC Public Header", func() {
|
||||
buf := &bytes.Buffer{}
|
||||
hdr := &Header{
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
}
|
||||
err := hdr.Write(buf, protocol.PerspectiveServer, versionPublicHeader)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -177,10 +190,11 @@ var _ = Describe("Header", func() {
|
|||
It("writes a IETF draft header", func() {
|
||||
buf := &bytes.Buffer{}
|
||||
hdr := &Header{
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
KeyPhase: 1,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
KeyPhase: 1,
|
||||
}
|
||||
err := hdr.Write(buf, protocol.PerspectiveServer, versionIETFHeader)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -194,7 +208,8 @@ var _ = Describe("Header", func() {
|
|||
It("get the length of a gQUIC Public Header", func() {
|
||||
buf := &bytes.Buffer{}
|
||||
hdr := &Header{
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
DiversificationNonce: bytes.Repeat([]byte{'f'}, 32),
|
||||
|
@ -214,11 +229,12 @@ var _ = Describe("Header", func() {
|
|||
It("get the length of a a IETF draft header", func() {
|
||||
buf := &bytes.Buffer{}
|
||||
hdr := &Header{
|
||||
IsLongHeader: true,
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
KeyPhase: 1,
|
||||
IsLongHeader: true,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
KeyPhase: 1,
|
||||
}
|
||||
err := hdr.Write(buf, protocol.PerspectiveServer, versionIETFHeader)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -252,16 +268,18 @@ var _ = Describe("Header", func() {
|
|||
|
||||
It("logs an IETF draft header", func() {
|
||||
(&Header{
|
||||
IsLongHeader: true,
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
IsLongHeader: true,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
}).Log(logger)
|
||||
Expect(buf.String()).To(ContainSubstring("Long Header"))
|
||||
})
|
||||
|
||||
It("logs a Public Header", func() {
|
||||
(&Header{
|
||||
isPublicHeader: true,
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
isPublicHeader: true,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
}).Log(logger)
|
||||
Expect(buf.String()).To(ContainSubstring("Public Header"))
|
||||
})
|
||||
|
|
|
@ -25,21 +25,42 @@ func parseHeader(b *bytes.Reader, packetSentBy protocol.Perspective) (*Header, e
|
|||
|
||||
// parse long header and version negotiation packets
|
||||
func parseLongHeader(b *bytes.Reader, sentBy protocol.Perspective, typeByte byte) (*Header, error) {
|
||||
connID := make(protocol.ConnectionID, 8)
|
||||
if _, err := io.ReadFull(b, connID); err != nil {
|
||||
if err == io.ErrUnexpectedEOF {
|
||||
err = io.EOF
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
v, err := utils.BigEndian.ReadUint32(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h := &Header{
|
||||
ConnectionID: connID,
|
||||
Version: protocol.VersionNumber(v),
|
||||
|
||||
connIDLenByte, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dcil, scil := decodeConnIDLen(connIDLenByte)
|
||||
var destConnID, srcConnID protocol.ConnectionID
|
||||
if dcil > 0 {
|
||||
destConnID = make(protocol.ConnectionID, dcil)
|
||||
if _, err := io.ReadFull(b, destConnID); err != nil {
|
||||
if err == io.ErrUnexpectedEOF {
|
||||
err = io.EOF
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if scil > 0 {
|
||||
srcConnID = make(protocol.ConnectionID, scil)
|
||||
if _, err := io.ReadFull(b, srcConnID); err != nil {
|
||||
if err == io.ErrUnexpectedEOF {
|
||||
err = io.EOF
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
h := &Header{
|
||||
Version: protocol.VersionNumber(v),
|
||||
DestConnectionID: destConnID,
|
||||
SrcConnectionID: srcConnID,
|
||||
}
|
||||
|
||||
if v == 0 { // version negotiation packet
|
||||
if sentBy == protocol.PerspectiveClient {
|
||||
return nil, qerr.InvalidVersion
|
||||
|
@ -58,6 +79,7 @@ func parseLongHeader(b *bytes.Reader, sentBy protocol.Perspective, typeByte byte
|
|||
}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
h.IsLongHeader = true
|
||||
pn, err := utils.BigEndian.ReadUint32(b)
|
||||
if err != nil {
|
||||
|
@ -76,22 +98,19 @@ func parseLongHeader(b *bytes.Reader, sentBy protocol.Perspective, typeByte byte
|
|||
}
|
||||
|
||||
func parseShortHeader(b *bytes.Reader, typeByte byte) (*Header, error) {
|
||||
omitConnID := typeByte&0x40 > 0
|
||||
connID := make(protocol.ConnectionID, 8)
|
||||
if !omitConnID {
|
||||
if _, err := io.ReadFull(b, connID); err != nil {
|
||||
if err == io.ErrUnexpectedEOF {
|
||||
err = io.EOF
|
||||
}
|
||||
return nil, err
|
||||
if _, err := io.ReadFull(b, connID); err != nil {
|
||||
if err == io.ErrUnexpectedEOF {
|
||||
err = io.EOF
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
// bit 4 must be set, bit 5 must be unset
|
||||
if typeByte&0x18 != 0x10 {
|
||||
return nil, errors.New("invalid bit 4 and 5")
|
||||
// bits 2 and 3 must be set, bit 4 must be unset
|
||||
if typeByte&0x38 != 0x30 {
|
||||
return nil, errors.New("invalid bits 3, 4 and 5")
|
||||
}
|
||||
var pnLen protocol.PacketNumberLen
|
||||
switch typeByte & 0x7 {
|
||||
switch typeByte & 0x3 {
|
||||
case 0x0:
|
||||
pnLen = protocol.PacketNumberLen1
|
||||
case 0x1:
|
||||
|
@ -106,9 +125,8 @@ func parseShortHeader(b *bytes.Reader, typeByte byte) (*Header, error) {
|
|||
return nil, err
|
||||
}
|
||||
return &Header{
|
||||
KeyPhase: int(typeByte&0x20) >> 5,
|
||||
OmitConnectionID: omitConnID,
|
||||
ConnectionID: connID,
|
||||
KeyPhase: int(typeByte&0x40) >> 6,
|
||||
DestConnectionID: connID,
|
||||
PacketNumber: protocol.PacketNumber(pn),
|
||||
PacketNumberLen: pnLen,
|
||||
}, nil
|
||||
|
@ -124,33 +142,40 @@ func (h *Header) writeHeader(b *bytes.Buffer) error {
|
|||
|
||||
// TODO: add support for the key phase
|
||||
func (h *Header) writeLongHeader(b *bytes.Buffer) error {
|
||||
if !h.DestConnectionID.Equal(h.SrcConnectionID) {
|
||||
return errors.New("Header: can't write a header with different source and destination connection ID")
|
||||
}
|
||||
if len(h.SrcConnectionID) != 8 {
|
||||
return fmt.Errorf("Header: source connection ID must be 8 bytes, is %d", len(h.SrcConnectionID))
|
||||
}
|
||||
b.WriteByte(byte(0x80 | h.Type))
|
||||
b.Write(h.ConnectionID)
|
||||
utils.BigEndian.WriteUint32(b, uint32(h.Version))
|
||||
connIDLen, err := encodeConnIDLen(h.DestConnectionID, h.SrcConnectionID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.WriteByte(connIDLen)
|
||||
b.Write(h.DestConnectionID)
|
||||
b.Write(h.SrcConnectionID)
|
||||
utils.BigEndian.WriteUint32(b, uint32(h.PacketNumber))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Header) writeShortHeader(b *bytes.Buffer) error {
|
||||
typeByte := byte(0x10)
|
||||
typeByte ^= byte(h.KeyPhase << 5)
|
||||
if h.OmitConnectionID {
|
||||
typeByte ^= 0x40
|
||||
}
|
||||
typeByte := byte(0x30)
|
||||
typeByte |= byte(h.KeyPhase << 6)
|
||||
switch h.PacketNumberLen {
|
||||
case protocol.PacketNumberLen1:
|
||||
case protocol.PacketNumberLen2:
|
||||
typeByte ^= 0x1
|
||||
typeByte |= 0x1
|
||||
case protocol.PacketNumberLen4:
|
||||
typeByte ^= 0x2
|
||||
typeByte |= 0x2
|
||||
default:
|
||||
return fmt.Errorf("invalid packet number length: %d", h.PacketNumberLen)
|
||||
}
|
||||
b.WriteByte(typeByte)
|
||||
|
||||
if !h.OmitConnectionID {
|
||||
b.Write(h.ConnectionID)
|
||||
}
|
||||
b.Write(h.DestConnectionID)
|
||||
switch h.PacketNumberLen {
|
||||
case protocol.PacketNumberLen1:
|
||||
b.WriteByte(uint8(h.PacketNumber))
|
||||
|
@ -165,13 +190,10 @@ func (h *Header) writeShortHeader(b *bytes.Buffer) error {
|
|||
// getHeaderLength gets the length of the Header in bytes.
|
||||
func (h *Header) getHeaderLength() (protocol.ByteCount, error) {
|
||||
if h.IsLongHeader {
|
||||
return 1 + 8 + 4 + 4, nil
|
||||
return 1 /* type byte */ + 4 /* version */ + 1 /* conn id len byte */ + protocol.ByteCount(len(h.DestConnectionID)+len(h.SrcConnectionID)) + 4 /* packet number */, nil
|
||||
}
|
||||
|
||||
length := protocol.ByteCount(1) // type byte
|
||||
if !h.OmitConnectionID {
|
||||
length += 8
|
||||
}
|
||||
length := protocol.ByteCount(1 /* type byte */ + len(h.DestConnectionID))
|
||||
if h.PacketNumberLen != protocol.PacketNumberLen1 && h.PacketNumberLen != protocol.PacketNumberLen2 && h.PacketNumberLen != protocol.PacketNumberLen4 {
|
||||
return 0, fmt.Errorf("invalid packet number length: %d", h.PacketNumberLen)
|
||||
}
|
||||
|
@ -181,12 +203,41 @@ func (h *Header) getHeaderLength() (protocol.ByteCount, error) {
|
|||
|
||||
func (h *Header) logHeader(logger utils.Logger) {
|
||||
if h.IsLongHeader {
|
||||
logger.Debugf(" Long Header{Type: %s, ConnectionID: %#x, PacketNumber: %#x, Version: %s}", h.Type, h.ConnectionID, h.PacketNumber, h.Version)
|
||||
logger.Debugf(" Long Header{Type: %s, DestConnectionID: %#x, SrcConnectionID: %#x, PacketNumber: %#x, Version: %s}", h.Type, h.DestConnectionID, h.SrcConnectionID, h.PacketNumber, h.Version)
|
||||
} else {
|
||||
connID := "(omitted)"
|
||||
if !h.OmitConnectionID {
|
||||
connID = fmt.Sprintf("%#x", h.ConnectionID)
|
||||
}
|
||||
logger.Debugf(" Short Header{ConnectionID: %s, PacketNumber: %#x, PacketNumberLen: %d, KeyPhase: %d}", connID, h.PacketNumber, h.PacketNumberLen, h.KeyPhase)
|
||||
logger.Debugf(" Short Header{DestConnectionID: %#x, PacketNumber: %#x, PacketNumberLen: %d, KeyPhase: %d}", h.DestConnectionID, h.PacketNumber, h.PacketNumberLen, h.KeyPhase)
|
||||
}
|
||||
}
|
||||
|
||||
func encodeConnIDLen(dest, src protocol.ConnectionID) (byte, error) {
|
||||
dcil, err := encodeSingleConnIDLen(dest)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
scil, err := encodeSingleConnIDLen(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return scil | dcil<<4, nil
|
||||
}
|
||||
|
||||
func encodeSingleConnIDLen(id protocol.ConnectionID) (byte, error) {
|
||||
if len(id) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if len(id) < 4 || len(id) > 18 {
|
||||
return 0, errors.New("invalid connection ID length")
|
||||
}
|
||||
return byte(len(id) - 3), nil
|
||||
}
|
||||
|
||||
func decodeConnIDLen(enc byte) (int /*dest conn id len*/, int /*src conn id len*/) {
|
||||
return decodeSingleConnIDLen(enc >> 4), decodeSingleConnIDLen(enc & 0xf)
|
||||
}
|
||||
|
||||
func decodeSingleConnIDLen(enc uint8) int {
|
||||
if enc == 0 {
|
||||
return 0
|
||||
}
|
||||
return int(enc) + 3
|
||||
}
|
||||
|
|
|
@ -15,19 +15,21 @@ import (
|
|||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("IETF draft Header", func() {
|
||||
var _ = Describe("IETF QUIC Header", func() {
|
||||
Context("parsing", func() {
|
||||
Context("Version Negotiation Packets", func() {
|
||||
It("parses", func() {
|
||||
connID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
versions := []protocol.VersionNumber{0x22334455, 0x33445566}
|
||||
data := ComposeVersionNegotiation(connID, versions)
|
||||
data, err := ComposeVersionNegotiation(connID, connID, versions)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
b := bytes.NewReader(data)
|
||||
h, err := parseHeader(b, protocol.PerspectiveServer)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(h.IsVersionNegotiation).To(BeTrue())
|
||||
Expect(h.Version).To(BeZero())
|
||||
Expect(h.ConnectionID).To(Equal(connID))
|
||||
Expect(h.DestConnectionID).To(Equal(connID))
|
||||
Expect(h.SrcConnectionID).To(Equal(connID))
|
||||
for _, v := range versions {
|
||||
Expect(h.SupportedVersions).To(ContainElement(v))
|
||||
}
|
||||
|
@ -36,18 +38,20 @@ var _ = Describe("IETF draft Header", func() {
|
|||
It("errors if it contains versions of the wrong length", func() {
|
||||
connID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
versions := []protocol.VersionNumber{0x22334455, 0x33445566}
|
||||
data := ComposeVersionNegotiation(connID, versions)
|
||||
data, err := ComposeVersionNegotiation(connID, connID, versions)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
b := bytes.NewReader(data[:len(data)-2])
|
||||
_, err := parseHeader(b, protocol.PerspectiveServer)
|
||||
_, err = parseHeader(b, protocol.PerspectiveServer)
|
||||
Expect(err).To(MatchError(qerr.InvalidVersionNegotiationPacket))
|
||||
})
|
||||
|
||||
It("errors if the version list is empty", func() {
|
||||
connID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
versions := []protocol.VersionNumber{0x22334455}
|
||||
data := ComposeVersionNegotiation(connID, versions)
|
||||
data, err := ComposeVersionNegotiation(connID, connID, versions)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
// remove 8 bytes (two versions), since ComposeVersionNegotiation also added a reserved version number
|
||||
_, err := parseHeader(bytes.NewReader(data[:len(data)-8]), protocol.PerspectiveServer)
|
||||
_, err = parseHeader(bytes.NewReader(data[:len(data)-8]), protocol.PerspectiveServer)
|
||||
Expect(err).To(MatchError("InvalidVersionNegotiationPacket: empty version list"))
|
||||
})
|
||||
})
|
||||
|
@ -56,8 +60,10 @@ var _ = Describe("IETF draft Header", func() {
|
|||
generatePacket := func(t protocol.PacketType) []byte {
|
||||
return []byte{
|
||||
0x80 ^ uint8(t),
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0x1, 0x2, 0x3, 0x4, // version number
|
||||
0x55, // connection ID lengths
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // destination connection ID
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // source connection ID
|
||||
0xde, 0xca, 0xfb, 0xad, // packet number
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +75,8 @@ var _ = Describe("IETF draft Header", func() {
|
|||
Expect(h.Type).To(Equal(protocol.PacketTypeInitial))
|
||||
Expect(h.IsLongHeader).To(BeTrue())
|
||||
Expect(h.OmitConnectionID).To(BeFalse())
|
||||
Expect(h.ConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}))
|
||||
Expect(h.DestConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}))
|
||||
Expect(h.SrcConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}))
|
||||
Expect(h.PacketNumber).To(Equal(protocol.PacketNumber(0xdecafbad)))
|
||||
Expect(h.PacketNumberLen).To(Equal(protocol.PacketNumberLen4))
|
||||
Expect(h.Version).To(Equal(protocol.VersionNumber(0x1020304)))
|
||||
|
@ -98,8 +105,10 @@ var _ = Describe("IETF draft Header", func() {
|
|||
It("rejects version 0 for packets sent by the client", func() {
|
||||
data := []byte{
|
||||
0x80 ^ uint8(protocol.PacketTypeInitial),
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0x0, 0x0, 0x0, 0x0, // version number
|
||||
0x55,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // dest connection ID
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // src connection ID
|
||||
0xde, 0xca, 0xfb, 0xad, // packet number
|
||||
}
|
||||
_, err := parseHeader(bytes.NewReader(data), protocol.PerspectiveClient)
|
||||
|
@ -118,7 +127,7 @@ var _ = Describe("IETF draft Header", func() {
|
|||
Context("short headers", func() {
|
||||
It("reads a short header with a connection ID", func() {
|
||||
data := []byte{
|
||||
0x10, // 1 byte packet number
|
||||
0x30, // 1 byte packet number
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0x42, // packet number
|
||||
}
|
||||
|
@ -128,7 +137,8 @@ var _ = Describe("IETF draft Header", func() {
|
|||
Expect(h.IsLongHeader).To(BeFalse())
|
||||
Expect(h.KeyPhase).To(Equal(0))
|
||||
Expect(h.OmitConnectionID).To(BeFalse())
|
||||
Expect(h.ConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}))
|
||||
Expect(h.DestConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}))
|
||||
Expect(h.SrcConnectionID).To(BeEmpty())
|
||||
Expect(h.PacketNumber).To(Equal(protocol.PacketNumber(0x42)))
|
||||
Expect(h.IsVersionNegotiation).To(BeFalse())
|
||||
Expect(b.Len()).To(BeZero())
|
||||
|
@ -136,7 +146,8 @@ var _ = Describe("IETF draft Header", func() {
|
|||
|
||||
It("reads the Key Phase Bit", func() {
|
||||
data := []byte{
|
||||
0x10 ^ 0x40 ^ 0x20,
|
||||
0x30 ^ 0x40,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0x11,
|
||||
}
|
||||
b := bytes.NewReader(data)
|
||||
|
@ -147,24 +158,10 @@ var _ = Describe("IETF draft Header", func() {
|
|||
Expect(b.Len()).To(BeZero())
|
||||
})
|
||||
|
||||
It("reads a header with omitted connection ID", func() {
|
||||
data := []byte{
|
||||
0x10 ^ 0x40,
|
||||
0x21, // packet number
|
||||
}
|
||||
b := bytes.NewReader(data)
|
||||
h, err := parseHeader(b, protocol.PerspectiveClient)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(h.IsLongHeader).To(BeFalse())
|
||||
Expect(h.OmitConnectionID).To(BeTrue())
|
||||
Expect(h.PacketNumber).To(Equal(protocol.PacketNumber(0x21)))
|
||||
Expect(h.PacketNumberLen).To(Equal(protocol.PacketNumberLen1))
|
||||
Expect(b.Len()).To(BeZero())
|
||||
})
|
||||
|
||||
It("reads a header with a 2 byte packet number", func() {
|
||||
data := []byte{
|
||||
0x10 ^ 0x40 ^ 0x1,
|
||||
0x30 ^ 0x40 ^ 0x1,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0x13, 0x37, // packet number
|
||||
}
|
||||
b := bytes.NewReader(data)
|
||||
|
@ -178,7 +175,8 @@ var _ = Describe("IETF draft Header", func() {
|
|||
|
||||
It("reads a header with a 4 byte packet number", func() {
|
||||
data := []byte{
|
||||
0x10 ^ 0x40 ^ 0x2,
|
||||
0x30 ^ 0x40 ^ 0x2,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0xde, 0xad, 0xbe, 0xef, // packet number
|
||||
}
|
||||
b := bytes.NewReader(data)
|
||||
|
@ -190,9 +188,31 @@ var _ = Describe("IETF draft Header", func() {
|
|||
Expect(b.Len()).To(BeZero())
|
||||
})
|
||||
|
||||
It("rejects headers that have an invalid type", func() {
|
||||
data := []byte{
|
||||
0x30 ^ 0x40 ^ 0x3,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0xde, 0xad, 0xbe, 0xef, // packet number
|
||||
}
|
||||
b := bytes.NewReader(data)
|
||||
_, err := parseHeader(b, protocol.PerspectiveClient)
|
||||
Expect(err).To(MatchError("invalid short header type"))
|
||||
})
|
||||
|
||||
It("rejects headers that have bit 3,4 and 5 set incorrectly", func() {
|
||||
data := []byte{
|
||||
0x38 ^ 0x2,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0xde, 0xca, 0xfb, 0xad, // packet number
|
||||
}
|
||||
b := bytes.NewReader(data)
|
||||
_, err := parseHeader(b, protocol.PerspectiveClient)
|
||||
Expect(err).To(MatchError("invalid bits 3, 4 and 5"))
|
||||
})
|
||||
|
||||
It("errors on EOF", func() {
|
||||
data := []byte{
|
||||
0x10 ^ 0x2,
|
||||
0x30 ^ 0x2,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0xde, 0xca, 0xfb, 0xad, // packet number
|
||||
}
|
||||
|
@ -214,32 +234,44 @@ var _ = Describe("IETF draft Header", func() {
|
|||
Context("long header", func() {
|
||||
It("writes", func() {
|
||||
err := (&Header{
|
||||
IsLongHeader: true,
|
||||
Type: 0x5,
|
||||
ConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37},
|
||||
PacketNumber: 0xdecafbad,
|
||||
Version: 0x1020304,
|
||||
IsLongHeader: true,
|
||||
Type: 0x5,
|
||||
DestConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37},
|
||||
SrcConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37},
|
||||
PacketNumber: 0xdecafbad,
|
||||
Version: 0x1020304,
|
||||
}).writeHeader(buf)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(buf.Bytes()).To(Equal([]byte{
|
||||
0x80 ^ 0x5,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0x1, 0x2, 0x3, 0x4, // version number
|
||||
0x55, // connection ID lengths
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0xde, 0xca, 0xfb, 0xad, // packet number
|
||||
}))
|
||||
})
|
||||
|
||||
It("refuses to write headers with unequal destination and source connection IDs", func() {
|
||||
err := (&Header{
|
||||
IsLongHeader: true,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{8, 7, 6, 5, 4, 3, 2, 1},
|
||||
}).writeHeader(buf)
|
||||
Expect(err).To(MatchError("Header: can't write a header with different source and destination connection ID"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("short header", func() {
|
||||
It("writes a header with connection ID", func() {
|
||||
err := (&Header{
|
||||
ConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37},
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
PacketNumber: 0x42,
|
||||
DestConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37},
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
PacketNumber: 0x42,
|
||||
}).writeHeader(buf)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(buf.Bytes()).To(Equal([]byte{
|
||||
0x10,
|
||||
0x30,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
|
||||
0x42, // packet number
|
||||
}))
|
||||
|
@ -247,13 +279,12 @@ var _ = Describe("IETF draft Header", func() {
|
|||
|
||||
It("writes a header without connection ID", func() {
|
||||
err := (&Header{
|
||||
OmitConnectionID: true,
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
PacketNumber: 0x42,
|
||||
}).writeHeader(buf)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(buf.Bytes()).To(Equal([]byte{
|
||||
0x10 ^ 0x40,
|
||||
0x30,
|
||||
0x42, // packet number
|
||||
}))
|
||||
})
|
||||
|
@ -266,7 +297,7 @@ var _ = Describe("IETF draft Header", func() {
|
|||
}).writeHeader(buf)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(buf.Bytes()).To(Equal([]byte{
|
||||
0x10 ^ 0x40 ^ 0x1,
|
||||
0x30 | 0x1,
|
||||
0x13, 0x37, // packet number
|
||||
}))
|
||||
})
|
||||
|
@ -279,7 +310,7 @@ var _ = Describe("IETF draft Header", func() {
|
|||
}).writeHeader(buf)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(buf.Bytes()).To(Equal([]byte{
|
||||
0x10 ^ 0x40 ^ 0x2,
|
||||
0x30 | 0x2,
|
||||
0xde, 0xca, 0xfb, 0xad, // packet number
|
||||
}))
|
||||
})
|
||||
|
@ -302,7 +333,7 @@ var _ = Describe("IETF draft Header", func() {
|
|||
}).writeHeader(buf)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(buf.Bytes()).To(Equal([]byte{
|
||||
0x10 ^ 0x40 ^ 0x20,
|
||||
0x30 | 0x40,
|
||||
0x42, // packet number
|
||||
}))
|
||||
})
|
||||
|
@ -318,19 +349,21 @@ var _ = Describe("IETF draft Header", func() {
|
|||
|
||||
It("has the right length for the long header", func() {
|
||||
h := &Header{
|
||||
IsLongHeader: true,
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
IsLongHeader: true,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
}
|
||||
Expect(h.getHeaderLength()).To(Equal(protocol.ByteCount(17)))
|
||||
expectedLen := 1 /* type byte */ + 4 /* version */ + 1 /* conn ID len */ + 8 /* dest conn id */ + 8 /* src conn id */ + 4 /* packet number */
|
||||
Expect(h.getHeaderLength()).To(BeEquivalentTo(expectedLen))
|
||||
err := h.writeHeader(buf)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(buf.Len()).To(Equal(17))
|
||||
Expect(buf.Len()).To(Equal(expectedLen))
|
||||
})
|
||||
|
||||
It("has the right length for a short header containing a connection ID", func() {
|
||||
h := &Header{
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
}
|
||||
Expect(h.getHeaderLength()).To(Equal(protocol.ByteCount(1 + 8 + 1)))
|
||||
err := h.writeHeader(buf)
|
||||
|
@ -397,33 +430,24 @@ var _ = Describe("IETF draft Header", func() {
|
|||
|
||||
It("logs Long Headers", func() {
|
||||
(&Header{
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeHandshake,
|
||||
PacketNumber: 0x1337,
|
||||
ConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37},
|
||||
Version: 0xfeed,
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeHandshake,
|
||||
PacketNumber: 0x1337,
|
||||
DestConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37},
|
||||
SrcConnectionID: protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad, 0x013, 0x37, 0x13, 0x37},
|
||||
Version: 0xfeed,
|
||||
}).logHeader(logger)
|
||||
Expect(buf.String()).To(ContainSubstring("Long Header{Type: Handshake, ConnectionID: 0xdeadbeefcafe1337, PacketNumber: 0x1337, Version: 0xfeed}"))
|
||||
Expect(buf.String()).To(ContainSubstring("Long Header{Type: Handshake, DestConnectionID: 0xdeadbeefcafe1337, SrcConnectionID: 0xdecafbad13371337, PacketNumber: 0x1337, Version: 0xfeed}"))
|
||||
})
|
||||
|
||||
It("logs Short Headers containing a connection ID", func() {
|
||||
(&Header{
|
||||
KeyPhase: 1,
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: 4,
|
||||
ConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37},
|
||||
KeyPhase: 1,
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: 4,
|
||||
DestConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37},
|
||||
}).logHeader(logger)
|
||||
Expect(buf.String()).To(ContainSubstring("Short Header{ConnectionID: 0xdeadbeefcafe1337, PacketNumber: 0x1337, PacketNumberLen: 4, KeyPhase: 1}"))
|
||||
})
|
||||
|
||||
It("logs Short Headers with omitted connection ID", func() {
|
||||
(&Header{
|
||||
PacketNumber: 0x12,
|
||||
PacketNumberLen: 1,
|
||||
OmitConnectionID: true,
|
||||
ConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37},
|
||||
}).logHeader(logger)
|
||||
Expect(buf.String()).To(ContainSubstring("Short Header{ConnectionID: (omitted), PacketNumber: 0x12, PacketNumberLen: 1, KeyPhase: 0}"))
|
||||
Expect(buf.String()).To(ContainSubstring("Short Header{DestConnectionID: 0xdeadbeefcafe1337, PacketNumber: 0x1337, PacketNumberLen: 4, KeyPhase: 1}"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -26,8 +26,11 @@ func (h *Header) writePublicHeader(b *bytes.Buffer, pers protocol.Perspective, _
|
|||
if h.VersionFlag && h.ResetFlag {
|
||||
return errResetAndVersionFlagSet
|
||||
}
|
||||
if len(h.ConnectionID) != 8 {
|
||||
return fmt.Errorf("PublicHeader: wrong length for Connection ID: %d (expected 8)", len(h.ConnectionID))
|
||||
if !h.DestConnectionID.Equal(h.SrcConnectionID) {
|
||||
return fmt.Errorf("PublicHeader: SrcConnectionID must be equal to DestConnectionID")
|
||||
}
|
||||
if len(h.DestConnectionID) != 8 {
|
||||
return fmt.Errorf("PublicHeader: wrong length for Connection ID: %d (expected 8)", len(h.DestConnectionID))
|
||||
}
|
||||
|
||||
publicFlagByte := uint8(0x00)
|
||||
|
@ -62,7 +65,7 @@ func (h *Header) writePublicHeader(b *bytes.Buffer, pers protocol.Perspective, _
|
|||
b.WriteByte(publicFlagByte)
|
||||
|
||||
if !h.OmitConnectionID {
|
||||
b.Write(h.ConnectionID)
|
||||
b.Write(h.DestConnectionID)
|
||||
}
|
||||
if h.VersionFlag && pers == protocol.PerspectiveClient {
|
||||
utils.BigEndian.WriteUint32(b, uint32(h.Version))
|
||||
|
@ -139,8 +142,8 @@ func parsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective) (*Hea
|
|||
if connID[0] == 0 && connID[1] == 0 && connID[2] == 0 && connID[3] == 0 && connID[4] == 0 && connID[5] == 0 && connID[6] == 0 && connID[7] == 0 {
|
||||
return nil, errInvalidConnectionID
|
||||
}
|
||||
header.ConnectionID = connID
|
||||
|
||||
header.DestConnectionID = connID
|
||||
header.SrcConnectionID = connID
|
||||
}
|
||||
|
||||
// Contrary to what the gQUIC wire spec says, the 0x4 bit only indicates the presence of the diversification nonce for packets sent by the server.
|
||||
|
@ -240,7 +243,7 @@ func (h *Header) hasPacketNumber(packetSentBy protocol.Perspective) bool {
|
|||
func (h *Header) logPublicHeader(logger utils.Logger) {
|
||||
connID := "(omitted)"
|
||||
if !h.OmitConnectionID {
|
||||
connID = fmt.Sprintf("%#x", h.ConnectionID)
|
||||
connID = fmt.Sprintf("%#x", h.DestConnectionID)
|
||||
}
|
||||
ver := "(unset)"
|
||||
if h.Version != 0 {
|
||||
|
|
|
@ -14,6 +14,8 @@ import (
|
|||
)
|
||||
|
||||
var _ = Describe("Public Header", func() {
|
||||
connID := protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6}
|
||||
|
||||
Context("when parsing", func() {
|
||||
It("accepts a sample client header", func() {
|
||||
ver := make([]byte, 4)
|
||||
|
@ -24,7 +26,9 @@ var _ = Describe("Public Header", func() {
|
|||
Expect(hdr.VersionFlag).To(BeTrue())
|
||||
Expect(hdr.IsVersionNegotiation).To(BeFalse())
|
||||
Expect(hdr.ResetFlag).To(BeFalse())
|
||||
Expect(hdr.ConnectionID).To(Equal(protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6}))
|
||||
connID := protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6}
|
||||
Expect(hdr.DestConnectionID).To(Equal(connID))
|
||||
Expect(hdr.SrcConnectionID).To(Equal(connID))
|
||||
Expect(hdr.Version).To(Equal(protocol.SupportedVersions[0]))
|
||||
Expect(hdr.SupportedVersions).To(BeEmpty())
|
||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||
|
@ -37,12 +41,13 @@ var _ = Describe("Public Header", func() {
|
|||
Expect(err).To(MatchError(errReceivedOmittedConnectionID))
|
||||
})
|
||||
|
||||
It("accepts aan d connection ID as a client", func() {
|
||||
It("accepts an omitted connection ID as a client", func() {
|
||||
b := bytes.NewReader([]byte{0x00, 0x01})
|
||||
hdr, err := parsePublicHeader(b, protocol.PerspectiveServer)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.OmitConnectionID).To(BeTrue())
|
||||
Expect(hdr.ConnectionID).To(BeEmpty())
|
||||
Expect(hdr.DestConnectionID).To(BeEmpty())
|
||||
Expect(hdr.SrcConnectionID).To(BeEmpty())
|
||||
Expect(b.Len()).To(BeZero())
|
||||
})
|
||||
|
||||
|
@ -52,14 +57,6 @@ var _ = Describe("Public Header", func() {
|
|||
Expect(err).To(MatchError(errInvalidConnectionID))
|
||||
})
|
||||
|
||||
It("reads a PUBLIC_RESET packet", func() {
|
||||
b := bytes.NewReader([]byte{0xa, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8})
|
||||
hdr, err := parsePublicHeader(b, protocol.PerspectiveServer)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.ResetFlag).To(BeTrue())
|
||||
Expect(hdr.ConnectionID).ToNot(BeEmpty())
|
||||
})
|
||||
|
||||
It("parses a PUBLIC_RESET packet", func() {
|
||||
b := bytes.NewReader([]byte{0xa, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8})
|
||||
hdr, err := parsePublicHeader(b, protocol.PerspectiveServer)
|
||||
|
@ -67,7 +64,9 @@ var _ = Describe("Public Header", func() {
|
|||
Expect(hdr.ResetFlag).To(BeTrue())
|
||||
Expect(hdr.VersionFlag).To(BeFalse())
|
||||
Expect(hdr.IsVersionNegotiation).To(BeFalse())
|
||||
Expect(hdr.ConnectionID).To(Equal(protocol.ConnectionID{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}))
|
||||
connID := protocol.ConnectionID{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}
|
||||
Expect(hdr.SrcConnectionID).To(Equal(connID))
|
||||
Expect(hdr.DestConnectionID).To(Equal(connID))
|
||||
})
|
||||
|
||||
It("reads a diversification nonce sent by the server", func() {
|
||||
|
@ -76,7 +75,8 @@ var _ = Describe("Public Header", func() {
|
|||
b := bytes.NewReader(append(append([]byte{0x0c, 0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c}, divNonce...), 0x37))
|
||||
hdr, err := parsePublicHeader(b, protocol.PerspectiveServer)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.ConnectionID).To(Not(BeEmpty()))
|
||||
Expect(hdr.DestConnectionID).ToNot(BeEmpty())
|
||||
Expect(hdr.SrcConnectionID).ToNot(BeEmpty())
|
||||
Expect(hdr.DiversificationNonce).To(Equal(divNonce))
|
||||
Expect(b.Len()).To(BeZero())
|
||||
})
|
||||
|
@ -94,7 +94,8 @@ var _ = Describe("Public Header", func() {
|
|||
b := bytes.NewReader(ComposeGQUICVersionNegotiation(connID, versions))
|
||||
hdr, err := parsePublicHeader(b, protocol.PerspectiveServer)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.ConnectionID).To(Equal(connID))
|
||||
Expect(hdr.DestConnectionID).To(Equal(connID))
|
||||
Expect(hdr.SrcConnectionID).To(Equal(connID))
|
||||
Expect(hdr.VersionFlag).To(BeTrue())
|
||||
Expect(hdr.Version).To(BeZero()) // unitialized
|
||||
Expect(hdr.IsVersionNegotiation).To(BeTrue())
|
||||
|
@ -177,9 +178,10 @@ var _ = Describe("Public Header", func() {
|
|||
It("writes a sample header as a server", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 2,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 2,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -189,20 +191,35 @@ var _ = Describe("Public Header", func() {
|
|||
It("writes a sample header as a client", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveClient, versionBigEndian)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(b.Bytes()).To(Equal([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x13, 0x37}))
|
||||
})
|
||||
|
||||
It("refuses to write a Public Header if the connection ID has the wrong length", func() {
|
||||
It("refuses to write a Public Header if the source and destination connection IDs are not matching", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7},
|
||||
PacketNumber: 2,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{8, 7, 6, 5, 4, 3, 2, 1},
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveClient, versionBigEndian)
|
||||
Expect(err).To(MatchError("PublicHeader: SrcConnectionID must be equal to DestConnectionID"))
|
||||
})
|
||||
|
||||
It("refuses to write a Public Header if the connection ID has the wrong length", func() {
|
||||
connID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7}
|
||||
hdr := Header{
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 2,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
}
|
||||
b := &bytes.Buffer{}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||
|
@ -210,9 +227,11 @@ var _ = Describe("Public Header", func() {
|
|||
})
|
||||
|
||||
It("refuses to write a Public Header if the PacketNumberLen is not set", func() {
|
||||
connID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
PacketNumber: 2,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 2,
|
||||
}
|
||||
b := &bytes.Buffer{}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||
|
@ -220,9 +239,11 @@ var _ = Describe("Public Header", func() {
|
|||
})
|
||||
|
||||
It("omits the connection ID", func() {
|
||||
connID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
OmitConnectionID: true,
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
PacketNumber: 1,
|
||||
|
@ -235,7 +256,8 @@ var _ = Describe("Public Header", func() {
|
|||
It("writes diversification nonces", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
DiversificationNonce: bytes.Repeat([]byte{1}, 32),
|
||||
|
@ -262,10 +284,11 @@ var _ = Describe("Public Header", func() {
|
|||
It("doesn't write Version Negotiation Packets", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
VersionFlag: true,
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 2,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
VersionFlag: true,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 2,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||
Expect(err).To(MatchError("PublicHeader: Writing of Version Negotiation Packets not supported"))
|
||||
|
@ -274,11 +297,12 @@ var _ = Describe("Public Header", func() {
|
|||
It("writes packets with Version Flag, as a client", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
VersionFlag: true,
|
||||
Version: protocol.Version39,
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
VersionFlag: true,
|
||||
Version: protocol.Version39,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0x42,
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveClient, protocol.VersionWhatever)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -294,9 +318,11 @@ var _ = Describe("Public Header", func() {
|
|||
Context("PublicReset packets", func() {
|
||||
It("sets the Reset Flag", func() {
|
||||
b := &bytes.Buffer{}
|
||||
connID := protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6}
|
||||
hdr := Header{
|
||||
ResetFlag: true,
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
ResetFlag: true,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -308,11 +334,13 @@ var _ = Describe("Public Header", func() {
|
|||
|
||||
It("doesn't add a packet number for headers with Reset Flag sent as a client", func() {
|
||||
b := &bytes.Buffer{}
|
||||
connID := protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6}
|
||||
hdr := Header{
|
||||
ResetFlag: true,
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 2,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
ResetFlag: true,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 2,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveClient, protocol.VersionWhatever)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -339,8 +367,9 @@ var _ = Describe("Public Header", func() {
|
|||
|
||||
It("errors when PacketNumberLen is not set", func() {
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 0xdecafbad,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0xdecafbad,
|
||||
}
|
||||
_, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||
Expect(err).To(MatchError(errPacketNumberLenNotSet))
|
||||
|
@ -348,9 +377,10 @@ var _ = Describe("Public Header", func() {
|
|||
|
||||
It("gets the length of a packet with longest packet number length and connectionID", func() {
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 0xdecafbad,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0xdecafbad,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
}
|
||||
length, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -359,7 +389,8 @@ var _ = Describe("Public Header", func() {
|
|||
|
||||
It("gets the lengths of a packet sent by the client with the VersionFlag set", func() {
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
OmitConnectionID: true,
|
||||
PacketNumber: 0xdecafbad,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
|
@ -373,7 +404,8 @@ var _ = Describe("Public Header", func() {
|
|||
|
||||
It("gets the length of a packet with longest packet number length and omitted connectionID", func() {
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
OmitConnectionID: true,
|
||||
PacketNumber: 0xDECAFBAD,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
|
@ -385,9 +417,10 @@ var _ = Describe("Public Header", func() {
|
|||
|
||||
It("gets the length of a packet 2 byte packet number length ", func() {
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 0xDECAFBAD,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0xDECAFBAD,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
}
|
||||
length, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -406,8 +439,9 @@ var _ = Describe("Public Header", func() {
|
|||
|
||||
It("gets the length of a PublicReset", func() {
|
||||
hdr := Header{
|
||||
ResetFlag: true,
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
ResetFlag: true,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
}
|
||||
length, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
@ -419,8 +453,9 @@ var _ = Describe("Public Header", func() {
|
|||
It("doesn't write a header if the packet number length is not set", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 0xDECAFBAD,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0xDECAFBAD,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||
Expect(err).To(MatchError("PublicHeader: PacketNumberLen not set"))
|
||||
|
@ -432,9 +467,10 @@ var _ = Describe("Public Header", func() {
|
|||
It("writes a header with a 1-byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 0xdecafbad,
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0xdecafbad,
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -444,9 +480,10 @@ var _ = Describe("Public Header", func() {
|
|||
It("writes a header with a 2-byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 0xdecafbad,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0xdecafbad,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -456,9 +493,10 @@ var _ = Describe("Public Header", func() {
|
|||
It("writes a header with a 4-byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 0x13decafbad,
|
||||
PacketNumberLen: protocol.PacketNumberLen4,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0x13decafbad,
|
||||
PacketNumberLen: protocol.PacketNumberLen4,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -468,9 +506,10 @@ var _ = Describe("Public Header", func() {
|
|||
It("writes a header with a 6-byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := Header{
|
||||
ConnectionID: protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6},
|
||||
PacketNumber: 0xbe1337decafbad,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0xbe1337decafbad,
|
||||
PacketNumberLen: protocol.PacketNumberLen6,
|
||||
}
|
||||
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -499,10 +538,11 @@ var _ = Describe("Public Header", func() {
|
|||
|
||||
It("logs a Public Header containing a connection ID", func() {
|
||||
(&Header{
|
||||
ConnectionID: protocol.ConnectionID{0x13, 0x37, 0, 0, 0xde, 0xca, 0xfb, 0xad},
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: 6,
|
||||
Version: protocol.Version39,
|
||||
DestConnectionID: protocol.ConnectionID{0x13, 0x37, 0, 0, 0xde, 0xca, 0xfb, 0xad},
|
||||
SrcConnectionID: protocol.ConnectionID{0x13, 0x37, 0, 0, 0xde, 0xca, 0xfb, 0xad},
|
||||
PacketNumber: 0x1337,
|
||||
PacketNumberLen: 6,
|
||||
Version: protocol.Version39,
|
||||
}).logPublicHeader(logger)
|
||||
Expect(buf.String()).To(ContainSubstring("Public Header{ConnectionID: 0x13370000decafbad, PacketNumber: 0x1337, PacketNumberLen: 6, Version: gQUIC 39"))
|
||||
})
|
||||
|
@ -528,7 +568,8 @@ var _ = Describe("Public Header", func() {
|
|||
|
||||
It("logs diversification nonces", func() {
|
||||
(&Header{
|
||||
ConnectionID: []byte{0x13, 0x13, 0, 0, 0xde, 0xca, 0xfb, 0xad},
|
||||
DestConnectionID: []byte{0x13, 0x13, 0, 0, 0xde, 0xca, 0xfb, 0xad},
|
||||
SrcConnectionID: []byte{0x13, 0x13, 0, 0, 0xde, 0xca, 0xfb, 0xad},
|
||||
DiversificationNonce: []byte{0xba, 0xdf, 0x00, 0x0d},
|
||||
}).logPublicHeader(logger)
|
||||
Expect(buf.String()).To(ContainSubstring("DiversificationNonce: []byte{0xba, 0xdf, 0x0, 0xd}"))
|
||||
|
|
|
@ -20,16 +20,22 @@ func ComposeGQUICVersionNegotiation(connID protocol.ConnectionID, versions []pro
|
|||
}
|
||||
|
||||
// ComposeVersionNegotiation composes a Version Negotiation according to the IETF draft
|
||||
func ComposeVersionNegotiation(connID protocol.ConnectionID, versions []protocol.VersionNumber) []byte {
|
||||
func ComposeVersionNegotiation(destConnID, srcConnID protocol.ConnectionID, versions []protocol.VersionNumber) ([]byte, error) {
|
||||
greasedVersions := protocol.GetGreasedVersions(versions)
|
||||
buf := bytes.NewBuffer(make([]byte, 0, 1+8+4+len(greasedVersions)*4))
|
||||
r := make([]byte, 1)
|
||||
_, _ = rand.Read(r) // ignore the error here. It is not critical to have perfect random here.
|
||||
buf.WriteByte(r[0] | 0x80)
|
||||
buf.Write(connID)
|
||||
utils.BigEndian.WriteUint32(buf, 0) // version 0
|
||||
connIDLen, err := encodeConnIDLen(destConnID, srcConnID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf.WriteByte(connIDLen)
|
||||
buf.Write(destConnID)
|
||||
buf.Write(srcConnID)
|
||||
for _, v := range greasedVersions {
|
||||
utils.BigEndian.WriteUint32(buf, uint32(v))
|
||||
}
|
||||
return buf.Bytes()
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
|
|
@ -16,19 +16,23 @@ var _ = Describe("Version Negotiation Packets", func() {
|
|||
hdr, err := parsePublicHeader(bytes.NewReader(data), protocol.PerspectiveServer)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.VersionFlag).To(BeTrue())
|
||||
Expect(hdr.ConnectionID).To(Equal(connID))
|
||||
Expect(hdr.DestConnectionID).To(Equal(connID))
|
||||
Expect(hdr.SrcConnectionID).To(Equal(connID))
|
||||
Expect(hdr.SupportedVersions).To(Equal(versions))
|
||||
})
|
||||
|
||||
It("writes in IETF draft style", func() {
|
||||
connID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}
|
||||
srcConnID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}
|
||||
destConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
versions := []protocol.VersionNumber{1001, 1003}
|
||||
data := ComposeVersionNegotiation(connID, versions)
|
||||
data, err := ComposeVersionNegotiation(destConnID, srcConnID, versions)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(data[0] & 0x80).ToNot(BeZero())
|
||||
hdr, err := parseHeader(bytes.NewReader(data), protocol.PerspectiveServer)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.IsVersionNegotiation).To(BeTrue())
|
||||
Expect(hdr.ConnectionID).To(Equal(connID))
|
||||
Expect(hdr.DestConnectionID).To(Equal(destConnID))
|
||||
Expect(hdr.SrcConnectionID).To(Equal(srcConnID))
|
||||
Expect(hdr.Version).To(BeZero())
|
||||
// the supported versions should include one reserved version number
|
||||
Expect(hdr.SupportedVersions).To(HaveLen(len(versions) + 1))
|
||||
|
|
|
@ -137,7 +137,7 @@ func unpackInitialPacket(aead crypto.AEAD, hdr *wire.Header, data []byte, logger
|
|||
return nil, errors.New("received stream data with non-zero offset")
|
||||
}
|
||||
if logger.Debug() {
|
||||
logger.Debugf("<- Reading packet 0x%x (%d bytes) for connection %x", hdr.PacketNumber, len(data)+len(hdr.Raw), hdr.ConnectionID)
|
||||
logger.Debugf("<- Reading packet 0x%x (%d bytes) for connection %x", hdr.PacketNumber, len(data)+len(hdr.Raw), hdr.DestConnectionID)
|
||||
hdr.Log(logger)
|
||||
wire.LogFrame(logger, frame, false)
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ func packUnencryptedPacket(aead crypto.AEAD, hdr *wire.Header, f wire.Frame, per
|
|||
_ = aead.Seal(raw[payloadStartIndex:payloadStartIndex], raw[payloadStartIndex:], hdr.PacketNumber, raw[:payloadStartIndex])
|
||||
raw = raw[0 : buffer.Len()+aead.Overhead()]
|
||||
if logger.Debug() {
|
||||
logger.Debugf("-> Sending packet 0x%x (%d bytes) for connection %x, %s", hdr.PacketNumber, len(raw), hdr.ConnectionID, protocol.EncryptionUnencrypted)
|
||||
logger.Debugf("-> Sending packet 0x%x (%d bytes) for connection %x, %s", hdr.PacketNumber, len(raw), hdr.SrcConnectionID, protocol.EncryptionUnencrypted)
|
||||
hdr.Log(logger)
|
||||
wire.LogFrame(logger, f, true)
|
||||
}
|
||||
|
|
|
@ -20,11 +20,12 @@ var _ = Describe("Packing and unpacking Initial packets", func() {
|
|||
connID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
ver := protocol.VersionTLS
|
||||
hdr := &wire.Header{
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeRetry,
|
||||
PacketNumber: 0x42,
|
||||
ConnectionID: connID,
|
||||
Version: ver,
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeRetry,
|
||||
PacketNumber: 0x42,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
Version: ver,
|
||||
}
|
||||
|
||||
BeforeEach(func() {
|
||||
|
|
|
@ -446,9 +446,10 @@ func (p *packetPacker) getHeader(encLevel protocol.EncryptionLevel) *wire.Header
|
|||
packetNumberLen := p.getPacketNumberLen(pnum)
|
||||
|
||||
header := &wire.Header{
|
||||
ConnectionID: p.connectionID,
|
||||
PacketNumber: pnum,
|
||||
PacketNumberLen: packetNumberLen,
|
||||
DestConnectionID: p.connectionID,
|
||||
SrcConnectionID: p.connectionID,
|
||||
PacketNumber: pnum,
|
||||
PacketNumberLen: packetNumberLen,
|
||||
}
|
||||
|
||||
if p.version.UsesTLS() && encLevel != protocol.EncryptionForwardSecure {
|
||||
|
|
25
server.go
25
server.go
|
@ -307,7 +307,10 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
|||
}
|
||||
hdr.Raw = packet[:len(packet)-r.Len()]
|
||||
packetData := packet[len(packet)-r.Len():]
|
||||
connID := hdr.ConnectionID
|
||||
|
||||
if hdr.IsLongHeader && !hdr.DestConnectionID.Equal(hdr.SrcConnectionID) {
|
||||
return errors.New("receiving packets with different destination and source connection IDs not supported")
|
||||
}
|
||||
|
||||
if hdr.Type == protocol.PacketTypeInitial {
|
||||
if s.supportsTLS {
|
||||
|
@ -317,7 +320,7 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
|||
}
|
||||
|
||||
s.sessionsMutex.RLock()
|
||||
session, sessionKnown := s.sessions[string(connID)]
|
||||
session, sessionKnown := s.sessions[string(hdr.DestConnectionID)]
|
||||
s.sessionsMutex.RUnlock()
|
||||
|
||||
if sessionKnown && session == nil {
|
||||
|
@ -331,12 +334,12 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
|||
var pr *wire.PublicReset
|
||||
pr, err = wire.ParsePublicReset(r)
|
||||
if err != nil {
|
||||
s.logger.Infof("Received a Public Reset for connection %x. An error occurred parsing the packet.", hdr.ConnectionID)
|
||||
s.logger.Infof("Received a Public Reset for connection %x. An error occurred parsing the packet.", hdr.DestConnectionID)
|
||||
} else {
|
||||
s.logger.Infof("Received a Public Reset for connection %x, rejected packet number: 0x%x.", hdr.ConnectionID, pr.RejectedPacketNumber)
|
||||
s.logger.Infof("Received a Public Reset for connection %x, rejected packet number: 0x%x.", hdr.DestConnectionID, pr.RejectedPacketNumber)
|
||||
}
|
||||
} else {
|
||||
s.logger.Infof("Received Public Reset for unknown connection %x.", hdr.ConnectionID)
|
||||
s.logger.Infof("Received Public Reset for unknown connection %x.", hdr.DestConnectionID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -345,7 +348,7 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
|||
// This should only happen after a server restart, when we still receive packets for connections that we lost the state for.
|
||||
// TODO(#943): implement sending of IETF draft style stateless resets
|
||||
if !sessionKnown && (!hdr.VersionFlag && hdr.Type != protocol.PacketTypeInitial) {
|
||||
_, err = pconn.WriteTo(wire.WritePublicReset(connID, 0, 0), remoteAddr)
|
||||
_, err = pconn.WriteTo(wire.WritePublicReset(hdr.DestConnectionID, 0, 0), remoteAddr)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -364,7 +367,7 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
|||
return errors.New("dropping small packet with unknown version")
|
||||
}
|
||||
s.logger.Infof("Client offered version %s, sending Version Negotiation Packet", hdr.Version)
|
||||
_, err := pconn.WriteTo(wire.ComposeGQUICVersionNegotiation(hdr.ConnectionID, s.config.Versions), remoteAddr)
|
||||
_, err := pconn.WriteTo(wire.ComposeGQUICVersionNegotiation(hdr.SrcConnectionID, s.config.Versions), remoteAddr)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -380,11 +383,11 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
|||
return errors.New("Server BUG: negotiated version not supported")
|
||||
}
|
||||
|
||||
s.logger.Infof("Serving new connection: %x, version %s from %v", hdr.ConnectionID, version, remoteAddr)
|
||||
s.logger.Infof("Serving new connection: %x, version %s from %v", hdr.DestConnectionID, version, remoteAddr)
|
||||
session, err = s.newSession(
|
||||
&conn{pconn: pconn, currentAddr: remoteAddr},
|
||||
version,
|
||||
hdr.ConnectionID,
|
||||
hdr.DestConnectionID,
|
||||
s.scfg,
|
||||
s.tlsConf,
|
||||
s.config,
|
||||
|
@ -394,10 +397,10 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
|||
return err
|
||||
}
|
||||
s.sessionsMutex.Lock()
|
||||
s.sessions[string(connID)] = session
|
||||
s.sessions[string(hdr.DestConnectionID)] = session
|
||||
s.sessionsMutex.Unlock()
|
||||
|
||||
s.runHandshakeAndSession(session, connID)
|
||||
s.runHandshakeAndSession(session, hdr.DestConnectionID)
|
||||
}
|
||||
session.handlePacket(&receivedPacket{
|
||||
remoteAddr: remoteAddr,
|
||||
|
|
|
@ -418,10 +418,11 @@ var _ = Describe("Server", func() {
|
|||
config.Versions = []protocol.VersionNumber{99}
|
||||
b := &bytes.Buffer{}
|
||||
hdr := wire.Header{
|
||||
VersionFlag: true,
|
||||
ConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
VersionFlag: true,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
}
|
||||
hdr.Write(b, protocol.PerspectiveClient, 13 /* not a valid QUIC version */)
|
||||
b.Write(bytes.Repeat([]byte{0}, protocol.MinClientHelloSize)) // add a fake CHLO
|
||||
|
@ -433,10 +434,11 @@ var _ = Describe("Server", func() {
|
|||
It("doesn't respond with a version negotiation packet if the first packet is too small", func() {
|
||||
b := &bytes.Buffer{}
|
||||
hdr := wire.Header{
|
||||
VersionFlag: true,
|
||||
ConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
VersionFlag: true,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
}
|
||||
hdr.Write(b, protocol.PerspectiveClient, 13 /* not a valid QUIC version */)
|
||||
b.Write(bytes.Repeat([]byte{0}, protocol.MinClientHelloSize-1)) // this packet is 1 byte too small
|
||||
|
@ -510,10 +512,11 @@ var _ = Describe("Server", func() {
|
|||
connID := protocol.ConnectionID{8, 7, 6, 5, 4, 3, 2, 1}
|
||||
b := &bytes.Buffer{}
|
||||
hdr := wire.Header{
|
||||
VersionFlag: true,
|
||||
ConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
VersionFlag: true,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
}
|
||||
hdr.Write(b, protocol.PerspectiveClient, 13 /* not a valid QUIC version */)
|
||||
b.Write(bytes.Repeat([]byte{0}, protocol.MinClientHelloSize)) // add a fake CHLO
|
||||
|
@ -535,7 +538,8 @@ var _ = Describe("Server", func() {
|
|||
packet, err := wire.ParseHeaderSentByServer(r, protocol.VersionUnknown)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.VersionFlag).To(BeTrue())
|
||||
Expect(packet.ConnectionID).To(Equal(connID))
|
||||
Expect(packet.DestConnectionID).To(Equal(connID))
|
||||
Expect(packet.SrcConnectionID).To(Equal(connID))
|
||||
Expect(r.Len()).To(BeZero())
|
||||
Consistently(done).ShouldNot(BeClosed())
|
||||
// make the go routine return
|
||||
|
@ -548,11 +552,12 @@ var _ = Describe("Server", func() {
|
|||
config.Versions = append(config.Versions, protocol.VersionTLS)
|
||||
b := &bytes.Buffer{}
|
||||
hdr := wire.Header{
|
||||
Type: protocol.PacketTypeInitial,
|
||||
IsLongHeader: true,
|
||||
ConnectionID: connID,
|
||||
PacketNumber: 0x55,
|
||||
Version: 0x1234,
|
||||
Type: protocol.PacketTypeInitial,
|
||||
IsLongHeader: true,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0x55,
|
||||
Version: 0x1234,
|
||||
}
|
||||
err := hdr.Write(b, protocol.PerspectiveClient, protocol.VersionTLS)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -575,7 +580,8 @@ var _ = Describe("Server", func() {
|
|||
packet, err := wire.ParseHeaderSentByServer(r, protocol.VersionUnknown)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(packet.IsVersionNegotiation).To(BeTrue())
|
||||
Expect(packet.ConnectionID).To(Equal(connID))
|
||||
Expect(packet.DestConnectionID).To(Equal(connID))
|
||||
Expect(packet.SrcConnectionID).To(Equal(connID))
|
||||
Expect(r.Len()).To(BeZero())
|
||||
Consistently(done).ShouldNot(BeClosed())
|
||||
// make the go routine return
|
||||
|
@ -587,11 +593,12 @@ var _ = Describe("Server", func() {
|
|||
connID := protocol.ConnectionID{8, 7, 6, 5, 4, 3, 2, 1}
|
||||
b := &bytes.Buffer{}
|
||||
hdr := wire.Header{
|
||||
Type: protocol.PacketTypeInitial,
|
||||
IsLongHeader: true,
|
||||
ConnectionID: connID,
|
||||
PacketNumber: 0x55,
|
||||
Version: protocol.VersionTLS,
|
||||
Type: protocol.PacketTypeInitial,
|
||||
IsLongHeader: true,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 0x55,
|
||||
Version: protocol.VersionTLS,
|
||||
}
|
||||
err := hdr.Write(b, protocol.PerspectiveClient, protocol.VersionTLS)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
|
|
@ -87,6 +87,7 @@ func newServerTLS(
|
|||
}
|
||||
|
||||
func (s *serverTLS) HandleInitial(remoteAddr net.Addr, hdr *wire.Header, data []byte) {
|
||||
// TODO: add a check that DestConnID == SrcConnID
|
||||
s.logger.Debugf("Received a Packet. Handling it statelessly.")
|
||||
sess, err := s.handleInitialImpl(remoteAddr, hdr, data)
|
||||
if err != nil {
|
||||
|
@ -97,7 +98,7 @@ func (s *serverTLS) HandleInitial(remoteAddr net.Addr, hdr *wire.Header, data []
|
|||
return
|
||||
}
|
||||
s.sessionChan <- tlsSession{
|
||||
connID: hdr.ConnectionID,
|
||||
connID: hdr.DestConnectionID,
|
||||
sess: sess,
|
||||
}
|
||||
}
|
||||
|
@ -116,11 +117,12 @@ func (s *serverTLS) sendConnectionClose(remoteAddr net.Addr, clientHdr *wire.Hea
|
|||
ReasonPhrase: closeErr.Error(),
|
||||
}
|
||||
replyHdr := &wire.Header{
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeHandshake,
|
||||
ConnectionID: clientHdr.ConnectionID, // echo the client's connection ID
|
||||
PacketNumber: 1, // random packet number
|
||||
Version: clientHdr.Version,
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeHandshake,
|
||||
SrcConnectionID: clientHdr.SrcConnectionID,
|
||||
DestConnectionID: clientHdr.DestConnectionID,
|
||||
PacketNumber: 1, // random packet number
|
||||
Version: clientHdr.Version,
|
||||
}
|
||||
data, err := packUnencryptedPacket(aead, replyHdr, ccf, protocol.PerspectiveServer, s.logger)
|
||||
if err != nil {
|
||||
|
@ -137,12 +139,16 @@ func (s *serverTLS) handleInitialImpl(remoteAddr net.Addr, hdr *wire.Header, dat
|
|||
// check version, if not matching send VNP
|
||||
if !protocol.IsSupportedVersion(s.supportedVersions, hdr.Version) {
|
||||
s.logger.Debugf("Client offered version %s, sending VersionNegotiationPacket", hdr.Version)
|
||||
_, err := s.conn.WriteTo(wire.ComposeVersionNegotiation(hdr.ConnectionID, s.supportedVersions), remoteAddr)
|
||||
vnp, err := wire.ComposeVersionNegotiation(hdr.SrcConnectionID, hdr.DestConnectionID, s.supportedVersions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = s.conn.WriteTo(vnp, remoteAddr)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// unpack packet and check stream frame contents
|
||||
aead, err := crypto.NewNullAEAD(protocol.PerspectiveServer, hdr.ConnectionID, hdr.Version)
|
||||
aead, err := crypto.NewNullAEAD(protocol.PerspectiveServer, hdr.DestConnectionID, protocol.VersionTLS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -170,15 +176,17 @@ func (s *serverTLS) handleUnpackedInitial(remoteAddr net.Addr, hdr *wire.Header,
|
|||
return nil, err
|
||||
}
|
||||
alert := tls.Handshake()
|
||||
s.logger.Debugf("%#v\n", hdr)
|
||||
if alert == mint.AlertStatelessRetry {
|
||||
// the HelloRetryRequest was written to the bufferConn
|
||||
// Take that data and write send a Retry packet
|
||||
replyHdr := &wire.Header{
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeRetry,
|
||||
ConnectionID: hdr.ConnectionID, // echo the client's connection ID
|
||||
PacketNumber: hdr.PacketNumber, // echo the client's packet number
|
||||
Version: version,
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeRetry,
|
||||
DestConnectionID: hdr.DestConnectionID,
|
||||
SrcConnectionID: hdr.SrcConnectionID,
|
||||
PacketNumber: hdr.PacketNumber, // echo the client's packet number
|
||||
Version: version,
|
||||
}
|
||||
f := &wire.StreamFrame{
|
||||
StreamID: version.CryptoStreamID(),
|
||||
|
@ -206,7 +214,7 @@ func (s *serverTLS) handleUnpackedInitial(remoteAddr net.Addr, hdr *wire.Header,
|
|||
params := <-paramsChan
|
||||
sess, err := newTLSServerSession(
|
||||
&conn{pconn: s.conn, currentAddr: remoteAddr},
|
||||
hdr.ConnectionID, // TODO: we can use a server-chosen connection ID here
|
||||
hdr.DestConnectionID, // TODO(#1003): we can use a server-chosen connection ID here
|
||||
protocol.PacketNumber(1), // TODO: use a random packet number here
|
||||
s.config,
|
||||
tls,
|
||||
|
|
|
@ -49,10 +49,11 @@ var _ = Describe("Stateless TLS handling", func() {
|
|||
connID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
hdrBuf := &bytes.Buffer{}
|
||||
hdr := &wire.Header{
|
||||
IsLongHeader: true,
|
||||
ConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
Version: protocol.VersionTLS,
|
||||
IsLongHeader: true,
|
||||
DestConnectionID: connID,
|
||||
SrcConnectionID: connID,
|
||||
PacketNumber: 1,
|
||||
Version: protocol.VersionTLS,
|
||||
}
|
||||
err := hdr.Write(hdrBuf, protocol.PerspectiveClient, protocol.VersionTLS)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -74,7 +75,7 @@ var _ = Describe("Stateless TLS handling", func() {
|
|||
hdr, err := wire.ParseHeaderSentByServer(r, protocol.VersionTLS)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
hdr.Raw = data[:len(data)-r.Len()]
|
||||
aead, err := crypto.NewNullAEAD(protocol.PerspectiveClient, hdr.ConnectionID, protocol.VersionTLS)
|
||||
aead, err := crypto.NewNullAEAD(protocol.PerspectiveClient, hdr.DestConnectionID, protocol.VersionTLS)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
payload, err := aead.Open(nil, data[len(data)-r.Len():], hdr.PacketNumber, hdr.Raw)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -83,8 +84,9 @@ var _ = Describe("Stateless TLS handling", func() {
|
|||
|
||||
It("sends a version negotiation packet if it doesn't support the version", func() {
|
||||
hdr := &wire.Header{
|
||||
ConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
Version: 0x1337,
|
||||
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
Version: 0x1337,
|
||||
}
|
||||
server.HandleInitial(nil, hdr, bytes.Repeat([]byte{0}, protocol.MinInitialPacketSize))
|
||||
Expect(conn.dataWritten.Len()).ToNot(BeZero())
|
||||
|
|
|
@ -598,9 +598,9 @@ func (s *session) handlePacketImpl(p *receivedPacket) error {
|
|||
packet, err := s.unpacker.Unpack(hdr.Raw, hdr, data)
|
||||
if s.logger.Debug() {
|
||||
if err != nil {
|
||||
s.logger.Debugf("<- Reading packet 0x%x (%d bytes) for connection %x", hdr.PacketNumber, len(data)+len(hdr.Raw), hdr.ConnectionID)
|
||||
s.logger.Debugf("<- Reading packet 0x%x (%d bytes) for connection %x", hdr.PacketNumber, len(data)+len(hdr.Raw), hdr.DestConnectionID)
|
||||
} else {
|
||||
s.logger.Debugf("<- Reading packet 0x%x (%d bytes) for connection %x, %s", hdr.PacketNumber, len(data)+len(hdr.Raw), hdr.ConnectionID, packet.encryptionLevel)
|
||||
s.logger.Debugf("<- Reading packet 0x%x (%d bytes) for connection %x, %s", hdr.PacketNumber, len(data)+len(hdr.Raw), hdr.DestConnectionID, packet.encryptionLevel)
|
||||
}
|
||||
hdr.Log(s.logger)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue