|
|
package client
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
"os"
|
|
|
"os/signal"
|
|
|
"syscall"
|
|
|
|
|
|
"github.com/azoic/wormhole-client/internal/config"
|
|
|
"github.com/azoic/wormhole-client/internal/proxy"
|
|
|
"github.com/azoic/wormhole-client/internal/system"
|
|
|
"github.com/azoic/wormhole-client/pkg/dns"
|
|
|
"github.com/azoic/wormhole-client/pkg/logger"
|
|
|
)
|
|
|
|
|
|
type Client struct {
|
|
|
mode string
|
|
|
config *config.Config
|
|
|
socks5Proxy *proxy.SOCKS5Proxy
|
|
|
dnsProxy *dns.DNSProxy
|
|
|
systemProxyMgr *system.SystemProxyManager
|
|
|
}
|
|
|
|
|
|
func NewClient(mode string) *Client {
|
|
|
return &Client{
|
|
|
mode: mode,
|
|
|
systemProxyMgr: system.NewSystemProxyManager(),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func (c *Client) Start(configPath string) error {
|
|
|
// 加载配置
|
|
|
cfg, err := config.LoadConfig(configPath)
|
|
|
if err != nil {
|
|
|
return fmt.Errorf("failed to load config: %v", err)
|
|
|
}
|
|
|
|
|
|
if err := cfg.Validate(); err != nil {
|
|
|
return fmt.Errorf("invalid config: %v", err)
|
|
|
}
|
|
|
|
|
|
c.config = cfg
|
|
|
|
|
|
// 设置日志级别
|
|
|
logger.SetLevel(cfg.LogLevel)
|
|
|
|
|
|
logger.Info("🚀 Starting Wormhole SOCKS5 Client")
|
|
|
logger.Info("📄 Config loaded from: %s", configPath)
|
|
|
logger.Info("🔧 Mode: %s", c.mode)
|
|
|
logger.Info("🎯 SOCKS5 Server: %s", cfg.GetServerAddr())
|
|
|
|
|
|
// 创建SOCKS5代理客户端
|
|
|
c.socks5Proxy = proxy.NewSOCKS5Proxy(
|
|
|
cfg.GetServerAddr(),
|
|
|
cfg.Server.Username,
|
|
|
cfg.Server.Password,
|
|
|
cfg.Timeout,
|
|
|
)
|
|
|
|
|
|
// 设置信号处理
|
|
|
c.setupSignalHandler()
|
|
|
|
|
|
switch c.mode {
|
|
|
case "http":
|
|
|
return c.startHTTPProxy()
|
|
|
case "global":
|
|
|
return c.startGlobalProxy()
|
|
|
case "transparent":
|
|
|
return c.startTransparentProxy()
|
|
|
default:
|
|
|
return fmt.Errorf("unsupported mode: %s", c.mode)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func (c *Client) startHTTPProxy() error {
|
|
|
logger.Info("🌐 Starting HTTP proxy mode...")
|
|
|
logger.Info("💡 Setting up HTTP proxy on port %d", c.config.Proxy.LocalPort)
|
|
|
|
|
|
server := c.socks5Proxy.CreateHTTPProxy(c.config.Proxy.LocalPort)
|
|
|
|
|
|
logger.Info("✅ HTTP proxy started on :%d", c.config.Proxy.LocalPort)
|
|
|
logger.Info("💡 Configure your browser to use HTTP proxy: 127.0.0.1:%d", c.config.Proxy.LocalPort)
|
|
|
|
|
|
return server.ListenAndServe()
|
|
|
}
|
|
|
|
|
|
func (c *Client) startGlobalProxy() error {
|
|
|
logger.Info("🌍 Starting global proxy mode...")
|
|
|
logger.Info("💡 This will configure system-wide proxy settings")
|
|
|
logger.Info("⚠️ Requires administrator privileges")
|
|
|
|
|
|
// 启动HTTP代理服务器
|
|
|
server := c.socks5Proxy.CreateHTTPProxy(c.config.Proxy.LocalPort)
|
|
|
go func() {
|
|
|
if err := server.ListenAndServe(); err != nil {
|
|
|
logger.Error("HTTP proxy server failed: %v", err)
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
// 设置系统代理
|
|
|
httpProxy := fmt.Sprintf("127.0.0.1:%d", c.config.Proxy.LocalPort)
|
|
|
httpsProxy := httpProxy
|
|
|
|
|
|
if err := c.systemProxyMgr.SetGlobalProxy(httpProxy, httpsProxy, ""); err != nil {
|
|
|
logger.Error("Failed to set system proxy: %v", err)
|
|
|
logger.Warn("You may need to run with administrator privileges")
|
|
|
logger.Info("Manual setup: Set HTTP/HTTPS proxy to %s", httpProxy)
|
|
|
} else {
|
|
|
logger.Info("✅ System proxy configured successfully")
|
|
|
}
|
|
|
|
|
|
// 启动DNS代理(如果启用)
|
|
|
if c.config.GlobalProxy.DNSProxy {
|
|
|
logger.Info("🔍 Starting DNS proxy on port %d", c.config.GlobalProxy.DNSPort)
|
|
|
c.dnsProxy = dns.NewDNSProxy("8.8.8.8:53", c.config.GlobalProxy.DNSPort)
|
|
|
if err := c.dnsProxy.Start(); err != nil {
|
|
|
logger.Warn("Failed to start DNS proxy: %v", err)
|
|
|
} else {
|
|
|
logger.Info("✅ DNS proxy started")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
logger.Info("🎉 Global proxy mode started successfully")
|
|
|
logger.Info("📍 HTTP/HTTPS Proxy: %s", httpProxy)
|
|
|
if c.dnsProxy != nil {
|
|
|
logger.Info("📍 DNS Proxy: 127.0.0.1:%d", c.config.GlobalProxy.DNSPort)
|
|
|
}
|
|
|
|
|
|
// 保持运行
|
|
|
select {}
|
|
|
}
|
|
|
|
|
|
func (c *Client) startTransparentProxy() error {
|
|
|
logger.Info("🔍 Starting transparent proxy mode...")
|
|
|
logger.Info("💡 This will intercept network traffic transparently")
|
|
|
logger.Info("⚠️ Requires root privileges and iptables support")
|
|
|
logger.Error("❌ Transparent proxy mode is not yet implemented")
|
|
|
|
|
|
return fmt.Errorf("transparent proxy mode not implemented")
|
|
|
}
|
|
|
|
|
|
func (c *Client) setupSignalHandler() {
|
|
|
sigChan := make(chan os.Signal, 1)
|
|
|
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
|
|
|
|
|
|
go func() {
|
|
|
<-sigChan
|
|
|
logger.Info("🛑 Shutting down...")
|
|
|
c.cleanup()
|
|
|
os.Exit(0)
|
|
|
}()
|
|
|
}
|
|
|
|
|
|
func (c *Client) cleanup() {
|
|
|
// 恢复系统代理设置
|
|
|
if c.systemProxyMgr != nil {
|
|
|
if err := c.systemProxyMgr.RestoreProxy(); err != nil {
|
|
|
logger.Error("Failed to restore system proxy: %v", err)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 停止DNS代理
|
|
|
if c.dnsProxy != nil {
|
|
|
if err := c.dnsProxy.Stop(); err != nil {
|
|
|
logger.Error("Failed to stop DNS proxy: %v", err)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
logger.Info("✅ Cleanup completed")
|
|
|
}
|
|
|
|