Smoothing over initial connection issues

This commit is contained in:
Owen 2025-08-16 16:42:34 -07:00
parent d771317e3f
commit 609435328e
No known key found for this signature in database
GPG key ID: 8271FDFFD9E0CCBD
5 changed files with 80 additions and 74 deletions

View file

@ -1 +1,2 @@
export * from "./exitNodes"; export * from "./exitNodes";
export * from "./shared";

View file

@ -0,0 +1,30 @@
import { db, exitNodes } from "@server/db";
import config from "@server/lib/config";
import { findNextAvailableCidr } from "@server/lib/ip";
export async function getNextAvailableSubnet(): Promise<string> {
// Get all existing subnets from routes table
const existingAddresses = await db
.select({
address: exitNodes.address
})
.from(exitNodes);
const addresses = existingAddresses.map((a) => a.address);
let subnet = findNextAvailableCidr(
addresses,
config.getRawConfig().gerbil.block_size,
config.getRawConfig().gerbil.subnet_group
);
if (!subnet) {
throw new Error("No available subnets remaining in space");
}
// replace the last octet with 1
subnet =
subnet.split(".").slice(0, 3).join(".") +
".1" +
"/" +
subnet.split("/")[1];
return subnet;
}

View file

@ -155,14 +155,11 @@ export class TraefikConfigManager {
method: error.config?.method method: error.config?.method
}); });
} else { } else {
logger.error( logger.error("Error updating local SNI:", error);
"Error updating local SNI:",
error
);
} }
} }
} else { } else {
logger.error("No exit node found"); logger.error("No exit node found. Has gerbil registered yet?");
} }
} catch (err) { } catch (err) {
logger.error("Failed to post domains to SNI proxy:", err); logger.error("Failed to post domains to SNI proxy:", err);
@ -213,18 +210,25 @@ export class TraefikConfigManager {
} }
} }
// logger.debug(
// `Successfully retrieved traefik config: ${JSON.stringify(traefikConfig)}`
// );
const badgerMiddlewareName = "badger"; const badgerMiddlewareName = "badger";
if (traefikConfig?.http?.middlewares) {
traefikConfig.http.middlewares[badgerMiddlewareName] = { traefikConfig.http.middlewares[badgerMiddlewareName] = {
plugin: { plugin: {
[badgerMiddlewareName]: { [badgerMiddlewareName]: {
apiBaseUrl: new URL( apiBaseUrl: new URL(
"/api/v1", "/api/v1",
`http://${ `http://${
config.getRawConfig().server.internal_hostname config.getRawConfig().server
.internal_hostname
}:${config.getRawConfig().server.internal_port}` }:${config.getRawConfig().server.internal_port}`
).href, ).href,
userSessionCookieName: userSessionCookieName:
config.getRawConfig().server.session_cookie_name, config.getRawConfig().server
.session_cookie_name,
// deprecated // deprecated
accessTokenQueryParam: accessTokenQueryParam:
@ -237,10 +241,7 @@ export class TraefikConfigManager {
} }
} }
}; };
}
// logger.debug(
// `Successfully retrieved traefik config: ${JSON.stringify(traefikConfig)}`
// );
return { domains, traefikConfig }; return { domains, traefikConfig };
} catch (error) { } catch (error) {

View file

@ -150,25 +150,20 @@ export class TokenManager {
this.token = response.data.data.token; this.token = response.data.data.token;
logger.debug("Token refreshed successfully"); logger.debug("Token refreshed successfully");
} catch (error) { } catch (error) {
logger.error("Failed to refresh token:", error);
if (axios.isAxiosError(error)) { if (axios.isAxiosError(error)) {
if (error.response) { logger.error("Error updating proxy mapping:", {
throw new Error( message: error.message,
`Failed to get token with status code: ${error.response.status}` code: error.code,
); status: error.response?.status,
} else if (error.request) { statusText: error.response?.statusText,
throw new Error( url: error.config?.url,
"Failed to request new token: No response received" method: error.config?.method
); });
} else { } else {
throw new Error( logger.error("Error updating proxy mapping:", error);
`Failed to request new token: ${error.message}`
);
}
} else {
throw new Error(`Failed to get token: ${error}`);
} }
throw new Error("Failed to refresh token");
} finally { } finally {
this.isRefreshing = false; this.isRefreshing = false;
} }

View file

@ -12,6 +12,7 @@ import { findNextAvailableCidr } from "@server/lib/ip";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
import { getAllowedIps } from "../target/helpers"; import { getAllowedIps } from "../target/helpers";
import { proxyToRemote } from "@server/lib/remoteProxy"; import { proxyToRemote } from "@server/lib/remoteProxy";
import { getNextAvailableSubnet } from "@server/lib/exitNodes";
// Define Zod schema for request validation // Define Zod schema for request validation
const getConfigSchema = z.object({ const getConfigSchema = z.object({
publicKey: z.string(), publicKey: z.string(),
@ -104,6 +105,11 @@ export async function getConfig(
// STOP HERE IN HYBRID MODE // STOP HERE IN HYBRID MODE
if (config.isHybridMode()) { if (config.isHybridMode()) {
req.body = {
...req.body,
endpoint: exitNode[0].endpoint,
listenPort: exitNode[0].listenPort
}
return proxyToRemote(req, res, next, "hybrid/gerbil/get-config"); return proxyToRemote(req, res, next, "hybrid/gerbil/get-config");
} }
@ -164,33 +170,6 @@ export async function generateGerbilConfig(exitNode: ExitNode) {
return configResponse; return configResponse;
} }
async function getNextAvailableSubnet(): Promise<string> {
// Get all existing subnets from routes table
const existingAddresses = await db
.select({
address: exitNodes.address
})
.from(exitNodes);
const addresses = existingAddresses.map((a) => a.address);
let subnet = findNextAvailableCidr(
addresses,
config.getRawConfig().gerbil.block_size,
config.getRawConfig().gerbil.subnet_group
);
if (!subnet) {
throw new Error("No available subnets remaining in space");
}
// replace the last octet with 1
subnet =
subnet.split(".").slice(0, 3).join(".") +
".1" +
"/" +
subnet.split("/")[1];
return subnet;
}
async function getNextAvailablePort(): Promise<number> { async function getNextAvailablePort(): Promise<number> {
// Get all existing ports from exitNodes table // Get all existing ports from exitNodes table
const existingPorts = await db const existingPorts = await db