diff --git a/server/hybridServer.ts b/server/hybridServer.ts index 7ce7efd7..f4e18b34 100644 --- a/server/hybridServer.ts +++ b/server/hybridServer.ts @@ -8,6 +8,7 @@ import { addPeer, deletePeer } from "./routers/gerbil/peers"; import { db, exitNodes } from "./db"; import { TraefikConfigManager } from "./lib/remoteTraefikConfig"; import { tokenManager } from "./lib/tokenManager"; +import { APP_VERSION } from "./lib/consts"; export async function createHybridClientServer() { const monitor = new TraefikConfigManager(); @@ -67,6 +68,9 @@ export async function createHybridClientServer() { // Listen to connection events client.on("connect", () => { console.log("Connected to WebSocket server"); + client.sendMessage("remoteExitNode/register", { + remoteExitNodeVersion: APP_VERSION + }); }); client.on("disconnect", () => { diff --git a/server/routers/gerbil/getConfig.ts b/server/routers/gerbil/getConfig.ts index 696e7ea2..0a1c0f23 100644 --- a/server/routers/gerbil/getConfig.ts +++ b/server/routers/gerbil/getConfig.ts @@ -1,6 +1,6 @@ import { Request, Response, NextFunction } from "express"; import { z } from "zod"; -import { sites, resources, targets, exitNodes } from "@server/db"; +import { sites, resources, targets, exitNodes, ExitNode } from "@server/db"; import { db } from "@server/db"; import { eq, isNotNull, and } from "drizzle-orm"; import HttpCode from "@server/types/HttpCode"; @@ -11,6 +11,7 @@ import { getUniqueExitNodeEndpointName } from "../../db/names"; import { findNextAvailableCidr } from "@server/lib/ip"; import { fromError } from "zod-validation-error"; import { getAllowedIps } from "../target/helpers"; +import { proxyToRemote } from "@server/lib/remoteProxy"; // Define Zod schema for request validation const getConfigSchema = z.object({ publicKey: z.string(), @@ -101,42 +102,12 @@ export async function getConfig( ); } - const sitesRes = await db - .select() - .from(sites) - .where( - and( - eq(sites.exitNodeId, exitNode[0].exitNodeId), - isNotNull(sites.pubKey), - isNotNull(sites.subnet) - ) - ); + // STOP HERE IN HYBRID MODE + if (config.isHybridMode()) { + return proxyToRemote(req, res, next, "gerbil/get-config"); + } - const peers = await Promise.all( - sitesRes.map(async (site) => { - if (site.type === "wireguard") { - return { - publicKey: site.pubKey, - allowedIps: await getAllowedIps(site.siteId) - }; - } else if (site.type === "newt") { - return { - publicKey: site.pubKey, - allowedIps: [site.subnet!] - }; - } - return { - publicKey: null, - allowedIps: [] - }; - }) - ); - - const configResponse: GetConfigResponse = { - listenPort: exitNode[0].listenPort || 51820, - ipAddress: exitNode[0].address, - peers - }; + const configResponse = await generateGerbilConfig(exitNode[0]); logger.debug("Sending config: ", configResponse); @@ -152,6 +123,47 @@ export async function getConfig( } } +async function generateGerbilConfig(exitNode: ExitNode) { + const sitesRes = await db + .select() + .from(sites) + .where( + and( + eq(sites.exitNodeId, exitNode.exitNodeId), + isNotNull(sites.pubKey), + isNotNull(sites.subnet) + ) + ); + + const peers = await Promise.all( + sitesRes.map(async (site) => { + if (site.type === "wireguard") { + return { + publicKey: site.pubKey, + allowedIps: await getAllowedIps(site.siteId) + }; + } else if (site.type === "newt") { + return { + publicKey: site.pubKey, + allowedIps: [site.subnet!] + }; + } + return { + publicKey: null, + allowedIps: [] + }; + }) + ); + + const configResponse: GetConfigResponse = { + listenPort: exitNode.listenPort || 51820, + ipAddress: exitNode.address, + peers + }; + + return configResponse; +} + async function getNextAvailableSubnet(): Promise { // Get all existing subnets from routes table const existingAddresses = await db diff --git a/server/routers/internal.ts b/server/routers/internal.ts index a84f6976..e91446dc 100644 --- a/server/routers/internal.ts +++ b/server/routers/internal.ts @@ -54,10 +54,6 @@ internalRouter.use("/gerbil", gerbilRouter); if (config.isHybridMode()) { // Use proxy router to forward requests to remote cloud server // Proxy endpoints for each gerbil route - gerbilRouter.post("/get-config", (req, res, next) => - proxyToRemote(req, res, next, "gerbil/get-config") - ); - gerbilRouter.post("/receive-bandwidth", (req, res, next) => proxyToRemote(req, res, next, "gerbil/receive-bandwidth") ); @@ -69,6 +65,9 @@ if (config.isHybridMode()) { gerbilRouter.post("/get-all-relays", (req, res, next) => proxyToRemote(req, res, next, "gerbil/get-all-relays") ); + + // GET CONFIG IS HANDLED IN THE ORIGINAL HANDLER + // SO IT CAN REGISTER THE LOCAL EXIT NODE } else { // Use local gerbil endpoints gerbilRouter.post("/get-config", gerbil.getConfig);