Skip to content

Commit

Permalink
fix endpoint selection when alternate hostnames are specified #881
Browse files Browse the repository at this point in the history
  • Loading branch information
erossignon committed Oct 7, 2020
1 parent 0cff4bc commit e522f1f
Show file tree
Hide file tree
Showing 17 changed files with 675 additions and 582 deletions.
9 changes: 5 additions & 4 deletions documentation/typescript_test.ts
Expand Up @@ -2,7 +2,8 @@ import {
AttributeIds,
ClientSession,
coerceNodeId,
OPCUAClient
OPCUAClient,
TimestampsToReturn
} from "../packages/node-opcua";

const endpointUrl = "opc.tcp://opcuademo.sterfive.com:26543";
Expand All @@ -12,7 +13,7 @@ async function main0() {
const client = OPCUAClient.create({applicationName: "MyClientApp"});

// async version
await client.withSession(endpointUrl, async (session) => {
await client.withSessionAsync(endpointUrl, async (session) => {

const dataValue = await session.read({
attributeId: AttributeIds.BrowseName,
Expand Down Expand Up @@ -65,7 +66,7 @@ async function main3() {
}
}

main();
main0();

async function main2() {
try {
Expand Down Expand Up @@ -95,7 +96,7 @@ async function main2() {
discardOldest: true
};

const monitoredItem = await subscription.monitor(itemToMonitor, requestedParameters);
const monitoredItem = await subscription.monitor(itemToMonitor, requestedParameters, TimestampsToReturn.Both);

monitoredItem.on("changed", (dataValue) => console.log("Temperature ", dataValue.value.value));
monitoredItem.on("err", (err) => console.log(err));
Expand Down
@@ -1,7 +1,7 @@
"use strict";
const should = require("should");
const async = require("async");

const chalk = require("chalk");

const { OPCUAClient, OPCUAServer, SessionContext } = require("node-opcua");
const context = SessionContext.defaultContext;
Expand Down
89 changes: 89 additions & 0 deletions packages/node-opcua-end2end-test/test/end_to_end/test_e2e_881.ts
@@ -0,0 +1,89 @@
import { get_mini_nodeset_filename, nodesets, OPCUAClient, OPCUAServer, UserTokenType } from "node-opcua";
import { networkInterfaces } from "os";

const doDebug = false;
function getIpAddresses() {
const nets = networkInterfaces();
const results: any = {};
for (const name of Object.keys(nets)) {
for (const net of nets[name]!) {
// skip over non-ipv4 and internal (i.e. 127.0.0.1) addresses
if (net.family === "IPv4" && !net.internal) {
if (!results[name]) {
results[name] = [];
}
results[name].push(net.address);
}
}
}
if (doDebug) {
console.log(results);
}

return [].concat.apply([], Object.values(results));
}
const port = 2000;
const ip = getIpAddresses();

async function startServer(): Promise<OPCUAServer> {
// get IP of the machine
const mini = get_mini_nodeset_filename();
if (doDebug) {
console.log(ip);
}
const server = new OPCUAServer({
port,
alternateHostname: ip,
nodeset_filename: [mini],
userManager: {
isValidUser(userName: string, password: string): boolean {
if (userName === "test" && password === "test") {
return true;
}
return false;
}
}
});
await server.initialize();
await server.start();
if (doDebug) {
console.log(`server started ${port}`);
}
return server;
}
// tslint:disable-next-line:no-var-requires
const describe = require("node-opcua-leak-detector").describeWithLeakDetector;
describe("building server with an AlternateName", () => {
let server: OPCUAServer;
before(async () => {
server = await startServer();
});
after(async () => {
await server.shutdown();
server.dispose();
});
it("should not confuse endpoints", async () => {
const client = OPCUAClient.create({ endpoint_must_exist: false });
client.on("backoff", () => console.log("keep trying", endpointUri));

const endpointUri = `opc.tcp://${ip[0]}:${port}`;
if (doDebug) {
console.log("endpoint = ", endpointUri);
}

await client.connect(endpointUri);

try {
const session = await client.createSession({
type: UserTokenType.UserName,
password: "test",
userName: "test"
});
await session.close();
} catch (err) {
throw err;
} finally {
await client.disconnect();
}
});
});
Expand Up @@ -83,10 +83,13 @@ function start_active_client(connectionStrategy, callback) {
},

function client_recreate_session(callback) {
client.createSession(function(err, session) {
if (!err) {
the_session = session;
client.createSession((err, session) => {
if (err) {
console.log("endpointUrl = ", endpointUrl);
console.log("err = ", err);
return callback(err);
}
the_session = session;
debugLog("session timeout = ", session.timeout);
the_session.on("keepalive", function(state) {
if (doDebug) {
Expand All @@ -98,7 +101,7 @@ function start_active_client(connectionStrategy, callback) {
the_session.on("session_closed", function(statusCode) {
debugLog(chalk.yellow("Session has closed : statusCode = "), statusCode ? statusCode.toString() : "????");
});
callback(err);
callback();
});
},

Expand Down Expand Up @@ -249,7 +252,9 @@ function terminate_active_client(callback) {
clearInterval(intervalId);
intervalId = null;
}

if (!the_session) {
return callback();
}
the_session.close(function(err) {
if (err) {
debugLog("session closed failed ?");
Expand Down
Expand Up @@ -50,7 +50,7 @@ describe("testing extension object with client residing on a different process t
const client = OPCUAClient.create({
endpoint_must_exist: false
});
const endpointUrl = "opc.tcp://localhost:23232";
const endpointUrl = serverHandle.endpointUrl;

const nodeId = "ns=2;i=6001";
perform_operation_on_client_session(client, endpointUrl, function(session, inner_done) {
Expand Down
Expand Up @@ -12,9 +12,10 @@ describe("Testing bug #574", function() {

const port = 2222;
let server = null;
let endpointUrl = "";


before(function(done) {
before(async () => {

server = new opcua.OPCUAServer({
port,
Expand All @@ -26,40 +27,40 @@ describe("Testing bug #574", function() {
}
});

server.start((err) => {
// note: Some OPCUA servers (such as Softing) allow user token policies that
// send password in clear text on the TCP unencrypted channel.
// This behavior is not recommended by the OPCUA specification but
// exists in many server on the field.
// On our side, node opcua doesn't allow password to be send unsecurely.
// We need to tweak the server to allow this for the purpose
// of this test.
// Let's remove all but policy and add a single
// userIdentityTokens policy for username and uncrypted password
let endpoints = server._get_endpoints();
endpoints = endpoints.filter((e) => e.securityMode === opcua.MessageSecurityMode.None);
endpoints.length.should.eql(1);

endpoints[0].userIdentityTokens = [];
endpoints[0].userIdentityTokens.push(new UserTokenPolicy({
policyId: "usernamePassword_unsecure",
tokenType: 1, /*UserTokenType.UserName,*/
issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: null
}));
done(err)
});
await server.start();
// note: Some OPCUA servers (such as Softing) allow user token policies that
// send password in clear text on the TCP unencrypted channel.
// This behavior is not recommended by the OPCUA specification but
// exists in many server on the field.
// On our side, node opcua doesn't allow password to be send unsecurely.
// We need to tweak the server to allow this for the purpose
// of this test.
// Let's remove all but policy and add a single
// userIdentityTokens policy for username and uncrypted password
let endpoints = server._get_endpoints();
endpointUrl = endpoints[0].endpointUrl;

endpoints = endpoints.filter((e) => e.securityMode === opcua.MessageSecurityMode.None);
endpoints.length.should.eql(1);

endpoints[0].userIdentityTokens = [];
endpoints[0].userIdentityTokens.push(new UserTokenPolicy({
policyId: "usernamePassword_unsecure",
tokenType: 1, /*UserTokenType.UserName,*/
issuedTokenType: null,
issuerEndpointUrl: null,
securityPolicyUri: null
}));


});
after(function(done) {
server.shutdown(done);
});

it("should create a aession with user/password on unsecure connection", function(done) {
it("should create a session with user/password on unsecured connection", (done) => {

// user1/password1
const endpointUrl = "opc.tcp://localhost:" + port;

const client = opcua.OPCUAClient.create({
endpoint_must_exist: false,
Expand Down

0 comments on commit e522f1f

Please sign in to comment.