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

@@ -140,23 +140,13 @@ func newClient(
) (*client, error) {
clientConfig := populateClientConfig(config)
version := clientConfig.Versions[0]
srcConnID, err := generateConnectionID()
if err != nil {
return nil, err
}
destConnID := srcConnID
if version.UsesTLS() {
destConnID, err = generateConnectionID()
if err != nil {
return nil, err
}
}
var hostname string
if tlsConf != nil {
hostname = tlsConf.ServerName
}
if hostname == "" {
var err error
hostname, _, err = net.SplitHostPort(host)
if err != nil {
return nil, err
@@ -175,10 +165,8 @@ func newClient(
if closeCallback != nil {
onClose = closeCallback
}
return &client{
c := &client{
conn: &conn{pconn: pconn, currentAddr: remoteAddr},
srcConnID: srcConnID,
destConnID: destConnID,
hostname: hostname,
tlsConf: tlsConf,
config: clientConfig,
@@ -186,7 +174,8 @@ func newClient(
handshakeChan: make(chan struct{}),
closeCallback: onClose,
logger: utils.DefaultLogger.WithPrefix("client"),
}, nil
}
return c, c.generateConnectionIDs()
}
// populateClientConfig populates fields in the quic.Config with their default values, if none are set
@@ -243,6 +232,23 @@ func populateClientConfig(config *Config) *Config {
}
}
func (c *client) generateConnectionIDs() error {
srcConnID, err := generateConnectionID(protocol.ConnectionIDLenGQUIC)
if err != nil {
return err
}
destConnID := srcConnID
if c.version.UsesTLS() {
destConnID, err = protocol.GenerateDestinationConnectionID()
if err != nil {
return err
}
}
c.srcConnID = srcConnID
c.destConnID = destConnID
return nil
}
func (c *client) dial(ctx context.Context) error {
c.logger.Infof("Starting new connection to %s (%s -> %s), source connection ID %s, destination connection ID %s, version %s", c.hostname, c.conn.LocalAddr(), c.conn.RemoteAddr(), c.srcConnID, c.destConnID, c.version)
@@ -506,15 +512,8 @@ func (c *client) handleVersionNegotiationPacket(hdr *wire.Header) error {
// switch to negotiated version
c.initialVersion = c.version
c.version = newVersion
var err error
c.destConnID, err = generateConnectionID()
if err != nil {
return err
}
// in gQUIC, there's only one connection ID
if !c.version.UsesTLS() {
c.srcConnID = c.destConnID
}
c.generateConnectionIDs()
c.logger.Infof("Switching to QUIC version %s. New connection ID: %s", newVersion, c.destConnID)
c.session.Close(errCloseSessionForNewVersion)
return nil