node-opcua-server 2.163.1 → 2.164.2
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/dist/addressSpace_accessor.js +7 -5
- package/dist/addressSpace_accessor.js.map +1 -1
- package/dist/base_server.js +6 -6
- package/dist/base_server.js.map +1 -1
- package/dist/monitored_item.js +32 -32
- package/dist/monitored_item.js.map +1 -1
- package/dist/node_sampler.js +1 -1
- package/dist/node_sampler.js.map +1 -1
- package/dist/opcua_server.js +48 -43
- package/dist/opcua_server.js.map +1 -1
- package/dist/register_server_manager.d.ts +2 -2
- package/dist/register_server_manager.js +12 -6
- package/dist/register_server_manager.js.map +1 -1
- package/dist/register_server_manager_mdns_only.js +1 -1
- package/dist/register_server_manager_mdns_only.js.map +1 -1
- package/dist/server_end_point.js +11 -11
- package/dist/server_end_point.js.map +1 -1
- package/dist/server_engine.js +6 -6
- package/dist/server_engine.js.map +1 -1
- package/dist/server_publish_engine.js +5 -5
- package/dist/server_publish_engine.js.map +1 -1
- package/dist/server_session.js +4 -4
- package/dist/server_session.js.map +1 -1
- package/dist/server_subscription.js +18 -18
- package/dist/server_subscription.js.map +1 -1
- package/dist/sessions_compatible_for_transfer.js +1 -1
- package/dist/sessions_compatible_for_transfer.js.map +1 -1
- package/package.json +47 -47
- package/source/addressSpace_accessor.ts +6 -3
- package/source/base_server.ts +7 -7
- package/source/monitored_item.ts +32 -32
- package/source/node_sampler.ts +1 -1
- package/source/opcua_server.ts +54 -49
- package/source/register_server_manager.ts +11 -5
- package/source/register_server_manager_mdns_only.ts +1 -1
- package/source/server_end_point.ts +11 -11
- package/source/server_engine.ts +15 -14
- package/source/server_publish_engine.ts +5 -5
- package/source/server_session.ts +4 -4
- package/source/server_subscription.ts +18 -18
- package/source/sessions_compatible_for_transfer.ts +4 -2
package/source/opcua_server.ts
CHANGED
|
@@ -449,7 +449,7 @@ function build_scanning_node_function(addressSpace: AddressSpace, itemToMonitor:
|
|
|
449
449
|
|
|
450
450
|
const node = addressSpace.findNode(itemToMonitor.nodeId) as UAVariable;
|
|
451
451
|
|
|
452
|
-
/*
|
|
452
|
+
/* c8 ignore next */
|
|
453
453
|
if (!node) {
|
|
454
454
|
errorLog(" INVALID NODE ID , ", itemToMonitor.nodeId.toString());
|
|
455
455
|
dump(itemToMonitor);
|
|
@@ -523,7 +523,7 @@ function _installRegisterServerManager(self: OPCUAServer) {
|
|
|
523
523
|
assert(self instanceof OPCUAServer);
|
|
524
524
|
assert(!self.registerServerManager);
|
|
525
525
|
|
|
526
|
-
/*
|
|
526
|
+
/* c8 ignore next */
|
|
527
527
|
if (!self.registerServerMethod) {
|
|
528
528
|
throw new Error("Internal Error");
|
|
529
529
|
}
|
|
@@ -545,7 +545,7 @@ function _installRegisterServerManager(self: OPCUAServer) {
|
|
|
545
545
|
server: self
|
|
546
546
|
});
|
|
547
547
|
break;
|
|
548
|
-
/*
|
|
548
|
+
/* c8 ignore next */
|
|
549
549
|
default:
|
|
550
550
|
throw new Error("Invalid switch");
|
|
551
551
|
}
|
|
@@ -604,7 +604,7 @@ function validate_applicationUri(channel: ServerSecureChannelLayer, request: Cre
|
|
|
604
604
|
const applicationUriFromCert =
|
|
605
605
|
uniformResourceIdentifier && uniformResourceIdentifier.length > 0 ? uniformResourceIdentifier[0] : null;
|
|
606
606
|
|
|
607
|
-
/*
|
|
607
|
+
/* c8 ignore next */
|
|
608
608
|
if (applicationUriFromCert !== applicationUri) {
|
|
609
609
|
errorLog("BadCertificateUriInvalid!");
|
|
610
610
|
errorLog("applicationUri = ", applicationUri);
|
|
@@ -1167,7 +1167,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1167
1167
|
// note: we need to delay initialization of endpoint as certain resources
|
|
1168
1168
|
// such as %FQDN% might not be ready yet at this stage
|
|
1169
1169
|
this._delayInit = async () => {
|
|
1170
|
-
/*
|
|
1170
|
+
/* c8 ignore next */
|
|
1171
1171
|
if (!options) {
|
|
1172
1172
|
throw new Error("Internal Error");
|
|
1173
1173
|
}
|
|
@@ -1267,7 +1267,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1267
1267
|
assert(!this.initialized, "server is already initialized"); // already initialized ?
|
|
1268
1268
|
|
|
1269
1269
|
this._preInitTask.push(async () => {
|
|
1270
|
-
/*
|
|
1270
|
+
/* c8 ignore next */
|
|
1271
1271
|
if (this._delayInit) {
|
|
1272
1272
|
await this._delayInit();
|
|
1273
1273
|
this._delayInit = undefined;
|
|
@@ -1362,7 +1362,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1362
1362
|
assert(typeof callback === "function");
|
|
1363
1363
|
debugLog("OPCUAServer#shutdown (timeout = ", timeout, ")");
|
|
1364
1364
|
|
|
1365
|
-
/*
|
|
1365
|
+
/* c8 ignore next */
|
|
1366
1366
|
if (!this.engine) {
|
|
1367
1367
|
return callback();
|
|
1368
1368
|
}
|
|
@@ -1419,7 +1419,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1419
1419
|
}
|
|
1420
1420
|
OPCUAServer.registry.unregister(this);
|
|
1421
1421
|
|
|
1422
|
-
/*
|
|
1422
|
+
/* c8 ignore next */
|
|
1423
1423
|
if (this.engine) {
|
|
1424
1424
|
this.engine.dispose();
|
|
1425
1425
|
}
|
|
@@ -1439,7 +1439,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1439
1439
|
public raiseEvent(eventType: "AuditCertificateMismatchEventType", options: RaiseAuditCertificateMismatchEventData): void;
|
|
1440
1440
|
|
|
1441
1441
|
public raiseEvent(eventType: EventTypeLike | UAObjectType, options: RaiseEventData): void {
|
|
1442
|
-
/*
|
|
1442
|
+
/* c8 ignore next */
|
|
1443
1443
|
if (!this.engine.addressSpace) {
|
|
1444
1444
|
errorLog("addressSpace missing");
|
|
1445
1445
|
return;
|
|
@@ -1447,7 +1447,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1447
1447
|
|
|
1448
1448
|
const server = this.engine.addressSpace.findNode("Server") as UAObject;
|
|
1449
1449
|
|
|
1450
|
-
/*
|
|
1450
|
+
/* c8 ignore next */
|
|
1451
1451
|
if (!server) {
|
|
1452
1452
|
// xx throw new Error("OPCUAServer#raiseEvent : cannot find Server object");
|
|
1453
1453
|
return;
|
|
@@ -1471,7 +1471,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1471
1471
|
* @private
|
|
1472
1472
|
*/
|
|
1473
1473
|
protected createSession(options: CreateSessionOption): ServerSession {
|
|
1474
|
-
/*
|
|
1474
|
+
/* c8 ignore next */
|
|
1475
1475
|
if (!this.engine) {
|
|
1476
1476
|
throw new Error("Internal Error");
|
|
1477
1477
|
}
|
|
@@ -1535,12 +1535,12 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1535
1535
|
}
|
|
1536
1536
|
const cryptoFactory = getCryptoFactory(securityPolicy);
|
|
1537
1537
|
|
|
1538
|
-
/*
|
|
1538
|
+
/* c8 ignore next */
|
|
1539
1539
|
if (!cryptoFactory) {
|
|
1540
1540
|
return callback(null, StatusCodes.BadSecurityPolicyRejected);
|
|
1541
1541
|
}
|
|
1542
1542
|
|
|
1543
|
-
/*
|
|
1543
|
+
/* c8 ignore next */
|
|
1544
1544
|
if (userIdentityToken.encryptionAlgorithm !== cryptoFactory.asymmetricEncryptionAlgorithm) {
|
|
1545
1545
|
errorLog("invalid encryptionAlgorithm");
|
|
1546
1546
|
errorLog("userTokenPolicy", userTokenPolicy.toString());
|
|
@@ -1569,7 +1569,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1569
1569
|
const securityPolicy = adjustSecurityPolicy(channel, userTokenPolicy.securityPolicyUri);
|
|
1570
1570
|
|
|
1571
1571
|
const cryptoFactory = getCryptoFactory(securityPolicy);
|
|
1572
|
-
/*
|
|
1572
|
+
/* c8 ignore next */
|
|
1573
1573
|
if (!cryptoFactory) {
|
|
1574
1574
|
return callback(null, StatusCodes.BadSecurityPolicyRejected);
|
|
1575
1575
|
}
|
|
@@ -1602,7 +1602,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1602
1602
|
|
|
1603
1603
|
// verify if certificate is Valid
|
|
1604
1604
|
this.userCertificateManager!.checkCertificate(certificate, (err, certificateStatus) => {
|
|
1605
|
-
/*
|
|
1605
|
+
/* c8 ignore next */
|
|
1606
1606
|
if (err) {
|
|
1607
1607
|
return callback(err);
|
|
1608
1608
|
}
|
|
@@ -1702,7 +1702,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1702
1702
|
assert(serverNonce instanceof Buffer);
|
|
1703
1703
|
|
|
1704
1704
|
const cryptoFactory = getCryptoFactory(securityPolicy);
|
|
1705
|
-
/*
|
|
1705
|
+
/* c8 ignore next */
|
|
1706
1706
|
if (!cryptoFactory) {
|
|
1707
1707
|
return callback(new Error(" Unsupported security Policy"));
|
|
1708
1708
|
}
|
|
@@ -1737,7 +1737,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1737
1737
|
callback: (err: Error | null, statusCode?: StatusCode) => void
|
|
1738
1738
|
): void {
|
|
1739
1739
|
assert(typeof callback === "function");
|
|
1740
|
-
/*
|
|
1740
|
+
/* c8 ignore next */
|
|
1741
1741
|
if (!userIdentityToken) {
|
|
1742
1742
|
throw new Error("Invalid token");
|
|
1743
1743
|
}
|
|
@@ -1794,7 +1794,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1794
1794
|
|
|
1795
1795
|
const userTokenType = getTokenType(userIdentityToken);
|
|
1796
1796
|
const userTokenPolicy = findUserTokenByPolicy(session.getEndpointDescription(), userTokenType, userIdentityToken.policyId!);
|
|
1797
|
-
/**
|
|
1797
|
+
/** c8 ignore next */
|
|
1798
1798
|
if (!userTokenPolicy) {
|
|
1799
1799
|
return callback(null, false);
|
|
1800
1800
|
}
|
|
@@ -2108,7 +2108,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
2108
2108
|
|
|
2109
2109
|
let response;
|
|
2110
2110
|
|
|
2111
|
-
/*
|
|
2111
|
+
/* c8 ignore next */
|
|
2112
2112
|
if (!session) {
|
|
2113
2113
|
// this may happen when the server has been restarted and a client tries to reconnect, thinking
|
|
2114
2114
|
// that the previous session may still be active
|
|
@@ -2190,7 +2190,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
2190
2190
|
session.endpoint!,
|
|
2191
2191
|
(err: Error | null, statusCode?: StatusCode) => {
|
|
2192
2192
|
if (!statusCode || statusCode.isNotGood()) {
|
|
2193
|
-
/*
|
|
2193
|
+
/* c8 ignore next */
|
|
2194
2194
|
if (!(statusCode && statusCode instanceof StatusCode)) {
|
|
2195
2195
|
return rejectConnection(this, StatusCodes.BadCertificateInvalid);
|
|
2196
2196
|
}
|
|
@@ -2203,7 +2203,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
2203
2203
|
session,
|
|
2204
2204
|
request.userIdentityToken as UserIdentityToken,
|
|
2205
2205
|
(err1: Error | null, authorized?: boolean) => {
|
|
2206
|
-
/*
|
|
2206
|
+
/* c8 ignore next */
|
|
2207
2207
|
if (err1) {
|
|
2208
2208
|
return rejectConnection(this, StatusCodes.BadInternalError);
|
|
2209
2209
|
}
|
|
@@ -2261,13 +2261,18 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
2261
2261
|
// --- check that provided session matches session attached to channel
|
|
2262
2262
|
if (channel.channelId !== session.channelId) {
|
|
2263
2263
|
if (!(request instanceof ActivateSessionRequest)) {
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2264
|
+
// Note: PublishRequests arriving on the new channel before
|
|
2265
|
+
// ActivateSession completes the session transfer are expected
|
|
2266
|
+
// transient occurrences, not errors worth logging.
|
|
2267
|
+
if (request.constructor.name !== "PublishRequest") {
|
|
2268
|
+
errorLog(
|
|
2269
|
+
chalk.red.bgWhite(
|
|
2270
|
+
"ERROR: channel.channelId !== session.channelId on processing request " + request.constructor.name
|
|
2271
|
+
),
|
|
2272
|
+
channel.channelId,
|
|
2273
|
+
session.channelId
|
|
2274
|
+
);
|
|
2275
|
+
}
|
|
2271
2276
|
}
|
|
2272
2277
|
message.session_statusCode = StatusCodes.BadSecureChannelIdInvalid;
|
|
2273
2278
|
} else if (channel_has_session(channel, session)) {
|
|
@@ -2315,9 +2320,9 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
2315
2320
|
return channel.send_response("MSG", response1, message);
|
|
2316
2321
|
} catch (err) {
|
|
2317
2322
|
warningLog(err);
|
|
2318
|
-
//
|
|
2323
|
+
// c8 ignore next
|
|
2319
2324
|
if (types.isNativeError(err)) {
|
|
2320
|
-
//
|
|
2325
|
+
// c8 ignore next
|
|
2321
2326
|
errorLog(
|
|
2322
2327
|
"Internal error in issuing response\nplease contact support@sterfive.com",
|
|
2323
2328
|
message.request.toString(),
|
|
@@ -2325,7 +2330,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
2325
2330
|
response1.toString()
|
|
2326
2331
|
);
|
|
2327
2332
|
}
|
|
2328
|
-
//
|
|
2333
|
+
// c8 ignore next
|
|
2329
2334
|
throw err;
|
|
2330
2335
|
}
|
|
2331
2336
|
}
|
|
@@ -2338,7 +2343,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
2338
2343
|
}
|
|
2339
2344
|
|
|
2340
2345
|
let response: any;
|
|
2341
|
-
/*
|
|
2346
|
+
/* c8 ignore next */
|
|
2342
2347
|
if (!message.session || message.session_statusCode !== StatusCodes.Good) {
|
|
2343
2348
|
const errMessage = "=>" + message.session_statusCode?.toString();
|
|
2344
2349
|
response = new ServiceFault({ responseHeader: { serviceResult: message.session_statusCode } });
|
|
@@ -2483,7 +2488,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
2483
2488
|
message,
|
|
2484
2489
|
channel,
|
|
2485
2490
|
async (session: ServerSession, subscriptionId: number) => {
|
|
2486
|
-
/*
|
|
2491
|
+
/* c8 ignore next */
|
|
2487
2492
|
if (isSubscriptionIdInvalid(subscriptionId)) {
|
|
2488
2493
|
return StatusCodes.BadSubscriptionIdInvalid;
|
|
2489
2494
|
}
|
|
@@ -2915,7 +2920,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
2915
2920
|
channel,
|
|
2916
2921
|
async (session: ServerSession, subscriptionId: number) => {
|
|
2917
2922
|
let subscription = this.engine.findOrphanSubscription(subscriptionId);
|
|
2918
|
-
//
|
|
2923
|
+
// c8 ignore next
|
|
2919
2924
|
if (subscription) {
|
|
2920
2925
|
warningLog("Deleting an orphan subscription", subscriptionId);
|
|
2921
2926
|
|
|
@@ -3078,7 +3083,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3078
3083
|
return sendError(StatusCodes.BadNothingToDo);
|
|
3079
3084
|
}
|
|
3080
3085
|
|
|
3081
|
-
/*
|
|
3086
|
+
/* c8 ignore next */
|
|
3082
3087
|
if (this.engine.serverCapabilities.operationLimits.maxMonitoredItemsPerCall > 0) {
|
|
3083
3088
|
if (request.itemsToModify.length > this.engine.serverCapabilities.operationLimits.maxMonitoredItemsPerCall) {
|
|
3084
3089
|
return sendError(StatusCodes.BadTooManyOperations);
|
|
@@ -3157,12 +3162,12 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3157
3162
|
sendResponse: (response: Response) => void,
|
|
3158
3163
|
sendError: (statusCode: StatusCode) => void
|
|
3159
3164
|
) => {
|
|
3160
|
-
/*
|
|
3165
|
+
/* c8 ignore next */
|
|
3161
3166
|
if (!request.monitoredItemIds || request.monitoredItemIds.length === 0) {
|
|
3162
3167
|
return sendError(StatusCodes.BadNothingToDo);
|
|
3163
3168
|
}
|
|
3164
3169
|
|
|
3165
|
-
/*
|
|
3170
|
+
/* c8 ignore next */
|
|
3166
3171
|
if (this.engine.serverCapabilities.operationLimits.maxMonitoredItemsPerCall > 0) {
|
|
3167
3172
|
if (request.monitoredItemIds.length > this.engine.serverCapabilities.operationLimits.maxMonitoredItemsPerCall) {
|
|
3168
3173
|
return sendError(StatusCodes.BadTooManyOperations);
|
|
@@ -3311,12 +3316,12 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3311
3316
|
sendResponse: (response: Response) => void,
|
|
3312
3317
|
sendError: (statusCode: StatusCode) => void
|
|
3313
3318
|
) => {
|
|
3314
|
-
/*
|
|
3319
|
+
/* c8 ignore next */
|
|
3315
3320
|
if (!request.monitoredItemIds || request.monitoredItemIds.length === 0) {
|
|
3316
3321
|
return sendError(StatusCodes.BadNothingToDo);
|
|
3317
3322
|
}
|
|
3318
3323
|
|
|
3319
|
-
/*
|
|
3324
|
+
/* c8 ignore next */
|
|
3320
3325
|
if (this.engine.serverCapabilities.operationLimits.maxMonitoredItemsPerCall > 0) {
|
|
3321
3326
|
if (request.monitoredItemIds.length > this.engine.serverCapabilities.operationLimits.maxMonitoredItemsPerCall) {
|
|
3322
3327
|
return sendError(StatusCodes.BadTooManyOperations);
|
|
@@ -3495,7 +3500,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3495
3500
|
);
|
|
3496
3501
|
}
|
|
3497
3502
|
|
|
3498
|
-
/*
|
|
3503
|
+
/* c8 ignore next */
|
|
3499
3504
|
protected _on_Cancel(message: Message, channel: ServerSecureChannelLayer): void {
|
|
3500
3505
|
return g_sendError(channel, message, CancelResponse, StatusCodes.BadServiceUnsupported);
|
|
3501
3506
|
}
|
|
@@ -3504,38 +3509,38 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3504
3509
|
// This Service Set defines Services to add and delete AddressSpace Nodes and References between them. All added
|
|
3505
3510
|
// Nodes continue to exist in the AddressSpace even if the Client that created them disconnects from the Server.
|
|
3506
3511
|
//
|
|
3507
|
-
/*
|
|
3512
|
+
/* c8 ignore next */
|
|
3508
3513
|
protected _on_AddNodes(message: Message, channel: ServerSecureChannelLayer): void {
|
|
3509
3514
|
return g_sendError(channel, message, AddNodesResponse, StatusCodes.BadServiceUnsupported);
|
|
3510
3515
|
}
|
|
3511
3516
|
|
|
3512
|
-
/*
|
|
3517
|
+
/* c8 ignore next */
|
|
3513
3518
|
protected _on_AddReferences(message: Message, channel: ServerSecureChannelLayer): void {
|
|
3514
3519
|
return g_sendError(channel, message, AddReferencesResponse, StatusCodes.BadServiceUnsupported);
|
|
3515
3520
|
}
|
|
3516
3521
|
|
|
3517
|
-
/*
|
|
3522
|
+
/* c8 ignore next */
|
|
3518
3523
|
protected _on_DeleteNodes(message: Message, channel: ServerSecureChannelLayer): void {
|
|
3519
3524
|
return g_sendError(channel, message, DeleteNodesResponse, StatusCodes.BadServiceUnsupported);
|
|
3520
3525
|
}
|
|
3521
3526
|
|
|
3522
|
-
/*
|
|
3527
|
+
/* c8 ignore next */
|
|
3523
3528
|
protected _on_DeleteReferences(message: Message, channel: ServerSecureChannelLayer): void {
|
|
3524
3529
|
return g_sendError(channel, message, DeleteReferencesResponse, StatusCodes.BadServiceUnsupported);
|
|
3525
3530
|
}
|
|
3526
3531
|
|
|
3527
3532
|
// Query Service
|
|
3528
|
-
/*
|
|
3533
|
+
/* c8 ignore next */
|
|
3529
3534
|
protected _on_QueryFirst(message: Message, channel: ServerSecureChannelLayer): void {
|
|
3530
3535
|
return g_sendError(channel, message, QueryFirstResponse, StatusCodes.BadServiceUnsupported);
|
|
3531
3536
|
}
|
|
3532
3537
|
|
|
3533
|
-
/*
|
|
3538
|
+
/* c8 ignore next */
|
|
3534
3539
|
protected _on_QueryNext(message: Message, channel: ServerSecureChannelLayer): void {
|
|
3535
3540
|
return g_sendError(channel, message, QueryNextResponse, StatusCodes.BadServiceUnsupported);
|
|
3536
3541
|
}
|
|
3537
3542
|
|
|
3538
|
-
/*
|
|
3543
|
+
/* c8 ignore next */
|
|
3539
3544
|
protected _on_HistoryUpdate(message: Message, channel: ServerSecureChannelLayer): void {
|
|
3540
3545
|
return g_sendError(channel, message, HistoryUpdateResponse, StatusCodes.BadServiceUnsupported);
|
|
3541
3546
|
}
|
|
@@ -3573,7 +3578,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3573
3578
|
serverOption: OPCUAServerOptions,
|
|
3574
3579
|
endpointOptions: OPCUAServerEndpointOptions
|
|
3575
3580
|
): OPCUAServerEndPoint {
|
|
3576
|
-
/*
|
|
3581
|
+
/* c8 ignore next */
|
|
3577
3582
|
if (!endpointOptions) {
|
|
3578
3583
|
throw new Error("internal error");
|
|
3579
3584
|
}
|
|
@@ -3581,7 +3586,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3581
3586
|
endpointOptions.hostname = endpointOptions.hostname || hostname;
|
|
3582
3587
|
endpointOptions.port = endpointOptions.port === undefined ? 26543 : endpointOptions.port;
|
|
3583
3588
|
|
|
3584
|
-
/*
|
|
3589
|
+
/* c8 ignore next */
|
|
3585
3590
|
if (
|
|
3586
3591
|
!Object.prototype.hasOwnProperty.call(endpointOptions, "port") ||
|
|
3587
3592
|
!isFinite(endpointOptions.port!) ||
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
2
|
* @module node-opcua-server
|
|
3
3
|
*/
|
|
4
4
|
// tslint:disable:no-console
|
|
@@ -112,8 +112,8 @@ function constructRegisteredServer(server: IPartialServer, isOnline: boolean): R
|
|
|
112
112
|
const info = exploreCertificate(server.getCertificate());
|
|
113
113
|
const commonName = info.tbsCertificate.subject.commonName!;
|
|
114
114
|
|
|
115
|
-
const serverUri = info.tbsCertificate.extensions?.subjectAltName
|
|
116
|
-
//
|
|
115
|
+
const serverUri = info.tbsCertificate.extensions?.subjectAltName?.uniformResourceIdentifier[0];
|
|
116
|
+
// c8 ignore next
|
|
117
117
|
if (serverUri !== server.serverInfo.applicationUri) {
|
|
118
118
|
warningLog(
|
|
119
119
|
chalk.yellow("Warning certificate uniformResourceIdentifier doesn't match serverInfo.applicationUri"),
|
|
@@ -128,7 +128,7 @@ function constructRegisteredServer(server: IPartialServer, isOnline: boolean): R
|
|
|
128
128
|
);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
//
|
|
131
|
+
// c8 ignore next
|
|
132
132
|
if (!server.serverInfo.applicationName.text) {
|
|
133
133
|
debugLog("warning: application name is missing");
|
|
134
134
|
}
|
|
@@ -403,7 +403,11 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
|
|
|
403
403
|
if (!this.#_isTerminating()) {
|
|
404
404
|
this.#_setState(RegisterServerManagerStatus.INACTIVE);
|
|
405
405
|
this.#_emitEvent("serverRegistrationFailure");
|
|
406
|
-
|
|
406
|
+
// interruptible pause: check for shutdown every 100ms
|
|
407
|
+
const delay = Math.min(5000, this.timeout);
|
|
408
|
+
for (let elapsed = 0; elapsed < delay && !this.#_isTerminating(); elapsed += 100) {
|
|
409
|
+
await pause(100);
|
|
410
|
+
}
|
|
407
411
|
}
|
|
408
412
|
}
|
|
409
413
|
}
|
|
@@ -513,6 +517,7 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
|
|
|
513
517
|
warningLog("RegisterServerManager#_establish_initial_connection: error disconnecting client", err);
|
|
514
518
|
}
|
|
515
519
|
}
|
|
520
|
+
server.serverCertificateManager.referenceCounter--;
|
|
516
521
|
}
|
|
517
522
|
}
|
|
518
523
|
|
|
@@ -681,6 +686,7 @@ export class RegisterServerManager extends EventEmitter implements IRegisterServ
|
|
|
681
686
|
this._registration_client = null;
|
|
682
687
|
await tmp.disconnect();
|
|
683
688
|
}
|
|
689
|
+
server.serverCertificateManager.referenceCounter--;
|
|
684
690
|
}
|
|
685
691
|
}
|
|
686
692
|
|
|
@@ -376,11 +376,11 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
|
|
|
376
376
|
securityPolicy: SecurityPolicy,
|
|
377
377
|
options: EndpointDescriptionParams
|
|
378
378
|
): void {
|
|
379
|
-
//
|
|
379
|
+
// c8 ignore next
|
|
380
380
|
if (securityMode === MessageSecurityMode.None && securityPolicy !== SecurityPolicy.None) {
|
|
381
381
|
throw new Error(" invalid security ");
|
|
382
382
|
}
|
|
383
|
-
//
|
|
383
|
+
// c8 ignore next
|
|
384
384
|
if (securityMode !== MessageSecurityMode.None && securityPolicy === SecurityPolicy.None) {
|
|
385
385
|
throw new Error(" invalid security ");
|
|
386
386
|
}
|
|
@@ -396,7 +396,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
|
|
|
396
396
|
|
|
397
397
|
const endpoint_desc = this.getEndpointDescription(securityMode, securityPolicy, endpointUrl);
|
|
398
398
|
|
|
399
|
-
//
|
|
399
|
+
// c8 ignore next
|
|
400
400
|
if (endpoint_desc) {
|
|
401
401
|
throw new Error(" endpoint already exist");
|
|
402
402
|
}
|
|
@@ -591,7 +591,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
|
|
|
591
591
|
this.shutdown_channel(channel, callback1);
|
|
592
592
|
},
|
|
593
593
|
(err?: Error | null) => {
|
|
594
|
-
/*
|
|
594
|
+
/* c8 ignore next */
|
|
595
595
|
if (!(Object.keys(this._channels).length === 0)) {
|
|
596
596
|
errorLog(" Bad !");
|
|
597
597
|
}
|
|
@@ -673,7 +673,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
|
|
|
673
673
|
this._listen_callback = undefined;
|
|
674
674
|
this._server
|
|
675
675
|
.on("connection", (socket: NodeJS.Socket) => {
|
|
676
|
-
//
|
|
676
|
+
// c8 ignore next
|
|
677
677
|
if (doDebug) {
|
|
678
678
|
this._dump_statistics();
|
|
679
679
|
debugLog("server connected with : " + (socket as any).remoteAddress + ":" + (socket as any).remotePort);
|
|
@@ -859,7 +859,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
|
|
|
859
859
|
this.transactionsCountOldChannels += channel.transactionsCount;
|
|
860
860
|
delete this._channels[channel.hashKey];
|
|
861
861
|
|
|
862
|
-
//
|
|
862
|
+
// c8 ignore next
|
|
863
863
|
if (doDebug) {
|
|
864
864
|
this._dump_statistics();
|
|
865
865
|
debugLog("un-registering channel - Count = ", this.currentChannelCount);
|
|
@@ -899,7 +899,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
|
|
|
899
899
|
const nbConnections = this.activeChannelCount;
|
|
900
900
|
|
|
901
901
|
if (nbConnections >= this.maxConnections) {
|
|
902
|
-
//
|
|
902
|
+
// c8 ignore next
|
|
903
903
|
errorLog(chalk.bgRed.white("PREVENTING DDOS ATTACK => maxConnection =" + this.maxConnections));
|
|
904
904
|
|
|
905
905
|
const unused_channels: ServerSecureChannelLayer[] = this.getChannels().filter((channel1: ServerSecureChannelLayer) => {
|
|
@@ -913,7 +913,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
|
|
|
913
913
|
);
|
|
914
914
|
// all channels are in used , we cannot get any
|
|
915
915
|
errorLog(`All channels are in used ! we cannot cancel any ${this.getChannels().length}`);
|
|
916
|
-
//
|
|
916
|
+
// c8 ignore next
|
|
917
917
|
if (doDebug) {
|
|
918
918
|
console.log(" - all channels are used !!!!");
|
|
919
919
|
false && dumpChannelInfo(this.getChannels());
|
|
@@ -921,7 +921,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
|
|
|
921
921
|
setTimeout(deny_connection, 1000);
|
|
922
922
|
return;
|
|
923
923
|
}
|
|
924
|
-
//
|
|
924
|
+
// c8 ignore next
|
|
925
925
|
if (doDebug) {
|
|
926
926
|
console.log(
|
|
927
927
|
" - Unused channels that can be clobbered",
|
|
@@ -931,7 +931,7 @@ export class OPCUAServerEndPoint extends EventEmitter implements ServerSecureCha
|
|
|
931
931
|
const channel = unused_channels[0];
|
|
932
932
|
errorLog(`${unused_channels.length} : Forcefully closing oldest channel that have no session: ${channel.hashKey}`);
|
|
933
933
|
channel.close(() => {
|
|
934
|
-
//
|
|
934
|
+
// c8 ignore next
|
|
935
935
|
if (doDebug) {
|
|
936
936
|
console.log(" _ Unused channel has been closed ", channel.hashKey);
|
|
937
937
|
}
|
|
@@ -1116,7 +1116,7 @@ function _makeEndpointDescription(options: MakeEndpointDescriptionOptions, paren
|
|
|
1116
1116
|
// when channel session security is not "None",
|
|
1117
1117
|
// userIdentityTokens can be left to null.
|
|
1118
1118
|
// in this case this mean that secure policy will be the same as connection security policy
|
|
1119
|
-
//
|
|
1119
|
+
// c8 ignore next
|
|
1120
1120
|
if (process.env.NODEOPCUA_SERVER_EMULATE_SIEMENS) {
|
|
1121
1121
|
// However, for some reason SIEMENS plc requires that password get encrypted even though
|
|
1122
1122
|
// the secure channel is also encrypted ....
|
package/source/server_engine.ts
CHANGED
|
@@ -413,15 +413,15 @@ export class ServerEngine extends EventEmitter implements IAddressSpaceAccessor
|
|
|
413
413
|
"http://opcfoundation.org/UA-Profile/Server/Standard", // Standard UA Server Profile",
|
|
414
414
|
"http://opcfoundation.org/UA-Profile/Server/DataAccess",
|
|
415
415
|
"http://opcfoundation.org/UA-Profile/Server/ComplexTypes2017",
|
|
416
|
-
|
|
416
|
+
"http://opcfoundation.org/UA-Profile/Server/Events",
|
|
417
417
|
"http://opcfoundation.org/UA-Profile/Client/HistoricalAccess",
|
|
418
418
|
"http://opcfoundation.org/UA-Profile/Server/Methods",
|
|
419
419
|
"http://opcfoundation.org/UA-Profile/Server/StandardEventSubscription",
|
|
420
420
|
"http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary",
|
|
421
421
|
"http://opcfoundation.org/UA-Profile/Server/FileAccess",
|
|
422
422
|
"http://opcfoundation.org/UA-Profile/Server/StateMachine",
|
|
423
|
-
|
|
424
|
-
|
|
423
|
+
|
|
424
|
+
|
|
425
425
|
// "http://opcfoundation.org/UA-Profile/Transport/wss-uajson",
|
|
426
426
|
// "http://opcfoundation.org/UA-Profile/Transport/wss-uasc-uabinary"
|
|
427
427
|
// "http://opcfoundation.org/UA-Profile/Server/DurableSubscription"
|
|
@@ -775,7 +775,7 @@ export class ServerEngine extends EventEmitter implements IAddressSpaceAccessor
|
|
|
775
775
|
callback(err);
|
|
776
776
|
})
|
|
777
777
|
.then(() => {
|
|
778
|
-
/*
|
|
778
|
+
/* c8 ignore next */
|
|
779
779
|
if (!this.addressSpace) {
|
|
780
780
|
throw new Error("Internal error");
|
|
781
781
|
}
|
|
@@ -864,7 +864,7 @@ export class ServerEngine extends EventEmitter implements IAddressSpaceAccessor
|
|
|
864
864
|
// make sur the provided function returns a valid value for the variant type
|
|
865
865
|
// This test may not be exhaustive but it will detect obvious mistakes.
|
|
866
866
|
|
|
867
|
-
/*
|
|
867
|
+
/* c8 ignore next */
|
|
868
868
|
if (!isValidVariant(VariantArrayType.Scalar, dataType, func())) {
|
|
869
869
|
errorLog("func", func());
|
|
870
870
|
throw new Error("bindStandardScalar : func doesn't provide an value of type " + DataType[dataType]);
|
|
@@ -1303,8 +1303,8 @@ export class ServerEngine extends EventEmitter implements IAddressSpaceAccessor
|
|
|
1303
1303
|
return;
|
|
1304
1304
|
}
|
|
1305
1305
|
const outputArguments = getMonitoredItemsMethod.outputArguments!;
|
|
1306
|
-
|
|
1307
|
-
|
|
1306
|
+
const dataValue = outputArguments.readValue();
|
|
1307
|
+
if (!dataValue.value?.value) {
|
|
1308
1308
|
// value is null or undefined , meaning no arguments necessary
|
|
1309
1309
|
return;
|
|
1310
1310
|
}
|
|
@@ -1553,7 +1553,7 @@ export class ServerEngine extends EventEmitter implements IAddressSpaceAccessor
|
|
|
1553
1553
|
|
|
1554
1554
|
const session = this.getSession(authenticationToken);
|
|
1555
1555
|
|
|
1556
|
-
//
|
|
1556
|
+
// c8 ignore next
|
|
1557
1557
|
if (!session) {
|
|
1558
1558
|
throw new Error("cannot find session with this authenticationToken " + authenticationToken.toString());
|
|
1559
1559
|
}
|
|
@@ -1689,7 +1689,7 @@ export class ServerEngine extends EventEmitter implements IAddressSpaceAccessor
|
|
|
1689
1689
|
statusCode: StatusCodes.Good
|
|
1690
1690
|
});
|
|
1691
1691
|
|
|
1692
|
-
//
|
|
1692
|
+
// c8 ignore next
|
|
1693
1693
|
if (doDebug) {
|
|
1694
1694
|
debugLog("TransferResult", result.toString());
|
|
1695
1695
|
}
|
|
@@ -1894,21 +1894,22 @@ export class ServerEngine extends EventEmitter implements IAddressSpaceAccessor
|
|
|
1894
1894
|
if (!methodNode) {
|
|
1895
1895
|
return;
|
|
1896
1896
|
}
|
|
1897
|
-
// istanbul ignore else
|
|
1898
1897
|
if (methodNode && methodNode.bindMethod) {
|
|
1899
1898
|
methodNode.bindMethod(func);
|
|
1900
|
-
}
|
|
1899
|
+
}
|
|
1900
|
+
/* c8 ignore next */
|
|
1901
|
+
else {
|
|
1901
1902
|
warningLog(
|
|
1902
1903
|
chalk.yellow("WARNING: cannot bind a method with id ") +
|
|
1903
|
-
|
|
1904
|
-
|
|
1904
|
+
chalk.cyan(nodeId.toString()) +
|
|
1905
|
+
chalk.yellow(". please check your nodeset.xml file or add this node programmatically")
|
|
1905
1906
|
);
|
|
1906
1907
|
warningLog(traceFromThisProjectOnly());
|
|
1907
1908
|
}
|
|
1908
1909
|
}
|
|
1909
1910
|
|
|
1910
1911
|
private _getServerSubscriptionDiagnosticsArrayNode(): UADynamicVariableArray<SubscriptionDiagnosticsDataType> | null {
|
|
1911
|
-
//
|
|
1912
|
+
// c8 ignore next
|
|
1912
1913
|
if (!this.addressSpace) {
|
|
1913
1914
|
doDebug && debugLog("ServerEngine#_getServerSubscriptionDiagnosticsArray : no addressSpace");
|
|
1914
1915
|
|
|
@@ -410,7 +410,7 @@ export class ServerSidePublishEngine extends EventEmitter implements IServerSide
|
|
|
410
410
|
callback = callback || dummy_function;
|
|
411
411
|
assert(typeof callback === "function");
|
|
412
412
|
|
|
413
|
-
//
|
|
413
|
+
// c8 ignore next
|
|
414
414
|
if (!(request instanceof PublishRequest)) {
|
|
415
415
|
throw new Error("Internal error : expecting a Publish Request here");
|
|
416
416
|
}
|
|
@@ -470,7 +470,7 @@ export class ServerSidePublishEngine extends EventEmitter implements IServerSide
|
|
|
470
470
|
}
|
|
471
471
|
late_subscriptions.sort(compare_subscriptions);
|
|
472
472
|
|
|
473
|
-
//
|
|
473
|
+
// c8 ignore next
|
|
474
474
|
if (doDebug) {
|
|
475
475
|
debugLog(
|
|
476
476
|
late_subscriptions
|
|
@@ -599,7 +599,7 @@ export class ServerSidePublishEngine extends EventEmitter implements IServerSide
|
|
|
599
599
|
// Notification Message that is to be sent.
|
|
600
600
|
|
|
601
601
|
const subscription = this.getSubscriptionById(subscriptionId);
|
|
602
|
-
/*
|
|
602
|
+
/* c8 ignore next */
|
|
603
603
|
if (!subscription) {
|
|
604
604
|
traceLog("send_keep_alive_response => invalid subscriptionId = ", subscriptionId);
|
|
605
605
|
return false;
|
|
@@ -652,7 +652,7 @@ export class ServerSidePublishEngine extends EventEmitter implements IServerSide
|
|
|
652
652
|
|
|
653
653
|
const invalid_published_request = parts[0];
|
|
654
654
|
for (const publishData of invalid_published_request) {
|
|
655
|
-
//
|
|
655
|
+
// c8 ignore next
|
|
656
656
|
if (doDebug) {
|
|
657
657
|
debugLog(chalk.cyan(" CANCELING TIMEOUT PUBLISH REQUEST "));
|
|
658
658
|
}
|
|
@@ -664,7 +664,7 @@ export class ServerSidePublishEngine extends EventEmitter implements IServerSide
|
|
|
664
664
|
publishData.callback(publishData.request, response);
|
|
665
665
|
}
|
|
666
666
|
public _send_valid_response_for_request(publishData: PublishData, response: PublishResponse): void {
|
|
667
|
-
//
|
|
667
|
+
// c8 ignore next
|
|
668
668
|
if (doDebug) {
|
|
669
669
|
debugLog("_send_response_for_request ", response.toString());
|
|
670
670
|
}
|