Closed mStirner closed 5 months ago
Relation: #458
Couple of things to be noted:
/usr/bin/node cap_net_bind_service,cap_net_admin,cap_net_raw=eip
, sudo needs to be used to run the connector for raw sockets. (see https://stackoverflow.com/q/78496672/5781499 & https://github.com/nodejs/help/issues/4395)How could be a "alive check" implemented without anything mentioned above?
interface.bridge/socket/whatever()
should emit on the component scope a "socket" event with payload:
{
"type": "request",
"uuid": "cf459c67-2f23-41a9-b9f5-70096114fdda",
"interface": "6647482a09095ddc6a03fc47"
"device": "66474820ad108d95b47b2481",
"protocol": "tcp|udp|raw|icmp",
"ping" true
}
This object is forwarded to all connectors via websocket on a endpoint (e.g. /api/system/connector
).
Each receiving connector checks then if filter rules apply or if they are responsible for this device/network subnet/etc.pp.
If so, the connector creates a websocket briddge between the interface and the corresponding underlaying networksocket, with a query string arguments socket=true&uuid=cf459c67-2f23-41a9-b9f5-70096114fdda&type=response
. Full URL:
http://open-haus.lan:8080/api/devices/6647496087d475120b295d3a/interfaces/664749688b0b43f41ec55e45?socket=true&uuid=cf459c67-2f23-41a9-b9f5-70096114fdda&type=response
This websocket connection is then transformed into a stream, which is passed through the adapter stack configured. At last, the adapter stack stream is returned via also a emitted "socket" event on the component scoped, with the object from above, type set to "response".
The properties "protocol" & "ping" are set to create a icmp ping request to the host/ip address set on the interface. This allows to check if the device is "online".
The described mechanism above is just a draft and need do be fine tuned. Especially the icmp/ping/raw part.
Add a handshake/signing method, that no one can hijack the connection request/attempt? Asked chatgpt for a simple signing/handshake:
const crypto = require("crypto");
const SECRET = "S3c4et";
const challenge = crypto.randomBytes(16).toString('hex');
// server
const expectedHash = crypto.createHash('sha256').update(challenge + SECRET).digest('hex');
// client
const hash = crypto.createHash('sha256').update(challenge + SECRET).digest('hex');
if (receivedHash === expectedHash) {
console.log('Client authorized.');
} else {
console.log('Client auth error');
}
Use something in combination like the auth token as secret?
Some modification of class.interface.js stream/bridge handling. Just for documentation purpose.
solution-works-no-2.txt solution-works-no-1.txt solution-works.txt
The initial idea/current interface implementation is garbage. There needs to be a way to open multiple sockets to a device.
interface.createSocket()
tells the connector to create a bridge between the device interface (e.g.tcp://192.168.122.53:8123
) and the interface websocket endpoint.This connections is then converted into a stream, which is returned by
.createSocket()
. (Maybe rename the function)For this, there needs a "management" websocket connections, just like the current
/api/events
one. Overt that connection the connector is told, "bridge from A to B" as described above.