Skip to content

Commit

Permalink
Take IP from headers
Browse files Browse the repository at this point in the history
  • Loading branch information
ivancea committed Aug 22, 2024
1 parent b60bccc commit dc2ce6a
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 2 deletions.
110 changes: 110 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"compression": "^1.7.4",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"forwarded-parse": "^2.1.2",
"is-ip": "^5.0.1",
"is-mobile": "^4.0.0",
"nipplejs": "^0.10.2",
"socket.io": "^4.7.5",
Expand Down
7 changes: 5 additions & 2 deletions server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { clampMagnitude } from "../common/vector";
import { env } from "./env";
import { disconnectPlayer, joinPlayer } from "./logic/logic";
import { server } from "./server";
import { getClientIp } from "./socket-utils";
import { getLogger, initializeLogger } from "./utils/logger";
import { getPlayer, getRoom } from "./world";

Expand All @@ -24,11 +25,13 @@ async function startServer() {
});

socket.on("requestJoin", async (event, callback) => {
const clientIp = getClientIp(socket);

getLogger().stats({
name: "user join request",
unit: "count",
extra: {
player_ip: socket.handshake.address,
player_ip: clientIp,
},
value: 1,
});
Expand All @@ -42,7 +45,7 @@ async function startServer() {
getLogger().info(
`User ${socket.id} with name "${event.username}" joined room ${room.id}`,
{
player_ip: socket.handshake.address,
player_ip: clientIp,
player_id: player.id,
room_id: `${room.id}`,
},
Expand Down
43 changes: 43 additions & 0 deletions server/socket-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import forwardedParse from "forwarded-parse";
import { isIP } from "is-ip";
import { Socket } from "socket.io";

/**
* Given a socket, returns the IP address of the client.
*
* This function will try to find the most accurate IP address, based on headers and other data.
*/
export function getClientIp(socket: Socket): string {
return (
checkedIp(getXForwardedFor(socket)) ||
checkedIp(getForwarded(socket)) ||
checkedIp(getCloudflareHeaders(socket)) ||
socket.handshake.address
);
}

function checkedIp(ip: string | undefined) {
return ip && isIP(ip) ? ip : undefined;
}

function getXForwardedFor(socket: Socket) {
return [socket.handshake.headers["x-forwarded-for"] ?? []]
.flat()
.map((forwardedFor) => forwardedFor.split(",")[0]?.trim())
.filter(Boolean)[0];
}

function getForwarded(socket: Socket) {
try {
const forwardedHeader = socket.handshake.headers["forwarded"];
return forwardedHeader
? forwardedParse(forwardedHeader)[0]?.for
: undefined;
} catch {
return undefined;
}
}

function getCloudflareHeaders(socket: Socket) {
return socket.handshake.headers["cf-connecting-ip"]?.[0];
}

0 comments on commit dc2ce6a

Please sign in to comment.