use new exit node info

This commit is contained in:
miloschwartz
2025-06-16 22:06:56 -04:00
parent 970feb75dd
commit 753307bb99

View File

@@ -4,7 +4,11 @@ import { exitNodes, Newt, resources, sites, Target, targets } from "@server/db";
import { eq, and, sql, inArray } from "drizzle-orm"; import { eq, and, sql, inArray } from "drizzle-orm";
import { addPeer, deletePeer } from "../gerbil/peers"; import { addPeer, deletePeer } from "../gerbil/peers";
import logger from "@server/logger"; import logger from "@server/logger";
import { exit } from "process"; import config from "@server/lib/config";
import {
findNextAvailableCidr,
getNextAvailableClientSubnet
} from "@server/lib/ip";
export const handleNewtRegisterMessage: MessageHandler = async (context) => { export const handleNewtRegisterMessage: MessageHandler = async (context) => {
const { message, client, sendToClient } = context; const { message, client, sendToClient } = context;
@@ -30,25 +34,62 @@ export const handleNewtRegisterMessage: MessageHandler = async (context) => {
return; return;
} }
const [site] = await db const [oldSite] = await db
.select() .select()
.from(sites) .from(sites)
.where(eq(sites.siteId, siteId)) .where(eq(sites.siteId, siteId))
.limit(1); .limit(1);
if (!site || !site.exitNodeId) { if (!oldSite || !oldSite.exitNodeId) {
logger.warn("Site not found or does not have exit node"); logger.warn("Site not found or does not have exit node");
return; return;
} }
let exitNodeIdToQuery = site.exitNodeId; let siteSubnet = oldSite.subnet;
if (exitNodeId && site.exitNodeId !== exitNodeId) { // This effectively moves the exit node to the new one let exitNodeIdToQuery = oldSite.exitNodeId;
if (exitNodeId && oldSite.exitNodeId !== exitNodeId) {
// This effectively moves the exit node to the new one
exitNodeIdToQuery = exitNodeId; // Use the provided exitNodeId if it differs from the site's exitNodeId exitNodeIdToQuery = exitNodeId; // Use the provided exitNodeId if it differs from the site's exitNodeId
const sitesQuery = await db
.select({
subnet: sites.subnet
})
.from(sites)
.where(eq(sites.exitNodeId, exitNodeId));
const [exitNode] = await db
.select()
.from(exitNodes)
.where(eq(exitNodes.exitNodeId, exitNodeIdToQuery))
.limit(1);
const blockSize = config.getRawConfig().gerbil.site_block_size;
const subnets = sitesQuery.map((site) => site.subnet);
subnets.push(
exitNode.address.replace(
/\/\d+$/,
`/${blockSize}`
)
);
const newSubnet = findNextAvailableCidr(
subnets,
blockSize,
exitNode.address
);
if (!newSubnet) {
logger.error("No available subnets found for the new exit node");
return;
}
siteSubnet = newSubnet;
await db await db
.update(sites) .update(sites)
.set({ .set({
pubKey: publicKey, pubKey: publicKey,
exitNodeId: exitNodeId exitNodeId: exitNodeId,
subnet: newSubnet
}) })
.where(eq(sites.siteId, siteId)) .where(eq(sites.siteId, siteId))
.returning(); .returning();
@@ -68,20 +109,20 @@ export const handleNewtRegisterMessage: MessageHandler = async (context) => {
.where(eq(exitNodes.exitNodeId, exitNodeIdToQuery)) .where(eq(exitNodes.exitNodeId, exitNodeIdToQuery))
.limit(1); .limit(1);
if (site.pubKey && site.pubKey !== publicKey) { if (oldSite.pubKey && oldSite.pubKey !== publicKey) {
logger.info("Public key mismatch. Deleting old peer..."); logger.info("Public key mismatch. Deleting old peer...");
await deletePeer(site.exitNodeId, site.pubKey); await deletePeer(oldSite.exitNodeId, oldSite.pubKey);
} }
if (!site.subnet) { if (!siteSubnet) {
logger.warn("Site has no subnet"); logger.warn("Site has no subnet");
return; return;
} }
// add the peer to the exit node // add the peer to the exit node
await addPeer(site.exitNodeId, { await addPeer(exitNodeIdToQuery, {
publicKey: publicKey, publicKey: publicKey,
allowedIps: [site.subnet] allowedIps: [siteSubnet]
}); });
// Improved version // Improved version
@@ -170,7 +211,7 @@ export const handleNewtRegisterMessage: MessageHandler = async (context) => {
endpoint: `${exitNode.endpoint}:${exitNode.listenPort}`, endpoint: `${exitNode.endpoint}:${exitNode.listenPort}`,
publicKey: exitNode.publicKey, publicKey: exitNode.publicKey,
serverIP: exitNode.address.split("/")[0], serverIP: exitNode.address.split("/")[0],
tunnelIP: site.subnet.split("/")[0], tunnelIP: siteSubnet.split("/")[0],
targets: { targets: {
udp: udpTargets, udp: udpTargets,
tcp: tcpTargets tcp: tcpTargets