This commit is contained in:
2025-01-10 14:07:07 +08:00
commit 312e30c87b
15 changed files with 1356 additions and 0 deletions

679
pkg/proxy/server.go Normal file
View File

@@ -0,0 +1,679 @@
// Package proxy 实现代理服务器功能
package proxy
import (
"context"
"encoding/binary"
"errors"
"fmt"
"io"
"net"
"net/http"
"strings"
"sync"
"sync/atomic"
"time"
"encoding/base64"
"s5/pkg/config"
"s5/pkg/logger"
)
// ServerConfig 代理服务器配置
type ServerConfig struct {
Socks5Addr string // SOCKS5 代理监听地址
HttpAddr string // HTTP 代理监听地址
BufferSize int // 数据传输缓冲区大小
}
// Server 代理服务器实例
type Server struct {
config ServerConfig // 服务器配置
socks5Listener net.Listener // SOCKS5 监听器
httpServer *http.Server // HTTP 服务器
done chan struct{} // 关闭信号
activeConns sync.WaitGroup // 活动连接计数
upstreamDialer *UpstreamDialer // 上游代理拨号器
shutdownTimeout time.Duration // 关闭超时时间
directList *DirectList // 直连域名管理器
}
// NewServer 创建新的代理服务器实例
func NewServer(config ServerConfig, upstreamConfig config.UpstreamConfig) *Server {
log := logger.Get()
if !upstreamConfig.Enable {
log.Fatal("必须配置上游代理")
}
upstreamDialer := NewUpstreamDialer(upstreamConfig)
if upstreamDialer == nil {
log.Fatal("创建上游代理连接器失败")
}
return &Server{
config: config,
done: make(chan struct{}),
upstreamDialer: upstreamDialer,
shutdownTimeout: 30 * time.Second,
directList: NewDirectList("direct.txt"),
}
}
// Start 启动代理服务器
func (s *Server) Start(ctx context.Context) error {
log := logger.Get()
log.Debugf("[SERVER] =====================================================")
log.Infof("[SERVER] 代理服务器启动")
log.Debugf("[SERVER] 服务器配置:")
log.Debugf("[SERVER] - SOCKS5监听: %s", s.config.Socks5Addr)
log.Debugf("[SERVER] - HTTP监听: %s", s.config.HttpAddr)
log.Debugf("[SERVER] - 缓冲区大小: %s", formatBytes(int64(s.config.BufferSize)))
log.Debugf("[SERVER] - 上游代理: %s", s.upstreamDialer.config.Server)
log.Debugf("[SERVER] - 关闭超时: %v", s.shutdownTimeout)
log.Debugf("[SERVER] =====================================================")
// 启动 SOCKS5 服务器
var err error
s.socks5Listener, err = net.Listen("tcp", s.config.Socks5Addr)
if err != nil {
log.Errorf("[SERVER] 启动SOCKS5服务器失败: %v", err)
return fmt.Errorf("启动SOCKS5服务器失败: %v", err)
}
log.Infof("[SERVER] SOCKS5服务器启动成功: %s", s.config.Socks5Addr)
// 启动SOCKS5处理协程
go s.serveSocks5(ctx)
// 配置 HTTP 服务器
s.httpServer = &http.Server{
Addr: s.config.HttpAddr,
Handler: http.HandlerFunc(s.handleHTTP),
// 添加服务器超时配置
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 120 * time.Second,
MaxHeaderBytes: 1 << 20, // 1MB
}
// 监听关闭信号
go func() {
<-ctx.Done()
log.Debugf("[SERVER] 收到关闭信号")
// 使用带超时的上下文进行关闭
shutdownCtx, cancel := context.WithTimeout(context.Background(), s.shutdownTimeout)
defer cancel()
s.Shutdown(shutdownCtx)
}()
log.Infof("[SERVER] HTTP服务器启动: %s", s.config.HttpAddr)
err = s.httpServer.ListenAndServe()
if err == http.ErrServerClosed {
log.Debugf("[SERVER] HTTP服务器正常关闭")
return nil
}
return err
}
// Shutdown 优雅关闭服务器
func (s *Server) Shutdown(ctx context.Context) error {
log := logger.Get()
log.Debugf("[SERVER] =====================================================")
log.Infof("[SERVER] 开始优雅关闭服务器...")
// 创建一个带超时的上下文
shutdownCtx, cancel := context.WithTimeout(ctx, s.shutdownTimeout)
defer cancel()
// 关闭 SOCKS5 监听器
if s.socks5Listener != nil {
log.Debugf("[SERVER] 关闭SOCKS5监听器")
s.socks5Listener.Close()
}
// 关闭 HTTP 服务器
if s.httpServer != nil {
log.Debugf("[SERVER] 开始关闭HTTP服务器")
if err := s.httpServer.Shutdown(shutdownCtx); err != nil {
log.Errorf("[SERVER] HTTP服务器关闭失败: %v", err)
}
}
// 等待所有活动连接完成
log.Debugf("[SERVER] 等待活动连接完成 (超时: %v)...", s.shutdownTimeout)
done := make(chan struct{})
go func() {
s.activeConns.Wait()
close(done)
}()
// 等待连接完成或超时
select {
case <-shutdownCtx.Done():
log.Warnf("[SERVER] 等待连接超时,强制关闭")
// 打印当前活动连接数
activeCount := 0
s.activeConns.Add(0) // 利用Add(0)获取当前值
log.Warnf("[SERVER] 剩余活动连接数: %d", activeCount)
return fmt.Errorf("关闭超时")
case <-done:
log.Infof("[SERVER] 所有连接已正常关闭")
}
log.Debugf("[SERVER] =====================================================")
return nil
}
// serveSocks5 处理SOCKS5连接
func (s *Server) serveSocks5(ctx context.Context) {
log := logger.Get()
for {
select {
case <-ctx.Done():
return
default:
client, err := s.socks5Listener.Accept()
if err != nil {
if !errors.Is(err, net.ErrClosed) {
log.Errorw("接受SOCKS5连接错误", "error", err)
}
continue
}
s.activeConns.Add(1)
go func() {
defer s.activeConns.Done()
s.handleSocks5Connection(client)
}()
}
}
}
// handleSocks5Connection 处理SOCKS5连接
func (s *Server) handleSocks5Connection(client net.Conn) {
log := logger.Get()
log.Debugf("[SOCKS5] =====================================================")
log.Debugf("[SOCKS5] 收到新的SOCKS5连接")
clientAddr := client.RemoteAddr().String()
startTime := time.Now()
upBytes := &atomic.Int64{}
downBytes := &atomic.Int64{}
log.Debugf("[SOCKS5] 连接信息:")
log.Debugf("[SOCKS5] - 客户端地址: %s", clientAddr)
log.Debugf("[SOCKS5] - 本地地址: %s", client.LocalAddr())
log.Debugf("[SOCKS5] - 开始时间: %s", startTime.Format("2006-01-02 15:04:05.000"))
defer func() {
client.Close()
duration := time.Since(startTime)
log.Debugf("[SOCKS5] =====================================================")
log.Infof("[SOCKS5] 连接统计 [%s]:", clientAddr)
log.Infof("[SOCKS5] - 连接时长: %v", duration.Round(time.Millisecond))
log.Infof("[SOCKS5] - 上行流量: %s", formatBytes(upBytes.Load()))
log.Infof("[SOCKS5] - 下行流量: %s", formatBytes(downBytes.Load()))
log.Infof("[SOCKS5] - 总流量: %s", formatBytes(upBytes.Load() + downBytes.Load()))
log.Infof("[SOCKS5] - 平均速度: %s/s", formatBytes(int64(float64(upBytes.Load()+downBytes.Load())/duration.Seconds())))
log.Debugf("[SOCKS5] =====================================================")
}()
// SOCKS5 握手
if err := s.handleSocks5Handshake(client); err != nil {
log.Errorf("[SOCKS5] 握手失败 [%s]: %v", clientAddr, err)
return
}
// 处理请求
target, targetAddr, err := s.handleSocks5Request(client)
if err != nil {
log.Errorf("[SOCKS5] 处理请求失败 [%s]: %v", clientAddr, err)
return
}
defer target.Close()
log.Infof("[SOCKS5] 成功建立连接:")
log.Infof("[SOCKS5] - 客户端: %s", clientAddr)
log.Infof("[SOCKS5] - 目标地址: %s", targetAddr)
log.Infof("[SOCKS5] - 上游代理: %s", s.upstreamDialer.config.Server)
// 双向数据转发
var wg sync.WaitGroup
wg.Add(2)
// 上行数据传输
go func() {
defer wg.Done()
log.Debugf("[SOCKS5] 开始上行数据传输: %s -> %s", clientAddr, targetAddr)
n, err := io.Copy(target, client)
upBytes.Add(n)
if err != nil {
log.Debugf("[SOCKS5] 上行传输错误 [%s -> %s]: %v", clientAddr, targetAddr, err)
}
log.Debugf("[SOCKS5] 上行传输完成: %s", formatBytes(n))
}()
// 下行数据传输
go func() {
defer wg.Done()
log.Debugf("[SOCKS5] 开始下行数据传输: %s -> %s", targetAddr, clientAddr)
n, err := io.Copy(client, target)
downBytes.Add(n)
if err != nil {
log.Debugf("[SOCKS5] 下行传输错误 [%s -> %s]: %v", targetAddr, clientAddr, err)
}
log.Debugf("[SOCKS5] 下行传输完成: %s", formatBytes(n))
}()
wg.Wait()
log.Debugf("[SOCKS5] 连接关闭: %s <-> %s", clientAddr, targetAddr)
}
// handleHTTP 处理HTTP代理请求
func (s *Server) handleHTTP(w http.ResponseWriter, r *http.Request) {
log := logger.Get()
log.Debugf("[HTTP] =====================================================")
log.Debugf("[HTTP] 收到新的HTTP代理请求")
log.Debugf("[HTTP] 代理链路: %s -> [HTTP:%s] -> [HTTPS:%s] -> %s",
r.RemoteAddr,
s.config.HttpAddr,
s.upstreamDialer.config.Server,
r.Host)
clientAddr := r.RemoteAddr
startTime := time.Now()
upBytes := &atomic.Int64{}
downBytes := &atomic.Int64{}
// 详细的请求信息
log.Debugf("[HTTP] 请求详情:")
log.Debugf("[HTTP] - 客户端地址: %s", clientAddr)
log.Debugf("[HTTP] - 请求方法: %s", r.Method)
log.Debugf("[HTTP] - 请求URL: %s", r.URL)
log.Debugf("[HTTP] - HTTP版本: %s", r.Proto)
log.Debugf("[HTTP] - Host头: %s", r.Host)
log.Debugf("[HTTP] - 远程地址: %s", r.RemoteAddr)
log.Debugf("[HTTP] - 请求URI: %s", r.RequestURI)
log.Debugf("[HTTP] - Content-Length: %d", r.ContentLength)
log.Debugf("[HTTP] - Transfer-Encoding: %v", r.TransferEncoding)
log.Debugf("[HTTP] - Close: %v", r.Close)
log.Debugf("[HTTP] - TLS: %v", r.TLS != nil)
// 打印所有请求头
log.Debugf("[HTTP] 请求头:")
for k, vs := range r.Header {
for _, v := range vs {
log.Debugf("[HTTP] %s: %s", k, v)
// 如果是认证头,解码并显示
if strings.EqualFold(k, "Proxy-Authorization") || strings.EqualFold(k, "Authorization") {
if strings.HasPrefix(v, "Basic ") {
if decoded, err := base64.StdEncoding.DecodeString(v[6:]); err == nil {
log.Debugf("[HTTP] %s (decoded): %s", k, string(decoded))
}
}
}
}
}
// 打印Cookie信息
if cookies := r.Cookies(); len(cookies) > 0 {
log.Debugf("[HTTP] Cookies:")
for _, cookie := range cookies {
log.Debugf("[HTTP] - %s: %s", cookie.Name, cookie.Value)
}
}
s.activeConns.Add(1)
defer s.activeConns.Done()
if r.Method != http.MethodConnect {
log.Debugf("[HTTP] 不支持的请求方法: %s", r.Method)
http.Error(w, "仅支持CONNECT方法", http.StatusMethodNotAllowed)
return
}
hij, ok := w.(http.Hijacker)
if !ok {
log.Debugf("[HTTP] 当前连接不支持hijacking")
http.Error(w, "不支持hijacking", http.StatusInternalServerError)
return
}
proxyClient, _, err := hij.Hijack()
if err != nil {
log.Debugf("[HTTP] Hijack失败: %v", err)
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
defer func() {
proxyClient.Close()
duration := time.Since(startTime)
log.Debugf("[HTTP] =====================================================")
log.Infof("[HTTP] 连接统计 [%s]:", clientAddr)
log.Infof("[HTTP] - 目标地址: %s", r.Host)
log.Infof("[HTTP] - 连接时长: %v", duration.Round(time.Millisecond))
log.Infof("[HTTP] - 上行流量: %s", formatBytes(upBytes.Load()))
log.Infof("[HTTP] - 下行流量: %s", formatBytes(downBytes.Load()))
log.Infof("[HTTP] - 总流量: %s", formatBytes(upBytes.Load() + downBytes.Load()))
log.Debugf("[HTTP] =====================================================")
}()
log.Debugf("[HTTP] 开始连接目标服务器: %s", r.Host)
target, err := s.dialTarget(r.Host)
if err != nil {
log.Errorf("[HTTP] 连接目标服务器失败: %v", err)
proxyClient.Write([]byte("HTTP/1.1 502 Bad Gateway\r\n\r\n"))
return
}
log.Debugf("[HTTP] 发送连接成功响应:")
respHeaders := "HTTP/1.1 200 Connection Established\r\n" +
"Proxy-Agent: Go-Proxy-Client\r\n" +
"Connection: keep-alive\r\n\r\n"
log.Debugf("[HTTP] 响应头:")
for _, line := range strings.Split(respHeaders, "\r\n") {
if line != "" {
log.Debugf("[HTTP] %s", line)
}
}
proxyClient.Write([]byte(respHeaders))
log.Infof("[HTTP] 成功建立连接: %s -> %s", clientAddr, r.Host)
var wg sync.WaitGroup
wg.Add(2)
// 上行数据传输
go func() {
defer wg.Done()
log.Debugf("[HTTP] 开始上行数据传输: %s -> %s", clientAddr, r.Host)
n, err := io.Copy(target, proxyClient)
upBytes.Add(n)
if err != nil {
log.Debugf("[HTTP] 上行传输错误 [%s -> %s]: %v", clientAddr, r.Host, err)
}
log.Debugf("[HTTP] 上行传输完成: %s", formatBytes(n))
}()
// 下行数据传输
go func() {
defer wg.Done()
log.Debugf("[HTTP] 开始下行数据传输: %s -> %s", r.Host, clientAddr)
n, err := io.Copy(proxyClient, target)
downBytes.Add(n)
if err != nil {
log.Debugf("[HTTP] 下行传输错误 [%s -> %s]: %v", r.Host, clientAddr, err)
}
log.Debugf("[HTTP] 下行传输完成: %s", formatBytes(n))
}()
wg.Wait()
log.Debugf("[HTTP] 连接关闭: %s <-> %s", clientAddr, r.Host)
}
// formatBytes 格式化字节数
func formatBytes(bytes int64) string {
const unit = 1024
if bytes < unit {
return fmt.Sprintf("%d B", bytes)
}
div, exp := int64(unit), 0
for n := bytes / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.2f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
}
// handleSocks5Handshake 处理SOCKS5握手
func (s *Server) handleSocks5Handshake(client net.Conn) error {
log := logger.Get()
log.Debugf("[SOCKS5] =====================================================")
log.Debugf("[SOCKS5] 开始握手阶段")
// 读取客户端支持的认证方法
buf := make([]byte, 2)
if _, err := io.ReadFull(client, buf); err != nil {
log.Debugf("[SOCKS5] 读取认证方法失败: %v", err)
return fmt.Errorf("读取认证方法失败: %v", err)
}
log.Debugf("[SOCKS5] 收到握手请求:")
log.Debugf("[SOCKS5] - 版本号: SOCKS%d", buf[0])
log.Debugf("[SOCKS5] - 认证方法数量: %d", buf[1])
// 读取认证方法列表
methods := make([]byte, buf[1])
if _, err := io.ReadFull(client, methods); err != nil {
log.Debugf("[SOCKS5] 读取认证方法列表失败: %v", err)
return fmt.Errorf("读取认证方法列表失败: %v", err)
}
log.Debugf("[SOCKS5] 支持的认证方法:")
for _, method := range methods {
log.Debugf("[SOCKS5] - 0x%02x (%s)", method, socks5AuthMethodToString(method))
}
// 选择无认证方法
response := []byte{0x05, 0x00}
if _, err := client.Write(response); err != nil {
log.Debugf("[SOCKS5] 发送认证响应失败: %v", err)
return fmt.Errorf("发送认证响应失败: %v", err)
}
log.Debugf("[SOCKS5] 发送握手响应:")
log.Debugf("[SOCKS5] - 版本号: SOCKS5")
log.Debugf("[SOCKS5] - 选择的认证方法: 0x00 (NO AUTHENTICATION REQUIRED)")
log.Debugf("[SOCKS5] 握手完成")
log.Debugf("[SOCKS5] =====================================================")
return nil
}
// handleSocks5Request 处理SOCKS5请求
func (s *Server) handleSocks5Request(client net.Conn) (net.Conn, string, error) {
log := logger.Get()
log.Debugf("[SOCKS5] =====================================================")
log.Debugf("[SOCKS5] 开始处理请求")
log.Debugf("[SOCKS5] 代理链路: %s -> [SOCKS5:%s] -> [HTTPS:%s]",
client.RemoteAddr(),
s.config.Socks5Addr,
s.upstreamDialer.config.Server)
// 读取请求头
buf := make([]byte, 4)
if _, err := io.ReadFull(client, buf); err != nil {
log.Debugf("[SOCKS5] 读取请求头失败: %v", err)
return nil, "", fmt.Errorf("读取请求头失败: %v", err)
}
log.Debugf("[SOCKS5] 收到请求头:")
log.Debugf("[SOCKS5] - 版本号: SOCKS%d", buf[0])
log.Debugf("[SOCKS5] - 命令: %s (0x%02x)", socks5CmdToString(buf[1]), buf[1])
log.Debugf("[SOCKS5] - 保留字节: 0x%02x", buf[2])
log.Debugf("[SOCKS5] - 地址类型: %s (0x%02x)", socks5AddrTypeToString(buf[3]), buf[3])
// 读取目标地址
var addr string
switch buf[3] {
case 0x01: // IPv4
ipv4 := make([]byte, 4)
if _, err := io.ReadFull(client, ipv4); err != nil {
log.Debugf("[SOCKS5] 读取IPv4地址失败: %v", err)
return nil, "", fmt.Errorf("读取IPv4地址失败: %v", err)
}
addr = net.IP(ipv4).String()
log.Debugf("[SOCKS5] - IPv4地址: %s", addr)
case 0x03: // 域名
domainLen := make([]byte, 1)
if _, err := io.ReadFull(client, domainLen); err != nil {
log.Debugf("[SOCKS5] 读取域名长度失败: %v", err)
return nil, "", fmt.Errorf("读取域名长度失败: %v", err)
}
domain := make([]byte, domainLen[0])
if _, err := io.ReadFull(client, domain); err != nil {
log.Debugf("[SOCKS5] 读取域名失败: %v", err)
return nil, "", fmt.Errorf("读取域名失败: %v", err)
}
addr = string(domain)
log.Debugf("[SOCKS5] - 域名长度: %d", domainLen[0])
log.Debugf("[SOCKS5] - 域名: %s", addr)
case 0x04: // IPv6
ipv6 := make([]byte, 16)
if _, err := io.ReadFull(client, ipv6); err != nil {
log.Debugf("[SOCKS5] 读取IPv6地址失败: %v", err)
return nil, "", fmt.Errorf("读取IPv6地址失败: %v", err)
}
addr = net.IP(ipv6).String()
log.Debugf("[SOCKS5] - IPv6地址: %s", addr)
}
// 读取端口
portBuf := make([]byte, 2)
if _, err := io.ReadFull(client, portBuf); err != nil {
log.Debugf("[SOCKS5] 读取端口失败: %v", err)
return nil, "", fmt.Errorf("读取端口失败: %v", err)
}
port := binary.BigEndian.Uint16(portBuf)
targetAddr := fmt.Sprintf("%s:%d", addr, port)
log.Debugf("[SOCKS5] 完整代理链路: %s -> [SOCKS5:%s] -> [HTTPS:%s] -> %s",
client.RemoteAddr(),
s.config.Socks5Addr,
s.upstreamDialer.config.Server,
targetAddr)
log.Debugf("[SOCKS5] - 端口: %d", port)
log.Debugf("[SOCKS5] - 完整目标地址: %s", targetAddr)
// 连接目标服务器
log.Debugf("[SOCKS5] 开始连接目标服务器...")
target, err := s.dialTarget(targetAddr)
if err != nil {
log.Debugf("[SOCKS5] 连接目标服务器失败: %v", err)
// 发送失败响应
resp := []byte{0x05, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
log.Debugf("[SOCKS5] 发送失败响应: %x", resp)
client.Write(resp)
return nil, "", fmt.Errorf("连接目标服务器失败: %v", err)
}
// 发送成功响应
resp := []byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
log.Debugf("[SOCKS5] 发送成功响应: %x", resp)
client.Write(resp)
log.Debugf("[SOCKS5] 请求处理完成")
log.Debugf("[SOCKS5] =====================================================")
return target, targetAddr, nil
}
// 辅助函数将SOCKS5认证方法转换为字符串
func socks5AuthMethodToString(method byte) string {
switch method {
case 0x00:
return "NO AUTHENTICATION REQUIRED"
case 0x01:
return "GSSAPI"
case 0x02:
return "USERNAME/PASSWORD"
case 0xff:
return "NO ACCEPTABLE METHODS"
default:
return fmt.Sprintf("UNKNOWN METHOD(0x%02x)", method)
}
}
// 辅助函数将SOCKS5命令转换为字符串
func socks5CmdToString(cmd byte) string {
switch cmd {
case 0x01:
return "CONNECT"
case 0x02:
return "BIND"
case 0x03:
return "UDP ASSOCIATE"
default:
return fmt.Sprintf("UNKNOWN COMMAND(0x%02x)", cmd)
}
}
// 辅助函数将SOCKS5地址类型转换为字符串
func socks5AddrTypeToString(addrType byte) string {
switch addrType {
case 0x01:
return "IPv4"
case 0x03:
return "DOMAIN"
case 0x04:
return "IPv6"
default:
return fmt.Sprintf("UNKNOWN ADDRESS TYPE(0x%02x)", addrType)
}
}
// dialTarget 连接目标服务器
func (s *Server) dialTarget(addr string) (net.Conn, error) {
log := logger.Get()
log.Debugf("[PROXY] =====================================================")
log.Debugf("[PROXY] 开始处理连接请求: %s", addr)
// 提取域名和端口
host := addr
port := ""
if idx := strings.LastIndex(addr, ":"); idx != -1 {
host = addr[:idx]
port = addr[idx+1:]
}
// 检查是否是IP地址
if ip := net.ParseIP(host); ip != nil {
log.Debugf("[PROXY] 目标是IP地址: %s", host)
log.Debugf("[PROXY] - 端口: %s", port)
} else {
log.Debugf("[PROXY] 目标是域名: %s", host)
log.Debugf("[PROXY] - 端口: %s", port)
}
// 检查是否是直连域名
useDirect := s.directList.Match(host)
log.Debugf("[PROXY] 连接方式判断:")
log.Debugf("[PROXY] - 是否直连域名: %v", useDirect)
if useDirect {
// 使用直接连接
log.Debugf("[PROXY] 使用直接连接")
conn, err := net.Dial("tcp", addr)
if err != nil {
log.Errorf("[PROXY] 直接连接失败: %v", err)
log.Debugf("[PROXY] =====================================================")
return nil, err
}
log.Debugf("[PROXY] 直接连接成功")
log.Debugf("[PROXY] 连接详情:")
log.Debugf("[PROXY] - 本地地址: %s", conn.LocalAddr())
log.Debugf("[PROXY] - 远程地址: %s", conn.RemoteAddr())
log.Debugf("[PROXY] =====================================================")
return conn, nil
}
// 使用代理连接
log.Debugf("[PROXY] 使用代理连接:")
log.Debugf("[PROXY] - 上游代理: %s", s.upstreamDialer.config.Server)
log.Debugf("[PROXY] - 代理类型: %s", s.upstreamDialer.config.Type)
conn, err := s.upstreamDialer.Dial("tcp", addr)
if err != nil {
log.Errorf("[PROXY] 代理连接失败: %v", err)
log.Debugf("[PROXY] =====================================================")
return nil, err
}
log.Debugf("[PROXY] 代理连接成功")
log.Debugf("[PROXY] 连接详情:")
log.Debugf("[PROXY] - 本地地址: %s", conn.LocalAddr())
log.Debugf("[PROXY] - 远程地址: %s", conn.RemoteAddr())
log.Debugf("[PROXY] =====================================================")
return conn, nil
}