Files
https-socks5-http/pkg/proxy/server.go
2025-01-10 14:07:07 +08:00

680 lines
21 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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
}