feat(NetworkConfigManager): improve IP address generation by passing used IPs to ensure uniqueness across tunnel creations; enhance error messaging for IP allocation failures
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m46s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m46s
This commit is contained in:
@@ -536,7 +536,7 @@ function NetworkConfigManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const newInterfaces = [];
|
const newInterfaces = [];
|
||||||
const usedIps = new Set(getAllUsedIpsSet);
|
const usedIps = new Set(getAllUsedIpsSet); // Создаем Set с уже использованными IP из существующих интерфейсов
|
||||||
|
|
||||||
// Создаем туннели для каждой пары
|
// Создаем туннели для каждой пары
|
||||||
templateServerPairs.forEach((pair, index) => {
|
templateServerPairs.forEach((pair, index) => {
|
||||||
@@ -560,15 +560,16 @@ function NetworkConfigManager() {
|
|||||||
|
|
||||||
// Генерируем IP адреса (учитываем уже использованные в этой итерации)
|
// Генерируем IP адреса (учитываем уже использованные в этой итерации)
|
||||||
// Важно: Local IP и Remote IP должны быть разными и в одной сети /30
|
// Важно: Local IP и Remote IP должны быть разными и в одной сети /30
|
||||||
|
// Передаем usedIps в функцию, чтобы она учитывала IP, выделенные для предыдущих туннелей
|
||||||
let localIp = null;
|
let localIp = null;
|
||||||
let remoteIp = null;
|
let remoteIp = null;
|
||||||
let attempts = 0;
|
let attempts = 0;
|
||||||
const maxAttempts = 1000;
|
const maxAttempts = 1000;
|
||||||
|
|
||||||
while ((!localIp || !remoteIp || localIp === remoteIp) && attempts < maxAttempts) {
|
while ((!localIp || !remoteIp || localIp === remoteIp) && attempts < maxAttempts) {
|
||||||
const candidateLocal = generateFreePrivateIp(null, false, null, pairIpPoolId || null);
|
const candidateLocal = generateFreePrivateIp(null, false, null, pairIpPoolId || null, usedIps);
|
||||||
if (candidateLocal && !usedIps.has(candidateLocal)) {
|
if (candidateLocal && !usedIps.has(candidateLocal)) {
|
||||||
const candidateRemote = generateFreePrivateIp(null, true, candidateLocal, pairIpPoolId || null);
|
const candidateRemote = generateFreePrivateIp(null, true, candidateLocal, pairIpPoolId || null, usedIps);
|
||||||
if (candidateRemote && !usedIps.has(candidateRemote) && candidateRemote !== candidateLocal) {
|
if (candidateRemote && !usedIps.has(candidateRemote) && candidateRemote !== candidateLocal) {
|
||||||
localIp = candidateLocal;
|
localIp = candidateLocal;
|
||||||
remoteIp = candidateRemote;
|
remoteIp = candidateRemote;
|
||||||
@@ -581,7 +582,7 @@ function NetworkConfigManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!localIp || !remoteIp || localIp === remoteIp) {
|
if (!localIp || !remoteIp || localIp === remoteIp) {
|
||||||
notify.error(`Не удалось найти свободные IP адреса для туннеля ${index + 1} (${server1.dns || server1.ip} ↔ ${server2.dns || server2.ip})`);
|
notify.error(`Не удалось найти свободные IP адреса для туннеля ${index + 1} (${server1.dns || server1.ip} ↔ ${server2.dns || server2.ip}). Возможно, в пуле закончились свободные адреса.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -781,8 +782,10 @@ function NetworkConfigManager() {
|
|||||||
// === Генерация свободного IP адреса из приватных диапазонов ===
|
// === Генерация свободного IP адреса из приватных диапазонов ===
|
||||||
// Генерирует IP в сетях /30 (четные базовые адреса)
|
// Генерирует IP в сетях /30 (четные базовые адреса)
|
||||||
// Если указан ipPoolId, использует IP пул, иначе использует приватные диапазоны RFC 1918
|
// Если указан ipPoolId, использует IP пул, иначе использует приватные диапазоны RFC 1918
|
||||||
const generateFreePrivateIp = (excludeIp = null, forRemote = false, pairedLocalIp = null, ipPoolId = null) => {
|
// usedIpsOverride - опциональный Set уже использованных IP (если не передан, создается копия getAllUsedIpsSet)
|
||||||
const usedIps = new Set(getAllUsedIpsSet);
|
const generateFreePrivateIp = (excludeIp = null, forRemote = false, pairedLocalIp = null, ipPoolId = null, usedIpsOverride = null) => {
|
||||||
|
// Создаем копию Set, чтобы не модифицировать оригинальный
|
||||||
|
const usedIps = usedIpsOverride || new Set(getAllUsedIpsSet);
|
||||||
if (excludeIp) {
|
if (excludeIp) {
|
||||||
usedIps.delete(excludeIp.trim());
|
usedIps.delete(excludeIp.trim());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user