forked from quic-go/quic-go
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:
@@ -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) {
|
||||
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user