feat(NetworkConfigManager): enhance IP generation logic to ensure unique local and remote IP pairs; improve handling of alternative IP generation for tunnel previews, ensuring better usability and error handling
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m42s

This commit is contained in:
2026-01-22 22:05:16 +07:00
parent fc27599222
commit ded2116b43
+35 -18
View File
@@ -926,7 +926,8 @@ function NetworkConfigManager() {
}
}
}
return null; // Не удалось сгенерировать парный Remote IP
// Если не удалось сгенерировать парный Remote IP, продолжаем поиск в общем цикле ниже
// Не возвращаем null сразу, чтобы попробовать найти другую пару
}
// Вычисляем количество хостов в сети
@@ -957,16 +958,9 @@ function NetworkConfigManager() {
// Проверяем, что 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;
}
// Для всех префиксов проверяем, что оба IP свободны (для туннелей нужны пары)
if (!usedIps.has(localIp) && !usedIps.has(remoteIp)) {
return forRemote ? remoteIp : localIp;
}
}
} else if (prefix >= 16) {
@@ -984,12 +978,12 @@ function NetworkConfigManager() {
if (!isIpInCidr(localIp, cidr)) continue;
if (localIp === remoteIp) continue;
// Проверяем, что Remote IP тоже входит в пул
if (!isIpInCidr(remoteIp, cidr)) continue;
// Для всех префиксов проверяем, что оба IP свободны (для туннелей нужны пары)
if (!usedIps.has(localIp) && !usedIps.has(remoteIp)) {
// Проверяем, что Remote IP тоже входит в пул (для префиксов >= 30 это всегда true)
if (prefix >= 30 || isIpInCidr(remoteIp, cidr)) {
return forRemote ? remoteIp : localIp;
}
return forRemote ? remoteIp : localIp;
}
}
}
@@ -3722,17 +3716,40 @@ function NetworkConfigManager() {
const prevPairIpPoolId = prevPair.ipPoolId || templateIpPoolId;
const prevPreviewLocal = generateFreePrivateIp(null, false, null, prevPairIpPoolId || null, previewUsedIps);
if (prevPreviewLocal) {
previewUsedIps.add(prevPreviewLocal);
const prevPreviewRemote = generateFreePrivateIp(null, true, prevPreviewLocal, prevPairIpPoolId || null, previewUsedIps);
if (prevPreviewRemote && prevPreviewRemote !== prevPreviewLocal) {
previewUsedIps.add(prevPreviewLocal);
previewUsedIps.add(prevPreviewRemote);
}
}
}
}
const previewLocalIp = generateFreePrivateIp(null, false, null, pairIpPoolId || null, previewUsedIps);
const previewRemoteIp = previewLocalIp ? generateFreePrivateIp(null, true, previewLocalIp, pairIpPoolId || null, previewUsedIps) : null;
// Генерируем IP для текущего туннеля
let previewLocalIp = generateFreePrivateIp(null, false, null, pairIpPoolId || null, previewUsedIps);
let previewRemoteIp = null;
if (previewLocalIp) {
// Генерируем Remote IP на основе Local IP
previewRemoteIp = generateFreePrivateIp(null, true, previewLocalIp, pairIpPoolId || null, previewUsedIps);
// Если Remote IP не сгенерировался или совпадает с Local IP, пробуем найти другую пару
if (!previewRemoteIp || previewRemoteIp === previewLocalIp) {
// Добавляем текущий Local IP в использованные и пробуем найти другую пару
previewUsedIps.add(previewLocalIp);
const altPreviewLocalIp = generateFreePrivateIp(null, false, null, pairIpPoolId || null, previewUsedIps);
if (altPreviewLocalIp && altPreviewLocalIp !== previewLocalIp) {
const altPreviewRemoteIp = generateFreePrivateIp(null, true, altPreviewLocalIp, pairIpPoolId || null, previewUsedIps);
if (altPreviewRemoteIp && altPreviewRemoteIp !== altPreviewLocalIp) {
previewLocalIp = altPreviewLocalIp;
previewRemoteIp = altPreviewRemoteIp;
} else {
// Если все равно не получилось, удаляем альтернативный Local IP
previewUsedIps.delete(altPreviewLocalIp);
}
}
}
}
return (
<div key={index} className="card card-sm border">