From c5ed47d41a181179d0255d208aae349bce07af79 Mon Sep 17 00:00:00 2001 From: ImBenji Date: Tue, 5 Aug 2025 12:21:29 +0100 Subject: [PATCH] Add logging for speed limit and traffic control commands --- lib/test_scripts/test_api.dart | 149 +++++++++++++++++++++++++++++ lib/wireguard/traffic_control.dart | 14 ++- pubspec.lock | 2 +- pubspec.yaml | 2 +- 4 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 lib/test_scripts/test_api.dart diff --git a/lib/test_scripts/test_api.dart b/lib/test_scripts/test_api.dart new file mode 100644 index 0000000..3f02e2e --- /dev/null +++ b/lib/test_scripts/test_api.dart @@ -0,0 +1,149 @@ +import 'dart:convert'; +import 'dart:io'; + +class ApiTester { + final String baseUrl; + final HttpClient httpClient; + + ApiTester(this.baseUrl) : httpClient = HttpClient(); + + Future> makeRequest(String method, String path, [Map? body]) async { + final uri = Uri.parse('$baseUrl$path'); + print('\n๐Ÿ” $method $uri'); + + late HttpClientRequest request; + switch (method.toUpperCase()) { + case 'GET': + request = await httpClient.getUrl(uri); + break; + case 'POST': + request = await httpClient.postUrl(uri); + break; + case 'PUT': + request = await httpClient.putUrl(uri); + break; + case 'DELETE': + request = await httpClient.deleteUrl(uri); + break; + default: + throw ArgumentError('Unsupported HTTP method: $method'); + } + + request.headers.set('Content-Type', 'application/json'); + + if (body != null) { + final jsonBody = jsonEncode(body); + print('๐Ÿ“ค Request Body: $jsonBody'); + request.write(jsonBody); + } + + final response = await request.close(); + final responseBody = await response.transform(utf8.decoder).join(); + + print('๐Ÿ“Š Status: ${response.statusCode}'); + print('๐Ÿ“ฅ Response: $responseBody'); + + try { + return { + 'statusCode': response.statusCode, + 'body': jsonDecode(responseBody), + }; + } catch (e) { + return { + 'statusCode': response.statusCode, + 'body': responseBody, + }; + } + } + + Future testAllEndpoints() async { + print('๐Ÿš€ Starting API Tests for $baseUrl'); + print('=' * 50); + + try { + // Test 1: Create a peer + print('\n๐Ÿ“‹ TEST 1: Create a new peer'); + final createResponse = await makeRequest('POST', '/api/peers'); + + if (createResponse['statusCode'] != 200 || createResponse['body']['success'] != true) { + print('โŒ Failed to create peer'); + return; + } + + final peer = createResponse['body']['peer'] as Map; + final publicKey = peer['publicKey'] as String; + final peerIP = peer['ip'] as String; + + print('โœ… Created peer successfully'); + print(' Public Key: $publicKey'); + print(' IP: $peerIP'); + + // Test 2: Set speed limit + print('\n๐Ÿ“‹ TEST 2: Set speed limit (500 kbps)'); + final speedResponse = await makeRequest('POST', '/api/peers/speed-limit', { + 'publicKey': publicKey, + 'speedKbps': 500, + }); + + if (speedResponse['statusCode'] == 200 && speedResponse['body']['success'] == true) { + print('โœ… Speed limit set successfully'); + } else { + print('โŒ Speed limit failed: ${speedResponse['body']}'); + } + + // Test 3: Set data cap + print('\n๐Ÿ“‹ TEST 3: Set data cap (1024 MB)'); + final dataCapResponse = await makeRequest('POST', '/api/peers/data-cap', { + 'publicKey': publicKey, + 'dataCapMB': 1024, + }); + + if (dataCapResponse['statusCode'] == 200 && dataCapResponse['body']['success'] == true) { + print('โœ… Data cap set successfully'); + } else { + print('โŒ Data cap failed: ${dataCapResponse['body']}'); + } + + // Test 4: Get peer config + print('\n๐Ÿ“‹ TEST 4: Get peer config'); + final configResponse = await makeRequest('POST', '/api/peers/config', { + 'publicKey': publicKey, + }); + + if (configResponse['statusCode'] == 404) { + print('โœ… Config endpoint working (returns not implemented as expected)'); + } else { + print('โ“ Unexpected config response: ${configResponse['body']}'); + } + + // Test 5: Delete peer + print('\n๐Ÿ“‹ TEST 5: Delete peer'); + final deleteResponse = await makeRequest('POST', '/api/peers/delete', { + 'publicKey': publicKey, + }); + + if (deleteResponse['statusCode'] == 200 && deleteResponse['body']['success'] == true) { + print('โœ… Peer deleted successfully'); + } else { + print('โŒ Delete failed: ${deleteResponse['body']}'); + } + + print('\n๐ŸŽ‰ All tests completed!'); + + } catch (e) { + print('โŒ Test failed with error: $e'); + } finally { + httpClient.close(); + } + } +} + +void main(List args) async { + final serverUrl = args.isNotEmpty ? args[0] : 'http://51.38.64.5:3002'; + + print('๐Ÿงช Waylume Server API Tester'); + print('Server: $serverUrl'); + + final tester = ApiTester(serverUrl); + await tester.testAllEndpoints(); +} \ No newline at end of file diff --git a/lib/wireguard/traffic_control.dart b/lib/wireguard/traffic_control.dart index 0526ab8..6f1d4d3 100644 --- a/lib/wireguard/traffic_control.dart +++ b/lib/wireguard/traffic_control.dart @@ -6,6 +6,11 @@ class TrafficControlService { print('Setting speed limit for peer $peerIP to ${speedKbps}kbps (mark: $mark)'); try { + // Ensure HTB qdisc exists on wg0 + print('Setting up HTB qdisc on wg0...'); + await _runTcCommand(['qdisc', 'add', 'dev', 'wg0', 'root', 'handle', '1:', 'htb', 'default', '30']); + await _runTcCommand(['class', 'add', 'dev', 'wg0', 'parent', '1:', 'classid', '1:1', 'htb', 'rate', '1000mbit']); + print('Running iptables MARK commands for $peerIP...'); await _runIptablesCommand(['-I', 'FORWARD', '-s', peerIP, '-j', 'MARK', '--set-mark', mark.toString()]); await _runIptablesCommand(['-I', 'FORWARD', '-d', peerIP, '-j', 'MARK', '--set-mark', mark.toString()]); @@ -19,7 +24,10 @@ class TrafficControlService { print('Speed limit set successfully for $peerIP'); } catch (e) { print('ERROR setting speed limit for $peerIP: $e'); - rethrow; + // Don't rethrow if it's just because qdisc already exists + if (!e.toString().contains('File exists')) { + rethrow; + } } } @@ -33,7 +41,9 @@ class TrafficControlService { } static int _getMarkForIP(String ip) { - return ip.split('.').last.hashCode % 65535 + 1; + // Use last octet of IP + 10 to ensure small, valid class IDs (10-255) + final lastOctet = int.parse(ip.split('.').last); + return lastOctet + 10; } static Future _runIptablesCommand(List args) async { diff --git a/pubspec.lock b/pubspec.lock index 3cb4840..10e7dbf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -506,4 +506,4 @@ packages: source: hosted version: "2.1.0" sdks: - dart: ">=3.9.0-100.2.beta <4.0.0" + dart: ">=3.8.0 <4.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index b2adae7..9f9f26e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ version: 0.0.1 # repository: https://github.com/my_org/my_repo environment: - sdk: ^3.9.0-100.2.beta + sdk: ^3.8.0 # Add regular dependencies here. dependencies: