diff --git a/lib/services/protocol_blocking_service.dart b/lib/services/protocol_blocking_service.dart index 7828f88..90ba771 100644 --- a/lib/services/protocol_blocking_service.dart +++ b/lib/services/protocol_blocking_service.dart @@ -68,38 +68,105 @@ class ProtocolBlockingService { static Future _scanForNewConnections() async { _scanCount++; + if (_activePeerIPs.isEmpty) { + return; // No peers to monitor + } + try { - // Monitor both TCP and UDP connections - final tcpResult = await Process.run('ss', ['-tnp']); - final udpResult = await Process.run('ss', ['-unp']); + // Monitor peer traffic directly using tcpdump on wg0 interface + await _monitorPeerTraffic(); - if (_scanCount % 100 == 0) { // Log every 10 seconds - print('🔍 Scan #$_scanCount - TCP exit code: ${tcpResult.exitCode}, UDP exit code: ${udpResult.exitCode}'); - } - - if (tcpResult.exitCode != 0) { - print('❌ TCP ss command failed: ${tcpResult.stderr}'); - return; - } - if (udpResult.exitCode != 0) { - print('❌ UDP ss command failed: ${udpResult.stderr}'); - return; - } - - final tcpConnections = _parseConnections(tcpResult.stdout.toString(), 'tcp'); - final udpConnections = _parseConnections(udpResult.stdout.toString(), 'udp'); - - if (_scanCount % 100 == 0 && _activePeerIPs.isNotEmpty) { + if (_scanCount % 100 == 0) { print('🔍 Monitoring ${_activePeerIPs.length} active peers: $_activePeerIPs'); } - - for (final conn in [...tcpConnections, ...udpConnections]) { - if (_isNewConnection(conn) && _isPeerConnection(conn)) { - await _handleNewConnection(conn); + } catch (e) { + print('❌ Error monitoring peer traffic: $e'); + } + } + + static Future _monitorPeerTraffic() async { + for (final peerIP in _activePeerIPs) { + try { + // Capture any new outbound traffic from this peer + final process = await Process.start('timeout', [ + '0.1', // Very short timeout - just check for new packets + 'tcpdump', + '-i', 'wg0', + '-c', '1', + '-l', // Line buffered + 'src $peerIP and (tcp[tcpflags] & tcp-syn != 0 or udp)', + ]); + + 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(); + await _analyzeNewPacket(packetData, peerIP); + } + } catch (e) { + // Ignore timeout errors - normal when no new packets + if (!e.toString().contains('timeout')) { + print('❌ Error monitoring peer $peerIP: $e'); } } + } + } + + static Future _analyzeNewPacket(String packetData, String peerIP) async { + if (_processedConnections.contains(packetData.hashCode.toString())) { + return; // Already processed this packet pattern + } + + _processedConnections.add(packetData.hashCode.toString()); + + print('🔍 New peer traffic detected from $peerIP'); + print('📡 Capturing detailed handshake...'); + + // Now capture the full handshake with more detail + await _captureDetailedHandshake(peerIP, packetData); + } + + static Future _captureDetailedHandshake(String peerIP, String initialPacket) async { + try { + final process = await Process.start('timeout', [ + '2', + 'tcpdump', + '-i', 'wg0', + '-c', '3', // Capture a few packets to get handshake + '-s', '200', + '-x', + 'src $peerIP', + ]); + + final handshakeData = []; + await for (final data in process.stdout) { + handshakeData.add(String.fromCharCodes(data)); + } + + final exitCode = await process.exitCode; + process.kill(); + + if (exitCode == 0 && handshakeData.isNotEmpty) { + final data = handshakeData.join(); + print('✅ Handshake captured for peer $peerIP'); + _analyzeHandshake(data, Connection( + protocol: 'unknown', + localIP: peerIP, + localPort: 0, + remoteIP: 'unknown', + remotePort: 0, + )); + } else { + print('⏱️ No additional handshake data captured for peer $peerIP'); + } } catch (e) { - print('❌ Error scanning for connections: $e'); + print('❌ Error capturing detailed handshake: $e'); } }