mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-04-28 14:15:06 +03:00
70 lines
1.6 KiB
Go
70 lines
1.6 KiB
Go
package core
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"github.com/Arceliar/phony"
|
|
"github.com/coder/websocket"
|
|
)
|
|
|
|
type linkWSS struct {
|
|
phony.Inbox
|
|
*links
|
|
tlsconfig *tls.Config
|
|
}
|
|
|
|
type linkWSSConn struct {
|
|
net.Conn
|
|
}
|
|
|
|
func (l *links) newLinkWSS() *linkWSS {
|
|
lwss := &linkWSS{
|
|
links: l,
|
|
tlsconfig: l.core.config.tls.Clone(),
|
|
}
|
|
return lwss
|
|
}
|
|
|
|
func (l *linkWSS) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) {
|
|
tlsconfig := l.tlsconfig.Clone()
|
|
return l.links.findSuitableIP(url, func(hostname string, ip net.IP, port int) (net.Conn, error) {
|
|
tlsconfig.ServerName = hostname
|
|
u := *url
|
|
u.Host = net.JoinHostPort(ip.String(), fmt.Sprintf("%d", port))
|
|
addr := &net.TCPAddr{
|
|
IP: ip,
|
|
Port: port,
|
|
}
|
|
dialer, err := l.tcp.dialerFor(addr, info.sintf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
wsconn, _, err := websocket.Dial(ctx, u.String(), &websocket.DialOptions{
|
|
HTTPClient: &http.Client{
|
|
Transport: &http.Transport{
|
|
Proxy: http.ProxyFromEnvironment,
|
|
Dial: dialer.Dial,
|
|
DialContext: dialer.DialContext,
|
|
TLSClientConfig: tlsconfig,
|
|
},
|
|
},
|
|
Subprotocols: []string{"ygg-ws"},
|
|
Host: hostname,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &linkWSSConn{
|
|
Conn: websocket.NetConn(ctx, wsconn, websocket.MessageBinary),
|
|
}, nil
|
|
})
|
|
}
|
|
|
|
func (l *linkWSS) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) {
|
|
return nil, fmt.Errorf("WSS listener not supported, use WS listener behind reverse proxy instead")
|
|
}
|