-
Notifications
You must be signed in to change notification settings - Fork 71
Open
Description
I try to use raw-socket in a worker thread, which results in a ERR_DLOPEN_FAILED/Module did not self-register error.
I have a wrapper script that can be treated as cli tool or as a worker thread entry point.
When used as CLI tool, everything works like expected.
As soon as i spawn the script as a worker thread, its results in the error above.
Wrapper script:
#! /usr/bin/node
const { EOL } = require("os");
const {
isMainThread,
workerData,
parentPort
} = require("worker_threads");
const WebSocket = require("ws");
const minimist = require("minimist");
const argv = minimist(process.argv, {
boolean: ["help"],
default: {
upstream: "",
socket: "tcp",
host: "",
port: ""
}
});
// check arguments if used as cli client or spawend via worker thread
if ((isMainThread && (!argv.upstream || !argv.host)) || argv.help) {
console.group("Usage of bridge.js as cli tool:", EOL);
console.log(`bridge.js --upstream="ws://example.com" --host="127.0.0.1" --port="8080"`);
console.log(`bridge.js --upstream="ws://open-haus.lan/api/foo/bar" --host="172.16.0.13" --socket=udp --port="53"`);
console.log(`bridge.js --upstream="ws://127.0.0.1:8080/api/devices/663fc49985397fe02064d60d/interfaces/663fc4a06a1e907dd8e86f0e" --host="127.0.0.1" --port="8123"`);
console.log(`bridge.js --upstream="ws://127.0.0.1:8080/api/devices/663fc4b0490a00181d03486c/interfaces/663fc4b5d6cf46265f713ba4" --host="192.168.2.1" --socket=raw`, EOL);
console.log("--upstream\tWebSocket upstream endpoint");
console.log("--socket\tNetwork socket type: tcp|udp|raw");
console.log("--host\tHost to connect to");
console.log("--port\tHost port to connect to");
console.log("");
process.exit(0);
}
if (!isMainThread) {
Object.assign(argv, workerData);
}
// bridge the websocket stream to underlaying network socket
let ws = new WebSocket(argv.upstream);
ws.once("error", (err) => {
console.error(err);
process.exit(10);
});
ws.once("close", (code) => {
console.log("Closed with code", code);
process.exit();
});
ws.once("open", () => {
let upstream = WebSocket.createWebSocketStream(ws);
console.log("ARGV", argv);
console.log("WorkerData", workerData)
let socket = require(`./sockets/${argv.socket}.js`)({
host: argv.host,
port: argv.port
});
upstream.pipe(socket);
socket.pipe(upstream);
if (!isMainThread) {
parentPort.on("message", (msg) => {
if (msg === "disconnect") {
ws.close(() => {
process.exit(0);
});
}
});
}
});sockets/raw.js:
const { Duplex } = require("stream");
const raw = require("raw-socket");
// this file handles raw network sockets
// the protocol implemtnation is done on the server side
const logger = require("../system/logger.js");
module.exports = ({ host, port }, options) => {
let socket = raw.createSocket({
protocol: raw.Protocol.ICMP
});
let stream = new Duplex({
write(chunk, encoding, cb) {
console.log("Write to device", `raw://${host}:${port}`, chunk);
socket.send(chunk, 0, chunk.length, host, (error, bytes) => {
console.log("Writen to devoce")
if (error)
console.log(error.toString());
});
},
read(size) {
logger.verbose(`raw://${host}:${port} Read called`, size);
},
end(chunk) {
if (chunk) {
socket.send(chunk, 0, chunk.length, host, (error, bytes) => {
if (error)
console.log(error.toString());
});
}
socket.close();
}
});
socket.on("error", (err) => {
logger.error(`[error] udp://${host}:${port}`, err);
});
socket.on("close", () => {
logger.debug(`[closed] udp://${host}:${port}`);
});
socket.on("message", (buffer, source) => {
if (source === host) {
console.log("received " + buffer.length + " bytes from " + source);
stream.push(buffer);
}
});
return stream;
};Full error message:
Worker died Error: Module did not self-register: '/home/marc/projects/OpenHaus/connector/node_modules/raw-socket/build/Release/raw.node'.
at Module._extensions..node (node:internal/modules/cjs/loader:1473:18)
at Module.load (node:internal/modules/cjs/loader:1207:32)
at Module._load (node:internal/modules/cjs/loader:1023:12)
at Module.require (node:internal/modules/cjs/loader:1235:19)
at require (node:internal/modules/helpers:176:18)
at Object.<anonymous> (/home/marc/projects/OpenHaus/connector/node_modules/raw-socket/index.js:4:11)
at Module._compile (node:internal/modules/cjs/loader:1376:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
at Module.load (node:internal/modules/cjs/loader:1207:32)
at Module._load (node:internal/modules/cjs/loader:1023:12) {
code: 'ERR_DLOPEN_FAILED'
}
Debugging details:
readelf -h node_modules/raw-socket/build/Release/raw.node
ELF-Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Klasse: ELF64
Daten: 2er-Komplement, Little-Endian
Version: 1 (aktuell)
OS/ABI: UNIX - System V
ABI-Version: 0
Typ: DYN (geteilte Objektadatei)
Maschine: Advanced Micro Devices X86-64
Version: 0x1
Einstiegspunktadresse: 0x0
Beginn der Programm-Header: 64 (Bytes in Datei)
Beginn der Sektions-header: 67936 (Bytes in Datei)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 11
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 30
node version: v20.11.0
npm version: v10.5.1
raw socket: v1.8.1
os: Ubuntu v23.10
An idea how to fix this?
Already tried to re-install & re-build dependencies.
But since it works as cli tool/standalone module, i think this is purposeful anyways.
Metadata
Metadata
Assignees
Labels
No labels