use a random length destination connection ID on the Initial packet

The destination connection ID on the Initial packet must be at least 8
bytes long. By using all valid values, we make sure that the everything
works correctly. The server chooses a new connection ID with the Retry
or Handshake packet it sends, so the overhead of this is negligible.
This commit is contained in:
Marten Seemann
2018-07-01 13:48:47 +07:00
parent 0bd7e744ff
commit 73f7636537
6 changed files with 78 additions and 38 deletions

View File

@@ -10,15 +10,28 @@ import (
// A ConnectionID in QUIC
type ConnectionID []byte
const maxConnectionIDLen = 18
// GenerateConnectionID generates a connection ID using cryptographic random
func GenerateConnectionID() (ConnectionID, error) {
b := make([]byte, ConnectionIDLenGQUIC)
func GenerateConnectionID(len int) (ConnectionID, error) {
b := make([]byte, len)
if _, err := rand.Read(b); err != nil {
return nil, err
}
return ConnectionID(b), nil
}
// GenerateDestinationConnectionID generates a connection ID for the Initial packet.
// It uses a length randomly chosen between 8 and 18 bytes.
func GenerateDestinationConnectionID() (ConnectionID, error) {
r := make([]byte, 1)
if _, err := rand.Read(r); err != nil {
return nil, err
}
len := MinConnectionIDLenInitial + int(r[0])%(maxConnectionIDLen-MinConnectionIDLenInitial+1)
return GenerateConnectionID(len)
}
// ReadConnectionID reads a connection ID of length len from the given io.Reader.
// It returns io.EOF if there are not enough bytes to read.
func ReadConnectionID(r io.Reader, len int) (ConnectionID, error) {

View File

@@ -10,14 +10,38 @@ import (
var _ = Describe("Connection ID generation", func() {
It("generates random connection IDs", func() {
c1, err := GenerateConnectionID()
c1, err := GenerateConnectionID(8)
Expect(err).ToNot(HaveOccurred())
Expect(c1).ToNot(BeZero())
c2, err := GenerateConnectionID()
c2, err := GenerateConnectionID(8)
Expect(err).ToNot(HaveOccurred())
Expect(c1).ToNot(Equal(c2))
})
It("generates connection IDs with the requested length", func() {
c, err := GenerateConnectionID(5)
Expect(err).ToNot(HaveOccurred())
Expect(c.Len()).To(Equal(5))
})
It("generates random length destination connection IDs", func() {
var has8ByteConnID, has18ByteConnID bool
for i := 0; i < 1000; i++ {
c, err := GenerateDestinationConnectionID()
Expect(err).ToNot(HaveOccurred())
Expect(c.Len()).To(BeNumerically(">=", 8))
Expect(c.Len()).To(BeNumerically("<=", 18))
if c.Len() == 8 {
has8ByteConnID = true
}
if c.Len() == 18 {
has18ByteConnID = true
}
}
Expect(has8ByteConnID).To(BeTrue())
Expect(has18ByteConnID).To(BeTrue())
})
It("says if connection IDs are equal", func() {
c1 := ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
c2 := ConnectionID{8, 7, 6, 5, 4, 3, 2, 1}