mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-01 18:20:35 +02:00
Handle the alias create and update special case exit nodes
This commit is contained in:
@@ -1137,7 +1137,9 @@ async function syncClientExitNodeConnections(
|
||||
)
|
||||
);
|
||||
|
||||
const needsConnectSet = new Set(requiresExitNodeRows.map((r) => r.clientId));
|
||||
const needsConnectSet = new Set(
|
||||
requiresExitNodeRows.map((r) => r.clientId)
|
||||
);
|
||||
|
||||
const exitNodeIds = Array.from(
|
||||
new Set(
|
||||
@@ -1249,6 +1251,61 @@ async function syncClientExitNodeConnections(
|
||||
}
|
||||
}
|
||||
|
||||
// Notifies the olms of every given client that the alias of the site resource
|
||||
// they're using an exit node connection for has changed, via the dedicated
|
||||
// exit node data-update message. Unlike syncClientExitNodeConnections, this
|
||||
// doesn't touch connect/disconnect state - it's purely a rename for clients
|
||||
// that are (and remain) connected to the exit node for this resource.
|
||||
async function syncClientExitNodeAliasUpdate(
|
||||
clientIds: number[],
|
||||
oldAlias: string | null,
|
||||
newAlias: string | null,
|
||||
trx: Transaction | typeof db = db
|
||||
): Promise<void> {
|
||||
const uniqueClientIds = Array.from(new Set(clientIds));
|
||||
if (uniqueClientIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldAliases = oldAlias ? [oldAlias] : [];
|
||||
const newAliases = newAlias ? [newAlias] : [];
|
||||
if (oldAliases.length === 0 && newAliases.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const olmRows = await trx
|
||||
.select({
|
||||
clientId: olms.clientId,
|
||||
olmId: olms.olmId,
|
||||
version: olms.version
|
||||
})
|
||||
.from(olms)
|
||||
.where(inArray(olms.clientId, uniqueClientIds));
|
||||
|
||||
const updatePayloads = olmRows
|
||||
.filter((r) => r.clientId !== null)
|
||||
.map((olm) => ({
|
||||
clientId: olm.olmId,
|
||||
message: {
|
||||
type: "olm/wg/exitnode/data/update",
|
||||
data: {
|
||||
oldAliases,
|
||||
newAliases
|
||||
}
|
||||
},
|
||||
options: { compress: canCompress(olm.version, "olm") }
|
||||
}));
|
||||
|
||||
if (updatePayloads.length > 0) {
|
||||
await sendToClientsBatch(updatePayloads).catch((error) => {
|
||||
logger.error(
|
||||
`rebuildClientAssociations: Error sending exit node alias update messages:`,
|
||||
error
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubnetProxyTargetUpdates(
|
||||
siteResource: SiteResource,
|
||||
sitesList: Site[],
|
||||
@@ -1479,7 +1536,7 @@ export async function handleMessagingForUpdatedSiteResource(
|
||||
`handleMessagingForUpdatedSiteResource: fetched newts for ${newtsForSites.length}/${allSiteIds.length} site(s)`
|
||||
);
|
||||
|
||||
// WARNING: THIS RELIES ON THE CACHE TABLES BEING UP TO DATE, SO CALL THIS AFTER THE ASSOCIATION CACHE IS UPDATED
|
||||
// !!!!!!!!!!!!!!!!!! WARNING: THIS RELIES ON THE CACHE TABLES BEING UP TO DATE, SO CALL THIS AFTER THE ASSOCIATION CACHE IS UPDATED !!!!!!!!!!!!!!!!!!
|
||||
const mergedAllClients = await trx
|
||||
.select({
|
||||
clientId: clientSiteResourcesAssociationsCache.clientId,
|
||||
@@ -1906,6 +1963,24 @@ export async function handleMessagingForUpdatedSiteResource(
|
||||
);
|
||||
}
|
||||
|
||||
// For a resource that stays on an exit node connection across the update,
|
||||
// the alias is the only field that affects already-connected clients (the
|
||||
// exit node itself, its endpoint, etc. are not per-resource). Tell those
|
||||
// clients' olms about the rename directly via the exit node data-update
|
||||
// message rather than a full connect/disconnect cycle.
|
||||
if (
|
||||
existingSiteResource?.requiresExitNodeConnection &&
|
||||
updatedSiteResource.requiresExitNodeConnection &&
|
||||
aliasChanged
|
||||
) {
|
||||
await syncClientExitNodeAliasUpdate(
|
||||
mergedAllClients.map((c) => c.clientId),
|
||||
existingSiteResource.alias,
|
||||
updatedSiteResource.alias,
|
||||
trx
|
||||
);
|
||||
}
|
||||
|
||||
// If this resource requires (or required) clients to be connected to the
|
||||
// exit node (e.g. an inference resource), re-sync connect/disconnect
|
||||
// state for every client currently associated with it - covers toggling
|
||||
|
||||
@@ -29,7 +29,7 @@ import response from "@server/lib/response";
|
||||
import logger from "@server/logger";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import { and, eq, inArray } from "drizzle-orm";
|
||||
import { and, eq, inArray, ne } from "drizzle-orm";
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import createHttpError from "http-errors";
|
||||
import { z } from "zod";
|
||||
@@ -490,7 +490,11 @@ export async function createSiteResource(
|
||||
.where(
|
||||
and(
|
||||
eq(siteResources.orgId, orgId),
|
||||
eq(siteResources.alias, alias.trim())
|
||||
eq(siteResources.alias, alias.trim()),
|
||||
ne(
|
||||
siteResources.requiresExitNodeConnection,
|
||||
mode == "inference"
|
||||
) // exclude looking at the ones on exit nodes if this is an inference resource
|
||||
)
|
||||
)
|
||||
.limit(1);
|
||||
@@ -527,6 +531,7 @@ export async function createSiteResource(
|
||||
let aliasAddress: string | null = null;
|
||||
let releaseAliasLock: (() => Promise<void>) | null = null;
|
||||
if (mode === "host" || mode === "http" || mode === "ssh") {
|
||||
// no alias address but we do have an alias for inference
|
||||
const { value, release } =
|
||||
await getNextAvailableAliasAddress(orgId);
|
||||
aliasAddress = value;
|
||||
|
||||
@@ -507,7 +507,11 @@ export async function updateSiteResource(
|
||||
and(
|
||||
eq(siteResources.orgId, existingSiteResource.orgId),
|
||||
eq(siteResources.alias, alias.trim()),
|
||||
ne(siteResources.siteResourceId, siteResourceId) // exclude self
|
||||
ne(siteResources.siteResourceId, siteResourceId), // exclude self
|
||||
ne(
|
||||
siteResources.requiresExitNodeConnection,
|
||||
mode == "inference"
|
||||
) // exclude looking at the ones on exit nodes if this is an inference resource
|
||||
)
|
||||
)
|
||||
.limit(1);
|
||||
@@ -587,8 +591,7 @@ export async function updateSiteResource(
|
||||
domainId,
|
||||
subdomain: finalSubdomain,
|
||||
fullDomain,
|
||||
networkId:
|
||||
mode === "inference" ? null : undefined,
|
||||
networkId: mode === "inference" ? null : undefined,
|
||||
requiresExitNodeConnection:
|
||||
mode !== undefined ? mode === "inference" : undefined,
|
||||
...sshPamSet
|
||||
|
||||
Reference in New Issue
Block a user