node-opcua-transport 2.99.0 → 2.102.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.
Files changed (36) hide show
  1. package/dist/source/client_tcp_transport.d.ts +4 -9
  2. package/dist/source/client_tcp_transport.js +38 -71
  3. package/dist/source/client_tcp_transport.js.map +1 -1
  4. package/dist/source/server_tcp_transport.d.ts +3 -15
  5. package/dist/source/server_tcp_transport.js +40 -41
  6. package/dist/source/server_tcp_transport.js.map +1 -1
  7. package/dist/source/tcp_transport.d.ts +45 -28
  8. package/dist/source/tcp_transport.js +160 -110
  9. package/dist/source/tcp_transport.js.map +1 -1
  10. package/dist/test_helpers/ITransportPair.d.ts +7 -0
  11. package/dist/test_helpers/ITransportPair.js +3 -0
  12. package/dist/test_helpers/ITransportPair.js.map +1 -0
  13. package/dist/test_helpers/fake_server.d.ts +2 -0
  14. package/dist/test_helpers/fake_server.js +3 -0
  15. package/dist/test_helpers/fake_server.js.map +1 -1
  16. package/dist/test_helpers/half_com_channel.d.ts +17 -10
  17. package/dist/test_helpers/half_com_channel.js +63 -4
  18. package/dist/test_helpers/half_com_channel.js.map +1 -1
  19. package/dist/test_helpers/index.d.ts +2 -2
  20. package/dist/test_helpers/index.js +2 -2
  21. package/dist/test_helpers/index.js.map +1 -1
  22. package/dist/test_helpers/{direct_transport.d.ts → transport_pair_direct.d.ts} +2 -6
  23. package/dist/test_helpers/{direct_transport.js → transport_pair_direct.js} +11 -18
  24. package/dist/test_helpers/transport_pair_direct.js.map +1 -0
  25. package/dist/test_helpers/transport_pair_socket.d.ts +14 -0
  26. package/dist/test_helpers/transport_pair_socket.js +33 -0
  27. package/dist/test_helpers/transport_pair_socket.js.map +1 -0
  28. package/dist/tsconfig.tsbuildinfo +1 -1
  29. package/package.json +3 -2
  30. package/source/client_tcp_transport.ts +56 -89
  31. package/source/server_tcp_transport.ts +48 -50
  32. package/source/tcp_transport.ts +226 -157
  33. package/dist/test_helpers/direct_transport.js.map +0 -1
  34. package/dist/test_helpers/socket_transport.d.ts +0 -10
  35. package/dist/test_helpers/socket_transport.js +0 -31
  36. package/dist/test_helpers/socket_transport.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-opcua-transport",
3
- "version": "2.99.0",
3
+ "version": "2.102.0",
4
4
  "description": "pure nodejs OPCUA SDK - module transport",
5
5
  "main": "./dist/source/index.js",
6
6
  "types": "./dist/source/index.d.ts",
@@ -26,6 +26,7 @@
26
26
  "node-opcua-utils": "2.98.1"
27
27
  },
28
28
  "devDependencies": {
29
+ "node-opcua-leak-detector": "2.99.0",
29
30
  "should": "^13.2.3",
30
31
  "sinon": "^15.0.3"
31
32
  },
@@ -44,7 +45,7 @@
44
45
  "internet of things"
45
46
  ],
46
47
  "homepage": "http://node-opcua.github.io/",
47
- "gitHead": "90ce9f5b44d74198d84a384de622dfa94fd05c0c",
48
+ "gitHead": "07dcdd8e8c7f2b55544c6e23023093e35674829c",
48
49
  "files": [
49
50
  "dist",
50
51
  "source"
@@ -2,7 +2,8 @@
2
2
  * @module node-opcua-transport
3
3
  */
4
4
  import * as os from "os";
5
- import { createConnection, Socket } from "net";
5
+ import { createConnection } from "net";
6
+ import { types } from "util";
6
7
  import * as chalk from "chalk";
7
8
 
8
9
  import { assert } from "node-opcua-assert";
@@ -11,7 +12,7 @@ import { readMessageHeader } from "node-opcua-chunkmanager";
11
12
  import { ErrorCallback } from "node-opcua-status-code";
12
13
 
13
14
  import * as debug from "node-opcua-debug";
14
- import { getFakeTransport, TCP_transport } from "./tcp_transport";
15
+ import { getFakeTransport, ISocketLike, TCP_transport } from "./tcp_transport";
15
16
  import { decodeMessage, packTcpMessage, parseEndpointUrl } from "./tools";
16
17
 
17
18
  import { AcknowledgeMessage } from "./AcknowledgeMessage";
@@ -25,31 +26,27 @@ const warningLog = debug.make_warningLog(__filename);
25
26
  const errorLog = debug.make_errorLog(__filename);
26
27
  const gHostname = os.hostname();
27
28
 
28
- function createClientSocket(endpointUrl: string): Socket {
29
+ function createClientSocket(endpointUrl: string, timeout: number): ISocketLike {
29
30
  // create a socket based on Url
30
31
  const ep = parseEndpointUrl(endpointUrl);
31
32
  const port = parseInt(ep.port!, 10);
32
33
  const hostname = ep.hostname!;
33
- let socket: Socket;
34
+
35
+ let socket: ISocketLike;
34
36
  switch (ep.protocol) {
35
37
  case "opc.tcp:":
36
- socket = createConnection({ host: hostname, port });
37
-
38
- socket.setKeepAlive(true);
39
-
40
- // Setting true for noDelay will immediately fire off data each time socket.write() is called.
41
- socket.setNoDelay(true);
42
-
38
+ socket = createConnection({ host: hostname, port, timeout }, () => {
39
+ doDebug && debugLog(`connected to server! ${hostname}:${port} timeout:${timeout} `);
40
+ });
43
41
  return socket;
44
42
  case "fake:":
45
- socket = getFakeTransport();
46
43
  assert(ep.protocol === "fake:", " Unsupported transport protocol");
47
- process.nextTick(() => socket.emit("connect"));
44
+ socket = getFakeTransport();
48
45
  return socket;
49
46
 
50
47
  case "websocket:":
51
48
  case "http:":
52
- case "https:FF":
49
+ case "https:":
53
50
  default: {
54
51
  const msg = "[NODE-OPCUA-E05] this transport protocol is not supported :" + ep.protocol;
55
52
  errorLog(msg);
@@ -59,19 +56,16 @@ function createClientSocket(endpointUrl: string): Socket {
59
56
  }
60
57
  export interface ClientTCP_transport {
61
58
  on(eventName: "chunk", eventHandler: (messageChunk: Buffer) => void): this;
62
- on(eventName: "socket_closed", eventHandler: (err: Error | null) => void): this;
63
59
  on(eventName: "close", eventHandler: (err: Error | null) => void): this;
64
60
  on(eventName: "connection_break", eventHandler: () => void): this;
65
61
  on(eventName: "connect", eventHandler: () => void): this;
66
62
 
67
63
  once(eventName: "chunk", eventHandler: (messageChunk: Buffer) => void): this;
68
- once(eventName: "socket_closed", eventHandler: (err: Error | null) => void): this;
69
64
  once(eventName: "close", eventHandler: (err: Error | null) => void): this;
70
65
  once(eventName: "connection_break", eventHandler: () => void): this;
71
66
  once(eventName: "connect", eventHandler: () => void): this;
72
67
 
73
68
  emit(eventName: "chunk", messageChunk: Buffer): boolean;
74
- emit(eventName: "socket_closed", err?: Error | null): boolean;
75
69
  emit(eventName: "close", err?: Error | null): boolean;
76
70
  emit(eventName: "connection_break"): boolean;
77
71
  emit(eventName: "connect"): boolean;
@@ -99,7 +93,7 @@ export interface TransportSettingsOptions {
99
93
  *
100
94
  * transport.timeout = 10000;
101
95
  *
102
- * transport.connect(function(err)) {
96
+ * transport.connect(function (err)) {
103
97
  * if (err) {
104
98
  * // cannot connect
105
99
  * } else {
@@ -109,16 +103,16 @@ export interface TransportSettingsOptions {
109
103
  * });
110
104
  * ....
111
105
  *
112
- * transport.write(message_chunk,'F');
106
+ * transport.write(message_chunk, 'F');
113
107
  *
114
108
  * ....
115
109
  *
116
- * transport.on("chunk",function(message_chunk) {
110
+ * transport.on("chunk", function (message_chunk) {
117
111
  * // do something with chunk from server...
118
112
  * });
119
113
  *
120
114
  *
121
- * ```
115
+ * ```
122
116
  *
123
117
  *
124
118
  */
@@ -133,7 +127,6 @@ export class ClientTCP_transport extends TCP_transport {
133
127
  public numberOfRetry: number;
134
128
  public parameters?: AcknowledgeMessage;
135
129
 
136
- private connected: boolean;
137
130
  private _counter: number;
138
131
  private _helloSettings: {
139
132
  maxChunkCount: number;
@@ -143,7 +136,6 @@ export class ClientTCP_transport extends TCP_transport {
143
136
  };
144
137
  constructor(transportSettings?: TransportSettingsOptions) {
145
138
  super();
146
- this.connected = false;
147
139
  this.endpointUrl = "";
148
140
  this.serverUri = "";
149
141
  this._counter = 0;
@@ -169,9 +161,8 @@ export class ClientTCP_transport extends TCP_transport {
169
161
 
170
162
  public dispose(): void {
171
163
  /* istanbul ignore next */
172
- if (doDebug) {
173
- debugLog(" ClientTCP_transport disposed");
174
- }
164
+ doDebug && debugLog(" ClientTCP_transport disposed");
165
+
175
166
  super.dispose();
176
167
  }
177
168
 
@@ -185,24 +176,25 @@ export class ClientTCP_transport extends TCP_transport {
185
176
 
186
177
  this.serverUri = "urn:" + gHostname + ":Sample";
187
178
  /* istanbul ignore next */
188
- if (doDebug) {
189
- debugLog(chalk.cyan("ClientTCP_transport#connect(endpointUrl = " + endpointUrl + ")"));
190
- }
179
+ doDebug && debugLog(chalk.cyan("ClientTCP_transport#connect(endpointUrl = " + endpointUrl + ")"));
180
+
181
+ let socket: ISocketLike | null = null;
191
182
  try {
192
- this._socket = createClientSocket(endpointUrl);
183
+ socket = createClientSocket(endpointUrl, this.timeout);
193
184
  } catch (err) {
194
185
  /* istanbul ignore next */
195
- if (doDebug) {
196
- debugLog("CreateClientSocket has failed");
197
- }
186
+ doDebug && debugLog("CreateClientSocket has failed");
187
+
198
188
  return callback(err as Error);
199
189
  }
200
190
 
191
+ /**
192
+ *
193
+ */
201
194
  const _on_socket_error_after_connection = (err: Error) => {
202
195
  /* istanbul ignore next */
203
- if (doDebug) {
204
- debugLog(" _on_socket_error_after_connection ClientTCP_transport Socket Error", err.message);
205
- }
196
+ doDebug && debugLog(" _on_socket_error_after_connection ClientTCP_transport Socket Error", err.message);
197
+
206
198
  // EPIPE : EPIPE (Broken pipe): A write on a pipe, socket, or FIFO for which there is no process to read the
207
199
  // data. Commonly encountered at the net and http layers, indicative that the remote side of the stream
208
200
  // being written to has been closed.
@@ -210,7 +202,11 @@ export class ClientTCP_transport extends TCP_transport {
210
202
  // ECONNRESET (Connection reset by peer): A connection was forcibly closed by a peer. This normally results
211
203
  // from a loss of the connection on the remote socket due to a timeout or reboot. Commonly encountered
212
204
  // via the http and net module
213
- if (err.message.match(/ECONNRESET|EPIPE/)) {
205
+
206
+ // socket termination could happen:
207
+ // * when the socket times out (lost of connection, network outage, etc...)
208
+ // * or, when the server abruptly disconnects the socket ( in case of invalid communication for instance)
209
+ if (err.message.match(/ECONNRESET|EPIPE|premature socket termination/)) {
214
210
  /**
215
211
  * @event connection_break
216
212
  *
@@ -221,11 +217,10 @@ export class ClientTCP_transport extends TCP_transport {
221
217
 
222
218
  const _on_socket_connect = () => {
223
219
  /* istanbul ignore next */
224
- if (doDebug) {
225
- debugLog("entering _on_socket_connect");
226
- }
220
+ doDebug && debugLog("entering _on_socket_connect");
221
+
227
222
  _remove_connect_listeners();
228
- this._perform_HEL_ACK_transaction((err?: Error) => {
223
+ this._perform_HEL_ACK_transaction((err) => {
229
224
  if (!err) {
230
225
  /* istanbul ignore next */
231
226
  if (!this._socket) {
@@ -234,7 +229,6 @@ export class ClientTCP_transport extends TCP_transport {
234
229
  // install error handler to detect connection break
235
230
  this._socket.on("error", _on_socket_error_after_connection);
236
231
 
237
- this.connected = true;
238
232
  /**
239
233
  * notify the observers that the transport is connected (the socket is connected and the the HEL/ACK
240
234
  * transaction has been done)
@@ -252,22 +246,16 @@ export class ClientTCP_transport extends TCP_transport {
252
246
  const _on_socket_error_for_connect = (err: Error) => {
253
247
  // this handler will catch attempt to connect to an inaccessible address.
254
248
  /* istanbul ignore next */
255
- if (doDebug) {
256
- debugLog(chalk.cyan("ClientTCP_transport#connect - _on_socket_error_for_connect"), err.message);
257
- }
258
- assert(err instanceof Error);
249
+ doDebug && debugLog(chalk.cyan("ClientTCP_transport#connect - _on_socket_error_for_connect"), err.message);
250
+ assert(types.isNativeError(err));
259
251
  _remove_connect_listeners();
260
252
  callback(err);
261
253
  };
262
254
 
263
- const _on_socket_end_for_connect = (err: Error | null) => {
255
+ const _on_socket_end_for_connect = () => {
264
256
  /* istanbul ignore next */
265
- if (doDebug) {
266
- debugLog(
267
- chalk.cyan("ClientTCP_transport#connect -> _on_socket_end_for_connect Socket has been closed by server"),
268
- err
269
- );
270
- }
257
+ doDebug &&
258
+ debugLog(chalk.cyan("ClientTCP_transport#connect -> _on_socket_end_for_connect Socket has been closed by server"));
271
259
  };
272
260
 
273
261
  const _remove_connect_listeners = () => {
@@ -279,21 +267,11 @@ export class ClientTCP_transport extends TCP_transport {
279
267
  this._socket.removeListener("end", _on_socket_end_for_connect);
280
268
  };
281
269
 
282
- this._socket.once("error", _on_socket_error_for_connect);
283
- this._socket.once("end", _on_socket_end_for_connect);
284
- this._socket.once("connect", _on_socket_connect);
270
+ this._install_socket(socket);
285
271
 
286
- this._install_socket(this._socket);
287
- }
288
-
289
- protected on_socket_ended(err: Error | null): void {
290
- debugLog("on_socket_ended", this.name, err ? err.message : "");
291
- if (this.connected) {
292
- super.on_socket_ended(err);
293
- }
294
- // if (this._socket) {
295
- // this._socket.removeAllListeners();
296
- // }
272
+ this._socket!.once("error", _on_socket_error_for_connect);
273
+ this._socket!.once("end", _on_socket_end_for_connect);
274
+ this._socket!.once("connect", _on_socket_connect);
297
275
  }
298
276
 
299
277
  private _handle_ACK_response(messageChunk: Buffer, callback: ErrorCallback) {
@@ -317,9 +295,8 @@ export class ClientTCP_transport extends TCP_transport {
317
295
  err = new Error("ACK: ERR received " + response.statusCode.toString() + " : " + response.reason);
318
296
  (err as any).statusCode = response.statusCode;
319
297
  // istanbul ignore next
320
- if (doTraceHelloAck) {
321
- warningLog("receiving ERR instead of Ack", response.toString());
322
- }
298
+ doTraceHelloAck && warningLog("receiving ERR instead of Ack", response.toString());
299
+
323
300
  callback(err);
324
301
  } else {
325
302
  responseClass = AcknowledgeMessage;
@@ -330,9 +307,7 @@ export class ClientTCP_transport extends TCP_transport {
330
307
  this.setLimits(response as AcknowledgeMessage);
331
308
 
332
309
  // istanbul ignore next
333
- if (doTraceHelloAck) {
334
- warningLog("receiving Ack\n", response.toString());
335
- }
310
+ doTraceHelloAck && warningLog("receiving Ack\n", response.toString());
336
311
 
337
312
  callback();
338
313
  }
@@ -340,9 +315,8 @@ export class ClientTCP_transport extends TCP_transport {
340
315
 
341
316
  private _send_HELLO_request() {
342
317
  /* istanbul ignore next */
343
- if (doDebug) {
344
- debugLog("entering _send_HELLO_request");
345
- }
318
+ doDebug && debugLog("entering _send_HELLO_request");
319
+
346
320
  assert(this._socket);
347
321
  assert(isFinite(this.protocolVersion));
348
322
  assert(this.endpointUrl.length > 0, " expecting a valid endpoint url");
@@ -360,9 +334,7 @@ export class ClientTCP_transport extends TCP_transport {
360
334
  sendBufferSize
361
335
  });
362
336
  // istanbul ignore next
363
- if (doTraceHelloAck) {
364
- warningLog(`sending Hello\n ${helloMessage.toString()}`);
365
- }
337
+ doTraceHelloAck && warningLog(`sending Hello\n ${helloMessage.toString()} `);
366
338
 
367
339
  const messageChunk = packTcpMessage("HEL", helloMessage);
368
340
  this._write_chunk(messageChunk);
@@ -370,9 +342,7 @@ export class ClientTCP_transport extends TCP_transport {
370
342
 
371
343
  private _on_ACK_response(externalCallback: ErrorCallback, err: Error | null, data?: Buffer) {
372
344
  /* istanbul ignore next */
373
- if (doDebug) {
374
- debugLog("entering _on_ACK_response");
375
- }
345
+ doDebug && debugLog("entering _on_ACK_response");
376
346
 
377
347
  assert(typeof externalCallback === "function");
378
348
  assert(this._counter === 0, "Ack response should only be received once !");
@@ -382,7 +352,6 @@ export class ClientTCP_transport extends TCP_transport {
382
352
  externalCallback(err || new Error("no data"));
383
353
  if (this._socket) {
384
354
  this._socket.end();
385
- // Xx this._socket.removeAllListeners();
386
355
  }
387
356
  } else {
388
357
  this._handle_ACK_response(data, externalCallback);
@@ -398,14 +367,12 @@ export class ClientTCP_transport extends TCP_transport {
398
367
  assert(typeof callback === "function");
399
368
  this._counter = 0;
400
369
  /* istanbul ignore next */
401
- if (doDebug) {
402
- debugLog("entering _perform_HEL_ACK_transaction");
403
- }
370
+ doDebug && debugLog("entering _perform_HEL_ACK_transaction");
371
+
404
372
  this._install_one_time_message_receiver((err: Error | null, data?: Buffer) => {
405
373
  /* istanbul ignore next */
406
- if (doDebug) {
407
- debugLog("before _on_ACK_response ", err ? err.message : "");
408
- }
374
+ doDebug && debugLog("before _on_ACK_response ", err ? err.message : "");
375
+
409
376
  this._on_ACK_response(callback, err, data);
410
377
  });
411
378
  this._send_HELLO_request();
@@ -4,6 +4,7 @@
4
4
  // tslint:disable:class-name
5
5
  // system
6
6
  import { Socket } from "net";
7
+ import { types } from "util";
7
8
  import * as chalk from "chalk";
8
9
  import { assert } from "node-opcua-assert";
9
10
 
@@ -17,16 +18,15 @@ import { ErrorCallback } from "node-opcua-status-code";
17
18
  // this package requires
18
19
  import { AcknowledgeMessage } from "./AcknowledgeMessage";
19
20
  import { HelloMessage } from "./HelloMessage";
20
- import { TCP_transport } from "./tcp_transport";
21
+ import { ISocketLike, TCP_transport } from "./tcp_transport";
21
22
  import { decodeMessage, packTcpMessage } from "./tools";
22
23
  import { doTraceHelloAck } from "./utils";
23
24
 
24
25
  const hexDump = debug.hexDump;
25
- const debugLog = debug.make_debugLog(__filename);
26
- const errorLog = debug.make_errorLog(__filename);
27
- const doDebug = debug.checkDebugFlag(__filename);
28
-
29
- type CallbackFunc = (err: null | Error) => void;
26
+ const debugLog = debug.make_debugLog("TRANSPORT");
27
+ const errorLog = debug.make_errorLog("TRANSPORT");
28
+ const warningLog = debug.make_warningLog("TRANSPORT");
29
+ const doDebug = debug.checkDebugFlag("TRANSPORT");
30
30
 
31
31
  function clamp_value(value: number, minVal: number, maxVal: number): number {
32
32
  assert(minVal < maxVal);
@@ -45,12 +45,6 @@ function clamp_value(value: number, minVal: number, maxVal: number): number {
45
45
 
46
46
  const minimumBufferSize = 8192;
47
47
 
48
- /**
49
- * @class ServerTCP_transport
50
- * @extends TCP_transport
51
- * @constructor
52
- *
53
- */
54
48
  export class ServerTCP_transport extends TCP_transport {
55
49
  public static throttleTime = 1000;
56
50
 
@@ -68,6 +62,13 @@ export class ServerTCP_transport extends TCP_transport {
68
62
  this.receiveBufferSize = 4 * 1024;
69
63
  }
70
64
 
65
+ public toString() {
66
+ let str = super.toString();
67
+ str += "helloReceived...... = " + this._helloReceived + "\n";
68
+ str += "aborted............ = " + this._aborted + "\n";
69
+ return str;
70
+ }
71
+
71
72
  protected _write_chunk(messageChunk: Buffer): void {
72
73
  // istanbul ignore next
73
74
  if (this.sendBufferSize > 0 && messageChunk.length > this.sendBufferSize) {
@@ -78,9 +79,9 @@ export class ServerTCP_transport extends TCP_transport {
78
79
  this.sendBufferSize
79
80
  );
80
81
  }
81
-
82
82
  super._write_chunk(messageChunk);
83
83
  }
84
+
84
85
  /**
85
86
  * Initialize the server transport.
86
87
  *
@@ -97,10 +98,11 @@ export class ServerTCP_transport extends TCP_transport {
97
98
  *
98
99
  *
99
100
  */
100
- public init(socket: Socket, callback: ErrorCallback): void {
101
- if (debugLog) {
102
- debugLog(chalk.cyan("init socket"));
103
- }
101
+ public init(socket: ISocketLike, callback: ErrorCallback): void {
102
+ assert(socket, "missing called!");
103
+ // istanbul ignore next
104
+ debugLog && debugLog(chalk.cyan("init socket"));
105
+
104
106
  assert(!this._socket, "init already called!");
105
107
  assert(typeof callback === "function", "expecting a valid callback ");
106
108
 
@@ -108,30 +110,28 @@ export class ServerTCP_transport extends TCP_transport {
108
110
  this._install_HEL_message_receiver(callback);
109
111
  }
110
112
 
111
- public abortWithError(statusCode: StatusCode, extraErrorDescription: string, callback: ErrorCallback): void {
112
- return this._abortWithError(statusCode, extraErrorDescription, callback);
113
- }
114
-
115
113
  private _abortWithError(statusCode: StatusCode, extraErrorDescription: string, callback: ErrorCallback): void {
116
114
  // When a fatal error occurs, the Server shall send an Error Message to the Client and
117
115
  // closes the TransportConnection gracefully.
118
- doDebug && debugLog(chalk.cyan("_abortWithError"));
116
+ doDebug && debugLog(this.name, chalk.cyan("_abortWithError", statusCode.toString(), extraErrorDescription));
119
117
 
120
118
  /* istanbul ignore next */
121
119
  if (this._aborted) {
120
+ errorLog("Internal Er!ror: _abortWithError already called! Should not happen here");
122
121
  // already called
123
122
  return callback(new Error(statusCode.name));
124
123
  }
125
124
  this._aborted = 1;
126
125
 
126
+ this._socket?.setTimeout(0);
127
+ const err = new Error(extraErrorDescription + " StatusCode = " + statusCode.name);
128
+ this._theCloseError = err;
127
129
  setTimeout(() => {
128
130
  // send the error message and close the connection
129
131
  this.sendErrorMessage(statusCode, statusCode.description);
130
-
131
- this.disconnect(() => {
132
- this._aborted = 2;
133
- callback(new Error(extraErrorDescription + " StatusCode = " + statusCode.name));
134
- });
132
+ this.prematureTerminate(err, statusCode);
133
+ this._emitClose(err);
134
+ callback(err);
135
135
  }, ServerTCP_transport.throttleTime);
136
136
  }
137
137
 
@@ -179,11 +179,12 @@ export class ServerTCP_transport extends TCP_transport {
179
179
 
180
180
  // istanbul ignore next
181
181
  if (doTraceHelloAck) {
182
- console.log(`received Hello \n${helloMessage.toString()}`);
183
- console.log("Client accepts only message of size => ", this.maxMessageSize);
182
+ warningLog(`received Hello \n${helloMessage.toString()}`);
183
+ warningLog("Client accepts only message of size => ", this.maxMessageSize);
184
184
  }
185
185
 
186
- debugLog("Client accepts only message of size => ", this.maxMessageSize);
186
+ // istanbul ignore next
187
+ doDebug && debugLog("Client accepts only message of size => ", this.maxMessageSize);
187
188
 
188
189
  const acknowledgeMessage = new AcknowledgeMessage({
189
190
  maxChunkCount: this.maxChunkCount,
@@ -194,9 +195,7 @@ export class ServerTCP_transport extends TCP_transport {
194
195
  });
195
196
 
196
197
  // istanbul ignore next
197
- if (doTraceHelloAck) {
198
- console.log(`sending Ack \n${acknowledgeMessage.toString()}`);
199
- }
198
+ doTraceHelloAck && warningLog(`sending Ack \n${acknowledgeMessage.toString()}`);
200
199
 
201
200
  const messageChunk = packTcpMessage("ACK", acknowledgeMessage);
202
201
 
@@ -213,12 +212,12 @@ export class ServerTCP_transport extends TCP_transport {
213
212
  }
214
213
 
215
214
  private _install_HEL_message_receiver(callback: ErrorCallback): void {
216
- if (debugLog) {
217
- debugLog(chalk.cyan("_install_HEL_message_receiver "));
218
- }
215
+ // istanbul ignore next
216
+ doDebug && debugLog(chalk.cyan("_install_HEL_message_receiver "));
217
+
219
218
  this._install_one_time_message_receiver((err?: Error | null, data?: Buffer) => {
220
219
  if (err) {
221
- this._abortWithError(StatusCodes.BadConnectionRejected, err.message, callback);
220
+ callback(err);
222
221
  } else {
223
222
  // handle the HEL message
224
223
  this._on_HEL_message(data!, callback);
@@ -227,9 +226,9 @@ export class ServerTCP_transport extends TCP_transport {
227
226
  }
228
227
 
229
228
  private _on_HEL_message(data: Buffer, callback: ErrorCallback): void {
230
- if (debugLog) {
231
- debugLog(chalk.cyan("_on_HEL_message"));
232
- }
229
+ // istanbul ignore next
230
+ doDebug && debugLog(chalk.cyan("_on_HEL_message"));
231
+
233
232
  assert(!this._helloReceived);
234
233
  const stream = new BinaryStream(data);
235
234
  const msgType = data.subarray(0, 3).toString("utf-8");
@@ -244,16 +243,17 @@ export class ServerTCP_transport extends TCP_transport {
244
243
  try {
245
244
  assert(data.length >= 24);
246
245
  const helloMessage = decodeMessage(stream, HelloMessage) as HelloMessage;
247
- assert(isFinite(this.protocolVersion));
248
246
 
249
247
  // OPCUA Spec 1.03 part 6 - page 41
250
248
  // The Server shall always accept versions greater than what it supports.
251
249
  if (helloMessage.protocolVersion !== this.protocolVersion) {
252
- debugLog(
253
- `warning ! client sent helloMessage.protocolVersion = ` +
254
- ` 0x${helloMessage.protocolVersion.toString(16)} ` +
255
- `whereas server protocolVersion is 0x${this.protocolVersion.toString(16)}`
256
- );
250
+ // istanbul ignore next
251
+ doDebug &&
252
+ debugLog(
253
+ `warning ! client sent helloMessage.protocolVersion = ` +
254
+ ` 0x${helloMessage.protocolVersion.toString(16)} ` +
255
+ `whereas server protocolVersion is 0x${this.protocolVersion.toString(16)}`
256
+ );
257
257
  }
258
258
 
259
259
  if (helloMessage.protocolVersion === 0xdeadbeef || helloMessage.protocolVersion < this.protocolVersion) {
@@ -283,15 +283,13 @@ export class ServerTCP_transport extends TCP_transport {
283
283
  this._send_ACK_response(helloMessage);
284
284
  } catch (err) {
285
285
  // connection rejected because of malformed message
286
- return this._abortWithError(StatusCodes.BadConnectionRejected, err instanceof Error ? err.message : "", callback);
286
+ return this._abortWithError(StatusCodes.BadConnectionRejected, types.isNativeError(err) ? err.message : "", callback);
287
287
  }
288
288
  callback(); // no Error
289
289
  } else {
290
290
  // invalid packet , expecting HEL
291
291
  /* istanbul ignore next*/
292
- if (doDebug) {
293
- debugLog(chalk.red("BadCommunicationError ") + "Expecting 'HEL' message to initiate communication");
294
- }
292
+ doDebug && debugLog(chalk.red("BadCommunicationError ") + "Expecting 'HEL' message to initiate communication");
295
293
  this._abortWithError(StatusCodes.BadCommunicationError, "Expecting 'HEL' message to initiate communication", callback);
296
294
  }
297
295
  }