|
|
@@ -6,6 +6,7 @@ import (
|
|
|
"encoding/base64"
|
|
|
"fmt"
|
|
|
"io"
|
|
|
+ gonet "net"
|
|
|
"net/http"
|
|
|
"os"
|
|
|
"time"
|
|
|
@@ -83,7 +84,31 @@ func dialWebSocket(ctx context.Context, dest net.Destination, streamSettings *in
|
|
|
|
|
|
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
|
|
|
protocol = "wss"
|
|
|
- dialer.TLSClientConfig = config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("http/1.1"))
|
|
|
+ tlsConfig := config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("http/1.1"))
|
|
|
+ dialer.TLSClientConfig = tlsConfig
|
|
|
+ if fingerprint, exists := tls.Fingerprints[config.Fingerprint]; exists {
|
|
|
+ dialer.NetDialTLSContext = func(_ context.Context, _, addr string) (gonet.Conn, error) {
|
|
|
+ // Like the NetDial in the dialer
|
|
|
+ pconn, err := internet.DialSystem(ctx, dest, streamSettings.SocketSettings)
|
|
|
+ if err != nil {
|
|
|
+ newError("failed to dial to " + addr).Base(err).AtError().WriteToLog()
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ // TLS and apply the handshake
|
|
|
+ cn := tls.UClient(pconn, tlsConfig, fingerprint).(*tls.UConn)
|
|
|
+ if err := cn.WebsocketHandshake(); err != nil {
|
|
|
+ newError("failed to dial to " + addr).Base(err).AtError().WriteToLog()
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ if !tlsConfig.InsecureSkipVerify {
|
|
|
+ if err := cn.VerifyHostname(tlsConfig.ServerName); err != nil {
|
|
|
+ newError("failed to dial to " + addr).Base(err).AtError().WriteToLog()
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return cn, nil
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
host := dest.NetAddr()
|