Skip to content

Commit ad8367c

Browse files
Merge pull request #2876 from lucas-clemente/fix-initial-padding
use PADDING frames to pad packets
2 parents e676a83 + d1a784d commit ad8367c

File tree

6 files changed

+591
-255
lines changed

6 files changed

+591
-255
lines changed

internal/utils/varint.go

+28
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,34 @@ func WriteVarInt(b *bytes.Buffer, i uint64) {
8383
}
8484
}
8585

86+
// WriteVarIntWithLen writes a number in the QUIC varint format, with the desired length.
87+
func WriteVarIntWithLen(b *bytes.Buffer, i uint64, length protocol.ByteCount) {
88+
if length != 1 && length != 2 && length != 4 && length != 8 {
89+
panic("invalid varint length")
90+
}
91+
l := VarIntLen(i)
92+
if l == length {
93+
WriteVarInt(b, i)
94+
return
95+
}
96+
if l > length {
97+
panic(fmt.Sprintf("cannot encode %d in %d bytes", i, length))
98+
}
99+
if length == 2 {
100+
b.WriteByte(0b01000000)
101+
} else if length == 4 {
102+
b.WriteByte(0b10000000)
103+
} else if length == 8 {
104+
b.WriteByte(0b11000000)
105+
}
106+
for j := protocol.ByteCount(1); j < length-l; j++ {
107+
b.WriteByte(0)
108+
}
109+
for j := protocol.ByteCount(0); j < l; j++ {
110+
b.WriteByte(uint8(i >> (8 * (l - 1 - j))))
111+
}
112+
}
113+
86114
// VarIntLen determines the number of bytes that will be needed to write a number
87115
func VarIntLen(i uint64) protocol.ByteCount {
88116
if i <= maxVarInt1 {

internal/utils/varint_test.go

+134-80
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,39 @@ import (
1010
var _ = Describe("Varint encoding / decoding", func() {
1111
Context("decoding", func() {
1212
It("reads a 1 byte number", func() {
13-
b := bytes.NewReader([]byte{25}) // 00011001
13+
b := bytes.NewReader([]byte{0b00011001})
1414
val, err := ReadVarInt(b)
1515
Expect(err).ToNot(HaveOccurred())
1616
Expect(val).To(Equal(uint64(25)))
1717
Expect(b.Len()).To(BeZero())
1818
})
1919

2020
It("reads a number that is encoded too long", func() {
21-
b := bytes.NewReader([]byte{0x40, 0x25}) // first byte: 01000000
21+
b := bytes.NewReader([]byte{0b01000000, 0x25})
2222
val, err := ReadVarInt(b)
2323
Expect(err).ToNot(HaveOccurred())
2424
Expect(val).To(Equal(uint64(37)))
2525
Expect(b.Len()).To(BeZero())
2626
})
2727

2828
It("reads a 2 byte number", func() {
29-
b := bytes.NewReader([]byte{0x7b, 0xbd}) // first byte: 01111011
29+
b := bytes.NewReader([]byte{0b01111011, 0xbd})
3030
val, err := ReadVarInt(b)
3131
Expect(err).ToNot(HaveOccurred())
3232
Expect(val).To(Equal(uint64(15293)))
3333
Expect(b.Len()).To(BeZero())
3434
})
3535

3636
It("reads a 4 byte number", func() {
37-
b := bytes.NewReader([]byte{0x9d, 0x7f, 0x3e, 0x7d}) // first byte: 10011011
37+
b := bytes.NewReader([]byte{0b10011101, 0x7f, 0x3e, 0x7d})
3838
val, err := ReadVarInt(b)
3939
Expect(err).ToNot(HaveOccurred())
4040
Expect(val).To(Equal(uint64(494878333)))
4141
Expect(b.Len()).To(BeZero())
4242
})
4343

4444
It("reads an 8 byte number", func() {
45-
b := bytes.NewReader([]byte{0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c}) // first byte: 10000010
45+
b := bytes.NewReader([]byte{0b11000010, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c})
4646
val, err := ReadVarInt(b)
4747
Expect(err).ToNot(HaveOccurred())
4848
Expect(val).To(Equal(uint64(151288809941952652)))
@@ -51,81 +51,135 @@ var _ = Describe("Varint encoding / decoding", func() {
5151
})
5252

5353
Context("encoding", func() {
54-
It("writes a 1 byte number", func() {
55-
b := &bytes.Buffer{}
56-
WriteVarInt(b, 37)
57-
Expect(b.Bytes()).To(Equal([]byte{0x25}))
58-
})
59-
60-
It("writes the maximum 1 byte number in 1 byte", func() {
61-
b := &bytes.Buffer{}
62-
WriteVarInt(b, maxVarInt1)
63-
Expect(b.Bytes()).To(Equal([]byte{0x3f /* 00111111 */}))
64-
})
65-
66-
It("writes the minimum 2 byte number in 2 bytes", func() {
67-
b := &bytes.Buffer{}
68-
WriteVarInt(b, maxVarInt1+1)
69-
Expect(b.Bytes()).To(Equal([]byte{0x40, maxVarInt1 + 1}))
70-
})
71-
72-
It("writes a 2 byte number", func() {
73-
b := &bytes.Buffer{}
74-
WriteVarInt(b, 15293)
75-
Expect(b.Bytes()).To(Equal([]byte{0x7b, 0xbd}))
76-
})
77-
78-
It("writes the maximum 2 byte number in 2 bytes", func() {
79-
b := &bytes.Buffer{}
80-
WriteVarInt(b, maxVarInt2)
81-
Expect(b.Bytes()).To(Equal([]byte{0x7f /* 01111111 */, 0xff}))
82-
})
83-
84-
It("writes the minimum 4 byte number in 4 bytes", func() {
85-
b := &bytes.Buffer{}
86-
WriteVarInt(b, maxVarInt2+1)
87-
Expect(b.Len()).To(Equal(4))
88-
num, err := ReadVarInt(b)
89-
Expect(err).ToNot(HaveOccurred())
90-
Expect(num).To(Equal(uint64(maxVarInt2 + 1)))
91-
})
92-
93-
It("writes a 4 byte number", func() {
94-
b := &bytes.Buffer{}
95-
WriteVarInt(b, 494878333)
96-
Expect(b.Bytes()).To(Equal([]byte{0x9d, 0x7f, 0x3e, 0x7d}))
97-
})
98-
99-
It("writes the maximum 4 byte number in 4 bytes", func() {
100-
b := &bytes.Buffer{}
101-
WriteVarInt(b, maxVarInt4)
102-
Expect(b.Bytes()).To(Equal([]byte{0xbf /* 10111111 */, 0xff, 0xff, 0xff}))
103-
})
104-
105-
It("writes the minimum 8 byte number in 8 bytes", func() {
106-
b := &bytes.Buffer{}
107-
WriteVarInt(b, maxVarInt4+1)
108-
Expect(b.Len()).To(Equal(8))
109-
num, err := ReadVarInt(b)
110-
Expect(err).ToNot(HaveOccurred())
111-
Expect(num).To(Equal(uint64(maxVarInt4 + 1)))
112-
})
113-
114-
It("writes an 8 byte number", func() {
115-
b := &bytes.Buffer{}
116-
WriteVarInt(b, 151288809941952652)
117-
Expect(b.Bytes()).To(Equal([]byte{0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c}))
118-
})
119-
120-
It("writes the maximum 8 byte number in 8 bytes", func() {
121-
b := &bytes.Buffer{}
122-
WriteVarInt(b, maxVarInt8)
123-
Expect(b.Bytes()).To(Equal([]byte{0xff /* 11111111 */, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}))
124-
})
125-
126-
It("panics when given a too large number (> 62 bit)", func() {
127-
b := &bytes.Buffer{}
128-
Expect(func() { WriteVarInt(b, maxVarInt8+1) }).Should(Panic())
54+
Context("with minimal length", func() {
55+
It("writes a 1 byte number", func() {
56+
b := &bytes.Buffer{}
57+
WriteVarInt(b, 37)
58+
Expect(b.Bytes()).To(Equal([]byte{0x25}))
59+
})
60+
61+
It("writes the maximum 1 byte number in 1 byte", func() {
62+
b := &bytes.Buffer{}
63+
WriteVarInt(b, maxVarInt1)
64+
Expect(b.Bytes()).To(Equal([]byte{0b00111111}))
65+
})
66+
67+
It("writes the minimum 2 byte number in 2 bytes", func() {
68+
b := &bytes.Buffer{}
69+
WriteVarInt(b, maxVarInt1+1)
70+
Expect(b.Bytes()).To(Equal([]byte{0x40, maxVarInt1 + 1}))
71+
})
72+
73+
It("writes a 2 byte number", func() {
74+
b := &bytes.Buffer{}
75+
WriteVarInt(b, 15293)
76+
Expect(b.Bytes()).To(Equal([]byte{0b01000000 ^ 0x3b, 0xbd}))
77+
})
78+
79+
It("writes the maximum 2 byte number in 2 bytes", func() {
80+
b := &bytes.Buffer{}
81+
WriteVarInt(b, maxVarInt2)
82+
Expect(b.Bytes()).To(Equal([]byte{0b01111111, 0xff}))
83+
})
84+
85+
It("writes the minimum 4 byte number in 4 bytes", func() {
86+
b := &bytes.Buffer{}
87+
WriteVarInt(b, maxVarInt2+1)
88+
Expect(b.Len()).To(Equal(4))
89+
num, err := ReadVarInt(b)
90+
Expect(err).ToNot(HaveOccurred())
91+
Expect(num).To(Equal(uint64(maxVarInt2 + 1)))
92+
})
93+
94+
It("writes a 4 byte number", func() {
95+
b := &bytes.Buffer{}
96+
WriteVarInt(b, 494878333)
97+
Expect(b.Bytes()).To(Equal([]byte{0b10000000 ^ 0x1d, 0x7f, 0x3e, 0x7d}))
98+
})
99+
100+
It("writes the maximum 4 byte number in 4 bytes", func() {
101+
b := &bytes.Buffer{}
102+
WriteVarInt(b, maxVarInt4)
103+
Expect(b.Bytes()).To(Equal([]byte{0b10111111, 0xff, 0xff, 0xff}))
104+
})
105+
106+
It("writes the minimum 8 byte number in 8 bytes", func() {
107+
b := &bytes.Buffer{}
108+
WriteVarInt(b, maxVarInt4+1)
109+
Expect(b.Len()).To(Equal(8))
110+
num, err := ReadVarInt(b)
111+
Expect(err).ToNot(HaveOccurred())
112+
Expect(num).To(Equal(uint64(maxVarInt4 + 1)))
113+
})
114+
115+
It("writes an 8 byte number", func() {
116+
b := &bytes.Buffer{}
117+
WriteVarInt(b, 151288809941952652)
118+
Expect(b.Bytes()).To(Equal([]byte{0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c}))
119+
})
120+
121+
It("writes the maximum 8 byte number in 8 bytes", func() {
122+
b := &bytes.Buffer{}
123+
WriteVarInt(b, maxVarInt8)
124+
Expect(b.Bytes()).To(Equal([]byte{0xff /* 11111111 */, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}))
125+
})
126+
127+
It("panics when given a too large number (> 62 bit)", func() {
128+
Expect(func() { WriteVarInt(&bytes.Buffer{}, maxVarInt8+1) }).Should(Panic())
129+
})
130+
})
131+
132+
Context("with fixed length", func() {
133+
It("panics when given an invalid length", func() {
134+
Expect(func() { WriteVarIntWithLen(&bytes.Buffer{}, 25, 3) }).Should(Panic())
135+
})
136+
137+
It("panics when given a too short length", func() {
138+
Expect(func() { WriteVarIntWithLen(&bytes.Buffer{}, maxVarInt1+1, 1) }).Should(Panic())
139+
Expect(func() { WriteVarIntWithLen(&bytes.Buffer{}, maxVarInt2+1, 2) }).Should(Panic())
140+
Expect(func() { WriteVarIntWithLen(&bytes.Buffer{}, maxVarInt4+1, 4) }).Should(Panic())
141+
})
142+
143+
It("writes a 1-byte number in minimal encoding", func() {
144+
b := &bytes.Buffer{}
145+
WriteVarIntWithLen(b, 37, 1)
146+
Expect(b.Bytes()).To(Equal([]byte{0x25}))
147+
})
148+
149+
It("writes a 1-byte number in 2 bytes", func() {
150+
b := &bytes.Buffer{}
151+
WriteVarIntWithLen(b, 37, 2)
152+
Expect(b.Bytes()).To(Equal([]byte{0b01000000, 0x25}))
153+
Expect(ReadVarInt(b)).To(BeEquivalentTo(37))
154+
})
155+
156+
It("writes a 1-byte number in 4 bytes", func() {
157+
b := &bytes.Buffer{}
158+
WriteVarIntWithLen(b, 37, 4)
159+
Expect(b.Bytes()).To(Equal([]byte{0b10000000, 0, 0, 0x25}))
160+
Expect(ReadVarInt(b)).To(BeEquivalentTo(37))
161+
})
162+
163+
It("writes a 1-byte number in 8 bytes", func() {
164+
b := &bytes.Buffer{}
165+
WriteVarIntWithLen(b, 37, 8)
166+
Expect(b.Bytes()).To(Equal([]byte{0b11000000, 0, 0, 0, 0, 0, 0, 0x25}))
167+
Expect(ReadVarInt(b)).To(BeEquivalentTo(37))
168+
})
169+
170+
It("writes a 2-byte number in 4 bytes", func() {
171+
b := &bytes.Buffer{}
172+
WriteVarIntWithLen(b, 15293, 4)
173+
Expect(b.Bytes()).To(Equal([]byte{0b10000000, 0, 0x3b, 0xbd}))
174+
Expect(ReadVarInt(b)).To(BeEquivalentTo(15293))
175+
})
176+
177+
It("write a 4-byte number in 8 bytes", func() {
178+
b := &bytes.Buffer{}
179+
WriteVarIntWithLen(b, 494878333, 8)
180+
Expect(b.Bytes()).To(Equal([]byte{0b11000000, 0, 0, 0, 0x1d, 0x7f, 0x3e, 0x7d}))
181+
Expect(ReadVarInt(b)).To(BeEquivalentTo(494878333))
182+
})
129183
})
130184
})
131185

internal/wire/extended_header.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,7 @@ func (h *ExtendedHeader) writeLongHeader(b *bytes.Buffer, _ protocol.VersionNumb
161161
utils.WriteVarInt(b, uint64(len(h.Token)))
162162
b.Write(h.Token)
163163
}
164-
165-
utils.WriteVarInt(b, uint64(h.Length))
164+
utils.WriteVarIntWithLen(b, uint64(h.Length), 2)
166165
return h.writePacketNumber(b)
167166
}
168167

@@ -201,7 +200,7 @@ func (h *ExtendedHeader) ParsedLen() protocol.ByteCount {
201200
// GetLength determines the length of the Header.
202201
func (h *ExtendedHeader) GetLength(v protocol.VersionNumber) protocol.ByteCount {
203202
if h.IsLongHeader {
204-
length := 1 /* type byte */ + 4 /* version */ + 1 /* dest conn ID len */ + protocol.ByteCount(h.DestConnectionID.Len()) + 1 /* src conn ID len */ + protocol.ByteCount(h.SrcConnectionID.Len()) + protocol.ByteCount(h.PacketNumberLen) + utils.VarIntLen(uint64(h.Length))
203+
length := 1 /* type byte */ + 4 /* version */ + 1 /* dest conn ID len */ + protocol.ByteCount(h.DestConnectionID.Len()) + 1 /* src conn ID len */ + protocol.ByteCount(h.SrcConnectionID.Len()) + protocol.ByteCount(h.PacketNumberLen) + 2 /* length */
205204
if h.Type == protocol.PacketTypeInitial {
206205
length += utils.VarIntLen(uint64(len(h.Token))) + protocol.ByteCount(len(h.Token))
207206
}

internal/wire/extended_header_test.go

+38-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ var _ = Describe("Header", func() {
3232
DestConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe},
3333
SrcConnectionID: protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad, 0x0, 0x0, 0x13, 0x37},
3434
Version: 0x1020304,
35-
Length: 0xcafe,
35+
Length: protocol.MaxPacketSizeIPv4,
3636
},
3737
PacketNumber: 0xdecaf,
3838
PacketNumberLen: protocol.PacketNumberLen3,
@@ -45,8 +45,8 @@ var _ = Describe("Header", func() {
4545
0x8, // src connection ID length
4646
0xde, 0xca, 0xfb, 0xad, 0x0, 0x0, 0x13, 0x37, // source connection ID
4747
}
48-
expected = append(expected, encodeVarInt(0xcafe)...) // length
49-
expected = append(expected, []byte{0xd, 0xec, 0xaf}...) // packet number
48+
expected = append(expected, encodeVarInt(protocol.MaxPacketSizeIPv4)...) // length
49+
expected = append(expected, []byte{0xd, 0xec, 0xaf}...) // packet number
5050
Expect(buf.Bytes()).To(Equal(expected))
5151
})
5252

@@ -97,6 +97,22 @@ var _ = Describe("Header", func() {
9797
Expect(buf.Bytes()).To(ContainSubstring(string(expectedSubstring)))
9898
})
9999

100+
It("uses a 2-byte encoding for the length on Initial packets", func() {
101+
Expect((&ExtendedHeader{
102+
Header: Header{
103+
IsLongHeader: true,
104+
Version: 0x1020304,
105+
Type: protocol.PacketTypeInitial,
106+
Length: 37,
107+
},
108+
PacketNumber: 0xdecafbad,
109+
PacketNumberLen: protocol.PacketNumberLen4,
110+
}).Write(buf, versionIETFHeader)).To(Succeed())
111+
b := &bytes.Buffer{}
112+
utils.WriteVarIntWithLen(b, 37, 2)
113+
Expect(buf.Bytes()[buf.Len()-6 : buf.Len()-4]).To(Equal(b.Bytes()))
114+
})
115+
100116
It("writes a Retry packet", func() {
101117
token := []byte("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.")
102118
Expect((&ExtendedHeader{Header: Header{
@@ -203,7 +219,7 @@ var _ = Describe("Header", func() {
203219
},
204220
PacketNumberLen: protocol.PacketNumberLen1,
205221
}
206-
expectedLen := 1 /* type byte */ + 4 /* version */ + 1 /* dest conn ID len */ + 8 /* dest conn id */ + 1 /* src conn ID len */ + 8 /* src conn id */ + 1 /* short len */ + 1 /* packet number */
222+
expectedLen := 1 /* type byte */ + 4 /* version */ + 1 /* dest conn ID len */ + 8 /* dest conn id */ + 1 /* src conn ID len */ + 8 /* src conn id */ + 2 /* length */ + 1 /* packet number */
207223
Expect(h.GetLength(versionIETFHeader)).To(BeEquivalentTo(expectedLen))
208224
Expect(h.Write(buf, versionIETFHeader)).To(Succeed())
209225
Expect(buf.Len()).To(Equal(expectedLen))
@@ -226,6 +242,23 @@ var _ = Describe("Header", func() {
226242
Expect(buf.Len()).To(Equal(expectedLen))
227243
})
228244

245+
It("has the right length for an Initial that has a short length", func() {
246+
h := &ExtendedHeader{
247+
Header: Header{
248+
IsLongHeader: true,
249+
Type: protocol.PacketTypeInitial,
250+
DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8},
251+
SrcConnectionID: protocol.ConnectionID{1, 2, 3, 4},
252+
Length: 15,
253+
},
254+
PacketNumberLen: protocol.PacketNumberLen2,
255+
}
256+
expectedLen := 1 /* type byte */ + 4 /* version */ + 1 /* dest conn id len */ + 8 /* dest conn id */ + 1 /* src conn ID len */ + 4 /* src conn id */ + 1 /* token length */ + 2 /* length len */ + 2 /* packet number */
257+
Expect(h.GetLength(versionIETFHeader)).To(BeEquivalentTo(expectedLen))
258+
Expect(h.Write(buf, versionIETFHeader)).To(Succeed())
259+
Expect(buf.Len()).To(Equal(expectedLen))
260+
})
261+
229262
It("has the right length for an Initial not containing a Token", func() {
230263
h := &ExtendedHeader{
231264
Header: Header{
@@ -237,7 +270,7 @@ var _ = Describe("Header", func() {
237270
},
238271
PacketNumberLen: protocol.PacketNumberLen2,
239272
}
240-
expectedLen := 1 /* type byte */ + 4 /* version */ + 1 /* dest conn id len */ + 8 /* dest conn id */ + 1 /* src conn ID len */ + 4 /* src conn id */ + 1 /* token length */ + 2 /* long len */ + 2 /* packet number */
273+
expectedLen := 1 /* type byte */ + 4 /* version */ + 1 /* dest conn id len */ + 8 /* dest conn id */ + 1 /* src conn ID len */ + 4 /* src conn id */ + 1 /* token length */ + 2 /* length len */ + 2 /* packet number */
241274
Expect(h.GetLength(versionIETFHeader)).To(BeEquivalentTo(expectedLen))
242275
Expect(h.Write(buf, versionIETFHeader)).To(Succeed())
243276
Expect(buf.Len()).To(Equal(expectedLen))

0 commit comments

Comments
 (0)