add a quic.Config option to ask the server to truncate the connection ID

This commit is contained in:
Marten Seemann
2017-05-10 00:00:45 +08:00
parent 650af86c70
commit 7a18b870e8
8 changed files with 64 additions and 6 deletions

View File

@@ -3,4 +3,5 @@
## v0.6.0 (unreleased)
- Add a `quic.Config` option for QUIC versions
- Add a `quic.Config` option to request truncation of the connection ID from a server
- Various bugfixes

View File

@@ -75,9 +75,10 @@ func populateClientConfig(config *Config) *Config {
}
return &Config{
TLSConfig: config.TLSConfig,
ConnState: config.ConnState,
Versions: versions,
TLSConfig: config.TLSConfig,
ConnState: config.ConnState,
Versions: versions,
RequestConnectionIDTruncation: config.RequestConnectionIDTruncation,
}
}

View File

@@ -51,6 +51,7 @@ type cryptoSetupClient struct {
forwardSecureAEAD crypto.AEAD
aeadChanged chan<- protocol.EncryptionLevel
params *TransportParameters
connectionParameters ConnectionParametersManager
}
@@ -71,6 +72,7 @@ func NewCryptoSetupClient(
tlsConfig *tls.Config,
connectionParameters ConnectionParametersManager,
aeadChanged chan<- protocol.EncryptionLevel,
params *TransportParameters,
negotiatedVersions []protocol.VersionNumber,
) (CryptoSetup, error) {
return &cryptoSetupClient{
@@ -86,6 +88,7 @@ func NewCryptoSetupClient(
aeadChanged: aeadChanged,
negotiatedVersions: negotiatedVersions,
divNonceChan: make(chan []byte),
params: params,
}, nil
}
@@ -428,10 +431,12 @@ func (h *cryptoSetupClient) getTags() (map[Tag][]byte, error) {
binary.LittleEndian.PutUint32(versionTag, protocol.VersionNumberToTag(h.version))
tags[TagVER] = versionTag
if h.params.RequestConnectionIDTruncation {
tags[TagTCID] = []byte{0, 0, 0, 0}
}
if len(h.stk) > 0 {
tags[TagSTK] = h.stk
}
if len(h.sno) > 0 {
tags[TagSNO] = h.sno
}

View File

@@ -105,7 +105,17 @@ var _ = Describe("Client Crypto Setup", func() {
certManager = &mockCertManager{}
version := protocol.Version36
aeadChanged = make(chan protocol.EncryptionLevel, 2)
csInt, err := NewCryptoSetupClient("hostname", 0, version, stream, nil, NewConnectionParamatersManager(protocol.PerspectiveClient, version), aeadChanged, nil)
csInt, err := NewCryptoSetupClient(
"hostname",
0,
version,
stream,
nil,
NewConnectionParamatersManager(protocol.PerspectiveClient, version),
aeadChanged,
&TransportParameters{},
nil,
)
Expect(err).ToNot(HaveOccurred())
cs = csInt.(*cryptoSetupClient)
cs.certManager = certManager
@@ -468,6 +478,14 @@ var _ = Describe("Client Crypto Setup", func() {
Expect(tags[TagPDMD]).To(Equal([]byte("X509")))
Expect(tags[TagVER]).To(Equal([]byte("Q036")))
Expect(tags[TagCCS]).To(Equal(certManager.commonCertificateHashes))
Expect(tags).ToNot(HaveKey(TagTCID))
})
It("requests to truncate the connection ID", func() {
cs.params.RequestConnectionIDTruncation = true
tags, err := cs.getTags()
Expect(err).ToNot(HaveOccurred())
Expect(tags).To(HaveKeyWithValue(TagTCID, []byte{0, 0, 0, 0}))
})
It("adds the tags returned from the connectionParametersManager to the CHLO", func() {

View File

@@ -16,3 +16,8 @@ type CryptoSetup interface {
GetSealer() (protocol.EncryptionLevel, Sealer)
GetSealerWithEncryptionLevel(protocol.EncryptionLevel) (Sealer, error)
}
// TransportParameters are parameters sent to the peer during the handshake
type TransportParameters struct {
RequestConnectionIDTruncation bool
}

View File

@@ -67,6 +67,10 @@ type Config struct {
// If not set, it uses all versions available.
// Warning: This API should not be considered stable and will change soon.
Versions []protocol.VersionNumber
// Ask the server to truncate the connection ID sent in the Public Header.
// This saves 8 bytes in the Public Header in every packet. However, if the IP address of the server changes, the connection cannot be migrated.
// Currently only valid for the client.
RequestConnectionIDTruncation bool
}
// A Listener for incoming QUIC connections

View File

@@ -175,7 +175,17 @@ func newClientSession(
s.aeadChanged = aeadChanged
cryptoStream, _ := s.OpenStream()
var err error
s.cryptoSetup, err = handshake.NewCryptoSetupClient(hostname, connectionID, v, cryptoStream, config.TLSConfig, s.connectionParameters, aeadChanged, negotiatedVersions)
s.cryptoSetup, err = handshake.NewCryptoSetupClient(
hostname,
connectionID,
v,
cryptoStream,
config.TLSConfig,
s.connectionParameters,
aeadChanged,
&handshake.TransportParameters{RequestConnectionIDTruncation: config.RequestConnectionIDTruncation},
negotiatedVersions,
)
if err != nil {
return nil, err
}

View File

@@ -749,6 +749,20 @@ var _ = Describe("Session", func() {
Expect(clientSess.Close(nil)).To(Succeed())
})
It("passes the transport parameters to the cryptoSetup, as a client", func() {
s, err := newClientSession(
nil,
"hostname",
protocol.Version35,
0,
func(Session, bool) {},
populateClientConfig(&Config{RequestConnectionIDTruncation: true}),
nil,
)
Expect(err).ToNot(HaveOccurred())
Expect(*(*bool)(unsafe.Pointer(reflect.ValueOf(s.cryptoSetup).Elem().FieldByName("params").Elem().FieldByName("RequestConnectionIDTruncation").UnsafeAddr()))).To(BeTrue())
})
Context("updating the remote address", func() {
It("sets the remote address", func() {
remoteIP := &net.IPAddr{IP: net.IPv4(192, 168, 0, 100)}