From 5ff4215bdee1fcbde261297d5f4f5bcf1b1e7073 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 1 Apr 2025 12:49:02 -0400 Subject: [PATCH] Able to connect multi site on olm - POC 1 --- server/lib/ip.ts | 11 +++-- server/routers/gerbil/getAllRelays.ts | 40 +++++++++---------- server/routers/gerbil/updateHolePunch.ts | 8 ++-- server/routers/newt/handleGetConfigMessage.ts | 8 +++- src/app/[orgId]/settings/clients/page.tsx | 2 - 5 files changed, 39 insertions(+), 30 deletions(-) diff --git a/server/lib/ip.ts b/server/lib/ip.ts index d06ce27f..16a926f1 100644 --- a/server/lib/ip.ts +++ b/server/lib/ip.ts @@ -218,6 +218,11 @@ export function isIpInCidr(ip: string, cidr: string): boolean { } export async function getNextAvailableClientSubnet(orgId: string): Promise { + const [org] = await db + .select() + .from(orgs) + .where(eq(orgs.orgId, orgId)); + const existingAddressesSites = await db .select({ address: sites.address @@ -233,14 +238,14 @@ export async function getNextAvailableClientSubnet(orgId: string): Promise site.address), - ...existingAddressesClients.map((client) => client.address) + ...existingAddressesSites.map((site) => `${site.address?.split("/")[0]}/32`), // we are overriding the 32 so that we pick individual addresses in the subnet of the org for the site and the client even though they are stored with the /block_size of the org + ...existingAddressesClients.map((client) => `${client.address.split("/")}/32`) ].filter((address) => address !== null) as string[]; let subnet = findNextAvailableCidr( addresses, 32, - config.getRawConfig().orgs.subnet_group + org.subnet ); // pick the sites address in the org if (!subnet) { throw new Error("No available subnets remaining in space"); diff --git a/server/routers/gerbil/getAllRelays.ts b/server/routers/gerbil/getAllRelays.ts index edc702b7..e846326a 100644 --- a/server/routers/gerbil/getAllRelays.ts +++ b/server/routers/gerbil/getAllRelays.ts @@ -51,32 +51,32 @@ export async function getAllRelays( } } - // get the clients on each site and map them to the site - const sitesAndClients = await Promise.all(sitesRes.map(async (site) => { - const clientsRes = await db.select().from(clients).where(eq(clients.siteId, site.siteId)); - return { - site, - clients: clientsRes - }; - })); + // // get the clients on each site and map them to the site + // const sitesAndClients = await Promise.all(sitesRes.map(async (site) => { + // const clientsRes = await db.select().from(clients).where(eq(clients.siteId, site.siteId)); + // return { + // site, + // clients: clientsRes + // }; + // })); let mappings: { [key: string]: { destinationIp: string; destinationPort: number; } } = {}; - for (const siteAndClients of sitesAndClients) { - const { site, clients } = siteAndClients; - for (const client of clients) { - if (!client.endpoint || !site.endpoint || !site.subnet) { - continue; - } - mappings[client.endpoint] = { - destinationIp: site.subnet.split("/")[0], - destinationPort: parseInt(site.endpoint.split(":")[1]) - }; - } - } + // for (const siteAndClients of sitesAndClients) { + // const { site, clients } = siteAndClients; + // for (const client of clients) { + // if (!client.endpoint || !site.endpoint || !site.subnet) { + // continue; + // } + // mappings[client.endpoint] = { + // destinationIp: site.subnet.split("/")[0], + // destinationPort: parseInt(site.endpoint.split(":")[1]) + // }; + // } + // } return res.status(HttpCode.OK).send({ mappings }); } catch (error) { diff --git a/server/routers/gerbil/updateHolePunch.ts b/server/routers/gerbil/updateHolePunch.ts index e2ba01c6..0149ec51 100644 --- a/server/routers/gerbil/updateHolePunch.ts +++ b/server/routers/gerbil/updateHolePunch.ts @@ -80,10 +80,10 @@ export async function updateHolePunch( .where(eq(clients.clientId, olm.clientId)) .returning(); - [site] = await db - .select() - .from(sites) - .where(eq(sites.siteId, client.siteId)); + // [site] = await db + // .select() + // .from(sites) + // .where(eq(sites.siteId, client.siteId)); } else if (newtId) { const { session, newt: newtSession } = diff --git a/server/routers/newt/handleGetConfigMessage.ts b/server/routers/newt/handleGetConfigMessage.ts index 78ec32aa..861a2e54 100644 --- a/server/routers/newt/handleGetConfigMessage.ts +++ b/server/routers/newt/handleGetConfigMessage.ts @@ -6,6 +6,7 @@ import db from "@server/db"; import { clients, clientSites, Newt, Site, sites } from "@server/db/schema"; import { eq } from "drizzle-orm"; import { getNextAvailableClientSubnet } from "@server/lib/ip"; +import config from "@server/lib/config"; const inputSchema = z.object({ publicKey: z.string(), @@ -58,7 +59,12 @@ export const handleGetConfigMessage: MessageHandler = async (context) => { let site: Site | undefined; if (!siteRes.address) { let address = await getNextAvailableClientSubnet(siteRes.orgId); - address = address.split("/")[0]; // get the first part of the CIDR + if (!address) { + logger.error("handleGetConfigMessage: No available address"); + return; + } + + address = `${address.split("/")[0]}/${config.getRawConfig().orgs.block_size}` // we want the block size of the whole org // create a new exit node const [updateRes] = await db diff --git a/src/app/[orgId]/settings/clients/page.tsx b/src/app/[orgId]/settings/clients/page.tsx index 2a422fc9..145d99a7 100644 --- a/src/app/[orgId]/settings/clients/page.tsx +++ b/src/app/[orgId]/settings/clients/page.tsx @@ -36,8 +36,6 @@ export default async function ClientsPage(props: ClientsPageProps) { const clientRows: ClientRow[] = clients.map((client) => { return { name: client.name, - siteName: client.siteName, - siteId: client.siteNiceId, id: client.clientId, mbIn: formatSize(client.megabytesIn || 0), mbOut: formatSize(client.megabytesOut || 0),