Add logging for speed limit and traffic control commands

This commit is contained in:
ImBenji
2025-08-05 12:21:29 +01:00
parent a5fc0e3644
commit c5ed47d41a
4 changed files with 163 additions and 4 deletions

View File

@@ -0,0 +1,149 @@
import 'dart:convert';
import 'dart:io';
class ApiTester {
final String baseUrl;
final HttpClient httpClient;
ApiTester(this.baseUrl) : httpClient = HttpClient();
Future<Map<String, dynamic>> makeRequest(String method, String path, [Map<String, dynamic>? 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<void> 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<String, dynamic>;
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<String> 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();
}

View File

@@ -6,6 +6,11 @@ class TrafficControlService {
print('Setting speed limit for peer $peerIP to ${speedKbps}kbps (mark: $mark)'); print('Setting speed limit for peer $peerIP to ${speedKbps}kbps (mark: $mark)');
try { 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...'); print('Running iptables MARK commands for $peerIP...');
await _runIptablesCommand(['-I', 'FORWARD', '-s', peerIP, '-j', 'MARK', '--set-mark', mark.toString()]); await _runIptablesCommand(['-I', 'FORWARD', '-s', peerIP, '-j', 'MARK', '--set-mark', mark.toString()]);
await _runIptablesCommand(['-I', 'FORWARD', '-d', peerIP, '-j', 'MARK', '--set-mark', mark.toString()]); await _runIptablesCommand(['-I', 'FORWARD', '-d', peerIP, '-j', 'MARK', '--set-mark', mark.toString()]);
@@ -19,9 +24,12 @@ class TrafficControlService {
print('Speed limit set successfully for $peerIP'); print('Speed limit set successfully for $peerIP');
} catch (e) { } catch (e) {
print('ERROR setting speed limit for $peerIP: $e'); print('ERROR setting speed limit for $peerIP: $e');
// Don't rethrow if it's just because qdisc already exists
if (!e.toString().contains('File exists')) {
rethrow; rethrow;
} }
} }
}
static Future<void> setDataCap(String peerIP, int dataCapMB) async { static Future<void> setDataCap(String peerIP, int dataCapMB) async {
final quotaBytes = dataCapMB * 1024 * 1024; final quotaBytes = dataCapMB * 1024 * 1024;
@@ -33,7 +41,9 @@ class TrafficControlService {
} }
static int _getMarkForIP(String ip) { 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<void> _runIptablesCommand(List<String> args) async { static Future<void> _runIptablesCommand(List<String> args) async {

View File

@@ -506,4 +506,4 @@ packages:
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
sdks: sdks:
dart: ">=3.9.0-100.2.beta <4.0.0" dart: ">=3.8.0 <4.0.0"

View File

@@ -4,7 +4,7 @@ version: 0.0.1
# repository: https://github.com/my_org/my_repo # repository: https://github.com/my_org/my_repo
environment: environment:
sdk: ^3.9.0-100.2.beta sdk: ^3.8.0
# Add regular dependencies here. # Add regular dependencies here.
dependencies: dependencies: