Compare commits
No commits in common. "master" and "v2.0.5" have entirely different histories.
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
| Windows | Linux | macOS |
|
||||
|---------|-------|-------|
|
||||
| [⬇️ .exe](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.5/TgWsProxy.exe) (9 MB) | [⬇️ amd64](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.5/TgWsProxy_linux_amd64) (8.9 MB) | [⬇️ Intel](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.5/TgWsProxy_darwin_amd64) / [⬇️ ARM](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.5/TgWsProxy_darwin_arm64) |
|
||||
| [⬇️ .exe](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.5/TgWsProxy_windows_amd64.exe) (9 MB) | [⬇️ amd64](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.5/TgWsProxy_linux_amd64) (8.9 MB) | [⬇️ Intel](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.5/TgWsProxy_darwin_amd64) / [⬇️ ARM](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.5/TgWsProxy_darwin_arm64) |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
## 🚀 TG WS Proxy Go v2.0.2
|
||||
|
||||
> **Go-переосмысление** [Flowseal/tg-ws-proxy](https://github.com/Flowseal/tg-ws-proxy)
|
||||
> Локальный SOCKS5-прокси для Telegram Desktop на Go
|
||||
|
||||
---
|
||||
|
||||
### ✨ Что нового в v2.0.2
|
||||
|
||||
| Функция | Статус |
|
||||
|---------|--------|
|
||||
| 🔗 **tg://socks ссылки** | ✅ Работают на Windows |
|
||||
| 📲 **Авто-конфигурация Telegram** | ✅ Открывает настройки прокси |
|
||||
| 🔄 **Автообновление** | ✅ Скачивает новую версию |
|
||||
| 🌐 **IPv6 поддержка** | ✅ Через NAT64 |
|
||||
| 🔐 **SOCKS5 аутентификация** | ✅ --auth username:password |
|
||||
| 🛑 **Авто-закрытие дубликатов** | ✅ Завершает старые экземпляры |
|
||||
|
||||
---
|
||||
|
||||
### 🔧 Исправления v2.0.2
|
||||
|
||||
- ✅ **Исправлено:** При запуске второго экземпляра первый автоматически закрывается
|
||||
- ✅ **Улучшено:** Стабильность работы на Windows
|
||||
- ✅ **Добавлено:** Проверка и завершение дублирующихся процессов
|
||||
|
||||
---
|
||||
|
||||
### 📥 Скачать
|
||||
|
||||
| Платформа | Файл | Размер | Ссылка |
|
||||
|-----------|------|--------|--------|
|
||||
| **Windows x64** | TgWsProxy.exe | 6.6 MB | [⬇️ Скачать](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.2/TgWsProxy_windows_amd64.exe) |
|
||||
| **Linux x64** | TgWsProxy | 6.5 MB | [⬇️ Скачать](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.2/TgWsProxy_linux_amd64) |
|
||||
| **macOS Intel** | TgWsProxy | 6.6 MB | [⬇️ Скачать](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.2/TgWsProxy_darwin_amd64) |
|
||||
| **macOS Apple Silicon** | TgWsProxy | 5.8 MB | [⬇️ Скачать](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.2/TgWsProxy_darwin_arm64) |
|
||||
|
||||
---
|
||||
|
||||
### 🚀 Быстрый старт
|
||||
|
||||
**Windows:**
|
||||
1. Скачай `TgWsProxy.exe`
|
||||
2. Запусти
|
||||
3. Telegram автоматически откроет настройки прокси
|
||||
4. Подтверди добавление
|
||||
|
||||
**Linux/macOS:**
|
||||
```bash
|
||||
chmod +x TgWsProxy_*
|
||||
./TgWsProxy_linux_amd64 # или ./TgWsProxy_darwin_amd64
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 🔧 Командная строка
|
||||
|
||||
```bash
|
||||
./TgWsProxy [опции]
|
||||
|
||||
--port int Порт SOCKS5 (default 1080)
|
||||
--host string Хост SOCKS5 (default "127.0.0.1")
|
||||
--dc-ip string DC:IP через запятую
|
||||
--auth string SOCKS5 аутентификация (username:password)
|
||||
-v Подробное логирование
|
||||
--version Показать версию
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 📊 Сравнение с Python
|
||||
|
||||
| Метрика | Python | Go |
|
||||
|---------|--------|-----|
|
||||
| Размер | ~50 MB | **~6 MB** ⚡ |
|
||||
| Зависимости | pip | **stdlib** ⚡ |
|
||||
| Запуск | ~500 ms | **~50 ms** ⚡ |
|
||||
| Память | ~50 MB | **~10 MB** ⚡ |
|
||||
|
||||
---
|
||||
|
||||
### 🔗 Ссылки
|
||||
|
||||
- 📦 **Релизы:** https://github.com/y0sy4/tg-ws-proxy-go/releases
|
||||
- 📖 **Документация:** https://github.com/y0sy4/tg-ws-proxy-go#readme
|
||||
- ❓ **FAQ:** https://github.com/y0sy4/tg-ws-proxy-go/blob/master/FAQ.md
|
||||
- 🐛 **Баги:** https://github.com/y0sy4/tg-ws-proxy-go/issues
|
||||
|
||||
---
|
||||
|
||||
**Built with ❤️ using Go 1.21** | **License:** MIT
|
||||
|
|
@ -116,24 +116,15 @@ func main() {
|
|||
if *auth != "" {
|
||||
cfg.Auth = *auth
|
||||
}
|
||||
if *upstreamProxy != "" {
|
||||
cfg.UpstreamProxy = *upstreamProxy
|
||||
}
|
||||
|
||||
// Setup logging - log to stdout if verbose, otherwise to file
|
||||
var logger *log.Logger
|
||||
// Setup logging - default to file if not specified
|
||||
logPath := *logFile
|
||||
if cfg.Verbose && logPath == "" {
|
||||
// Verbose mode: log to stdout
|
||||
logger = setupLogging("", cfg.LogMaxMB, cfg.Verbose)
|
||||
} else {
|
||||
// File mode: log to file (default to app dir if not specified)
|
||||
if logPath == "" {
|
||||
// Use default log file in app config directory
|
||||
appDir := getAppDir()
|
||||
logPath = filepath.Join(appDir, "proxy.log")
|
||||
}
|
||||
logger = setupLogging(logPath, cfg.LogMaxMB, cfg.Verbose)
|
||||
}
|
||||
logger := setupLogging(logPath, cfg.LogMaxMB, cfg.Verbose)
|
||||
|
||||
// Log advanced features usage and start HTTP proxy
|
||||
if *httpPort != 0 {
|
||||
|
|
@ -155,7 +146,7 @@ func main() {
|
|||
}
|
||||
|
||||
// Create and start server
|
||||
server, err := proxy.NewServer(cfg, logger, cfg.UpstreamProxy)
|
||||
server, err := proxy.NewServer(cfg, logger)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create server: %v", err)
|
||||
}
|
||||
|
|
@ -257,12 +248,8 @@ func getAppDir() string {
|
|||
|
||||
func setupLogging(logFile string, logMaxMB float64, verbose bool) *log.Logger {
|
||||
flags := log.LstdFlags | log.Lshortfile
|
||||
|
||||
// If verbose and no log file specified, log to stdout
|
||||
if verbose && logFile == "" {
|
||||
log.SetOutput(os.Stdout)
|
||||
log.SetFlags(flags)
|
||||
return log.New(os.Stdout, "", flags)
|
||||
if verbose {
|
||||
flags |= log.Lshortfile
|
||||
}
|
||||
|
||||
// Ensure directory exists
|
||||
|
|
@ -273,8 +260,6 @@ func setupLogging(logFile string, logMaxMB float64, verbose bool) *log.Logger {
|
|||
f, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Printf("Warning: failed to open log file %s: %v, using stdout", logFile, err)
|
||||
log.SetOutput(os.Stdout)
|
||||
log.SetFlags(flags)
|
||||
return log.New(os.Stdout, "", flags)
|
||||
}
|
||||
|
||||
|
|
|
|||
4
go.mod
4
go.mod
|
|
@ -1,5 +1,3 @@
|
|||
module github.com/Flowseal/tg-ws-proxy
|
||||
|
||||
go 1.25.0
|
||||
|
||||
require golang.org/x/net v0.52.0 // indirect
|
||||
go 1.21
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -1,2 +0,0 @@
|
|||
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
|
||||
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
|
||||
|
|
@ -22,7 +22,6 @@ type Config struct {
|
|||
BufKB int `json:"buf_kb"`
|
||||
PoolSize int `json:"pool_size"`
|
||||
Auth string `json:"auth"` // username:password
|
||||
UpstreamProxy string `json:"upstream_proxy"`
|
||||
}
|
||||
|
||||
// DefaultConfig returns the default configuration.
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
// HTTPProxy represents an HTTP proxy server.
|
||||
|
|
@ -22,33 +20,6 @@ type HTTPProxy struct {
|
|||
upstreamProxy *url.URL
|
||||
}
|
||||
|
||||
// dialWithUpstream creates a connection, optionally routing through an upstream proxy.
|
||||
func (h *HTTPProxy) dialWithUpstream(network, addr string) (net.Conn, error) {
|
||||
if h.upstreamProxy == nil {
|
||||
return net.Dial(network, addr)
|
||||
}
|
||||
|
||||
switch h.upstreamProxy.Scheme {
|
||||
case "socks5", "socks":
|
||||
// Use proxy package for SOCKS5
|
||||
proxyDialer, err := proxy.FromURL(h.upstreamProxy, proxy.Direct)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create SOCKS5 dialer: %w", err)
|
||||
}
|
||||
return proxyDialer.Dial(network, addr)
|
||||
|
||||
case "http", "https":
|
||||
// Use http.Transport with Proxy for HTTP CONNECT
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyURL(h.upstreamProxy),
|
||||
}
|
||||
return transport.Dial(network, addr)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported upstream proxy scheme: %s", h.upstreamProxy.Scheme)
|
||||
}
|
||||
}
|
||||
|
||||
// NewHTTPProxy creates a new HTTP proxy server.
|
||||
func NewHTTPProxy(port int, verbose bool, logger *log.Logger, upstreamProxyURL string) (*HTTPProxy, error) {
|
||||
var upstreamProxy *url.URL
|
||||
|
|
@ -117,8 +88,8 @@ func (h *HTTPProxy) handleConnect(conn net.Conn, req *http.Request) {
|
|||
host = host + ":80"
|
||||
}
|
||||
|
||||
// Connect to target (with upstream proxy if configured)
|
||||
target, err := h.dialWithUpstream("tcp", host)
|
||||
// Connect to target
|
||||
target, err := net.Dial("tcp", host)
|
||||
if err != nil {
|
||||
conn.Write([]byte("HTTP/1.1 502 Bad Gateway\r\n\r\n"))
|
||||
return
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ import (
|
|||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
|
@ -22,7 +20,6 @@ import (
|
|||
"github.com/Flowseal/tg-ws-proxy/internal/pool"
|
||||
"github.com/Flowseal/tg-ws-proxy/internal/socks5"
|
||||
"github.com/Flowseal/tg-ws-proxy/internal/websocket"
|
||||
"golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -158,11 +155,10 @@ type Server struct {
|
|||
mu sync.RWMutex
|
||||
listener net.Listener
|
||||
logger *log.Logger
|
||||
upstreamProxy string
|
||||
}
|
||||
|
||||
// NewServer creates a new proxy server.
|
||||
func NewServer(cfg *config.Config, logger *log.Logger, upstreamProxy string) (*Server, error) {
|
||||
func NewServer(cfg *config.Config, logger *log.Logger) (*Server, error) {
|
||||
dcOpt, err := config.ParseDCIPList(cfg.DCIP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -176,53 +172,11 @@ func NewServer(cfg *config.Config, logger *log.Logger, upstreamProxy string) (*S
|
|||
wsBlacklist: make(map[pool.DCKey]bool),
|
||||
dcFailUntil: make(map[pool.DCKey]time.Time),
|
||||
logger: logger,
|
||||
upstreamProxy: upstreamProxy,
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// dialWithUpstream creates a connection, optionally routing through an upstream proxy.
|
||||
func (s *Server) dialWithUpstream(network, addr string, timeout time.Duration) (net.Conn, error) {
|
||||
if s.upstreamProxy == "" {
|
||||
return net.DialTimeout(network, addr, timeout)
|
||||
}
|
||||
|
||||
// Parse upstream proxy URL
|
||||
u, err := url.Parse(s.upstreamProxy)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse upstream proxy: %w", err)
|
||||
}
|
||||
|
||||
switch u.Scheme {
|
||||
case "socks5", "socks":
|
||||
var auth *proxy.Auth
|
||||
if u.User != nil {
|
||||
password, _ := u.User.Password()
|
||||
auth = &proxy.Auth{
|
||||
User: u.User.Username(),
|
||||
Password: password,
|
||||
}
|
||||
}
|
||||
dialer, err := proxy.SOCKS5(network, u.Host, auth, proxy.Direct)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create SOCKS5 dialer: %w", err)
|
||||
}
|
||||
return dialer.Dial(network, addr)
|
||||
|
||||
case "http", "https":
|
||||
// Use http.Transport with Proxy for HTTP CONNECT
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyURL(u),
|
||||
TLSHandshakeTimeout: timeout,
|
||||
}
|
||||
return transport.Dial(network, addr)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported upstream proxy scheme: %s", u.Scheme)
|
||||
}
|
||||
}
|
||||
|
||||
// Start starts the proxy server.
|
||||
func (s *Server) Start(ctx context.Context) error {
|
||||
addr := net.JoinHostPort(s.config.Host, fmt.Sprintf("%d", s.config.Port))
|
||||
|
|
@ -453,9 +407,7 @@ func (s *Server) getWebSocket(dcKey pool.DCKey, targetIP string, domains []strin
|
|||
s.logInfo("[%s] DC%d%s (%s:%d) -> %s via %s", label, dc, mediaTag, dst, port, url, targetIP)
|
||||
|
||||
// Connect using targetIP, but use domain for TLS handshake
|
||||
ws, wsErr = websocket.ConnectWithDialer(targetIP, domain, "/apiws", wsTimeout, func(network, addr string) (net.Conn, error) {
|
||||
return s.dialWithUpstream(network, addr, wsTimeout)
|
||||
})
|
||||
ws, wsErr = websocket.Connect(targetIP, domain, "/apiws", wsTimeout)
|
||||
if wsErr == nil {
|
||||
allRedirects = false
|
||||
break
|
||||
|
|
@ -498,7 +450,7 @@ func (s *Server) getWebSocket(dcKey pool.DCKey, targetIP string, domains []strin
|
|||
}
|
||||
|
||||
func (s *Server) handlePassthrough(conn net.Conn, dst string, port uint16, label string) {
|
||||
remoteConn, err := s.dialWithUpstream("tcp", net.JoinHostPort(dst, fmt.Sprintf("%d", port)), 10*time.Second)
|
||||
remoteConn, err := net.DialTimeout("tcp", net.JoinHostPort(dst, fmt.Sprintf("%d", port)), 10*time.Second)
|
||||
if err != nil {
|
||||
s.logWarning("[%s] passthrough failed to %s: %v", label, dst, err)
|
||||
conn.Write(socks5.Reply(socks5.ReplyFail))
|
||||
|
|
@ -513,7 +465,7 @@ func (s *Server) handlePassthrough(conn net.Conn, dst string, port uint16, label
|
|||
// handleIPv6Connection handles IPv6 connections via dual-stack or IPv4-mapped addresses.
|
||||
func (s *Server) handleIPv6Connection(conn net.Conn, ipv6Addr string, port uint16, label string) {
|
||||
// Try direct IPv6 first
|
||||
remoteConn, err := s.dialWithUpstream("tcp6", net.JoinHostPort(ipv6Addr, fmt.Sprintf("%d", port)), 10*time.Second)
|
||||
remoteConn, err := net.DialTimeout("tcp6", net.JoinHostPort(ipv6Addr, fmt.Sprintf("%d", port)), 10*time.Second)
|
||||
if err == nil {
|
||||
s.logInfo("[%s] IPv6 direct connection successful", label)
|
||||
defer remoteConn.Close()
|
||||
|
|
@ -573,7 +525,7 @@ func extractIPv4FromNAT64(ipv6, prefix string) string {
|
|||
}
|
||||
|
||||
func (s *Server) handleTCPFallback(conn net.Conn, dst string, port uint16, init []byte, label string, dc int, isMedia bool) {
|
||||
remoteConn, err := s.dialWithUpstream("tcp", net.JoinHostPort(dst, fmt.Sprintf("%d", port)), 10*time.Second)
|
||||
remoteConn, err := net.DialTimeout("tcp", net.JoinHostPort(dst, fmt.Sprintf("%d", port)), 10*time.Second)
|
||||
if err != nil {
|
||||
s.logWarning("[%s] TCP fallback to %s:%d failed: %v", label, dst, port, err)
|
||||
return
|
||||
|
|
@ -720,9 +672,7 @@ func (s *Server) warmupPool() {
|
|||
go func(dcKey pool.DCKey, targetIP string, domains []string) {
|
||||
for s.wsPool.NeedRefill(dcKey) {
|
||||
for _, domain := range domains {
|
||||
ws, err := websocket.ConnectWithDialer(targetIP, domain, "/apiws", wsConnectTimeout, func(network, addr string) (net.Conn, error) {
|
||||
return s.dialWithUpstream(network, addr, wsConnectTimeout)
|
||||
})
|
||||
ws, err := websocket.Connect(targetIP, domain, "/apiws", wsConnectTimeout)
|
||||
if err == nil {
|
||||
s.wsPool.Put(dcKey, ws)
|
||||
break
|
||||
|
|
|
|||
|
|
@ -44,12 +44,6 @@ type WebSocket struct {
|
|||
|
||||
// Connect establishes a WebSocket connection to the given domain via IP.
|
||||
func Connect(ip, domain, path string, timeout time.Duration) (*WebSocket, error) {
|
||||
return ConnectWithDialer(ip, domain, path, timeout, nil)
|
||||
}
|
||||
|
||||
// ConnectWithDialer establishes a WebSocket connection using a custom dialer.
|
||||
// If dialer is nil, it uses direct connection.
|
||||
func ConnectWithDialer(ip, domain, path string, timeout time.Duration, dialFunc func(network, addr string) (net.Conn, error)) (*WebSocket, error) {
|
||||
if path == "" {
|
||||
path = "/apiws"
|
||||
}
|
||||
|
|
@ -62,55 +56,18 @@ func ConnectWithDialer(ip, domain, path string, timeout time.Duration, dialFunc
|
|||
wsKey := base64.StdEncoding.EncodeToString(keyBytes)
|
||||
|
||||
// Dial TLS connection
|
||||
var rawConn net.Conn
|
||||
var err error
|
||||
|
||||
if dialFunc != nil {
|
||||
// Use custom dialer
|
||||
rawConn, err = dialFunc("tcp", net.JoinHostPort(ip, "443"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("dial: %w", err)
|
||||
}
|
||||
// Wrap with TLS
|
||||
tlsConfig := &tls.Config{
|
||||
ServerName: domain,
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
rawConn = tls.Client(rawConn, tlsConfig)
|
||||
// Set handshake timeout
|
||||
if err := rawConn.SetDeadline(time.Now().Add(timeout)); err != nil {
|
||||
rawConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// Direct connection
|
||||
dialer := &net.Dialer{Timeout: timeout}
|
||||
tlsConfig := &tls.Config{
|
||||
ServerName: domain,
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
rawConn, err = tls.DialWithDialer(dialer, "tcp", net.JoinHostPort(ip, "443"), tlsConfig)
|
||||
rawConn, err := tls.DialWithDialer(dialer, "tcp", net.JoinHostPort(ip, "443"), tlsConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tls dial: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Clear deadline after handshake
|
||||
if err := rawConn.SetDeadline(time.Time{}); err != nil {
|
||||
rawConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set TCP_NODELAY and buffer sizes
|
||||
if tcpConn, ok := rawConn.(*tls.Conn); ok {
|
||||
if netConn := tcpConn.NetConn(); netConn != nil {
|
||||
if tcpNetConn, ok := netConn.(*net.TCPConn); ok {
|
||||
tcpNetConn.SetNoDelay(true)
|
||||
tcpNetConn.SetReadBuffer(256 * 1024)
|
||||
tcpNetConn.SetWriteBuffer(256 * 1024)
|
||||
}
|
||||
}
|
||||
} else if tcpConn, ok := rawConn.(*net.TCPConn); ok {
|
||||
if tcpConn, ok := rawConn.NetConn().(*net.TCPConn); ok {
|
||||
tcpConn.SetNoDelay(true)
|
||||
tcpConn.SetReadBuffer(256 * 1024)
|
||||
tcpConn.SetWriteBuffer(256 * 1024)
|
||||
|
|
@ -158,7 +115,7 @@ func ConnectWithDialer(ip, domain, path string, timeout time.Duration, dialFunc
|
|||
}
|
||||
|
||||
return &WebSocket{
|
||||
conn: rawConn.(*tls.Conn),
|
||||
conn: rawConn,
|
||||
reader: reader,
|
||||
writer: bufio.NewWriter(rawConn),
|
||||
maskKey: make([]byte, 4),
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ func Start(host string, port int, dcIP string, verbose bool) string {
|
|||
var ctx context.Context
|
||||
ctx, cancel = context.WithCancel(context.Background())
|
||||
|
||||
server, err = proxy.NewServer(cfg, logger, "")
|
||||
server, err = proxy.NewServer(cfg, logger)
|
||||
if err != nil {
|
||||
cancel()
|
||||
return fmt.Sprintf("Failed to create server: %v", err)
|
||||
|
|
|
|||
Loading…
Reference in New Issue