Initial commit
This commit is contained in:
143
internal/vpn/vpn.go
Normal file
143
internal/vpn/vpn.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package vpn
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"vpn-client/internal/config"
|
||||
"vpn-client/internal/logger"
|
||||
"vpn-client/internal/wireguard"
|
||||
)
|
||||
|
||||
// Disconnect отключает VPN
|
||||
func Disconnect(logsDir string) error {
|
||||
// Загружаем состояние
|
||||
state, err := config.LoadState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("ошибка загрузки состояния: %w", err)
|
||||
}
|
||||
|
||||
if !state.Connected {
|
||||
return fmt.Errorf("VPN не подключен")
|
||||
}
|
||||
|
||||
fmt.Printf("Отключение от '%s'...\n", state.ConfigName)
|
||||
|
||||
// Логируем отключение
|
||||
var logFile string
|
||||
if state.ConfigType == "wireguard" {
|
||||
logFile = logger.GetLogPath(logsDir, "wireguard")
|
||||
} else if state.ConfigType == "vless" {
|
||||
logFile = logger.GetLogPath(logsDir, "vless")
|
||||
}
|
||||
|
||||
if logFile != "" {
|
||||
logger.LogMessage(logFile, fmt.Sprintf("Начало отключения от '%s'", state.ConfigName))
|
||||
}
|
||||
|
||||
// Останавливаем процесс в зависимости от типа
|
||||
if state.ConfigType == "wireguard" {
|
||||
// Отключаем WireGuard
|
||||
if err := wireguard.Disconnect(state.Interface, logsDir); err != nil {
|
||||
fmt.Printf("%s Ошибка отключения WireGuard: %v\n", "⚠", err)
|
||||
}
|
||||
} else if state.ProcessPID > 0 {
|
||||
// Останавливаем процесс VLESS
|
||||
process, err := os.FindProcess(state.ProcessPID)
|
||||
if err == nil {
|
||||
if runtime.GOOS == "windows" {
|
||||
// На Windows используем taskkill
|
||||
process.Kill()
|
||||
} else {
|
||||
// На Unix используем SIGTERM
|
||||
process.Signal(syscall.SIGTERM)
|
||||
}
|
||||
|
||||
// Ждем завершения процесса
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
if logFile != "" {
|
||||
logger.LogMessage(logFile, fmt.Sprintf("Отключено от '%s' (PID: %d)", state.ConfigName, state.ProcessPID))
|
||||
}
|
||||
|
||||
if state.LogFile != "" && logFile != "" {
|
||||
logger.LogMessage(logFile, fmt.Sprintf("Лог трафика сохранен: %s", state.LogFile))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Сбрасываем состояние
|
||||
newState := &config.ConnectionState{
|
||||
Connected: false,
|
||||
ConfigName: "",
|
||||
ConfigType: "",
|
||||
StartTime: "",
|
||||
Interface: "",
|
||||
ProcessPID: 0,
|
||||
LogFile: "",
|
||||
}
|
||||
|
||||
if err := config.SaveState(newState); err != nil {
|
||||
return fmt.Errorf("ошибка сохранения состояния: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("✓ Отключено от VPN")
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetStatus возвращает текущий статус подключения
|
||||
func GetStatus() (*config.ConnectionState, error) {
|
||||
return config.LoadState()
|
||||
}
|
||||
|
||||
// ShowStatus отображает детальный статус подключения
|
||||
func ShowStatus() error {
|
||||
state, err := GetStatus()
|
||||
if err != nil {
|
||||
return fmt.Errorf("ошибка получения статуса: %w", err)
|
||||
}
|
||||
|
||||
if !state.Connected {
|
||||
fmt.Println("\n❌ VPN не подключен")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("\n" + "==================================================")
|
||||
fmt.Println("📊 Статус VPN")
|
||||
fmt.Println("==================================================")
|
||||
fmt.Printf("Статус: ✓ Подключено\n")
|
||||
fmt.Printf("Конфиг: %s\n", state.ConfigName)
|
||||
fmt.Printf("Тип: %s\n", state.ConfigType)
|
||||
|
||||
if state.StartTime != "" {
|
||||
startTime, err := time.Parse(time.RFC3339, state.StartTime)
|
||||
if err == nil {
|
||||
duration := time.Since(startTime)
|
||||
hours := int(duration.Hours())
|
||||
minutes := int(duration.Minutes()) % 60
|
||||
seconds := int(duration.Seconds()) % 60
|
||||
fmt.Printf("Время подключения: %02d:%02d:%02d\n", hours, minutes, seconds)
|
||||
}
|
||||
}
|
||||
|
||||
if state.ConfigType == "vless" {
|
||||
fmt.Printf("Прокси: 127.0.0.1:10808\n")
|
||||
if state.LogFile != "" {
|
||||
fmt.Printf("Лог трафика: %s\n", state.LogFile)
|
||||
}
|
||||
} else if state.ConfigType == "wireguard" {
|
||||
// Получаем статистику WireGuard
|
||||
stats, err := wireguard.GetStats(state.Interface)
|
||||
if err == nil {
|
||||
fmt.Printf("\nСтатистика трафика:\n")
|
||||
fmt.Printf(" Получено: %s\n", stats["rx"])
|
||||
fmt.Printf(" Отправлено: %s\n", stats["tx"])
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("==================================================")
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user