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,92 +140,101 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
) )
.where(eq(clientSitesAssociationsCache.siteId, siteId)); .where(eq(clientSitesAssociationsCache.siteId, siteId));
// Prepare peers data for the response let peers: Array<{
const peers = await Promise.all( publicKey: string;
clientsRes allowedIps: string[];
.filter((client) => { endpoint?: string;
if (!client.clients.pubKey) { }> = [];
logger.warn(
`Client ${client.clients.clientId} has no public key, skipping`
);
return false;
}
if (!client.clients.subnet) {
logger.warn(
`Client ${client.clients.clientId} has no subnet, skipping`
);
return false;
}
return true;
})
.map(async (client) => {
// 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) { if (site.publicKey && site.endpoint && exitNode) {
logger.warn(`Exit node not found for site ${site.siteId}`); // Prepare peers data for the response
return null; peers = await Promise.all(
} clientsRes
.filter((client) => {
if (!client.clients.pubKey) {
logger.warn(
`Client ${client.clients.clientId} has no public key, skipping`
);
return false;
}
if (!client.clients.subnet) {
logger.warn(
`Client ${client.clients.clientId} has no subnet, skipping`
);
return false;
}
return true;
})
.map(async (client) => {
// Add or update this peer on the olm if it is connected
if (!site.endpoint) { // const allSiteResources = await db // only get the site resources that this client has access to
logger.warn( // .select()
`Site ${site.siteId} has no endpoint, skipping` // .from(siteResources)
); // .innerJoin(
return null; // clientSiteResourcesAssociationsCache,
} // eq(
// siteResources.siteResourceId,
// const allSiteResources = await db // only get the site resources that this client has access to // clientSiteResourcesAssociationsCache.siteResourceId
// .select() // )
// .from(siteResources)
// .innerJoin(
// clientSiteResourcesAssociationsCache,
// eq(
// siteResources.siteResourceId,
// clientSiteResourcesAssociationsCache.siteResourceId
// )
// )
// .where(
// and(
// eq(siteResources.siteId, site.siteId),
// eq(
// clientSiteResourcesAssociationsCache.clientId,
// client.clients.clientId
// )
// )
// );
await updatePeer(client.clients.clientId, {
siteId: site.siteId,
endpoint: site.endpoint,
relayEndpoint: `${exitNode.endpoint}:${config.getRawConfig().gerbil.clients_start_port}`,
publicKey: site.publicKey,
serverIP: site.address,
serverPort: site.listenPort
// remoteSubnets: generateRemoteSubnets(
// allSiteResources.map(
// ({ siteResources }) => siteResources
// ) // )
// ), // .where(
// aliases: generateAliasConfig( // and(
// allSiteResources.map( // eq(siteResources.siteId, site.siteId),
// ({ siteResources }) => siteResources // eq(
// ) // clientSiteResourcesAssociationsCache.clientId,
// ) // client.clients.clientId
}); // )
// )
// );
return { // update the peer info on the olm
publicKey: client.clients.pubKey!, // if the peer has not been added yet this will be a no-op
allowedIps: [`${client.clients.subnet.split("/")[0]}/32`], // we want to only allow from that client await updatePeer(client.clients.clientId, {
endpoint: client.clientSitesAssociationsCache.isRelayed siteId: site.siteId,
? "" endpoint: site.endpoint!,
: client.clientSitesAssociationsCache.endpoint! // if its relayed it should be localhost relayEndpoint: `${exitNode.endpoint}:${config.getRawConfig().gerbil.clients_start_port}`,
}; publicKey: site.publicKey!,
}) serverIP: site.address,
); serverPort: site.listenPort
// remoteSubnets: generateRemoteSubnets(
// allSiteResources.map(
// ({ siteResources }) => siteResources
// )
// ),
// aliases: generateAliasConfig(
// allSiteResources.map(
// ({ siteResources }) => siteResources
// )
// )
});
// 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 {
publicKey: client.clients.pubKey!,
allowedIps: [
`${client.clients.subnet.split("/")[0]}/32`
], // we want to only allow from that client
endpoint: client.clientSitesAssociationsCache.isRelayed
? ""
: 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);