Skip to content

Commit

Permalink
fix serverEndpoint in CreateSessionResponse
Browse files Browse the repository at this point in the history
- serverEndpoints need to be populated with valid server endpoints even if
  the client did not connect with exactly the same endpoint as one exposed
  by the server.
- prior to this fix, node-opcua server was returning serverEndpoints=null
  when the endppoint used by the client was unknown. This causes
  third party client to reject the connection as they couldn't verify
  the endpoints.
- https://reference.opcfoundation.org/v104/Core/docs/Part4/5.6.2/

- the spec says:
     The Server returns its EndpointDescriptions in the response. Clients
    use this information to determine whether the list of EndpointDescriptions
    returned from the DiscoveryEndpoint matches the Endpoints that the
    Server has. If there is a difference then the Client shall close
    the Session and report an error. The Server returns all
    EndpointDescriptions for the serverUri specified by the
    Client in the request. The Client only verifies EndpointDescriptions
    with a transportProfileUri that matches the profileUri specified in
    the original GetEndpoints request. A Client may skip this check if
    the EndpointDescriptions were provided by a trusted source such as
    the Administrator.

- the way to interpret the phrase:
    The Server returns all  EndpointDescriptions for the serverUri
    specified by the Client in the request.
    is still unclear , as Endpoints have no serverURI
  • Loading branch information
erossignon committed Dec 11, 2020
1 parent 3c817b5 commit e88f10a
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 1 deletion.
Expand Up @@ -264,6 +264,8 @@ describe("testing Client - Umbrella ", function() {
require("./u_test_e2e_monitoredItem_client_terminated_event")(test);
require("./u_test_e2e_endpoint_should_be_case_insensitive")(test);
require("./u_test_e2e_keepAlive")(test);
require("./u_test_e2e_createsSession_endpoints")(test);

// typescripts tests starts here...
require("./u_test_e2e_deadband_filter").t(test);
});
@@ -0,0 +1,80 @@
"use strict";

const { assert } = require("node-opcua-assert");
const should = require("should");
const {OPCUAClient} = require("node-opcua");
const { promises } = require("fs");
const { reject } = require("underscore");

async function testCreateSessionResponse(endpointUrl) {

const client1 = OPCUAClient.create({
endpoint_must_exist: false,
connectionStrategy: {
maxRetry: 1
}
});
let createSessionResponse = "";
let createSessionRequest = "";
client1.on("send_request", (c)=>{
if (c.constructor.name === "CreateSessionRequest") {
createSessionRequest = c;
}

});
client1.on("receive_response", (c)=> {
if (c.constructor.name === "CreateSessionResponse") {
createSessionResponse = c;
}
})
try {

await client1.connect(endpointUrl);

const session = await new Promise((resolve, reject)=>{
client1._createSession((err,session) =>{
if (err) { return reject(err) } else { resolve(session);}
});

})
await session.close();

} catch(err) {
console.log("Error = ",err.message);
console.log(err);
return{ createSessionResponse, err};
}
finally {
await client1.disconnect();

}
// console.log("c", createSessionResponse.toString());
return{ createSessionResponse};

}
module.exports = function(test) {

describe("PP1 CreateSessionResponse endpoints", function() {

it("should receive server endpoint in CreateSessionResponse when endpointUrl user by the client matches a valid endpoint", async () => {

const endpointUrl = test.endpointUrl;
//xx console.log("e=", endpointUrl);
const { createSessionResponse, err }= await testCreateSessionResponse(endpointUrl);
should.not.exist(err);
createSessionResponse.serverEndpoints.length.should.eql(7);
createSessionResponse.serverEndpoints[0].endpointUrl.should.eql(test.endpointUrl);

});
it("should receive server endpoint in CreateSessionResponse when endpointUrl used by the client doesn't match a valid endpoint", async () => {

const endpointUrl = "opc.tcp://localhost:2002";
const { createSessionResponse, err }= await testCreateSessionResponse(endpointUrl);
should.not.exist(err);
createSessionResponse.serverEndpoints.length.should.eql(7);
createSessionResponse.serverEndpoints[0].endpointUrl.should.eql(test.endpointUrl);
});

});

};
2 changes: 1 addition & 1 deletion packages/node-opcua-server/source/opcua_server.ts
Expand Up @@ -1785,7 +1785,7 @@ export class OPCUAServer extends OPCUABaseServer {
// securityPolicyUri, userIdentityTokens, transportProfileUri and securityLevel with all
// other parameters set to null. Only the recommended parameters shall be verified by
// the client.
serverEndpoints: _serverEndpointsForCreateSessionResponse(server, request.endpointUrl, request.serverUri),
serverEndpoints: _serverEndpointsForCreateSessionResponse(server, session.endpoint!.endpointUrl, request.serverUri),

// This parameter is deprecated and the array shall be empty.
serverSoftwareCertificates: null,
Expand Down

0 comments on commit e88f10a

Please sign in to comment.