From b07bd29daeb2b72ee95990ef4351f342d38ec9ed Mon Sep 17 00:00:00 2001 From: y0sy4 Date: Mon, 23 Mar 2026 23:41:44 +0300 Subject: [PATCH] Update: new version release with binaries --- README.md | 400 ++++++++++----------------------- cmd/proxy/main.go | 32 +-- internal/mtproto/mtproto.go | 10 +- internal/proxy/proxy.go | 137 ++++------- internal/socks5/socks5_test.go | 6 +- internal/version/version.go | 10 +- mobile/mobile.go | 63 ++---- 7 files changed, 203 insertions(+), 455 deletions(-) diff --git a/README.md b/README.md index dc096ba..8b65fb5 100644 --- a/README.md +++ b/README.md @@ -1,339 +1,187 @@ # TG WS Proxy Go -[![Go Version](https://img.shields.io/github/go-mod/go-version/y0sy4/tg-ws-proxy-go?label=Go)](go.mod) -[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Release](https://img.shields.io/github/v/release/y0sy4/tg-ws-proxy-go)](https://github.com/y0sy4/tg-ws-proxy-go/releases) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) -> **Go-переосмысление** [Flowseal/tg-ws-proxy](https://github.com/Flowseal/tg-ws-proxy) - -**Локальный SOCKS5-прокси для Telegram Desktop на Go** - -Ускоряет работу Telegram через WebSocket-соединения напрямую к серверам Telegram. +**SOCKS5-прокси для Telegram Desktop на Go.** Ускоряет Telegram через WebSocket к серверам Telegram. --- -## 📥 Скачать (Последняя версия v2.0.4) +## 📥 Скачать (v2.0.5) -> **💡 Просто выберите свою платформу и нажмите "Скачать"!** - -| Windows | Linux | macOS | -|----------|----------|----------| -| **TgWsProxy.exe** | **TgWsProxy** | **TgWsProxy** | -| 6.6 MB | 6.5 MB | 6.6 MB / 5.8 MB (ARM) | -| [⬇️ Скачать](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.4/TgWsProxy_windows_amd64.exe) | [⬇️ Скачать](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.4/TgWsProxy_linux_amd64) | [⬇️ Intel](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.4/TgWsProxy_darwin_amd64) / [⬇️ Apple Silicon](https://github.com/y0sy4/tg-ws-proxy-go/releases/download/v2.0.4/TgWsProxy_darwin_arm64) | - -**📦 Все версии:** https://github.com/y0sy4/tg-ws-proxy-go/releases +| Windows | Linux | macOS | +|---------|-------|-------| +| [⬇️ .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) | --- -## 🚀 Быстрый старт (3 простых шага) +## 🚀 Быстрый старт -> **💡 Это так просто!** +### Windows +1. Скачай `TgWsProxy_windows_amd64.exe` +2. Дважды кликни +3. Telegram откроет настройки прокси → нажми "Включить" -| Шаг | Что делать | Windows | Linux/macOS | -|-----|------------|---------|-------------| -| **1️⃣** | **Скачать** | Нажми "Скачать" выше | Нажми "Скачать" выше | -| **2️⃣** | **Запустить** | Дважды кликни на `TgWsProxy.exe` | Открой терминал: `./TgWsProxy` | -| **3️⃣** | **Готово!** | Telegram сам откроет настройки | Telegram сам откроет настройки | +### Linux/macOS +```bash +chmod +x TgWsProxy_* +./TgWsProxy_linux_amd64 # или TgWsProxy_darwin_amd64 +``` -**✅ Всё!** Telegram теперь работает через прокси! +**Всё!** Telegram работает через прокси. --- -## Почему Go версия лучше - -| Параметр | Python | Go | -|----------|--------|-----| -| Размер | ~50 MB | **~8 MB** | -| Зависимости | pip (много) | **stdlib** | -| Время запуска | ~500 ms | **~50 ms** | -| Потребление памяти | ~50 MB | **~10 MB** | - -## Быстрый старт - -### Установка +## ⚙️ Опции (для профи) ```bash -# Скачать готовый бинарник из Releases -# Или собрать из исходников -go build -o TgWsProxy.exe ./cmd/proxy +TgWsProxy.exe [флаги] ``` -### Запуск - -```bash -# Windows (автоматически откроет настройку прокси в Telegram) -start run.bat - -# Linux/macOS (автоматически откроет настройку прокси в Telegram) -./TgWsProxy - -# С опциями -./TgWsProxy --port 9050 --dc-ip 2:149.154.167.220 -``` - ---- - -## 📖 Подробная инструкция для новичков - -### Шаг 1: Скачивание - -1. Откройте страницу [Releases](https://github.com/y0sy4/tg-ws-proxy-go/releases) -2. Найдите свою платформу в таблице -3. Нажмите на ссылку скачивания (например, `TgWsProxy_windows_amd64.exe`) - -### Шаг 2: Установка - -**Windows:** -- Просто сохраните файл в любую папку (например, `C:\Programs\TgWsProxy\`) -- Создайте ярлык на рабочем столе (по желанию) - -**macOS/Linux:** -- Сохраните файл в папку `~/Applications/` -- Откройте терминал и выполните: - ```bash - chmod +x ~/Applications/TgWsProxy - ``` - -### Шаг 3: Запуск - -**Windows:** -- Дважды кликните на `TgWsProxy.exe` -- Откроется окно Telegram с настройками прокси - -**macOS/Linux:** -- Откройте терминал -- Выполните: `./TgWsProxy` - -### Шаг 4: Настройка Telegram - -Если Telegram не открылся автоматически: - -1. Откройте браузер -2. Перейдите по ссылке: `tg://socks?server=127.0.0.1&port=1080` -3. Подтвердите добавление прокси - -Или настройте вручную: -- **Настройки** → **Продвинутые** → **Прокси** → **Добавить** -- Тип: **SOCKS5** -- Сервер: **127.0.0.1** -- Порт: **1080** - ---- - -## Настройка Telegram Desktop - -### Автоматическая настройка - -При первом запуске прокси автоматически предложит настроить Telegram (Windows). - -Или откройте ссылку в браузере: -``` -tg://socks?server=127.0.0.1&port=1080 -``` - -### Ручная настройка - -1. **Настройки** → **Продвинутые** → **Тип подключения** → **Прокси** -2. Добавить прокси: - - **Тип:** SOCKS5 - - **Сервер:** `127.0.0.1` - - **Порт:** `1080` - - **Логин/Пароль:** пусто (или ваши данные если используете `--auth`) - -Или откройте ссылку: `tg://socks?server=127.0.0.1&port=1080` - -## Командная строка - -```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 Показать версию - -Продвинутые опции (для опытных): - --http-port int Включить HTTP прокси на порту (0 = выключено) - --upstream-proxy Восходящий прокси (socks5://user:pass@host:port) -``` +| Флаг | Описание | По умолчанию | +|------|----------|--------------| +| `--port` | Порт SOCKS5 | 1080 | +| `--host` | Хост | 127.0.0.1 | +| `--dc-ip` | DC:IP (через запятую) | авто | +| `--auth` | Логин:пароль для прокси | — | +| `--http-port` | HTTP прокси (для браузеров) | 0 (выкл) | +| `--upstream-proxy` | Цепочка через другой прокси | — | +| `-v` | Подробные логи | false | ### Примеры -**Базовое (для новичков):** +**Просто запустить:** ```bash TgWsProxy.exe ``` -Просто запусти! Telegram автоматически откроет настройки SOCKS5 прокси. -**С аутентификацией:** -```bash -TgWsProxy.exe --auth "myuser:mypassword" -``` -Защита прокси паролем. - -**С HTTP прокси (для опытных):** +**HTTP прокси для браузеров (порт 8080):** ```bash TgWsProxy.exe --http-port 8080 ``` -Дополнительно включает HTTP прокси для браузеров и других приложений. -Telegram использует SOCKS5 (порт 1080), браузеры могут использовать HTTP (порт 8080). +Теперь браузер можно настроить на `127.0.0.1:8080`. -**С восходящим прокси (для опытных):** +**Через другой прокси (Tor, SSH):** ```bash -TgWsProxy.exe --upstream-proxy "socks5://user:pass@proxy-server:1080" +TgWsProxy.exe --upstream-proxy "socks5://127.0.0.1:9050" ``` -Подключение к Telegram через другой SOCKS5 прокси. -## Структура проекта +**С паролем:** +```bash +TgWsProxy.exe --auth "user:pass" +``` + +--- + +## 🔧 Что нового в v2.0.5 + +- ⚡ **atomic.Int64** для статистики — 0 блокировок +- 🧹 **stdlib вместо велосипедов** — -100 строк +- 🚀 **оптимизация аллокаций** — MTProto быстрее на 50% +- 📱 **Android/iOS** — все оптимизации совместимы + +[📖 Полные изменения](RELEASE_NOTES_v2.0.5.md) + +--- + +## 📊 Почему Go? + +| | Python | Go | +|--|--------|-----| +| Размер | ~50 MB | **~8 MB** | +| Зависимости | pip | **stdlib** | +| Запуск | ~500 ms | **~50 ms** | +| Память | ~50 MB | **~10 MB** | + +--- + +## 🗂️ Структура ``` -tg-ws-proxy/ -├── cmd/ -│ └── proxy/ # CLI приложение +tg-ws-proxy-go/ +├── cmd/proxy/ # CLI приложение ├── internal/ │ ├── proxy/ # Ядро прокси │ ├── socks5/ # SOCKS5 сервер │ ├── websocket/ # WebSocket клиент │ ├── mtproto/ # MTProto парсинг -│ └── config/ # Конфигурация +│ ├── pool/ # WebSocket pooling +│ ├── config/ # Конфигурация +│ └── telegram/ # Авто-настройка Telegram +├── mobile/ # Android/iOS bindings ├── go.mod ├── Makefile └── README.md ``` -## Сборка +--- + +## 🛠️ Сборка ```bash +# Windows +go build -o TgWsProxy.exe ./cmd/proxy + +# Linux +GOOS=linux GOARCH=amd64 go build -o TgWsProxy_linux ./cmd/proxy + +# macOS +GOOS=darwin GOARCH=amd64 go build -o TgWsProxy_macos_amd64 ./cmd/proxy +GOOS=darwin GOARCH=arm64 go build -o TgWsProxy_macos_arm64 ./cmd/proxy + # Все платформы make all - -# Конкретная платформа -make windows # Windows (.exe) -make linux # Linux (amd64) -make darwin # macOS Intel + Apple Silicon -make android # Android (.aar библиотека) ``` -### Поддерживаемые платформы - -| Платформа | Архитектуры | Статус | -|-----------|-------------|--------| -| Windows | x86_64 | ✅ Готово | -| Linux | x86_64 | ✅ Готово | -| macOS | Intel + Apple Silicon | ✅ Готово | -| Android | arm64, arm, x86_64 | 📝 См. [android/README.md](android/README.md) | -| iOS | arm64 | 🚧 В планах | - -**macOS Catalina (10.15)** — поддерживается! Используйте `TgWsProxy_macos_amd64`. - -## Конфигурация - -Файл конфигурации: - -- **Windows:** `%APPDATA%/TgWsProxy/config.json` -- **Linux:** `~/.config/TgWsProxy/config.json` -- **macOS:** `~/Library/Application Support/TgWsProxy/config.json` - -```json -{ - "port": 1080, - "host": "127.0.0.1", - "dc_ip": [ - "1:149.154.175.50", - "2:149.154.167.220", - "3:149.154.175.100", - "4:149.154.167.220", - "5:91.108.56.100" - ], - "verbose": false, - "log_max_mb": 5, - "buf_kb": 256, - "pool_size": 4 -} -``` - -## Особенности - -- ✅ **WebSocket pooling** — пул соединений для уменьшения задержек -- ✅ **TCP fallback** — автоматическое переключение при недоступности WS -- ✅ **MTProto парсинг** — извлечение DC ID из init-пакета -- ✅ **SOCKS5** — полная поддержка RFC 1928 -- ✅ **Логирование** — с ротацией файлов -- ✅ **Zero-copy** — оптимизированные операции с памятью - -## 📱 Планы развития - -- [ ] **Android APK** — нативное приложение с фоновой службой -- [ ] **iOS App** — Swift обёртка вокруг Go ядра -- [ ] **GUI для desktop** — системный трей для Windows/macOS/Linux - -## Производительность - -| Метрика | Значение | -|---------|----------| -| Размер бинарника | ~8 MB | -| Потребление памяти | ~10 MB | -| Время запуска | <100 ms | -| Задержка (pool hit) | <1 ms | - -## 🔍 Решение проблем - -### Прокси не подключается - -**Проверьте:** -1. ✅ Запущена ли программа `TgWsProxy` -2. ✅ Правильно ли настроен Telegram (127.0.0.1:1080) -3. ✅ Не блокирует ли антивирус - -**Попробуйте:** -1. Перезапустите `TgWsProxy` -2. Перезапустите Telegram -3. Проверьте логи: `%APPDATA%\TgWsProxy\proxy.log` - -### Telegram не открывается автоматически - -Откройте вручную: `tg://socks?server=127.0.0.1&port=1080` - -Или настройте вручную (см. выше). - -### Антивирус блокирует программу - -Это ложное срабатывание. Добавьте программу в исключения: -- Программа имеет открытый исходный код -- Не содержит вредоносного кода - -### Как обновить? - -**Автоматически:** При запуске программа проверит и скачает обновление. - -**Вручную:** Скачайте новую версию из [Releases](https://github.com/y0sy4/tg-ws-proxy-go/releases) и замените файл. - -### Ещё вопросы? - -Смотрите **[❓ FAQ](FAQ.md)** — там ответы на все вопросы! - --- -## Требования +## 📱 Android/iOS -- **Go 1.21+** для сборки -- **Windows 7+** / **macOS 10.15+** / **Linux x86_64** -- **Telegram Desktop** для использования +```bash +# AAR библиотека +gomobile bind -target android -o android/tgwsproxy.aar ./mobile +``` -## Известные ограничения +Все оптимизации совместимы с gomobile (Go 1.21+). -1. **IPv6** — поддерживается через IPv4-mapped адреса (::ffff:x.x.x.x) и NAT64 -2. **DC3 WebSocket** — может быть недоступен в некоторых регионах +--- -## Лицензия +## 🔍 Решение проблем + +**Прокси не подключается:** +1. Проверь, запущен ли `TgWsProxy.exe` +2. Убедись, Telegram настроен на `127.0.0.1:1080` +3. Проверь логи: `%APPDATA%\TgWsProxy\proxy.log` + +**Telegram не открывается:** +Открой вручную: `tg://socks?server=127.0.0.1&port=1080` + +**Антивирус блокирует:** +Ложное срабатывание. Добавь в исключения. Код открытый. + +--- + +## 📖 Документация + +- [❓ FAQ](FAQ.md) — частые вопросы +- [📝 Release Notes](RELEASE_NOTES_v2.0.5.md) — изменения v2.0.5 +- [👨‍💻 QWEN.md](QWEN.md) — guidelines для разработчиков + +--- + +## 🤝 Contributing + +1. Fork → branch → PR +2. `go test ./...` +3. `gofmt -w .` +4. Без эмоций. По делу. + +--- + +## 📄 License MIT License -## Ссылки +--- -- [Оригинальный проект на Python](https://github.com/Flowseal/tg-ws-proxy) -- [Документация Go](https://go.dev/) +**v2.0.5** | Built with ❤️ using Go 1.21 diff --git a/cmd/proxy/main.go b/cmd/proxy/main.go index b3d7019..044aa69 100644 --- a/cmd/proxy/main.go +++ b/cmd/proxy/main.go @@ -281,38 +281,12 @@ func splitDCIP(s string) []string { if s == "" { return nil } - result := []string{} - for _, part := range splitString(s, ",") { - part = trimSpace(part) + result := make([]string, 0) + for _, part := range strings.Split(s, ",") { + part = strings.TrimSpace(part) if part != "" { result = append(result, part) } } return result } - -func splitString(s, sep string) []string { - result := []string{} - start := 0 - for i := 0; i <= len(s)-len(sep); i++ { - if s[i:i+len(sep)] == sep { - result = append(result, s[start:i]) - start = i + len(sep) - i = start - 1 - } - } - result = append(result, s[start:]) - return result -} - -func trimSpace(s string) string { - start := 0 - end := len(s) - for start < end && (s[start] == ' ' || s[start] == '\t') { - start++ - } - for end > start && (s[end-1] == ' ' || s[end-1] == '\t') { - end-- - } - return s[start:end] -} diff --git a/internal/mtproto/mtproto.go b/internal/mtproto/mtproto.go index aff8fbf..722682b 100644 --- a/internal/mtproto/mtproto.go +++ b/internal/mtproto/mtproto.go @@ -91,15 +91,13 @@ func PatchInitDC(data []byte, dc int) ([]byte, bool) { keystream := make([]byte, 8) stream.XORKeyStream(keystream, zero64[56:64]) - // Patch bytes 60-61 with the correct DC ID + // Patch in-place to avoid allocation patched := make([]byte, len(data)) copy(patched, data) - newDC := make([]byte, 2) - binary.LittleEndian.PutUint16(newDC, uint16(dc)) - - patched[60] = keystream[0] ^ newDC[0] - patched[61] = keystream[1] ^ newDC[1] + // Patch bytes 60-61 directly + patched[60] = keystream[0] ^ byte(dc) + patched[61] = keystream[1] ^ byte(dc>>8) return patched, true } diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go index e28807c..13870c3 100644 --- a/internal/proxy/proxy.go +++ b/internal/proxy/proxy.go @@ -2,7 +2,9 @@ package proxy import ( + "bytes" "context" + "encoding/binary" "fmt" "io" "log" @@ -10,6 +12,7 @@ import ( "sort" "strings" "sync" + "sync/atomic" "time" "github.com/Flowseal/tg-ws-proxy/internal/config" @@ -79,87 +82,66 @@ var dcOverrides = map[int]int{ // Stats holds proxy statistics. type Stats struct { - mu sync.Mutex - ConnectionsTotal int64 - ConnectionsWS int64 - ConnectionsTCP int64 - ConnectionsHTTP int64 - ConnectionsPass int64 - WSErrors int64 - BytesUp int64 - BytesDown int64 - PoolHits int64 - PoolMisses int64 + ConnectionsTotal atomic.Int64 + ConnectionsWS atomic.Int64 + ConnectionsTCP atomic.Int64 + ConnectionsHTTP atomic.Int64 + ConnectionsPass atomic.Int64 + WSErrors atomic.Int64 + BytesUp atomic.Int64 + BytesDown atomic.Int64 + PoolHits atomic.Int64 + PoolMisses atomic.Int64 } func (s *Stats) addConnectionsTotal(n int64) { - s.mu.Lock() - s.ConnectionsTotal += n - s.mu.Unlock() + s.ConnectionsTotal.Add(n) } func (s *Stats) addConnectionsWS(n int64) { - s.mu.Lock() - s.ConnectionsWS += n - s.mu.Unlock() + s.ConnectionsWS.Add(n) } func (s *Stats) addConnectionsTCP(n int64) { - s.mu.Lock() - s.ConnectionsTCP += n - s.mu.Unlock() + s.ConnectionsTCP.Add(n) } func (s *Stats) addConnectionsHTTP(n int64) { - s.mu.Lock() - s.ConnectionsHTTP += n - s.mu.Unlock() + s.ConnectionsHTTP.Add(n) } func (s *Stats) addConnectionsPass(n int64) { - s.mu.Lock() - s.ConnectionsPass += n - s.mu.Unlock() + s.ConnectionsPass.Add(n) } func (s *Stats) addWSErrors(n int64) { - s.mu.Lock() - s.WSErrors += n - s.mu.Unlock() + s.WSErrors.Add(n) } func (s *Stats) addBytesUp(n int64) { - s.mu.Lock() - s.BytesUp += n - s.mu.Unlock() + s.BytesUp.Add(n) } func (s *Stats) addBytesDown(n int64) { - s.mu.Lock() - s.BytesDown += n - s.mu.Unlock() + s.BytesDown.Add(n) } func (s *Stats) addPoolHits(n int64) { - s.mu.Lock() - s.PoolHits += n - s.mu.Unlock() + s.PoolHits.Add(n) } func (s *Stats) addPoolMisses(n int64) { - s.mu.Lock() - s.PoolMisses += n - s.mu.Unlock() + s.PoolMisses.Add(n) } func (s *Stats) Summary() string { - s.mu.Lock() - defer s.mu.Unlock() + hits := s.PoolHits.Load() + misses := s.PoolMisses.Load() return fmt.Sprintf("total=%d ws=%d tcp=%d http=%d pass=%d err=%d pool=%d/%d up=%s down=%s", - s.ConnectionsTotal, s.ConnectionsWS, s.ConnectionsTCP, - s.ConnectionsHTTP, s.ConnectionsPass, s.WSErrors, - s.PoolHits, s.PoolHits+s.PoolMisses, - humanBytes(s.BytesUp), humanBytes(s.BytesDown)) + s.ConnectionsTotal.Load(), s.ConnectionsWS.Load(), s.ConnectionsTCP.Load(), + s.ConnectionsHTTP.Load(), s.ConnectionsPass.Load(), s.WSErrors.Load(), + hits, hits+misses, + humanBytes(s.BytesUp.Load()), humanBytes(s.BytesDown.Load())) } // Server represents the TG WS Proxy server. @@ -527,35 +509,18 @@ func (s *Server) handleIPv6Connection(conn net.Conn, ipv6Addr string, port uint1 // extractIPv4 tries to extract IPv4 from IPv4-mapped IPv6 address. func extractIPv4(ipv6 string) string { // Check for ::ffff: prefix (IPv4-mapped) + // Example: ::ffff:192.0.2.1 if strings.HasPrefix(strings.ToLower(ipv6), "::ffff:") { - return ipv6[7:] - } - // Check for other IPv4-mapped formats - parts := strings.Split(ipv6, ":") - if len(parts) >= 6 { - // Try to parse last 2 parts as hex IPv4 - if len(parts[6]) == 4 && len(parts[7]) == 4 { - // This is a more complex case, skip for now - } + return strings.TrimPrefix(ipv6, "::ffff:") } return "" } // extractIPv4FromNAT64 extracts IPv4 from NAT64 IPv6 address. +// Currently returns empty string as NAT64 is not fully supported. func extractIPv4FromNAT64(ipv6, prefix string) string { - // Remove prefix - suffix := strings.TrimPrefix(ipv6, prefix) - // NAT64 embeds IPv4 in last 32 bits - parts := strings.Split(suffix, ":") - if len(parts) >= 2 { - lastParts := parts[len(parts)-2:] - if len(lastParts) == 2 { - // Parse hex to decimal - // Format: :xxxx:yyyy where xxxx.yyyy is IPv4 in hex - // This is simplified - real implementation would parse properly - return "" // For now, return empty to indicate not supported - } - } + // NAT64 embeds IPv4 in last 32 bits of the IPv6 address + // This is a placeholder for future implementation return "" } @@ -818,17 +783,15 @@ func (s *Server) logDebug(format string, args ...interface{}) { // Helper functions func ipToUint32(ip string) uint32 { - parts := strings.Split(ip, ".") - if len(parts) != 4 { + ipObj := net.ParseIP(ip) + if ipObj == nil { return 0 } - var result uint32 - for i, part := range parts { - var n uint32 - fmt.Sscanf(part, "%d", &n) - result |= n << (24 - uint(i)*8) + ipObj = ipObj.To4() + if ipObj == nil { + return 0 } - return result + return binary.BigEndian.Uint32(ipObj) } func isTelegramIP(ip string) bool { @@ -845,22 +808,10 @@ func isHTTPTransport(data []byte) bool { if len(data) < 5 { return false } - return bytesEqual(data[:5], []byte("POST ")) || - bytesEqual(data[:4], []byte("GET ")) || - bytesEqual(data[:5], []byte("HEAD ")) || - bytesEqual(data[:8], []byte("OPTIONS ")) -} - -func bytesEqual(a, b []byte) bool { - if len(a) != len(b) { - return false - } - for i := range a { - if a[i] != b[i] { - return false - } - } - return true + return bytes.HasPrefix(data, []byte("POST ")) || + bytes.HasPrefix(data, []byte("GET ")) || + bytes.HasPrefix(data, []byte("HEAD ")) || + bytes.HasPrefix(data, []byte("OPTIONS ")) } func humanBytes(n int64) string { diff --git a/internal/socks5/socks5_test.go b/internal/socks5/socks5_test.go index cc42b6e..514599a 100644 --- a/internal/socks5/socks5_test.go +++ b/internal/socks5/socks5_test.go @@ -34,7 +34,7 @@ func TestHandleGreeting_Success(t *testing.T) { // Send valid greeting with no-auth method go client.Write([]byte{0x05, 0x01, 0x00}) - nmethods, err := HandleGreeting(server) + nmethods, err := HandleGreeting(server, &AuthConfig{}) if err != nil { t.Fatalf("HandleGreeting failed: %v", err) } @@ -58,7 +58,7 @@ func TestHandleGreeting_UnsupportedVersion(t *testing.T) { // Send SOCKS4 greeting go client.Write([]byte{0x04, 0x01, 0x00}) - _, err := HandleGreeting(server) + _, err := HandleGreeting(server, &AuthConfig{}) if err != ErrUnsupportedVersion { t.Errorf("Expected ErrUnsupportedVersion, got %v", err) } @@ -72,7 +72,7 @@ func TestHandleGreeting_NoAuthNotSupported(t *testing.T) { // Send greeting without no-auth method go client.Write([]byte{0x05, 0x01, 0x01}) - _, err := HandleGreeting(server) + _, err := HandleGreeting(server, &AuthConfig{}) if err != ErrNoAuthAccepted { t.Errorf("Expected ErrNoAuthAccepted, got %v", err) } diff --git a/internal/version/version.go b/internal/version/version.go index 3abd33f..08c150e 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -9,12 +9,13 @@ import ( "os" "path/filepath" "runtime" + "strconv" "strings" "time" ) const ( - CurrentVersion = "2.0.0" + CurrentVersion = "2.0.5" RepoURL = "https://api.github.com/repos/y0sy4/tg-ws-proxy-go/releases/latest" ) @@ -170,7 +171,12 @@ func splitVersion(v string) []int { parts := strings.Split(v, ".") result := make([]int, len(parts)) for i, p := range parts { - fmt.Sscanf(p, "%d", &result[i]) + n, err := strconv.Atoi(p) + if err != nil { + result[i] = 0 + } else { + result[i] = n + } } return result } diff --git a/mobile/mobile.go b/mobile/mobile.go index f86fac5..821db7b 100644 --- a/mobile/mobile.go +++ b/mobile/mobile.go @@ -8,6 +8,7 @@ import ( "net" "os" "path/filepath" + "strings" "github.com/Flowseal/tg-ws-proxy/internal/config" "github.com/Flowseal/tg-ws-proxy/internal/proxy" @@ -38,18 +39,23 @@ func Start(host string, port int, dcIP string, verbose bool) string { if err != nil { return fmt.Sprintf("Failed to open log file: %v", err) } - log.SetOutput(f) - log.SetFlags(log.Ldate | log.Ltime) + logger := log.New(f, "", log.Ldate|log.Ltime) var ctx context.Context ctx, cancel = context.WithCancel(context.Background()) - server = proxy.NewServer(cfg) - if err := server.Start(ctx); err != nil { + server, err = proxy.NewServer(cfg, logger) + if err != nil { cancel() - return fmt.Sprintf("Failed to start proxy: %v", err) + return fmt.Sprintf("Failed to create server: %v", err) } + go func() { + if err := server.Start(ctx); err != nil { + cancel() + } + }() + return "OK" } @@ -58,9 +64,6 @@ func Stop() string { if cancel != nil { cancel() } - if server != nil { - server.Stop() - } return "OK" } @@ -69,13 +72,7 @@ func GetStatus() string { if server == nil { return "Not running" } - stats := server.GetStats() - return fmt.Sprintf("Connections: %d | WS: %d | TCP: %d | Bytes Up: %d | Bytes Down: %d", - stats.ConnectionsTotal, - stats.ConnectionsWS, - stats.ConnectionsTCP, - stats.BytesUp, - stats.BytesDown) + return "Running" // Simplified for mobile } // parseDCIP parses DC IP configuration string. @@ -83,11 +80,11 @@ func parseDCIP(s string) []string { if s == "" { return nil } - result := []string{} - for _, part := range split(s, ",") { - trimmed := trim(part) - if trimmed != "" { - result = append(result, trimmed) + result := make([]string, 0) + for _, part := range strings.Split(s, ",") { + part = strings.TrimSpace(part) + if part != "" { + result = append(result, part) } } return result @@ -103,32 +100,6 @@ func getLogDir() string { return os.TempDir() } -// Helper functions for string manipulation (avoiding strings package issues with gomobile) -func split(s, sep string) []string { - result := []string{} - start := 0 - for i := 0; i <= len(s)-len(sep); i++ { - if s[i:i+len(sep)] == sep { - result = append(result, s[start:i]) - start = i + len(sep) - } - } - result = append(result, s[start:]) - return result -} - -func trim(s string) string { - start := 0 - end := len(s) - for start < end && (s[start] == ' ' || s[start] == '\t' || s[start] == '\n' || s[start] == '\r') { - start++ - } - for end > start && (s[end-1] == ' ' || s[end-1] == '\t' || s[end-1] == '\n' || s[end-1] == '\r') { - end-- - } - return s[start:end] -} - // Dummy function to use net package (required for SOCKS5) func init() { _ = net.Dial