diff --git a/Libraries/Opc.Ua.Client/Session.cs b/Libraries/Opc.Ua.Client/Session.cs
index 0973fd1257..750a953cc8 100644
--- a/Libraries/Opc.Ua.Client/Session.cs
+++ b/Libraries/Opc.Ua.Client/Session.cs
@@ -67,44 +67,31 @@ namespace Opc.Ua.Client
///
/// The channel used to communicate with the server.
/// The configuration for the client application.
- /// The endpoint use to initialize the channel.
+ /// The endpoint used to initialize the channel.
/// The certificate to use for the client.
+ /// The list of available endpoints returned by server in GetEndpoints() response.
+ /// The value of profileUris used in GetEndpoints() request.
///
/// The application configuration is used to look up the certificate if none is provided.
/// The clientCertificate must have the private key. This will require that the certificate
/// be loaded from a certicate store. Converting a DER encoded blob to a X509Certificate2
/// will not include a private key.
+ /// The availableEndpoints and discoveryProfileUris parameters are used to validate
+ /// that the list of EndpointDescriptions returned at GetEndpoints matches the list returned at CreateSession.
///
- public Session(
- ITransportChannel channel,
- ApplicationConfiguration configuration,
- ConfiguredEndpoint endpoint,
- X509Certificate2 clientCertificate)
- :
- base(channel)
- {
- Initialize(channel, configuration, endpoint, clientCertificate);
- }
-
- ///
- /// Constructs a new instance of the class.
- ///
- /// The channel used to communicate with the server.
- /// The configuration for the client application.
- /// The endpoint use to initialize the channel.
- /// The certificate to use for the client.
- /// A collection of available endpoints to connect to the server.
public Session(
ITransportChannel channel,
ApplicationConfiguration configuration,
ConfiguredEndpoint endpoint,
X509Certificate2 clientCertificate,
- EndpointDescriptionCollection availableEndpoints)
+ EndpointDescriptionCollection availableEndpoints = null,
+ StringCollection discoveryProfileUris = null)
:
base(channel)
{
Initialize(channel, configuration, endpoint, clientCertificate);
- m_expectedServerEndpoints = availableEndpoints;
+ m_discoveryServerEndpoints = availableEndpoints;
+ m_discoveryProfileUris = discoveryProfileUris;
}
///
@@ -2585,20 +2572,41 @@ namespace Opc.Ua.Client
// "Server signature is null or empty.");
}
- if (m_expectedServerEndpoints != null && m_expectedServerEndpoints.Count > 0)
+ if (m_discoveryServerEndpoints != null && m_discoveryServerEndpoints.Count > 0)
{
- // verify that the list of endpoints returned by CreateSession matches the list returned at GetEndpoints.
- if (m_expectedServerEndpoints.Count != serverEndpoints.Count)
+ // Compare EndpointDescriptions returned at GetEndpoints with values returned at CreateSession
+ EndpointDescriptionCollection expectedServerEndpoints = null;
+
+ if (m_discoveryProfileUris != null && m_discoveryProfileUris.Count > 0)
+ {
+ // Select EndpointDescriptions with a transportProfileUri that matches the
+ // profileUris specified in the original GetEndpoints() request.
+ expectedServerEndpoints = new EndpointDescriptionCollection();
+
+ foreach (EndpointDescription serverEndpoint in serverEndpoints)
+ {
+ if (m_discoveryProfileUris.Contains(serverEndpoint.TransportProfileUri))
+ {
+ expectedServerEndpoints.Add(serverEndpoint);
+ }
+ }
+ }
+ else
+ {
+ expectedServerEndpoints = serverEndpoints;
+ }
+
+ if (m_discoveryServerEndpoints.Count != expectedServerEndpoints.Count)
{
throw ServiceResultException.Create(
StatusCodes.BadSecurityChecksFailed,
"Server did not return a number of ServerEndpoints that matches the one from GetEndpoints.");
}
- for (int ii = 0; ii < serverEndpoints.Count; ii++)
+ for (int ii = 0; ii < expectedServerEndpoints.Count; ii++)
{
- EndpointDescription serverEndpoint = serverEndpoints[ii];
- EndpointDescription expectedServerEndpoint = m_expectedServerEndpoints[ii];
+ EndpointDescription serverEndpoint = expectedServerEndpoints[ii];
+ EndpointDescription expectedServerEndpoint = m_discoveryServerEndpoints[ii];
if (serverEndpoint.SecurityMode != expectedServerEndpoint.SecurityMode ||
serverEndpoint.SecurityPolicyUri != expectedServerEndpoint.SecurityPolicyUri ||
@@ -4679,7 +4687,8 @@ namespace Opc.Ua.Client
private bool m_reconnecting;
private LinkedList m_outstandingRequests;
- private EndpointDescriptionCollection m_expectedServerEndpoints;
+ private EndpointDescriptionCollection m_discoveryServerEndpoints;
+ private StringCollection m_discoveryProfileUris;
private class AsyncRequestState
{