Rename subnet for clarity, pick subnet on client

This commit is contained in:
Owen
2026-07-30 12:13:09 -04:00
parent 719baa201e
commit 915e8d5b1f
19 changed files with 135 additions and 78 deletions
@@ -0,0 +1,41 @@
import { db, ExitNode, Transaction, sites, clients } from "@server/db";
import { eq } from "drizzle-orm";
import config from "@server/lib/config";
import { findNextAvailableCidr } from "@server/lib/ip";
import { lockManager } from "#dynamic/lib/lock";
export async function getUniqueSubnetForExitNode(
exitNode: ExitNode,
trx: Transaction | typeof db = db
): Promise<string | null> {
const lockKey = `subnet-allocation:${exitNode.exitNodeId}`;
return await lockManager.withLock(
lockKey,
async () => {
const [sitesQuery, clientsQuery] = await Promise.all([
trx
.select({ subnet: sites.exitNodeSubnet })
.from(sites)
.where(eq(sites.exitNodeId, exitNode.exitNodeId)),
trx
.select({ subnet: clients.exitNodeSubnet })
.from(clients)
.where(eq(clients.exitNodeId, exitNode.exitNodeId))
]);
const blockSize = config.getRawConfig().gerbil.site_block_size;
const subnets = [...sitesQuery, ...clientsQuery]
.map((row) => row.subnet)
.filter(
(subnet): subnet is string =>
!!subnet &&
/^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$/.test(subnet)
);
subnets.push(exitNode.address.replace(/\/\d+$/, `/${blockSize}`));
return findNextAvailableCidr(subnets, blockSize, exitNode.address);
},
5000 // 5 second lock TTL - subnet allocation should be quick
);
}
+1
View File
@@ -3,3 +3,4 @@ export * from "./exitNodeComms";
export * from "./subnet";
export * from "./getCurrentExitNodeId";
export * from "./calculateExitNodeWeight";
export * from "./getUniqueSubnetForExitNode";