feat(NetworkConfigManager): enhance IP address generation logic to validate local and remote IPs against CIDR; ensure unique IPs and improve handling for /30 networks
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m39s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m39s
This commit is contained in:
@@ -896,6 +896,11 @@ function NetworkConfigManager() {
|
||||
if (forRemote && pairedLocalIp) {
|
||||
const localIpParts = pairedLocalIp.trim().split('.');
|
||||
if (localIpParts.length === 4) {
|
||||
// Проверяем, что Local IP входит в пул
|
||||
if (!isIpInCidr(pairedLocalIp, cidr)) {
|
||||
return null; // Local IP не в пуле, не можем сгенерировать Remote
|
||||
}
|
||||
|
||||
const baseOctet = parseInt(localIpParts[3]);
|
||||
const networkBase = Math.floor(baseOctet / 4) * 4;
|
||||
const localOffset = baseOctet - networkBase;
|
||||
@@ -912,73 +917,86 @@ function NetworkConfigManager() {
|
||||
const remoteOctet = networkBase + remoteOffset;
|
||||
if (remoteOctet >= 0 && remoteOctet <= 255) {
|
||||
const remoteIp = `${localIpParts[0]}.${localIpParts[1]}.${localIpParts[2]}.${remoteOctet}`;
|
||||
// Проверяем, что IP входит в диапазон пула
|
||||
if (isIpInCidr(remoteIp, cidr) && !usedIps.has(remoteIp)) {
|
||||
// Проверяем, что Remote IP входит в диапазон пула и отличается от Local IP
|
||||
if (isIpInCidr(remoteIp, cidr) && !usedIps.has(remoteIp) && remoteIp !== pairedLocalIp) {
|
||||
return remoteIp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; // Не удалось сгенерировать парный Remote IP
|
||||
}
|
||||
|
||||
// Вычисляем количество хостов в сети
|
||||
const hostBits = 32 - prefix;
|
||||
const totalHosts = Math.pow(2, hostBits);
|
||||
|
||||
// Для /30 сетей используем шаг 4 (базовые адреса кратные 4)
|
||||
const step = prefix >= 30 ? 4 : 1;
|
||||
|
||||
// Определяем диапазон для перебора в зависимости от префикса
|
||||
let startOctet = 0;
|
||||
let endOctet = 255;
|
||||
|
||||
if (prefix >= 24) {
|
||||
// /24 - /32: меняем только последний октет
|
||||
startOctet = d;
|
||||
endOctet = Math.min(d + totalHosts - 1, 255);
|
||||
const startOctet = d;
|
||||
const maxHosts = Math.pow(2, hostBits);
|
||||
const endOctet = Math.min(d + maxHosts - 1, 255);
|
||||
|
||||
// Перебираем IP в диапазоне
|
||||
for (let dVal = startOctet; dVal <= endOctet; dVal += step) {
|
||||
if (prefix >= 30 && dVal % 4 !== 0) continue; // Для /30 только кратные 4
|
||||
|
||||
// Local IP = базовый + 1, Remote IP = базовый + 2
|
||||
const localIp = `${a}.${b}.${c}.${dVal + 1}`;
|
||||
const remoteIp = `${a}.${b}.${c}.${dVal + 2}`;
|
||||
|
||||
// Проверяем, что IP входят в диапазон пула
|
||||
if (!isIpInCidr(localIp, cidr)) continue;
|
||||
if (!isIpInCidr(remoteIp, cidr)) continue;
|
||||
|
||||
// Проверяем, что IP отличаются друг от друга
|
||||
if (localIp === remoteIp) continue;
|
||||
|
||||
// Проверяем, свободны ли оба IP (для /30)
|
||||
if (prefix >= 30) {
|
||||
if (!usedIps.has(localIp) && !usedIps.has(remoteIp)) {
|
||||
return forRemote ? remoteIp : localIp;
|
||||
}
|
||||
} else {
|
||||
// Для других префиксов просто проверяем один IP
|
||||
if (!usedIps.has(localIp)) {
|
||||
return localIp;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (prefix >= 16) {
|
||||
// /16 - /23: меняем третий и четвертый октеты
|
||||
const thirdOctetRange = Math.pow(2, Math.max(0, 24 - prefix));
|
||||
for (let cVal = c; cVal < c + thirdOctetRange && cVal <= 255; cVal++) {
|
||||
const dStart = (cVal === c) ? d : 0;
|
||||
const dEnd = (cVal === c + thirdOctetRange - 1) ? Math.min(d + totalHosts - 1, 255) : 255;
|
||||
const dEnd = 255;
|
||||
for (let dVal = dStart; dVal <= dEnd; dVal += step) {
|
||||
if (prefix >= 30 && dVal % 4 !== 0) continue; // Для /30 только кратные 4
|
||||
const ip = `${a}.${b}.${cVal}.${dVal + 1}`; // Local IP = базовый + 1
|
||||
if (isIpInCidr(ip, cidr) && !usedIps.has(ip)) {
|
||||
return ip;
|
||||
const localIp = `${a}.${b}.${cVal}.${dVal + 1}`; // Local IP = базовый + 1
|
||||
const remoteIp = `${a}.${b}.${cVal}.${dVal + 2}`; // Remote IP = базовый + 2
|
||||
|
||||
// Проверяем, что IP входят в диапазон пула и отличаются
|
||||
if (!isIpInCidr(localIp, cidr)) continue;
|
||||
if (isIpInCidr(remoteIp, cidr) && localIp !== remoteIp) {
|
||||
if (prefix >= 30) {
|
||||
if (!usedIps.has(localIp) && !usedIps.has(remoteIp)) {
|
||||
return forRemote ? remoteIp : localIp;
|
||||
}
|
||||
} else {
|
||||
if (!usedIps.has(localIp)) {
|
||||
return localIp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
// /0 - /15: слишком большой диапазон, используем упрощенную логику
|
||||
return null;
|
||||
}
|
||||
|
||||
// Перебираем IP в диапазоне
|
||||
for (let dVal = startOctet; dVal <= endOctet; dVal += step) {
|
||||
if (prefix >= 30 && dVal % 4 !== 0) continue; // Для /30 только кратные 4
|
||||
|
||||
// Local IP = базовый + 1, Remote IP = базовый + 2
|
||||
const localIp = `${a}.${b}.${c}.${dVal + 1}`;
|
||||
const remoteIp = `${a}.${b}.${c}.${dVal + 2}`;
|
||||
|
||||
// Проверяем, что IP входит в диапазон пула
|
||||
if (!isIpInCidr(localIp, cidr)) continue;
|
||||
|
||||
// Проверяем, свободны ли оба IP (для /30)
|
||||
if (prefix >= 30) {
|
||||
if (!usedIps.has(localIp) && !usedIps.has(remoteIp)) {
|
||||
return forRemote ? remoteIp : localIp;
|
||||
}
|
||||
} else {
|
||||
// Для других префиксов просто проверяем один IP
|
||||
if (!usedIps.has(localIp)) {
|
||||
return localIp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user