Skip to content

Commit 722e70f

Browse files
committed
feat: include device ip and ICE server list in device handshake payload
1 parent 954303a commit 722e70f

File tree

4 files changed

+40
-9
lines changed

4 files changed

+40
-9
lines changed

.env.example

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@ R2_SECRET_ACCESS_KEY=XXX # Any S3 compatible secret access key
1717
R2_BUCKET=XXX # Any S3 compatible bucket
1818
R2_CDN_URL=XXX # Any S3 compatible CDN URL
1919

20-
CORS_ORIGINS=https://app.jetkvm.com,http://localhost:5173 # Allowed CORS Origins, split by comma
20+
CORS_ORIGINS=https://app.jetkvm.com,http://localhost:5173 # Allowed CORS Origins, split by comma
21+
22+
REAL_IP_HEADER=XXX # Real IP Header for the reverse proxy (e.g. X-Real-IP), leave empty if not needed
23+
ICE_SERVERS=XXX # ICE Servers for WebRTC, split by comma (e.g. stun:stun.l.google.com:19302,stun:stun1.l.google.com:19302)

src/devices.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,9 @@ export const Delete = async (req: express.Request, res: express.Response) => {
119119
await prisma.device.delete({ where: { id, user: { googleId: sub } } });
120120

121121
// We just removed the device, so we should close any running open socket connections
122-
const socket = activeConnections.get(id);
123-
if (socket) {
122+
const conn = activeConnections.get(id);
123+
if (conn) {
124+
const [socket] = conn;
124125
socket.send("Deregistered from server");
125126
socket.close();
126127
}

src/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ declare global {
3838
R2_CDN_URL: string;
3939

4040
CORS_ORIGINS: string;
41+
42+
// Real IP
43+
REAL_IP_HEADER: string;
44+
ICE_SERVERS: string;
4145
}
4246
}
4347
}

src/webrtc.ts

+29-6
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,19 @@ import { IncomingMessage } from "http";
77
import { Socket } from "node:net";
88
import { Device } from "@prisma/client";
99

10-
export const activeConnections: Map<string, WebSocket> = new Map();
10+
export const activeConnections: Map<string, [WebSocket, string]> = new Map();
1111
export const inFlight: Set<string> = new Set();
1212

13+
function toICEServers(str: string) {
14+
return str.split(",").filter(
15+
(url) => url.startsWith("stun:")
16+
);
17+
}
18+
19+
export const iceServers = toICEServers(
20+
process.env.ICE_SERVERS || "stun.cloudflare.com:3478,stun:stun.l.google.com:19302,stun:stun1.l.google.com:5349"
21+
);
22+
1323
export const CreateSession = async (req: express.Request, res: express.Response) => {
1424
const idToken = req.session?.id_token;
1525
const { sub } = jose.decodeJwt(idToken);
@@ -35,12 +45,15 @@ export const CreateSession = async (req: express.Request, res: express.Response)
3545
);
3646
}
3747

38-
const ws = activeConnections.get(id);
39-
if (!ws) {
48+
const wsTuple = activeConnections.get(id);
49+
if (!wsTuple) {
4050
console.log("No socket for id", id);
4151
throw new NotFoundError(`No socket for id found`, "kvm_socket_not_found");
4252
}
4353

54+
// extract the websocket and ip from the tuple
55+
const [ws, ip] = wsTuple;
56+
4457
let wsRes: ((value: unknown) => void) | null = null,
4558
wsRej: ((value: unknown) => void) | null = null;
4659

@@ -63,7 +76,13 @@ export const CreateSession = async (req: express.Request, res: express.Response)
6376

6477
// If the HTTP client closes the connection before the websocket response is received, reject the promise
6578
req.socket.on("close", wsRej);
66-
ws.send(JSON.stringify({ sd, OidcGoogle: idToken }));
79+
80+
ws.send(JSON.stringify({
81+
sd,
82+
ip,
83+
iceServers,
84+
OidcGoogle: idToken
85+
}));
6786
});
6887

6988
return res.json(JSON.parse(resp.data));
@@ -170,7 +189,7 @@ export const registerWebsocketServer = (server: any) => {
170189
console.log(
171190
"Device already in active connection list. Terminating & deleting existing websocket.",
172191
);
173-
activeConnections.get(device.id)?.terminate();
192+
activeConnections.get(device.id)?.[0]?.terminate();
174193
activeConnections.delete(device.id);
175194
}
176195

@@ -227,7 +246,11 @@ export const registerWebsocketServer = (server: any) => {
227246
return ws.close();
228247
}
229248

230-
activeConnections.set(id, ws);
249+
const ip = (
250+
process.env.REAL_IP_HEADER && req.headers[process.env.REAL_IP_HEADER]
251+
) || req.socket.remoteAddress;
252+
253+
activeConnections.set(id, [ws, `${ip}`]);
231254
console.log("New socket for id", id);
232255

233256
ws.on("error", async () => {

0 commit comments

Comments
 (0)