Update: new version release with binaries

This commit is contained in:
y0sy4 2026-03-23 23:41:44 +03:00
parent 6855662a27
commit b07bd29dae
7 changed files with 203 additions and 455 deletions

400
README.md
View File

@ -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)
> **💡 Просто выберите свою платформу и нажмите "Скачать"!**
| <img src="https://img.icons8.com/color/48/000000/windows-10.png" width="24"/> Windows | <img src="https://img.icons8.com/color/48/000000/linux.png" width="24"/> Linux | <img src="https://img.icons8.com/color/48/000000/mac-os.png" width="24"/> 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

View File

@ -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]
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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)
}

View File

@ -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
}

View File

@ -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,17 +39,22 @@ 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)
server, err = proxy.NewServer(cfg, logger)
if err != nil {
cancel()
return fmt.Sprintf("Failed to create server: %v", err)
}
go func() {
if err := server.Start(ctx); err != nil {
cancel()
return fmt.Sprintf("Failed to start proxy: %v", err)
}
}()
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