mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-07 06:07:36 +03:00
implement sending of truncated ConnectionIDs
This commit is contained in:
parent
965addac79
commit
bb807fa5bd
8 changed files with 81 additions and 21 deletions
|
@ -39,7 +39,7 @@ func (h *ConnectionParametersManager) SetFromMap(params map[Tag][]byte) error {
|
|||
h.mutex.Lock()
|
||||
for key, value := range params {
|
||||
switch key {
|
||||
case TagSFCW, TagCFCW, TagICSL, TagMSPC:
|
||||
case TagSFCW, TagCFCW, TagICSL, TagMSPC, TagTCID:
|
||||
h.params[key] = value
|
||||
}
|
||||
}
|
||||
|
@ -61,10 +61,10 @@ func (h *ConnectionParametersManager) GetRawValue(tag Tag) ([]byte, error) {
|
|||
|
||||
// GetSHLOMap gets all values (except crypto values) needed for the SHLO
|
||||
func (h *ConnectionParametersManager) GetSHLOMap() map[Tag][]byte {
|
||||
// Since GetSHLOMap is only called from the crypto stream, and changes to
|
||||
// the params are only made by the crypto stream itself, there is no data race
|
||||
// here, and we need not copy the map.
|
||||
return h.params
|
||||
return map[Tag][]byte{
|
||||
TagICSL: []byte{0x1e, 0x00, 0x00, 0x00}, //30
|
||||
TagMSPC: []byte{0x64, 0x00, 0x00, 0x00}, //100
|
||||
}
|
||||
}
|
||||
|
||||
// GetStreamFlowControlWindow gets the size of the stream-level flow control window
|
||||
|
@ -96,3 +96,23 @@ func (h *ConnectionParametersManager) GetIdleConnectionStateLifetime() time.Dura
|
|||
}
|
||||
return time.Duration(binary.LittleEndian.Uint32(rawValue)) * time.Second
|
||||
}
|
||||
|
||||
// TruncateConnectionID determines if the client requests truncated ConnectionIDs
|
||||
func (h *ConnectionParametersManager) TruncateConnectionID() bool {
|
||||
rawValue, err := h.GetRawValue(TagTCID)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var value uint32
|
||||
buf := bytes.NewBuffer(rawValue)
|
||||
err = binary.Read(buf, binary.LittleEndian, &value)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if value == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -39,6 +39,20 @@ var _ = Describe("ConnectionsParameterManager", func() {
|
|||
Expect(entryMap).To(HaveKey(TagMSPC))
|
||||
})
|
||||
|
||||
Context("Truncated connection IDs", func() {
|
||||
It("does not send truncated connection IDs if the TCID tag is missing", func() {
|
||||
Expect(cpm.TruncateConnectionID()).To(BeFalse())
|
||||
})
|
||||
|
||||
It("reads the tag for truncated connection IDs", func() {
|
||||
values := map[Tag][]byte{
|
||||
TagTCID: []byte{0, 0, 0, 0},
|
||||
}
|
||||
cpm.SetFromMap(values)
|
||||
Expect(cpm.TruncateConnectionID()).To(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Context("flow control", func() {
|
||||
It("has the correct default flow control window", func() {
|
||||
val, err := cpm.GetStreamFlowControlWindow()
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/lucas-clemente/quic-go/crypto"
|
||||
"github.com/lucas-clemente/quic-go/frames"
|
||||
"github.com/lucas-clemente/quic-go/handshake"
|
||||
"github.com/lucas-clemente/quic-go/protocol"
|
||||
"github.com/lucas-clemente/quic-go/utils"
|
||||
)
|
||||
|
@ -20,6 +21,7 @@ type packedPacket struct {
|
|||
type packetPacker struct {
|
||||
connectionID protocol.ConnectionID
|
||||
aead crypto.AEAD
|
||||
connectionParametersManager *handshake.ConnectionParametersManager
|
||||
|
||||
streamFrameQueue StreamFrameQueue
|
||||
|
||||
|
@ -68,6 +70,7 @@ func (p *packetPacker) PackPacket(stopWaitingFrame *frames.StopWaitingFrame, con
|
|||
responsePublicHeader := PublicHeader{
|
||||
ConnectionID: p.connectionID,
|
||||
PacketNumber: currentPacketNumber,
|
||||
TruncateConnectionID: p.connectionParametersManager.TruncateConnectionID(),
|
||||
}
|
||||
if err := responsePublicHeader.WritePublicHeader(&raw); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/lucas-clemente/quic-go/crypto"
|
||||
"github.com/lucas-clemente/quic-go/frames"
|
||||
"github.com/lucas-clemente/quic-go/handshake"
|
||||
"github.com/lucas-clemente/quic-go/protocol"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
@ -17,7 +18,7 @@ var _ = Describe("Packet packer", func() {
|
|||
|
||||
BeforeEach(func() {
|
||||
aead := &crypto.NullAEAD{}
|
||||
packer = &packetPacker{aead: aead}
|
||||
packer = &packetPacker{aead: aead, connectionParametersManager: handshake.NewConnectionParamatersManager()}
|
||||
})
|
||||
|
||||
It("returns nil when no packet is queued", func() {
|
||||
|
|
|
@ -21,6 +21,7 @@ type PublicHeader struct {
|
|||
VersionFlag bool
|
||||
ResetFlag bool
|
||||
ConnectionID protocol.ConnectionID
|
||||
TruncateConnectionID bool
|
||||
VersionNumber protocol.VersionNumber
|
||||
QuicVersion uint32
|
||||
PacketNumberLen uint8
|
||||
|
@ -29,7 +30,7 @@ type PublicHeader struct {
|
|||
|
||||
// WritePublicHeader writes a public header
|
||||
func (h *PublicHeader) WritePublicHeader(b *bytes.Buffer) error {
|
||||
publicFlagByte := uint8(0x3c)
|
||||
publicFlagByte := uint8(0x34)
|
||||
if h.VersionFlag && h.ResetFlag {
|
||||
return errResetAndVersionFlagSet
|
||||
}
|
||||
|
@ -39,9 +40,16 @@ func (h *PublicHeader) WritePublicHeader(b *bytes.Buffer) error {
|
|||
if h.ResetFlag {
|
||||
publicFlagByte |= 0x02
|
||||
}
|
||||
if !h.TruncateConnectionID {
|
||||
publicFlagByte |= 0x08
|
||||
}
|
||||
|
||||
b.WriteByte(publicFlagByte)
|
||||
utils.WriteUint64(b, uint64(h.ConnectionID)) // TODO: Send shorter connection id if possible
|
||||
|
||||
if !h.TruncateConnectionID {
|
||||
utils.WriteUint64(b, uint64(h.ConnectionID))
|
||||
}
|
||||
|
||||
utils.WriteUint48(b, uint64(h.PacketNumber)) // TODO: Send shorter packet number if possible
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -125,5 +125,18 @@ var _ = Describe("Public Header", func() {
|
|||
Expect(err).To(HaveOccurred())
|
||||
Expect(err).To(Equal(errResetAndVersionFlagSet))
|
||||
})
|
||||
|
||||
It("truncates the connection ID", func() {
|
||||
b := &bytes.Buffer{}
|
||||
publicHeader := PublicHeader{
|
||||
ConnectionID: 0x4cfa9f9b668619f6,
|
||||
TruncateConnectionID: true,
|
||||
}
|
||||
err := publicHeader.WritePublicHeader(b)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
firstByte, _ := b.ReadByte()
|
||||
Expect(firstByte & 0x08).To(BeZero())
|
||||
Expect(b.Bytes()).ToNot(ContainSubstring(string([]byte{0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c})))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -94,7 +94,7 @@ func NewSession(conn connection, v protocol.VersionNumber, connectionID protocol
|
|||
}
|
||||
}()
|
||||
|
||||
session.packer = &packetPacker{aead: cryptoSetup, connectionID: connectionID}
|
||||
session.packer = &packetPacker{aead: cryptoSetup, connectionParametersManager: session.connectionParametersManager, connectionID: connectionID}
|
||||
session.unpacker = &packetUnpacker{aead: cryptoSetup}
|
||||
|
||||
return session
|
||||
|
|
|
@ -352,6 +352,7 @@ var _ = Describe("Session", func() {
|
|||
session.connectionParametersManager.SetFromMap(map[handshake.Tag][]byte{
|
||||
handshake.TagICSL: {0, 0, 0, 0},
|
||||
})
|
||||
session.packer.connectionParametersManager = session.connectionParametersManager
|
||||
session.Run() // Would normally not return
|
||||
Expect(conn.written[0]).To(ContainSubstring("No recent network activity."))
|
||||
close(done)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue