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 usedIps = new Set(getAllUsedIpsSet);
|
||||
const usedIps = new Set(getAllUsedIpsSet); // Создаем Set с уже использованными IP из существующих интерфейсов
|
||||
|
||||
// Создаем туннели для каждой пары
|
||||
templateServerPairs.forEach((pair, index) => {
|
||||
@@ -560,15 +560,16 @@ function NetworkConfigManager() {
|
||||
|
||||
// Генерируем IP адреса (учитываем уже использованные в этой итерации)
|
||||
// Важно: Local IP и Remote IP должны быть разными и в одной сети /30
|
||||
// Передаем usedIps в функцию, чтобы она учитывала IP, выделенные для предыдущих туннелей
|
||||
let localIp = null;
|
||||
let remoteIp = null;
|
||||
let attempts = 0;
|
||||
const maxAttempts = 1000;
|
||||
|
||||
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)) {
|
||||
const candidateRemote = generateFreePrivateIp(null, true, candidateLocal, pairIpPoolId || null);
|
||||
const candidateRemote = generateFreePrivateIp(null, true, candidateLocal, pairIpPoolId || null, usedIps);
|
||||
if (candidateRemote && !usedIps.has(candidateRemote) && candidateRemote !== candidateLocal) {
|
||||
localIp = candidateLocal;
|
||||
remoteIp = candidateRemote;
|
||||
@@ -581,7 +582,7 @@ function NetworkConfigManager() {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -781,8 +782,10 @@ function NetworkConfigManager() {
|
||||
// === Генерация свободного IP адреса из приватных диапазонов ===
|
||||
// Генерирует IP в сетях /30 (четные базовые адреса)
|
||||
// Если указан ipPoolId, использует IP пул, иначе использует приватные диапазоны RFC 1918
|
||||
const generateFreePrivateIp = (excludeIp = null, forRemote = false, pairedLocalIp = null, ipPoolId = null) => {
|
||||
const usedIps = new Set(getAllUsedIpsSet);
|
||||
// usedIpsOverride - опциональный Set уже использованных IP (если не передан, создается копия getAllUsedIpsSet)
|
||||
const generateFreePrivateIp = (excludeIp = null, forRemote = false, pairedLocalIp = null, ipPoolId = null, usedIpsOverride = null) => {
|
||||
// Создаем копию Set, чтобы не модифицировать оригинальный
|
||||
const usedIps = usedIpsOverride || new Set(getAllUsedIpsSet);
|
||||
if (excludeIp) {
|
||||
usedIps.delete(excludeIp.trim());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user