const Component = require("./_component"); const dgram = require('node:dgram'); const fs = require('fs'); function logger (...p) { return; console.debug("[UDP reverse]:", ...p); }; function isFirewalled () { // TODO: Firewall return false; } module.exports = class UDPServer extends Component { static type () { return "udp-proxy"; } constructor (adr, syntaxTree) { super(adr, syntaxTree); if (syntaxTree.firewall) { throw new Error("Firewall doesn't supports"); } } run () { const server = dgram.createSocket('udp4', (srvSocket) => {}); const connections = {}; // const connectionsTimeout = {}; const remote = { ip: this.syntax.target.split(/:/)[0], port: this.syntax.target.split(/:/)[1], }; server.on('error', (err) => { logger("Caught UDP server socket error: "); logger(err.stack); }); server.on('connect', (peer) => { logger("connect event:", peer); if (!isFirewalled(peer.address)) { logger(`${peer.address}:${peer.port} connected!`); connections[`${peer.address}:${peer.port}`] = dgram.createSocket('udp4'); connections[`${peer.address}:${peer.port}`].on('message', (data, rmt) => { if (`${rmt.address}:${rmt.port}` === `${remote.ip}:${remote.port}`) { logger(`to ${peer.address}:${peer.port} sended: ${data.length} bytes`); server.send(data, peer.port, peer.address, (err) => { if (err) logger(`error: ${peer.address}:${peer.port} throwed: ${err.name}`); }); } }); } else { logger(`${peer.address} firewalled, reject`); } }); server.on('message', (data, peer) => { logger(`from ${peer.address}:${peer.port} attempt send to ${remote.ip}:${remote.port} ${data.length} bytes`); if (`${peer.address}:${peer.port}` !== `${remote.ip}:${remote.port}`) { logger(`from ${peer.address}:${peer.port} sended: ${data.length} bytes to ${remote.ip}:${remote.port}`); if (connections[`${peer.address}:${peer.port}`] === undefined) { server.emit("connect", peer); } if (connections[`${peer.address}:${peer.port}`] !== undefined) { connections[`${peer.address}:${peer.port}`].send(data, remote.port, remote.ip, (err) => { if (err) logger(`error: ${peer.address} (remote) throwed: ${err.name}`); }); } } }); server.on('listening', () => { const address = server.address(); console.log(`UDP reverse proxy server listening on ${address.address}:${address.port}`); }); server.bind(this.adr.port, this.adr.address, (err) => { if (err) throw err; console.log("UDP reverse proxy connected!"); }); server.on('error', (err) => { logger("Error of server"); logger(err.stack); }); this.server = server; } }