diff --git a/server/db/schema.ts b/server/db/schema.ts index 0c29459e..7688bddc 100644 --- a/server/db/schema.ts +++ b/server/db/schema.ts @@ -26,6 +26,8 @@ export const sites = sqliteTable("sites", { subdomain: text("subdomain"), pubKey: text("pubKey"), subnet: text("subnet"), + megabytesIn: integer("bytesIn"), + megabytesOut: integer("bytesOut") }); // Resources table diff --git a/server/migrations/0000_wealthy_captain_midlands.sql b/server/migrations/0000_flimsy_shotgun.sql similarity index 97% rename from server/migrations/0000_wealthy_captain_midlands.sql rename to server/migrations/0000_flimsy_shotgun.sql index 0643a3d6..ea8f617e 100644 --- a/server/migrations/0000_wealthy_captain_midlands.sql +++ b/server/migrations/0000_flimsy_shotgun.sql @@ -35,6 +35,8 @@ CREATE TABLE `sites` ( `subdomain` text, `pubKey` text, `subnet` text, + `bytesIn` integer, + `bytesOut` integer, FOREIGN KEY (`orgId`) REFERENCES `orgs`(`orgId`) ON UPDATE no action ON DELETE cascade, FOREIGN KEY (`exitNode`) REFERENCES `exitNodes`(`exitNodeId`) ON UPDATE no action ON DELETE set null ); diff --git a/server/migrations/meta/0000_snapshot.json b/server/migrations/meta/0000_snapshot.json index 99da50f3..cba5df37 100644 --- a/server/migrations/meta/0000_snapshot.json +++ b/server/migrations/meta/0000_snapshot.json @@ -1,7 +1,7 @@ { "version": "6", "dialect": "sqlite", - "id": "379ca2f9-068a-4289-8a23-001e7dc269b1", + "id": "8f8a2cda-fb58-438b-bc67-e5c34eda0580", "prevId": "00000000-0000-0000-0000-000000000000", "tables": { "exitNodes": { @@ -224,6 +224,20 @@ "primaryKey": false, "notNull": false, "autoincrement": false + }, + "bytesIn": { + "name": "bytesIn", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "bytesOut": { + "name": "bytesOut", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false } }, "indexes": {}, diff --git a/server/migrations/meta/_journal.json b/server/migrations/meta/_journal.json index 4eb8fe00..839fed65 100644 --- a/server/migrations/meta/_journal.json +++ b/server/migrations/meta/_journal.json @@ -5,8 +5,8 @@ { "idx": 0, "version": "6", - "when": 1727557783608, - "tag": "0000_wealthy_captain_midlands", + "when": 1727577233301, + "tag": "0000_flimsy_shotgun", "breakpoints": true } ] diff --git a/server/routers/badger/badger.ts b/server/routers/badger/badger.ts index 5cb8e34f..4224291b 100644 --- a/server/routers/badger/badger.ts +++ b/server/routers/badger/badger.ts @@ -1,5 +1,6 @@ import { Router } from "express"; import { getConfig } from "./getConfig"; +import { receiveBandwidth } from "./receiveBandwidth"; const badger = Router(); @@ -8,5 +9,6 @@ badger.get("/", (_, res) => { }); badger.get("/getConfig", getConfig); +badger.post("/receiveBandwidth", receiveBandwidth); export default badger; diff --git a/server/routers/badger/getConfig.ts b/server/routers/badger/getConfig.ts index b586effb..676c5832 100644 --- a/server/routers/badger/getConfig.ts +++ b/server/routers/badger/getConfig.ts @@ -1,7 +1,7 @@ import { Request, Response, NextFunction } from 'express'; import { DrizzleError, eq } from 'drizzle-orm'; -import { sites, resources, targets, exitNodes } from '../../db/schema'; -import db from '../../db'; +import { sites, resources, targets, exitNodes } from '@server/db/schema'; +import db from '@server/db'; export const getConfig = async (req: Request, res: Response, next: NextFunction): Promise => { try { @@ -51,7 +51,6 @@ export const getConfig = async (req: Request, res: Response, next: NextFunction) peers, }; - res.json(config); } catch (error) { console.error('Error querying database:', error); diff --git a/server/routers/badger/receiveBandwidth.ts b/server/routers/badger/receiveBandwidth.ts new file mode 100644 index 00000000..1e0d8ee5 --- /dev/null +++ b/server/routers/badger/receiveBandwidth.ts @@ -0,0 +1,57 @@ +import { Request, Response, NextFunction } from 'express'; +import { DrizzleError, eq } from 'drizzle-orm'; +import { sites, resources, targets, exitNodes } from '@server/db/schema'; +import db from '@server/db'; +import logger from '@server/logger'; + +interface PeerBandwidth { + publicKey: string; + bytesIn: number; + bytesOut: number; +} + +export const receiveBandwidth = async (req: Request, res: Response, next: NextFunction): Promise => { + try { + const bandwidthData: PeerBandwidth[] = req.body; + + if (!Array.isArray(bandwidthData)) { + throw new Error('Invalid bandwidth data'); + } + + for (const peer of bandwidthData) { + const { publicKey, bytesIn, bytesOut } = peer; + + // Find the site by public key + const site = await db.query.sites.findFirst({ + where: eq(sites.pubKey, publicKey), + }); + + if (!site) { + console.warn(`Site not found for public key: ${publicKey}`); + continue; + } + + // Update the site's bandwidth usage + await db.update(sites) + .set({ + megabytesIn: (site.megabytesIn || 0) + bytesIn, + megabytesOut: (site.megabytesOut || 0) + bytesOut, + }) + .where(eq(sites.siteId, site.siteId)); + + logger.debug(`Updated bandwidth for site: ${site.siteId}: megabytesIn: ${(site.megabytesIn || 0) + bytesIn}, megabytesOut: ${(site.megabytesOut || 0) + bytesOut}`); + + } + + res.status(200).json({ message: 'Bandwidth data updated successfully' }); + } catch (error) { + console.error('Error updating bandwidth data:', error); + res.status(500).json({ error: 'Internal server error' }); + } +}; + +function calculateSubnet(index: number): string { + const baseIp = 10 << 24; + const subnetSize = 16; + return `${(baseIp | (index * subnetSize)).toString()}/28`; +}