fix(network-proxy, route-utils, route-manager): Normalize IPv6-mapped IPv4 addresses in IP matching functions and remove deprecated legacy configuration methods in NetworkProxy. Update route-utils and route-manager to compare both canonical and IPv6-mapped IP forms, adjust tests accordingly, and clean up legacy exports.

This commit is contained in:
2025-05-14 12:26:43 +00:00
parent 0fe0692e43
commit bb54ea8192
15 changed files with 511 additions and 1208 deletions

View File

@ -291,12 +291,15 @@ export class RouteManager {
/**
* Match an IP pattern against an IP
* Supports exact matches, wildcard patterns, and CIDR notation
*/
private matchIp(pattern: string, ip: string): boolean {
// Exact match
if (pattern === ip) {
return true;
}
// Wildcard matching (e.g., 192.168.0.*)
if (pattern.includes('*')) {
const regexPattern = pattern
.replace(/\./g, '\\.')
@ -306,10 +309,65 @@ export class RouteManager {
return regex.test(ip);
}
// TODO: Implement CIDR matching
// CIDR matching (e.g., 192.168.0.0/24)
if (pattern.includes('/')) {
try {
const [subnet, bits] = pattern.split('/');
// Convert IP addresses to numeric format for comparison
const ipBinary = this.ipToBinary(ip);
const subnetBinary = this.ipToBinary(subnet);
if (!ipBinary || !subnetBinary) {
return false;
}
// Get the subnet mask from CIDR notation
const mask = parseInt(bits, 10);
if (isNaN(mask) || mask < 0 || mask > 32) {
return false;
}
// Check if the first 'mask' bits match between IP and subnet
return ipBinary.slice(0, mask) === subnetBinary.slice(0, mask);
} catch (error) {
// If we encounter any error during CIDR matching, return false
return false;
}
}
return false;
}
/**
* Convert an IP address to its binary representation
* @param ip The IP address to convert
* @returns Binary string representation or null if invalid
*/
private ipToBinary(ip: string): string | null {
// Handle IPv4 addresses only for now
const parts = ip.split('.');
// Validate IP format
if (parts.length !== 4) {
return null;
}
// Convert each octet to 8-bit binary and concatenate
try {
return parts
.map(part => {
const num = parseInt(part, 10);
if (isNaN(num) || num < 0 || num > 255) {
throw new Error('Invalid IP octet');
}
return num.toString(2).padStart(8, '0');
})
.join('');
} catch (error) {
return null;
}
}
}
/**