diff --git a/frontend/src/NetworkConfigManager.jsx b/frontend/src/NetworkConfigManager.jsx index f605331..9d196a0 100644 --- a/frontend/src/NetworkConfigManager.jsx +++ b/frontend/src/NetworkConfigManager.jsx @@ -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; };