diff --git a/lib/services/protocol_blocking_service.dart b/lib/services/protocol_blocking_service.dart index d4ae634..9f2bbd3 100644 --- a/lib/services/protocol_blocking_service.dart +++ b/lib/services/protocol_blocking_service.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:waylume_server/services/vpn_session_service.dart'; @@ -91,44 +92,84 @@ class ProtocolBlockingService { } } + static Process? _continuousMonitor; + static StreamSubscription? _monitorSubscription; + static Future _monitorPeerTraffic() async { - // Monitor FORWARDED traffic (after VPN decryption, before internet) + // Start continuous monitoring if not already running + if (_continuousMonitor == null) { + await _startContinuousMonitoring(); + } + } + + static Future _startContinuousMonitoring() async { try { - final process = await Process.start('timeout', [ - '0.1', // Very short timeout - 'tcpdump', + print('🔄 Starting continuous packet monitoring...'); + _continuousMonitor = await Process.start('tcpdump', [ '-i', 'any', - '-c', '1', + '-l', // Line buffered for real-time output '-v', // Verbose // Only capture forwarded packets from VPN peers to internet 'src net 10.0.0.0/24 and not dst net 10.0.0.0/24', ]); - - final output = []; - await for (final data in process.stdout) { - output.add(String.fromCharCodes(data)); - } - - final exitCode = await process.exitCode; - process.kill(); - - if (exitCode == 0 && output.isNotEmpty) { - final packetData = output.join().trim(); - print('📦 DECRYPTED VPN TRAFFIC TO INTERNET: $packetData'); - - // Check if it's from our monitored peers - for (final peerIP in _activePeerIPs) { - if (packetData.contains(peerIP)) { - print('🎯 PEER TRAFFIC FROM $peerIP: $packetData'); - await _analyzeNewPacket(packetData, peerIP); - break; - } - } - } + + _monitorSubscription = _continuousMonitor!.stdout + .transform(utf8.decoder) + .transform(LineSplitter()) + .listen((line) async { + if (line.trim().isNotEmpty) { + await _processCapturedPacket(line.trim()); + } + }); + + // Handle process errors + _continuousMonitor!.stderr + .transform(utf8.decoder) + .listen((error) { + if (!error.contains('listening on')) { + print('❌ tcpdump error: $error'); + } + }); + } catch (e) { - // Ignore timeout errors - normal when no packets - if (!e.toString().contains('timeout') && !e.toString().contains('No such device')) { - print('❌ Error monitoring traffic: $e'); + print('❌ Failed to start continuous monitoring: $e'); + } + } + + static Future _processCapturedPacket(String packetLine) async { + print('📦 DECRYPTED VPN TRAFFIC: $packetLine'); + + // Check if it's from our monitored peers and analyze + for (final peerIP in _activePeerIPs) { + if (packetLine.contains(peerIP)) { + print('🎯 PEER TRAFFIC FROM $peerIP: $packetLine'); + await _analyzePacketLine(packetLine, peerIP); + break; + } + } + } + + static Future _analyzePacketLine(String packetLine, String peerIP) async { + // Simple protocol detection from packet line + String? protocol; + + if (packetLine.toLowerCase().contains('bittorrent') || + packetLine.contains(':6881') || packetLine.contains(':6882')) { + protocol = 'BitTorrent'; + } else if (packetLine.contains('.https:') || packetLine.contains(':443')) { + protocol = 'HTTPS'; + } else if (packetLine.contains('.http:') || packetLine.contains(':80')) { + protocol = 'HTTP'; + } else if (packetLine.contains('.ssh:') || packetLine.contains(':22')) { + protocol = 'SSH'; + } + + if (protocol != null) { + print('🎯 PROTOCOL DETECTED: $protocol'); + if (['BitTorrent', 'P2P'].contains(protocol)) { + print('🚫 BLOCKING PROTOCOL: $protocol'); + } else { + print('✅ ALLOWING PROTOCOL: $protocol'); } } }