Send site add in case the client does not have the site

This commit is contained in:
Owen
2025-12-10 11:57:45 -05:00
parent b68c0962c6
commit c56574e431
2 changed files with 100 additions and 87 deletions

View File

@@ -24,7 +24,7 @@ import {
deletePeer as newtDeletePeer deletePeer as newtDeletePeer
} from "@server/routers/newt/peers"; } from "@server/routers/newt/peers";
import { import {
initPeerAddHandshake as holepunchSiteAdd, initPeerAddHandshake,
deletePeer as olmDeletePeer deletePeer as olmDeletePeer
} from "@server/routers/olm/peers"; } from "@server/routers/olm/peers";
import { sendToExitNode } from "#dynamic/lib/exitNodes"; import { sendToExitNode } from "#dynamic/lib/exitNodes";
@@ -477,7 +477,7 @@ async function handleMessagesForSiteClients(
} }
if (isAdd) { if (isAdd) {
await holepunchSiteAdd( await initPeerAddHandshake(
// this will kick off the add peer process for the client // this will kick off the add peer process for the client
client.clientId, client.clientId,
{ {
@@ -545,9 +545,13 @@ export async function updateClientSiteDestinations(
} }
// Parse the endpoint properly for both IPv4 and IPv6 // Parse the endpoint properly for both IPv4 and IPv6
const parsedEndpoint = parseEndpoint(site.clientSitesAssociationsCache.endpoint); const parsedEndpoint = parseEndpoint(
site.clientSitesAssociationsCache.endpoint
);
if (!parsedEndpoint) { if (!parsedEndpoint) {
logger.warn(`Failed to parse endpoint ${site.clientSitesAssociationsCache.endpoint}, skipping`); logger.warn(
`Failed to parse endpoint ${site.clientSitesAssociationsCache.endpoint}, skipping`
);
continue; continue;
} }

View File

@@ -11,7 +11,7 @@ import {
} from "@server/db"; } from "@server/db";
import { clients, clientSitesAssociationsCache, Newt, sites } from "@server/db"; import { clients, clientSitesAssociationsCache, Newt, sites } from "@server/db";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { updatePeer } from "../olm/peers"; import { initPeerAddHandshake, updatePeer } from "../olm/peers";
import { sendToExitNode } from "#dynamic/lib/exitNodes"; import { sendToExitNode } from "#dynamic/lib/exitNodes";
import { generateSubnetProxyTargets, SubnetProxyTarget } from "@server/lib/ip"; import { generateSubnetProxyTargets, SubnetProxyTarget } from "@server/lib/ip";
import config from "@server/lib/config"; import config from "@server/lib/config";
@@ -140,8 +140,15 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
) )
.where(eq(clientSitesAssociationsCache.siteId, siteId)); .where(eq(clientSitesAssociationsCache.siteId, siteId));
let peers: Array<{
publicKey: string;
allowedIps: string[];
endpoint?: string;
}> = [];
if (site.publicKey && site.endpoint && exitNode) {
// Prepare peers data for the response // Prepare peers data for the response
const peers = await Promise.all( peers = await Promise.all(
clientsRes clientsRes
.filter((client) => { .filter((client) => {
if (!client.clients.pubKey) { if (!client.clients.pubKey) {
@@ -160,24 +167,6 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
}) })
.map(async (client) => { .map(async (client) => {
// Add or update this peer on the olm if it is connected // Add or update this peer on the olm if it is connected
if (!site.publicKey) {
logger.warn(
`Site ${site.siteId} has no public key, skipping`
);
return null;
}
if (!exitNode) {
logger.warn(`Exit node not found for site ${site.siteId}`);
return null;
}
if (!site.endpoint) {
logger.warn(
`Site ${site.siteId} has no endpoint, skipping`
);
return null;
}
// const allSiteResources = await db // only get the site resources that this client has access to // const allSiteResources = await db // only get the site resources that this client has access to
// .select() // .select()
@@ -198,11 +187,14 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
// ) // )
// ) // )
// ); // );
// update the peer info on the olm
// if the peer has not been added yet this will be a no-op
await updatePeer(client.clients.clientId, { await updatePeer(client.clients.clientId, {
siteId: site.siteId, siteId: site.siteId,
endpoint: site.endpoint, endpoint: site.endpoint!,
relayEndpoint: `${exitNode.endpoint}:${config.getRawConfig().gerbil.clients_start_port}`, relayEndpoint: `${exitNode.endpoint}:${config.getRawConfig().gerbil.clients_start_port}`,
publicKey: site.publicKey, publicKey: site.publicKey!,
serverIP: site.address, serverIP: site.address,
serverPort: site.listenPort serverPort: site.listenPort
// remoteSubnets: generateRemoteSubnets( // remoteSubnets: generateRemoteSubnets(
@@ -217,15 +209,32 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
// ) // )
}); });
// also trigger the peer add handshake in case the peer was not already added to the olm and we need to hole punch
// if it has already been added this will be a no-op
await initPeerAddHandshake(
// this will kick off the add peer process for the client
client.clients.clientId,
{
siteId,
exitNode: {
publicKey: exitNode.publicKey,
endpoint: exitNode.endpoint
}
}
);
return { return {
publicKey: client.clients.pubKey!, publicKey: client.clients.pubKey!,
allowedIps: [`${client.clients.subnet.split("/")[0]}/32`], // we want to only allow from that client allowedIps: [
`${client.clients.subnet.split("/")[0]}/32`
], // we want to only allow from that client
endpoint: client.clientSitesAssociationsCache.isRelayed endpoint: client.clientSitesAssociationsCache.isRelayed
? "" ? ""
: client.clientSitesAssociationsCache.endpoint! // if its relayed it should be localhost : client.clientSitesAssociationsCache.endpoint! // if its relayed it should be localhost
}; };
}) })
); );
}
// Filter out any null values from peers that didn't have an olm // Filter out any null values from peers that didn't have an olm
const validPeers = peers.filter((peer) => peer !== null); const validPeers = peers.filter((peer) => peer !== null);