mirror of
https://github.com/fosrl/pangolin.git
synced 2025-08-04 01:55:10 +02:00
Still working on stability
This commit is contained in:
parent
e2efd0e65a
commit
f6a19631dc
6 changed files with 128 additions and 86 deletions
|
@ -10,7 +10,8 @@ import {
|
|||
olms,
|
||||
clientSites,
|
||||
exitNodes,
|
||||
orgs
|
||||
orgs,
|
||||
sites
|
||||
} from "@server/db/schema";
|
||||
import response from "@server/lib/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
|
@ -115,13 +116,28 @@ export async function createClient(
|
|||
const updatedSubnet = `${subnet}/${org.subnet.split("/")[1]}`; // we want the block size of the whole org
|
||||
|
||||
// make sure the subnet is unique
|
||||
const subnetExists = await db
|
||||
const subnetExistsClients = await db
|
||||
.select()
|
||||
.from(clients)
|
||||
.where(eq(clients.subnet, updatedSubnet))
|
||||
.limit(1);
|
||||
|
||||
if (subnetExists.length > 0) {
|
||||
if (subnetExistsClients.length > 0) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.CONFLICT,
|
||||
`Subnet ${subnet} already exists`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const subnetExistsSites = await db
|
||||
.select()
|
||||
.from(sites)
|
||||
.where(eq(sites.address, updatedSubnet))
|
||||
.limit(1);
|
||||
|
||||
if (subnetExistsSites.length > 0) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.CONFLICT,
|
||||
|
|
|
@ -3,18 +3,9 @@ import { MessageHandler } from "../ws";
|
|||
import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import db from "@server/db";
|
||||
import {
|
||||
clients,
|
||||
clientSites,
|
||||
Newt,
|
||||
Site,
|
||||
sites,
|
||||
olms
|
||||
} from "@server/db/schema";
|
||||
import { clients, clientSites, Newt, sites } from "@server/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { getNextAvailableClientSubnet } from "@server/lib/ip";
|
||||
import config from "@server/lib/config";
|
||||
import { addPeer } from "../olm/peers";
|
||||
import { updatePeer } from "../olm/peers";
|
||||
|
||||
const inputSchema = z.object({
|
||||
publicKey: z.string(),
|
||||
|
@ -27,7 +18,7 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
|
|||
const { message, client, sendToClient } = context;
|
||||
const newt = client as Newt;
|
||||
|
||||
logger.debug(JSON.stringify(message.data));
|
||||
const now = new Date().getTime() / 1000;
|
||||
|
||||
logger.debug("Handling Newt get config message!");
|
||||
|
||||
|
@ -63,6 +54,19 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
|
|||
logger.warn("handleGetConfigMessage: Site not found");
|
||||
return;
|
||||
}
|
||||
// todo check if the public key has changed
|
||||
// we need to wait for hole punch success
|
||||
if (!existingSite.endpoint) {
|
||||
logger.warn(`Site ${existingSite.siteId} has no endpoint, skipping`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (existingSite.lastHolePunch && now - existingSite.lastHolePunch > 6) {
|
||||
logger.warn(
|
||||
`Site ${existingSite.siteId} last hole punch is too old, skipping`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// update the endpoint and the public key
|
||||
const [site] = await db
|
||||
|
@ -106,29 +110,30 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
|
|||
return true;
|
||||
})
|
||||
.map(async (client) => {
|
||||
const peerData = {
|
||||
publicKey: client.clients.pubKey!,
|
||||
allowedIps: [client.clients.subnet!],
|
||||
endpoint: client.clientSites.isRelayed
|
||||
? ""
|
||||
: client.clients.endpoint! // if its relayed it should be localhost
|
||||
};
|
||||
|
||||
// Add or update this peer on the olm if it is connected
|
||||
try {
|
||||
await addPeer(client.clients.clientId, {
|
||||
...peerData,
|
||||
siteId: siteId,
|
||||
serverIP: site.address,
|
||||
serverPort: site.listenPort
|
||||
});
|
||||
if (site.endpoint && site.publicKey) {
|
||||
await updatePeer(client.clients.clientId, {
|
||||
siteId: site.siteId,
|
||||
endpoint: site.endpoint,
|
||||
publicKey: site.publicKey,
|
||||
serverIP: site.address,
|
||||
serverPort: site.listenPort
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
`Failed to add/update peer ${client.clients.pubKey} to newt ${newt.newtId}: ${error}`
|
||||
);
|
||||
}
|
||||
|
||||
return peerData;
|
||||
return {
|
||||
publicKey: client.clients.pubKey!,
|
||||
allowedIps: [client.clients.subnet!],
|
||||
endpoint: client.clientSites.isRelayed
|
||||
? ""
|
||||
: client.clients.endpoint! // if its relayed it should be localhost
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import db from "@server/db";
|
||||
import { MessageHandler } from "../ws";
|
||||
import { clients, clientSites, Olm, olms, sites } from "@server/db/schema";
|
||||
import { clients, clientSites, Olm } from "@server/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { updatePeer } from "../newt/peers";
|
||||
import logger from "@server/logger";
|
||||
|
@ -42,6 +42,13 @@ export const handleOlmRelayMessage: MessageHandler = async (context) => {
|
|||
|
||||
const { siteId } = message.data;
|
||||
|
||||
await db
|
||||
.update(clientSites)
|
||||
.set({
|
||||
isRelayed: true
|
||||
})
|
||||
.where(eq(clientSites.clientId, olm.clientId));
|
||||
|
||||
// update the peer on the exit node
|
||||
await updatePeer(siteId, client.pubKey, {
|
||||
endpoint: "" // this removes the endpoint
|
||||
|
|
|
@ -7,7 +7,6 @@ import logger from '@server/logger';
|
|||
export async function addPeer(clientId: number, peer: {
|
||||
siteId: number,
|
||||
publicKey: string;
|
||||
allowedIps: string[];
|
||||
endpoint: string;
|
||||
serverIP: string | null;
|
||||
serverPort: number | null;
|
||||
|
@ -20,8 +19,8 @@ export async function addPeer(clientId: number, peer: {
|
|||
sendToClient(olm.olmId, {
|
||||
type: 'olm/wg/peer/add',
|
||||
data: {
|
||||
siteId: peer.siteId,
|
||||
publicKey: peer.publicKey,
|
||||
allowedIps: peer.allowedIps,
|
||||
endpoint: peer.endpoint,
|
||||
serverIP: peer.serverIP,
|
||||
serverPort: peer.serverPort
|
||||
|
@ -47,11 +46,12 @@ export async function deletePeer(clientId: number, publicKey: string) {
|
|||
logger.info(`Deleted peer ${publicKey} from olm ${olm.olmId}`);
|
||||
}
|
||||
|
||||
export async function updatePeer(clientId: number, publicKey: string, peer: {
|
||||
allowedIps?: string[];
|
||||
endpoint?: string;
|
||||
serverIP?: string;
|
||||
serverPort?: number;
|
||||
export async function updatePeer(clientId: number, peer: {
|
||||
siteId: number,
|
||||
publicKey: string;
|
||||
endpoint: string;
|
||||
serverIP: string | null;
|
||||
serverPort: number | null;
|
||||
}) {
|
||||
const [olm] = await db.select().from(olms).where(eq(olms.clientId, clientId)).limit(1);
|
||||
if (!olm) {
|
||||
|
@ -59,12 +59,15 @@ export async function updatePeer(clientId: number, publicKey: string, peer: {
|
|||
}
|
||||
|
||||
sendToClient(olm.olmId, {
|
||||
type: 'olm/wg/peer/update',
|
||||
type: 'olm/wg/peer/update',
|
||||
data: {
|
||||
publicKey,
|
||||
...peer
|
||||
siteId: peer.siteId,
|
||||
publicKey: peer.publicKey,
|
||||
endpoint: peer.endpoint,
|
||||
serverIP: peer.serverIP,
|
||||
serverPort: peer.serverPort
|
||||
}
|
||||
});
|
||||
|
||||
logger.info(`Updated peer ${publicKey} on olm ${olm.olmId}`);
|
||||
logger.info(`Added peer ${peer.publicKey} to olm ${olm.olmId}`);
|
||||
}
|
|
@ -128,14 +128,16 @@ export async function createSite(
|
|||
);
|
||||
}
|
||||
|
||||
updatedAddress = `${address}/${org.subnet.split("/")[1]}`; // we want the block size of the whole org
|
||||
|
||||
// make sure the subnet is unique
|
||||
const addressExists = await db
|
||||
const addressExistsSites = await db
|
||||
.select()
|
||||
.from(sites)
|
||||
.where(eq(sites.address, address))
|
||||
.where(eq(sites.address, updatedAddress))
|
||||
.limit(1);
|
||||
|
||||
if (addressExists.length > 0) {
|
||||
if (addressExistsSites.length > 0) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.CONFLICT,
|
||||
|
@ -144,7 +146,19 @@ export async function createSite(
|
|||
);
|
||||
}
|
||||
|
||||
updatedAddress = `${address}/${org.subnet.split("/")[1]}`; // we want the block size of the whole org
|
||||
const addressExistsClients = await db
|
||||
.select()
|
||||
.from(sites)
|
||||
.where(eq(sites.subnet, updatedAddress))
|
||||
.limit(1);
|
||||
if (addressExistsClients.length > 0) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.CONFLICT,
|
||||
`Subnet ${subnet} already exists`
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const niceId = await getUniqueSiteName(orgId);
|
||||
|
|
|
@ -544,6 +544,42 @@ PersistentKeepalive = 5`;
|
|||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="clientAddress"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Client Address
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
autoComplete="off"
|
||||
value={
|
||||
clientAddress
|
||||
}
|
||||
onChange={(
|
||||
e
|
||||
) => {
|
||||
setClientAddress(
|
||||
e.target
|
||||
.value
|
||||
);
|
||||
field.onChange(
|
||||
e.target
|
||||
.value
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
<FormDescription>
|
||||
Specify the IP
|
||||
address of the host.
|
||||
</FormDescription>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
</SettingsSectionForm>
|
||||
|
@ -662,50 +698,11 @@ PersistentKeepalive = 5`;
|
|||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="clientAddress"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
Client Address
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
autoComplete="off"
|
||||
value={
|
||||
clientAddress
|
||||
}
|
||||
onChange={(
|
||||
e
|
||||
) => {
|
||||
setClientAddress(
|
||||
e
|
||||
.target
|
||||
.value
|
||||
);
|
||||
field.onChange(
|
||||
e
|
||||
.target
|
||||
.value
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
<FormDescription>
|
||||
Specify the IP
|
||||
address of the
|
||||
host.
|
||||
</FormDescription>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
</SettingsSectionBody>
|
||||
</SettingsSection>
|
||||
<SettingsSection>
|
||||
<SettingsSection>
|
||||
<SettingsSectionHeader>
|
||||
<SettingsSectionTitle>
|
||||
Install Newt
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue