This commit is contained in:
2025-01-10 14:31:56 +08:00
parent 312e30c87b
commit e8a63b28e2
6 changed files with 329 additions and 153 deletions

View File

@@ -3,6 +3,7 @@ package proxy
import (
"context"
"encoding/base64"
"encoding/binary"
"errors"
"fmt"
@@ -13,7 +14,6 @@ import (
"sync"
"sync/atomic"
"time"
"encoding/base64"
"s5/pkg/config"
"s5/pkg/logger"
@@ -28,14 +28,14 @@ type ServerConfig struct {
// 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 // 直连域名管理器
config ServerConfig // 服务器配置
socks5Listener net.Listener // SOCKS5 监听器
httpServer *http.Server // HTTP 服务器
done chan struct{} // 关闭信号
activeConns sync.WaitGroup // 活动连接计数
upstreamDialer *UpstreamDialer // 上游代理拨号器
shutdownTimeout time.Duration // 关闭超时时间
directList *ProxyList // 直连域名管理器
}
// NewServer 创建新的代理服务器实例
@@ -52,11 +52,11 @@ func NewServer(config ServerConfig, upstreamConfig config.UpstreamConfig) *Serve
}
return &Server{
config: config,
done: make(chan struct{}),
upstreamDialer: upstreamDialer,
config: config,
done: make(chan struct{}),
upstreamDialer: upstreamDialer,
shutdownTimeout: 30 * time.Second,
directList: NewDirectList("direct.txt"),
directList: NewProxyList("proxy.txt"),
}
}
@@ -193,7 +193,7 @@ 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{}
@@ -212,7 +212,7 @@ func (s *Server) handleSocks5Connection(client net.Conn) {
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", formatBytes(upBytes.Load()+downBytes.Load()))
log.Infof("[SOCKS5] - 平均速度: %s/s", formatBytes(int64(float64(upBytes.Load()+downBytes.Load())/duration.Seconds())))
log.Debugf("[SOCKS5] =====================================================")
}()
@@ -278,7 +278,7 @@ func (s *Server) handleHTTP(w http.ResponseWriter, r *http.Request) {
s.config.HttpAddr,
s.upstreamDialer.config.Server,
r.Host)
clientAddr := r.RemoteAddr
startTime := time.Now()
upBytes := &atomic.Int64{}
@@ -297,7 +297,7 @@ func (s *Server) handleHTTP(w http.ResponseWriter, r *http.Request) {
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 {
@@ -354,7 +354,7 @@ func (s *Server) handleHTTP(w http.ResponseWriter, r *http.Request) {
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.Infof("[HTTP] - 总流量: %s", formatBytes(upBytes.Load()+downBytes.Load()))
log.Debugf("[HTTP] =====================================================")
}()
@@ -429,43 +429,43 @@ 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
}
@@ -478,20 +478,20 @@ func (s *Server) handleSocks5Request(client net.Conn) (net.Conn, string, error)
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] {
@@ -503,7 +503,7 @@ func (s *Server) handleSocks5Request(client net.Conn) (net.Conn, string, error)
}
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 {
@@ -518,7 +518,7 @@ func (s *Server) handleSocks5Request(client net.Conn) (net.Conn, string, error)
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 {
@@ -528,7 +528,7 @@ func (s *Server) handleSocks5Request(client net.Conn) (net.Conn, string, error)
addr = net.IP(ipv6).String()
log.Debugf("[SOCKS5] - IPv6地址: %s", addr)
}
// 读取端口
portBuf := make([]byte, 2)
if _, err := io.ReadFull(client, portBuf); err != nil {
@@ -544,7 +544,7 @@ func (s *Server) handleSocks5Request(client net.Conn) (net.Conn, string, error)
targetAddr)
log.Debugf("[SOCKS5] - 端口: %d", port)
log.Debugf("[SOCKS5] - 完整目标地址: %s", targetAddr)
// 连接目标服务器
log.Debugf("[SOCKS5] 开始连接目标服务器...")
target, err := s.dialTarget(targetAddr)
@@ -556,15 +556,15 @@ func (s *Server) handleSocks5Request(client net.Conn) (net.Conn, string, error)
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
}
@@ -617,7 +617,7 @@ func (s *Server) dialTarget(addr string) (net.Conn, error) {
log := logger.Get()
log.Debugf("[PROXY] =====================================================")
log.Debugf("[PROXY] 开始处理连接请求: %s", addr)
// 提取域名和端口
host := addr
port := ""
@@ -630,19 +630,8 @@ func (s *Server) dialTarget(addr string) (net.Conn, error) {
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] 使用直接连接")
// IP地址默认直连
log.Debugf("[PROXY] IP地址默认使用直连")
conn, err := net.Dial("tcp", addr)
if err != nil {
log.Errorf("[PROXY] 直接连接失败: %v", err)
@@ -657,22 +646,49 @@ func (s *Server) dialTarget(addr string) (net.Conn, error) {
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)
// 检查是否在代理列表中
useProxy := s.directList.Match(host)
log.Debugf("[PROXY] 域名检查:")
log.Debugf("[PROXY] - 目标地址: %s", addr)
log.Debugf("[PROXY] - 域名: %s", host)
log.Debugf("[PROXY] - 端口: %s", port)
log.Debugf("[PROXY] - 是否在代理列表: %v", useProxy)
if useProxy {
// 使用代理连接
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] - 连接方式: 代理")
log.Debugf("[PROXY] - 判断依据: 域名在代理列表中")
log.Debugf("[PROXY] =====================================================")
return conn, nil
}
// 不在代理列表中的域名直连
log.Debugf("[PROXY] 使用直接连接")
conn, err := net.Dial("tcp", addr)
if err != nil {
log.Errorf("[PROXY] 代理连接失败: %v", err)
log.Errorf("[PROXY] 直接连接失败: %v", err)
log.Debugf("[PROXY] =====================================================")
return nil, err
}
log.Debugf("[PROXY] 代理连接成功")
log.Debugf("[PROXY] 直接连接成功")
log.Debugf("[PROXY] 连接详情:")
log.Debugf("[PROXY] - 本地地址: %s", conn.LocalAddr())
log.Debugf("[PROXY] - 远程地址: %s", conn.RemoteAddr())
log.Debugf("[PROXY] - 连接方式: 直连")
log.Debugf("[PROXY] - 判断依据: 域名不在代理列表中")
log.Debugf("[PROXY] =====================================================")
return conn, nil