92 lines
3.2 KiB
Dart
92 lines
3.2 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'package:supabase/supabase.dart';
|
|
import 'package:waylume_server/config/supabase_config.dart';
|
|
|
|
class VpnSessionService {
|
|
|
|
/// Detects existing VPN sessions for this server and prints their IDs with keepalive info
|
|
static Future<void> detectSessions() async {
|
|
try {
|
|
final serverId = fromEnivronment('SERVER_ID');
|
|
|
|
if (serverId == null) {
|
|
print('ERROR: SERVER_ID environment variable not set');
|
|
return;
|
|
}
|
|
|
|
// Get all sessions for this server
|
|
final sessions = await SUPABASE_CLIENT
|
|
.from('vpn_sessions')
|
|
.select('id, peer_info')
|
|
.eq('server_id', serverId);
|
|
|
|
if (sessions.isEmpty) {
|
|
print('No VPN sessions found for server: $serverId');
|
|
} else {
|
|
print('Found ${sessions.length} VPN sessions for server: $serverId');
|
|
|
|
for (final session in sessions) {
|
|
final sessionId = session['id'];
|
|
final peerInfo = session['peer_info'];
|
|
|
|
if (peerInfo != null && peerInfo['peer'] != null && peerInfo['peer']['publicKey'] != null) {
|
|
final publicKey = peerInfo['peer']['publicKey'] as String;
|
|
final keepaliveInfo = await _getKeepaliveForPeer(publicKey);
|
|
|
|
print('Session ID: $sessionId - Peer: ${publicKey.substring(0, 8)}... - $keepaliveInfo');
|
|
} else {
|
|
print('Session ID: $sessionId - No peer public key available');
|
|
}
|
|
}
|
|
}
|
|
|
|
} catch (e) {
|
|
print('Error detecting sessions: $e');
|
|
}
|
|
}
|
|
|
|
/// Gets keepalive info for a specific peer
|
|
static Future<String> _getKeepaliveForPeer(String publicKey) async {
|
|
try {
|
|
final result = await Process.run('wg', ['show', 'wg0', 'dump']);
|
|
if (result.exitCode != 0) {
|
|
return 'Failed to get WireGuard info';
|
|
}
|
|
|
|
final lines = result.stdout.toString().trim().split('\n');
|
|
|
|
// Skip first line (server info) and look for this peer
|
|
for (int i = 1; i < lines.length; i++) {
|
|
final line = lines[i].trim();
|
|
if (line.isEmpty) continue;
|
|
|
|
final parts = line.split('\t');
|
|
if (parts.length >= 5 && parts[0] == publicKey) {
|
|
final latestHandshake = parts[4];
|
|
final handshakeTime = int.tryParse(latestHandshake) ?? 0;
|
|
|
|
if (handshakeTime == 0) {
|
|
return 'No handshake yet';
|
|
} else {
|
|
final handshakeDateTime = DateTime.fromMillisecondsSinceEpoch(handshakeTime * 1000);
|
|
final now = DateTime.now();
|
|
final duration = now.difference(handshakeDateTime);
|
|
|
|
// Check if connection is dead (more than 2 minutes 30 seconds)
|
|
if (duration.inSeconds > 150) {
|
|
return 'DEAD - Last handshake: ${handshakeDateTime.toLocal()} (${duration.inMinutes}m ${duration.inSeconds % 60}s ago)';
|
|
} else {
|
|
return 'ALIVE - Last handshake: ${handshakeDateTime.toLocal()} (${duration.inSeconds}s ago)';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 'Peer not found in WireGuard';
|
|
|
|
} catch (e) {
|
|
return 'Error checking keepalive: $e';
|
|
}
|
|
}
|
|
} |