github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/transport/internet/websocket/dialer.go (about) 1 // +build !confonly 2 3 package websocket 4 5 import ( 6 "context" 7 "time" 8 9 "github.com/gorilla/websocket" 10 "v2ray.com/core/common" 11 "v2ray.com/core/common/net" 12 "v2ray.com/core/common/session" 13 "v2ray.com/core/transport/internet" 14 "v2ray.com/core/transport/internet/tls" 15 ) 16 17 // Dial dials a WebSocket connection to the given destination. 18 func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) { 19 newError("creating connection to ", dest).WriteToLog(session.ExportIDToError(ctx)) 20 21 conn, err := dialWebsocket(ctx, dest, streamSettings) 22 if err != nil { 23 return nil, newError("failed to dial WebSocket").Base(err) 24 } 25 return internet.Connection(conn), nil 26 } 27 28 func init() { 29 common.Must(internet.RegisterTransportDialer(protocolName, Dial)) 30 } 31 32 func dialWebsocket(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (net.Conn, error) { 33 wsSettings := streamSettings.ProtocolSettings.(*Config) 34 35 dialer := &websocket.Dialer{ 36 NetDial: func(network, addr string) (net.Conn, error) { 37 return internet.DialSystem(ctx, dest, streamSettings.SocketSettings) 38 }, 39 ReadBufferSize: 4 * 1024, 40 WriteBufferSize: 4 * 1024, 41 HandshakeTimeout: time.Second * 8, 42 } 43 44 protocol := "ws" 45 46 if config := tls.ConfigFromStreamSettings(streamSettings); config != nil { 47 protocol = "wss" 48 dialer.TLSClientConfig = config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("http/1.1")) 49 } 50 51 host := dest.NetAddr() 52 if (protocol == "ws" && dest.Port == 80) || (protocol == "wss" && dest.Port == 443) { 53 host = dest.Address.String() 54 } 55 uri := protocol + "://" + host + wsSettings.GetNormalizedPath() 56 57 conn, resp, err := dialer.Dial(uri, wsSettings.GetRequestHeader()) 58 if err != nil { 59 var reason string 60 if resp != nil { 61 reason = resp.Status 62 } 63 return nil, newError("failed to dial to (", uri, "): ", reason).Base(err) 64 } 65 66 return newConnection(conn, conn.RemoteAddr()), nil 67 }