diff --git a/src/core/link.go b/src/core/link.go index ccab9219..f753156e 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -98,6 +98,7 @@ func (l *links) call(u *url.URL, sintf string) error { l.tcp.call(pathtokens[0], tcpOpts, sintf) case "tls": tcpOpts.upgrade = l.tcp.tls.forDialer + tcpOpts.tlsSNI = u.Query().Get("sni") l.tcp.call(u.Host, tcpOpts, sintf) default: return errors.New("unknown call scheme: " + u.Scheme) diff --git a/src/core/tcp.go b/src/core/tcp.go index 572fd652..7b1773b8 100644 --- a/src/core/tcp.go +++ b/src/core/tcp.go @@ -64,6 +64,7 @@ type tcpOptions struct { socksProxyAddr string socksProxyAuth *proxy.Auth socksPeerAddr string + tlsSNI string } func (l *TcpListener) Stop() { diff --git a/src/core/tls.go b/src/core/tls.go index 4c25225b..eb21fcbc 100644 --- a/src/core/tls.go +++ b/src/core/tls.go @@ -77,8 +77,8 @@ func (t *tcptls) init(tcp *tcp) { } } -func (t *tcptls) configForOptions(options *tcpOptions) *tls.Config { - config := *t.config +func (t *tcptls) configForOptions(options *tcpOptions, serverName string) *tls.Config { + config := t.config.Clone() config.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error { if len(rawCerts) != 1 { return errors.New("tls not exactly 1 cert") @@ -103,11 +103,14 @@ func (t *tcptls) configForOptions(options *tcpOptions) *tls.Config { } return nil } - return &config + if serverName != "" { + config.ServerName = serverName + } + return config } func (t *tcptls) upgradeListener(c net.Conn, options *tcpOptions) (net.Conn, error) { - config := t.configForOptions(options) + config := t.configForOptions(options, "") conn := tls.Server(c, config) if err := conn.Handshake(); err != nil { return c, err @@ -116,7 +119,7 @@ func (t *tcptls) upgradeListener(c net.Conn, options *tcpOptions) (net.Conn, err } func (t *tcptls) upgradeDialer(c net.Conn, options *tcpOptions) (net.Conn, error) { - config := t.configForOptions(options) + config := t.configForOptions(options, options.tlsSNI) conn := tls.Client(c, config) if err := conn.Handshake(); err != nil { return c, err