diodejs 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bindPort.js +41 -38
- package/connection.js +97 -75
- package/index.js +6 -0
- package/logger.js +10 -5
- package/package.json +6 -8
- package/publishPort.js +67 -48
- package/rpc.js +78 -55
- package/testServers/udpTest.js +1 -2
- package/utils.js +19 -13
package/bindPort.js
CHANGED
|
@@ -2,6 +2,7 @@ const net = require('net');
|
|
|
2
2
|
const tls = require('tls');
|
|
3
3
|
const dgram = require('dgram');
|
|
4
4
|
const { Buffer } = require('buffer');
|
|
5
|
+
const { toBufferView } = require('./utils');
|
|
5
6
|
const { Duplex } = require('stream');
|
|
6
7
|
const DiodeRPC = require('./rpc');
|
|
7
8
|
const logger = require('./logger');
|
|
@@ -9,7 +10,7 @@ const logger = require('./logger');
|
|
|
9
10
|
// Custom Duplex stream to handle the Diode connection
|
|
10
11
|
class DiodeSocket extends Duplex {
|
|
11
12
|
constructor(ref, rpc) {
|
|
12
|
-
super();
|
|
13
|
+
super({ readableHighWaterMark: 256 * 1024, writableHighWaterMark: 256 * 1024, allowHalfOpen: false });
|
|
13
14
|
this.ref = ref;
|
|
14
15
|
this.rpc = rpc;
|
|
15
16
|
this.destroyed = false;
|
|
@@ -92,14 +93,14 @@ class BindPort {
|
|
|
92
93
|
this.connection.on('unsolicited', (message) => {
|
|
93
94
|
const [messageIdRaw, messageContent] = message;
|
|
94
95
|
const messageTypeRaw = messageContent[0];
|
|
95
|
-
const messageType =
|
|
96
|
+
const messageType = toBufferView(messageTypeRaw).toString('utf8');
|
|
96
97
|
|
|
97
98
|
if (messageType === 'data' || messageType === 'portsend') {
|
|
98
99
|
const refRaw = messageContent[1];
|
|
99
100
|
const dataRaw = messageContent[2];
|
|
100
101
|
|
|
101
|
-
const dataRef =
|
|
102
|
-
const data =
|
|
102
|
+
const dataRef = toBufferView(refRaw);
|
|
103
|
+
const data = toBufferView(dataRaw);
|
|
103
104
|
|
|
104
105
|
// Find the associated client socket from connection
|
|
105
106
|
const clientSocket = this.connection.getClientSocket(dataRef);
|
|
@@ -114,14 +115,14 @@ class BindPort {
|
|
|
114
115
|
} else {
|
|
115
116
|
const connectionInfo = this.connection.getConnection(dataRef);
|
|
116
117
|
if (connectionInfo) {
|
|
117
|
-
logger.debug(`No client socket found for ref: ${dataRef.toString('hex')}, but connection exists for ${connectionInfo.host}:${connectionInfo.port}`);
|
|
118
|
+
logger.debug(() => `No client socket found for ref: ${dataRef.toString('hex')}, but connection exists for ${connectionInfo.host}:${connectionInfo.port}`);
|
|
118
119
|
} else {
|
|
119
|
-
logger.warn(`No client socket found for ref: ${dataRef.toString('hex')}`);
|
|
120
|
+
logger.warn(() => `No client socket found for ref: ${dataRef.toString('hex')}`);
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
123
|
} else if (messageType === 'portclose') {
|
|
123
124
|
const refRaw = messageContent[1];
|
|
124
|
-
const dataRef =
|
|
125
|
+
const dataRef = toBufferView(refRaw);
|
|
125
126
|
|
|
126
127
|
// Close the associated client socket
|
|
127
128
|
const clientSocket = this.connection.getClientSocket(dataRef);
|
|
@@ -131,31 +132,31 @@ class BindPort {
|
|
|
131
132
|
}
|
|
132
133
|
clientSocket.end();
|
|
133
134
|
this.connection.deleteClientSocket(dataRef);
|
|
134
|
-
logger.info(`Port closed for ref: ${dataRef.toString('hex')}`);
|
|
135
|
+
logger.info(() => `Port closed for ref: ${dataRef.toString('hex')}`);
|
|
135
136
|
}
|
|
136
137
|
} else {
|
|
137
138
|
if (messageType != 'portopen') {
|
|
138
|
-
logger.warn(`Unknown unsolicited message type: ${messageType}`);
|
|
139
|
+
logger.warn(() => `Unknown unsolicited message type: ${messageType}`);
|
|
139
140
|
}
|
|
140
141
|
}
|
|
141
142
|
});
|
|
142
143
|
|
|
143
144
|
// Handle device disconnect
|
|
144
145
|
this.connection.on('end', () => {
|
|
145
|
-
logger.info('Disconnected from Diode.io server');
|
|
146
|
+
logger.info(() => 'Disconnected from Diode.io server');
|
|
146
147
|
this.closeAllServers();
|
|
147
148
|
});
|
|
148
149
|
|
|
149
150
|
// Handle connection errors
|
|
150
151
|
this.connection.on('error', (err) => {
|
|
151
|
-
logger.error(`Connection error: ${err}`);
|
|
152
|
+
logger.error(() => `Connection error: ${err}`);
|
|
152
153
|
this.closeAllServers();
|
|
153
154
|
});
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
addPort(localPort, targetPort, deviceIdHex, protocol = 'tls') {
|
|
157
158
|
if (this.servers.has(localPort)) {
|
|
158
|
-
logger.warn(`Port ${localPort} is already bound`);
|
|
159
|
+
logger.warn(() => `Port ${localPort} is already bound`);
|
|
159
160
|
return false;
|
|
160
161
|
}
|
|
161
162
|
|
|
@@ -172,7 +173,7 @@ class BindPort {
|
|
|
172
173
|
|
|
173
174
|
removePort(localPort) {
|
|
174
175
|
if (!this.portsConfig[localPort]) {
|
|
175
|
-
logger.warn(`Port ${localPort} is not configured`);
|
|
176
|
+
logger.warn(() => `Port ${localPort} is not configured`);
|
|
176
177
|
return false;
|
|
177
178
|
}
|
|
178
179
|
|
|
@@ -180,7 +181,7 @@ class BindPort {
|
|
|
180
181
|
if (this.servers.has(localPort)) {
|
|
181
182
|
const server = this.servers.get(localPort);
|
|
182
183
|
server.close(() => {
|
|
183
|
-
logger.info(`Server on port ${localPort} closed`);
|
|
184
|
+
logger.info(() => `Server on port ${localPort} closed`);
|
|
184
185
|
});
|
|
185
186
|
this.servers.delete(localPort);
|
|
186
187
|
}
|
|
@@ -193,7 +194,7 @@ class BindPort {
|
|
|
193
194
|
closeAllServers() {
|
|
194
195
|
for (const [localPort, server] of this.servers.entries()) {
|
|
195
196
|
server.close();
|
|
196
|
-
logger.info(`Server on port ${localPort} closed`);
|
|
197
|
+
logger.info(() => `Server on port ${localPort} closed`);
|
|
197
198
|
}
|
|
198
199
|
this.servers.clear();
|
|
199
200
|
}
|
|
@@ -201,7 +202,7 @@ class BindPort {
|
|
|
201
202
|
bindSinglePort(localPort) {
|
|
202
203
|
const config = this.portsConfig[localPort];
|
|
203
204
|
if (!config) {
|
|
204
|
-
logger.error(`No configuration found for port ${localPort}`);
|
|
205
|
+
logger.error(() => `No configuration found for port ${localPort}`);
|
|
205
206
|
return false;
|
|
206
207
|
}
|
|
207
208
|
|
|
@@ -210,14 +211,14 @@ class BindPort {
|
|
|
210
211
|
|
|
211
212
|
// Format the target port with protocol prefix for the remote connection
|
|
212
213
|
const formattedTargetPort = `${protocol}:${targetPort}`;
|
|
213
|
-
logger.info(`Binding local port ${localPort} to remote ${formattedTargetPort}`);
|
|
214
|
+
logger.info(() => `Binding local port ${localPort} to remote ${formattedTargetPort}`);
|
|
214
215
|
|
|
215
216
|
// For udp protocol, use udp server
|
|
216
217
|
if (protocol === 'udp') {
|
|
217
218
|
const server = dgram.createSocket('udp4');
|
|
218
219
|
|
|
219
220
|
server.on('listening', () => {
|
|
220
|
-
logger.info(`udp server listening on port ${localPort} forwarding to device port ${targetPort}`);
|
|
221
|
+
logger.info(() => `udp server listening on port ${localPort} forwarding to device port ${targetPort}`);
|
|
221
222
|
});
|
|
222
223
|
|
|
223
224
|
server.on('message', async (data, rinfo) => {
|
|
@@ -229,10 +230,10 @@ class BindPort {
|
|
|
229
230
|
try {
|
|
230
231
|
ref = await this.rpc.portOpen(deviceId, formattedTargetPort, 'rw');
|
|
231
232
|
if (!ref) {
|
|
232
|
-
logger.error(`Error opening port ${formattedTargetPort} on deviceId: ${deviceIdHex}`);
|
|
233
|
+
logger.error(() => `Error opening port ${formattedTargetPort} on deviceId: ${deviceIdHex}`);
|
|
233
234
|
return;
|
|
234
235
|
} else {
|
|
235
|
-
logger.info(`Port ${formattedTargetPort} opened on device with ref: ${ref.toString('hex')} for udp client ${clientKey}`);
|
|
236
|
+
logger.info(() => `Port ${formattedTargetPort} opened on device with ref: ${ref.toString('hex')} for udp client ${clientKey}`);
|
|
236
237
|
if (!server.clientRefs) server.clientRefs = {};
|
|
237
238
|
server.clientRefs[clientKey] = ref;
|
|
238
239
|
|
|
@@ -247,7 +248,7 @@ class BindPort {
|
|
|
247
248
|
});
|
|
248
249
|
}
|
|
249
250
|
} catch (error) {
|
|
250
|
-
logger.error(`Error opening port ${formattedTargetPort} on device: ${error}`);
|
|
251
|
+
logger.error(() => `Error opening port ${formattedTargetPort} on device: ${error}`);
|
|
251
252
|
return;
|
|
252
253
|
}
|
|
253
254
|
}
|
|
@@ -256,12 +257,12 @@ class BindPort {
|
|
|
256
257
|
try {
|
|
257
258
|
await this.rpc.portSend(ref, data);
|
|
258
259
|
} catch (error) {
|
|
259
|
-
logger.error(`Error sending udp data to device: ${error}`);
|
|
260
|
+
logger.error(() => `Error sending udp data to device: ${error}`);
|
|
260
261
|
}
|
|
261
262
|
});
|
|
262
263
|
|
|
263
264
|
server.on('error', (err) => {
|
|
264
|
-
logger.error(`udp Server error: ${err}`);
|
|
265
|
+
logger.error(() => `udp Server error: ${err}`);
|
|
265
266
|
});
|
|
266
267
|
|
|
267
268
|
server.bind(localPort);
|
|
@@ -269,21 +270,22 @@ class BindPort {
|
|
|
269
270
|
} else {
|
|
270
271
|
// For TCP and tls protocols, use TCP server locally
|
|
271
272
|
const server = net.createServer(async (clientSocket) => {
|
|
272
|
-
logger.info(`Client connected to local server on port ${localPort}`);
|
|
273
|
+
logger.info(() => `Client connected to local server on port ${localPort}`);
|
|
274
|
+
clientSocket.setNoDelay(true);
|
|
273
275
|
|
|
274
276
|
// Open a new port on the device for this client
|
|
275
277
|
let ref;
|
|
276
278
|
try {
|
|
277
279
|
ref = await this.rpc.portOpen(deviceId, formattedTargetPort, 'rw');
|
|
278
280
|
if (!ref) {
|
|
279
|
-
logger.error(`Error opening port ${formattedTargetPort} on deviceId: ${deviceIdHex}`);
|
|
281
|
+
logger.error(() => `Error opening port ${formattedTargetPort} on deviceId: ${deviceIdHex}`);
|
|
280
282
|
clientSocket.destroy();
|
|
281
283
|
return;
|
|
282
284
|
} else {
|
|
283
|
-
logger.info(`Port ${formattedTargetPort} opened on device with ref: ${ref.toString('hex')} for client`);
|
|
285
|
+
logger.info(() => `Port ${formattedTargetPort} opened on device with ref: ${ref.toString('hex')} for client`);
|
|
284
286
|
}
|
|
285
287
|
} catch (error) {
|
|
286
|
-
logger.error(`Error opening port ${formattedTargetPort} on device: ${error}`);
|
|
288
|
+
logger.error(() => `Error opening port ${formattedTargetPort} on device: ${error}`);
|
|
287
289
|
clientSocket.destroy();
|
|
288
290
|
return;
|
|
289
291
|
}
|
|
@@ -316,15 +318,16 @@ class BindPort {
|
|
|
316
318
|
socket: diodeSocket,
|
|
317
319
|
...tlsOptions
|
|
318
320
|
}, () => {
|
|
319
|
-
logger.info(`tls connection established to device ${deviceIdHex}`);
|
|
321
|
+
logger.info(() => `tls connection established to device ${deviceIdHex}`);
|
|
320
322
|
});
|
|
323
|
+
tlsSocket.setNoDelay(true);
|
|
321
324
|
|
|
322
325
|
// Pipe data between the client socket and the tls socket
|
|
323
326
|
tlsSocket.pipe(clientSocket).pipe(tlsSocket);
|
|
324
327
|
|
|
325
328
|
// Handle tls socket errors
|
|
326
329
|
tlsSocket.on('error', (err) => {
|
|
327
|
-
logger.error(`tls Socket error: ${err}`);
|
|
330
|
+
logger.error(() => `tls Socket error: ${err}`);
|
|
328
331
|
clientSocket.destroy();
|
|
329
332
|
});
|
|
330
333
|
|
|
@@ -342,7 +345,7 @@ class BindPort {
|
|
|
342
345
|
this.connection.addClientSocket(ref, socketWrapper);
|
|
343
346
|
|
|
344
347
|
} catch (error) {
|
|
345
|
-
logger.error(`Error setting up tls connection: ${error}`);
|
|
348
|
+
logger.error(() => `Error setting up tls connection: ${error}`);
|
|
346
349
|
clientSocket.destroy();
|
|
347
350
|
return;
|
|
348
351
|
}
|
|
@@ -355,7 +358,7 @@ class BindPort {
|
|
|
355
358
|
try {
|
|
356
359
|
await this.rpc.portSend(ref, data);
|
|
357
360
|
} catch (error) {
|
|
358
|
-
logger.error(`Error sending data to device: ${error}`);
|
|
361
|
+
logger.error(() => `Error sending data to device: ${error}`);
|
|
359
362
|
clientSocket.destroy();
|
|
360
363
|
}
|
|
361
364
|
});
|
|
@@ -363,28 +366,28 @@ class BindPort {
|
|
|
363
366
|
|
|
364
367
|
// Handle client socket closure (common for all protocols)
|
|
365
368
|
clientSocket.on('end', async () => {
|
|
366
|
-
logger.info('Client disconnected');
|
|
369
|
+
logger.info(() => 'Client disconnected');
|
|
367
370
|
if (ref && this.connection.hasClientSocket(ref)) {
|
|
368
371
|
try {
|
|
369
372
|
await this.rpc.portClose(ref);
|
|
370
|
-
logger.info(`Port closed on device for ref: ${ref.toString('hex')}`);
|
|
373
|
+
logger.info(() => `Port closed on device for ref: ${ref.toString('hex')}`);
|
|
371
374
|
this.connection.deleteClientSocket(ref);
|
|
372
375
|
} catch (error) {
|
|
373
|
-
logger.error(`Error closing port on device: ${error}`);
|
|
376
|
+
logger.error(() => `Error closing port on device: ${error}`);
|
|
374
377
|
}
|
|
375
378
|
} else {
|
|
376
|
-
logger.warn('Ref is invalid or no longer in clientSockets.');
|
|
379
|
+
logger.warn(() => 'Ref is invalid or no longer in clientSockets.');
|
|
377
380
|
}
|
|
378
381
|
});
|
|
379
382
|
|
|
380
383
|
// Handle client socket errors
|
|
381
384
|
clientSocket.on('error', (err) => {
|
|
382
|
-
logger.error(`Client socket error: ${err}`);
|
|
385
|
+
logger.error(() => `Client socket error: ${err}`);
|
|
383
386
|
});
|
|
384
387
|
});
|
|
385
388
|
|
|
386
389
|
server.listen(localPort, () => {
|
|
387
|
-
logger.info(`Local server listening on port ${localPort} forwarding to device ${protocol} port ${targetPort}`);
|
|
390
|
+
logger.info(() => `Local server listening on port ${localPort} forwarding to device ${protocol} port ${targetPort}`);
|
|
388
391
|
});
|
|
389
392
|
|
|
390
393
|
this.servers.set(parseInt(localPort), server);
|
|
@@ -404,4 +407,4 @@ class BindPort {
|
|
|
404
407
|
}
|
|
405
408
|
}
|
|
406
409
|
|
|
407
|
-
module.exports = BindPort;
|
|
410
|
+
module.exports = BindPort;
|