2022-09-17 22:07:00 +03:00
|
|
|
package core
|
|
|
|
|
|
|
|
import (
|
2023-04-06 23:45:49 +03:00
|
|
|
"context"
|
2023-11-04 20:57:15 +03:00
|
|
|
"crypto/tls"
|
2022-09-17 22:07:00 +03:00
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"net/url"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"golang.org/x/net/proxy"
|
|
|
|
)
|
|
|
|
|
|
|
|
type linkSOCKS struct {
|
|
|
|
*links
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *links) newLinkSOCKS() *linkSOCKS {
|
|
|
|
lt := &linkSOCKS{
|
|
|
|
links: l,
|
|
|
|
}
|
|
|
|
return lt
|
|
|
|
}
|
|
|
|
|
2023-08-12 20:12:58 +03:00
|
|
|
func (l *linkSOCKS) dial(_ context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) {
|
2023-04-06 23:45:49 +03:00
|
|
|
var proxyAuth *proxy.Auth
|
|
|
|
if url.User != nil && url.User.Username() != "" {
|
|
|
|
proxyAuth = &proxy.Auth{
|
|
|
|
User: url.User.Username(),
|
|
|
|
}
|
|
|
|
proxyAuth.Password, _ = url.User.Password()
|
2022-09-17 22:07:00 +03:00
|
|
|
}
|
|
|
|
dialer, err := proxy.SOCKS5("tcp", url.Host, proxyAuth, proxy.Direct)
|
|
|
|
if err != nil {
|
2023-04-06 23:45:49 +03:00
|
|
|
return nil, fmt.Errorf("failed to configure proxy")
|
2022-09-17 22:07:00 +03:00
|
|
|
}
|
|
|
|
pathtokens := strings.Split(strings.Trim(url.Path, "/"), "/")
|
2023-11-04 20:57:15 +03:00
|
|
|
conn, err := dialer.Dial("tcp", pathtokens[0])
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to dial: %w", err)
|
|
|
|
}
|
|
|
|
if url.Scheme == "sockstls" {
|
|
|
|
tlsconfig := l.tls.config.Clone()
|
|
|
|
tlsconfig.ServerName = options.tlsSNI
|
|
|
|
conn = tls.Client(conn, tlsconfig)
|
|
|
|
}
|
|
|
|
return conn, nil
|
2022-09-17 22:07:00 +03:00
|
|
|
}
|
|
|
|
|
2023-04-06 23:45:49 +03:00
|
|
|
func (l *linkSOCKS) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) {
|
|
|
|
return nil, fmt.Errorf("SOCKS listener not supported")
|
2022-09-17 22:07:00 +03:00
|
|
|
}
|