From 7c31c26d866afe8d4f9ce2cb0fccd1b746e686f5 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 6 Jul 2020 17:37:52 +0200 Subject: [PATCH] Don't perform TLS handshake in connectToUpstream This defers TLS handshake until the first read or write operation. This allows the upcoming identd server to register the connection before the TLS handshake is complete, and is necessary because some IRC servers send an ident request before that. --- upstream.go | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/upstream.go b/upstream.go index b1b8330..25b0bf5 100644 --- a/upstream.go +++ b/upstream.go @@ -98,13 +98,15 @@ func connectToUpstream(network *network) (*upstreamConn, error) { switch u.Scheme { case "ircs": addr := u.Host - if _, _, err := net.SplitHostPort(addr); err != nil { - addr = addr + ":6697" + host, _, err := net.SplitHostPort(u.Host) + if err != nil { + host = u.Host + addr = u.Host + ":6697" } logger.Printf("connecting to TLS server at address %q", addr) - var tlsConfig *tls.Config + tlsConfig := &tls.Config{ServerName: host} if network.SASL.Mechanism == "EXTERNAL" { if network.SASL.External.CertBlob == nil { return nil, fmt.Errorf("missing certificate for authentication") @@ -116,21 +118,24 @@ func connectToUpstream(network *network) (*upstreamConn, error) { if err != nil { return nil, fmt.Errorf("failed to parse private key: %v", err) } - tlsConfig = &tls.Config{ - Certificates: []tls.Certificate{ - { - Certificate: [][]byte{network.SASL.External.CertBlob}, - PrivateKey: key.(crypto.PrivateKey), - }, + tlsConfig.Certificates = []tls.Certificate{ + { + Certificate: [][]byte{network.SASL.External.CertBlob}, + PrivateKey: key.(crypto.PrivateKey), }, } logger.Printf("using TLS client certificate %x", sha256.Sum256(network.SASL.External.CertBlob)) } - netConn, err = tls.DialWithDialer(&dialer, "tcp", addr, tlsConfig) + netConn, err = dialer.Dial("tcp", addr) if err != nil { return nil, fmt.Errorf("failed to dial %q: %v", addr, err) } + + // Don't do the TLS handshake immediately, because we need to register + // the new connection with identd ASAP. See: + // https://todo.sr.ht/~emersion/soju/69#event-41859 + netConn = tls.Client(netConn, tlsConfig) case "irc+insecure": addr := u.Host if _, _, err := net.SplitHostPort(addr); err != nil {