Add docz
This commit is contained in:
parent
936d83a89c
commit
bb86fe1ccf
2 changed files with 41 additions and 3 deletions
|
@ -1,3 +1,9 @@
|
|||
# valproxy
|
||||
|
||||
UDP proxy for Valheim dedicated server Systemd socket activation.
|
||||
|
||||
This is theoretically a non-Valheim specific UDP proxy that can proxy any UDP traffic from a Systemd socket
|
||||
into a specified local or remote target (bi-directionally), but the feature set and configuration is focused
|
||||
on running the Valheim dedicated server.
|
||||
|
||||
The `systemd` folder contains example socket and server files detailing how it can be set up.
|
||||
|
|
38
index.js
38
index.js
|
@ -34,6 +34,7 @@ const SOCKET_TYPE = "udp4";
|
|||
*/
|
||||
const SYSTEMD_READ_SOCKET_FD = 3;
|
||||
|
||||
/** A network target. */
|
||||
class Target {
|
||||
/** @type {string} */
|
||||
address;
|
||||
|
@ -51,7 +52,11 @@ class Target {
|
|||
}
|
||||
}
|
||||
|
||||
/** @template T */
|
||||
/**
|
||||
* A convenience over a 2-dimensional map.
|
||||
*
|
||||
* @template T
|
||||
*/
|
||||
class TargetMap extends Map {
|
||||
/**
|
||||
* @param {Target} target
|
||||
|
@ -89,11 +94,20 @@ class TargetMap extends Map {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A connection from a remote to our target.
|
||||
*/
|
||||
class Connection {
|
||||
/** @type {Target} */
|
||||
/**
|
||||
* The remote client address information.
|
||||
* @type {Target}
|
||||
*/
|
||||
source;
|
||||
|
||||
/** @type {Socket | null} */
|
||||
/**
|
||||
* The socket used to connect to the target, and to receive messages from it.
|
||||
* @type {Socket | null}
|
||||
*/
|
||||
writeSocket;
|
||||
|
||||
/** @type {NodeJS.Timer | null} */
|
||||
|
@ -123,6 +137,9 @@ class Connection {
|
|||
this.onMessage = onMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise {@link writeSocket} by setting up the event handlers and connecting it to target.
|
||||
*/
|
||||
initTargetSocket() {
|
||||
this.connected = false;
|
||||
clearTimeout(this.reconnectTimeout);
|
||||
|
@ -135,6 +152,7 @@ class Connection {
|
|||
this.source.port
|
||||
);
|
||||
});
|
||||
|
||||
this.writeSocket.on("message", (fromMsg) => {
|
||||
this.#resetIdleTimeout();
|
||||
if (DEBUG) {
|
||||
|
@ -149,9 +167,11 @@ class Connection {
|
|||
|
||||
this.onMessage(fromMsg);
|
||||
});
|
||||
|
||||
this.writeSocket.on("error", (err) => {
|
||||
this.#writeError(err);
|
||||
});
|
||||
|
||||
this.writeSocket.on("close", () => {
|
||||
console.log(
|
||||
"Socket for",
|
||||
|
@ -169,6 +189,10 @@ class Connection {
|
|||
}
|
||||
|
||||
/**
|
||||
* Send a message to target using our socket.
|
||||
*
|
||||
* If the socket is down, the message is discarded.
|
||||
*
|
||||
* @param {Buffer} msg
|
||||
*/
|
||||
send(msg) {
|
||||
|
@ -200,6 +224,7 @@ class Connection {
|
|||
this.source.port
|
||||
);
|
||||
console.error(err);
|
||||
|
||||
this.writeSocket = null;
|
||||
this.reconnectTimeout = setTimeout(() => {
|
||||
this.writeSocket = createSocket(SOCKET_TYPE);
|
||||
|
@ -255,6 +280,8 @@ READ_SOCKET.on("listening", () => {
|
|||
});
|
||||
|
||||
READ_SOCKET.on("message", (toMsg, rinfo) => {
|
||||
// We need to strip off the dual stack mapped address prefix, if one exists. Otherwise our replies will not be
|
||||
// delivered to the origin.
|
||||
let raddress = rinfo.address;
|
||||
if (raddress.indexOf("::ffff:") === 0) {
|
||||
raddress = raddress.substring(7);
|
||||
|
@ -267,6 +294,9 @@ READ_SOCKET.on("message", (toMsg, rinfo) => {
|
|||
const source = new Target(raddress, rinfo.port);
|
||||
|
||||
let connection = CONNECTIONS.get(source);
|
||||
|
||||
// Create a new connection for each new client address/port pair. This allows us to route the replies from the target
|
||||
// back to the correct client address/port and thus the correct remote client.
|
||||
if (!connection) {
|
||||
clearTimeout(TOTAL_IDLE_TIMER);
|
||||
|
||||
|
@ -305,6 +335,8 @@ READ_SOCKET.on("close", () => {
|
|||
console.log("Systemd read socket closed.");
|
||||
});
|
||||
|
||||
// Bind the read socket to the file descriptor given by Systemd. Systemd is already listening to packets for us, so we
|
||||
// don't open our own socket.
|
||||
READ_SOCKET.bind({
|
||||
fd: SYSTEMD_READ_SOCKET_FD,
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue