fix: SOCKS5ProxyDialer 使用 ContextDialer 避免 Docker 内本地 DNS 解析失败
- 原实现 proxy.SOCKS5(..., proxy.Direct) 会先在本地做 DNS 解析
Docker 容器内无法解析 platform.claude.com 导致 30s 超时
- 改用 &net.Dialer{} + DialContext 让域名直接发给代理端远端解析
- 同时影响 OAuth token exchange 和 API 请求的 SOCKS5 路由
This commit is contained in:
parent
1a6a077743
commit
78f91da858
@ -160,7 +160,11 @@ func (d *SOCKS5ProxyDialer) DialTLSContext(ctx context.Context, network, addr st
|
|||||||
proxyAddr = net.JoinHostPort(d.proxyURL.Hostname(), "1080") // Default SOCKS5 port
|
proxyAddr = net.JoinHostPort(d.proxyURL.Hostname(), "1080") // Default SOCKS5 port
|
||||||
}
|
}
|
||||||
|
|
||||||
socksDialer, err := proxy.SOCKS5("tcp", proxyAddr, auth, proxy.Direct)
|
// Use a TCP-only forward dialer (no DNS resolution) so the SOCKS5 protocol
|
||||||
|
// sends the target hostname to the proxy for remote DNS resolution (socks5h semantics).
|
||||||
|
// proxy.Direct would attempt local DNS first, which fails inside Docker.
|
||||||
|
tcpDialer := &net.Dialer{}
|
||||||
|
socksDialer, err := proxy.SOCKS5("tcp", proxyAddr, auth, tcpDialer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Debug("tls_fingerprint_socks5_dialer_failed", "error", err)
|
slog.Debug("tls_fingerprint_socks5_dialer_failed", "error", err)
|
||||||
return nil, fmt.Errorf("create SOCKS5 dialer: %w", err)
|
return nil, fmt.Errorf("create SOCKS5 dialer: %w", err)
|
||||||
@ -168,7 +172,7 @@ func (d *SOCKS5ProxyDialer) DialTLSContext(ctx context.Context, network, addr st
|
|||||||
|
|
||||||
// Step 2: Establish SOCKS5 tunnel to target
|
// Step 2: Establish SOCKS5 tunnel to target
|
||||||
slog.Debug("tls_fingerprint_socks5_establishing_tunnel", "target", addr)
|
slog.Debug("tls_fingerprint_socks5_establishing_tunnel", "target", addr)
|
||||||
conn, err := socksDialer.Dial("tcp", addr)
|
conn, err := socksDialer.(proxy.ContextDialer).DialContext(ctx, "tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Debug("tls_fingerprint_socks5_connect_failed", "error", err)
|
slog.Debug("tls_fingerprint_socks5_connect_failed", "error", err)
|
||||||
return nil, fmt.Errorf("SOCKS5 connect: %w", err)
|
return nil, fmt.Errorf("SOCKS5 connect: %w", err)
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
@ -287,11 +288,9 @@ func createReqClient(proxyURL string) (*req.Client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.LegacyPrintf("repository.claude_oauth", "[OAuth] createReqClient: proxyURL=%q trimmed=%q", logredact.RedactProxyURL(proxyURL), logredact.RedactProxyURL(trimmed))
|
|
||||||
|
|
||||||
if trimmed != "" && parsedProxy != nil {
|
if trimmed != "" && parsedProxy != nil {
|
||||||
scheme := strings.ToLower(parsedProxy.Scheme)
|
scheme := strings.ToLower(parsedProxy.Scheme)
|
||||||
logger.LegacyPrintf("repository.claude_oauth", "[OAuth] createReqClient: using proxy scheme=%s host=%s", scheme, parsedProxy.Hostname())
|
slog.Info("oauth_create_client", "proxy_scheme", scheme, "proxy_host", parsedProxy.Hostname())
|
||||||
switch scheme {
|
switch scheme {
|
||||||
case "socks5", "socks5h":
|
case "socks5", "socks5h":
|
||||||
socks5Dialer := tlsfingerprint.NewSOCKS5ProxyDialer(profile, parsedProxy)
|
socks5Dialer := tlsfingerprint.NewSOCKS5ProxyDialer(profile, parsedProxy)
|
||||||
@ -303,7 +302,7 @@ func createReqClient(proxyURL string) (*req.Client, error) {
|
|||||||
client.SetProxyURL(trimmed)
|
client.SetProxyURL(trimmed)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.LegacyPrintf("repository.claude_oauth", "[OAuth] createReqClient: no proxy, using direct connection with utls")
|
slog.Info("oauth_create_client", "proxy_scheme", "none", "raw_proxy_url", proxyURL)
|
||||||
dialer := tlsfingerprint.NewDialer(profile, nil)
|
dialer := tlsfingerprint.NewDialer(profile, nil)
|
||||||
client.SetDialTLS(dialer.DialTLSContext)
|
client.SetDialTLS(dialer.DialTLSContext)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user