28
28
import java .security .cert .CertificateEncodingException ;
29
29
import java .security .cert .CertificateFactory ;
30
30
import java .security .cert .X509Certificate ;
31
- import java .util .Collection ;
32
31
import java .util .Comparator ;
33
- import java .util .HashSet ;
34
32
import java .util .Map .Entry ;
35
33
import java .util .Set ;
36
34
import java .util .concurrent .ScheduledExecutorService ;
54
52
import org .slf4j .Logger ;
55
53
import org .slf4j .LoggerFactory ;
56
54
57
- import java .net .InetAddress ;
58
- import java .net .UnknownHostException ;
59
55
import java .nio .ByteBuffer ;
60
56
import java .nio .ByteOrder ;
61
57
import java .util .ArrayList ;
@@ -95,7 +91,6 @@ public class SecureChannel {
95
91
private final OpcuaDriverContext driverContext ;
96
92
private final Conversation conversation ;
97
93
private ScheduledFuture <?> keepAlive ;
98
- private final Set <String > endpoints = new HashSet <>();
99
94
private double sessionTimeout ;
100
95
private long revisedLifetime ;
101
96
@@ -118,17 +113,6 @@ public SecureChannel(Conversation conversation, RequestTransactionManager tm, Op
118
113
this .password = configuration .getPassword ();
119
114
}
120
115
121
- // Generate a list of endpoints we can use.
122
- try {
123
- InetAddress address = InetAddress .getByName (driverContext .getHost ());
124
- this .endpoints .add ("opc.tcp://" + address .getHostAddress () + ":" + driverContext .getPort () + driverContext .getTransportEndpoint ());
125
- this .endpoints .add ("opc.tcp://" + address .getHostName () + ":" + driverContext .getPort () + driverContext .getTransportEndpoint ());
126
- this .endpoints .add ("opc.tcp://" + address .getCanonicalHostName () + ":" + driverContext .getPort () + driverContext .getTransportEndpoint ());
127
- } catch (UnknownHostException e ) {
128
- LOGGER .warn ("Unable to resolve host name. Using original host from connection string which may cause issues connecting to server" );
129
- this .endpoints .add (driverContext .getHost ());
130
- }
131
-
132
116
if (conversation .getSecurityPolicy () == SecurityPolicy .NONE ) {
133
117
this .localCertificateString = NULL_BYTE_STRING ;
134
118
this .remoteCertificateThumbprint = NULL_BYTE_STRING ;
@@ -314,23 +298,10 @@ private CompletableFuture<ActivateSessionResponse> onConnectActivateSessionReque
314
298
conversation .setRemoteCertificate (getX509Certificate (sessionResponse .getServerCertificate ().getStringValue ()));
315
299
conversation .setRemoteNonce (sessionResponse .getServerNonce ().getStringValue ());
316
300
317
- List <String > contactPoints = new ArrayList <>(3 );
318
- String port = driverContext .getPort () == null ? "" : ":" + driverContext .getPort ();
319
- try {
320
- InetAddress address = InetAddress .getByName (driverContext .getHost ());
321
- contactPoints .add ("opc.tcp://" + address .getHostAddress () + port + driverContext .getTransportEndpoint ());
322
- contactPoints .add ("opc.tcp://" + address .getHostName () + port + driverContext .getTransportEndpoint ());
323
- contactPoints .add ("opc.tcp://" + address .getCanonicalHostName () + port + driverContext .getTransportEndpoint ());
324
- } catch (UnknownHostException e ) {
325
- // fall back to declared host
326
- contactPoints .add ("opc.tcp://" + driverContext .getHost () + port + driverContext .getTransportEndpoint ());
327
- LOGGER .warn ("Could not reach host {}, possible network failure" , driverContext .getHost (), e );
328
- }
329
-
330
- Entry <EndpointDescription , UserTokenPolicy > selectedEndpoint = selectEndpoint (sessionResponse .getServerEndpoints (), contactPoints ,
301
+ Entry <EndpointDescription , UserTokenPolicy > selectedEndpoint = selectEndpoint (sessionResponse .getServerEndpoints (),
331
302
configuration .getSecurityPolicy (), configuration .getMessageSecurity ());
332
303
if (selectedEndpoint == null ) {
333
- throw new PlcRuntimeException ("Unable to find endpoint matching " + contactPoints . get ( 0 ));
304
+ throw new PlcRuntimeException ("Unable to find endpoint matching " + driverContext . getEndpoint ( ));
334
305
}
335
306
336
307
PascalString policyId = selectedEndpoint .getValue ().getPolicyId ();
@@ -421,7 +392,8 @@ public CompletableFuture<EndpointDescription> onDiscoverGetEndpointsRequest() {
421
392
);
422
393
423
394
return conversation .submit (endpointsRequest , GetEndpointsResponse .class ).thenApply (response -> {
424
- Entry <EndpointDescription , UserTokenPolicy > entry = selectEndpoint (response .getEndpoints (), this .endpoints , this .configuration .getSecurityPolicy (), this .configuration .getMessageSecurity ());
395
+ Entry <EndpointDescription , UserTokenPolicy > entry = selectEndpoint (response .getEndpoints (),
396
+ this .configuration .getSecurityPolicy (), this .configuration .getMessageSecurity ());
425
397
426
398
if (entry == null ) {
427
399
Set <String > endpointUris = response .getEndpoints ().stream ()
@@ -494,19 +466,18 @@ private static ReadBufferByteBased toBuffer(Supplier<Payload> supplier) {
494
466
* Selects the endpoint and authentication policy based on client settings.
495
467
*
496
468
* @param extensionObjects Endpoint descriptions returned by the server.
497
- * @param contactPoints Contact points expected by client.
498
469
* @param securityPolicy Security policy searched in endpoints.
499
470
* @param messageSecurity Message security needed by client.
500
471
* @return Endpoint matching given.
501
472
*/
502
- private Entry <EndpointDescription , UserTokenPolicy > selectEndpoint (List <EndpointDescription > extensionObjects , Collection < String > contactPoints ,
473
+ private Entry <EndpointDescription , UserTokenPolicy > selectEndpoint (List <EndpointDescription > extensionObjects ,
503
474
SecurityPolicy securityPolicy , MessageSecurity messageSecurity ) throws PlcRuntimeException {
504
475
// Get a list of the endpoints which match ours.
505
476
MessageSecurityMode effectiveMessageSecurity = SecurityPolicy .NONE == securityPolicy ? MessageSecurityMode .messageSecurityModeNone : messageSecurity .getMode ();
506
477
List <Entry <EndpointDescription , UserTokenPolicy >> serverEndpoints = new ArrayList <>();
507
478
508
479
for (EndpointDescription endpointDescription : extensionObjects ) {
509
- if (isMatchingEndpoint (endpointDescription , contactPoints )) {
480
+ if (isMatchingEndpointDescription (endpointDescription )) {
510
481
boolean policyMatch = endpointDescription .getSecurityPolicyUri ().getStringValue ().equals (securityPolicy .getSecurityPolicyUri ());
511
482
boolean msgSecurityMatch = endpointDescription .getSecurityMode ().equals (effectiveMessageSecurity );
512
483
@@ -530,22 +501,32 @@ private Entry<EndpointDescription, UserTokenPolicy> selectEndpoint(List<Endpoint
530
501
return serverEndpoints .get (0 );
531
502
}
532
503
504
+ private boolean isMatchingEndpointDescription (EndpointDescription endpointDescription ) {
505
+ if (isMatchingEndpoint (endpointDescription , driverContext .getHost (), driverContext .getPort (), driverContext .getTransportEndpoint ())) {
506
+ return true ;
507
+ }
508
+ if (configuration .getEndpointHost () != null ) {
509
+ return isMatchingEndpoint (endpointDescription , configuration .getEndpointHost (), configuration .getEndpointPort () == null ? driverContext .getPort () : String .valueOf (configuration .getEndpointPort ()), driverContext .getTransportEndpoint ());
510
+ } else if (configuration .getEndpointPort () != null ) {
511
+ return isMatchingEndpoint (endpointDescription , driverContext .getHost (), configuration .getEndpointPort ().toString (), driverContext .getTransportEndpoint ());
512
+ }
513
+ return false ;
514
+ }
515
+
533
516
/**
534
517
* Checks each component of the return endpoint description against the connection string.
535
518
* If all are correct then return true.
536
519
*
537
520
* @param endpoint - EndpointDescription returned from server
521
+ * @param host Permitted host
522
+ * @param port Permitted port
523
+ * @param transportEndpoint Transport endpoint
538
524
* @return true if this endpoint matches our configuration
539
525
* @throws PlcRuntimeException - If the returned endpoint string doesn't match the format expected
540
526
*/
541
- private static boolean isMatchingEndpoint (EndpointDescription endpoint , Collection <String > contactPoints ) throws PlcRuntimeException {
542
- // Split up the connection string into it's individual segments.
543
- for (String contactPoint : contactPoints ) {
544
- if (endpoint .getEndpointUrl ().getStringValue ().startsWith (contactPoint )) {
545
- return true ;
546
- }
547
- }
548
- return false ;
527
+ private static boolean isMatchingEndpoint (EndpointDescription endpoint , String host , String port , String transportEndpoint ) throws PlcRuntimeException {
528
+ String portAddition = port == null ? "" : ":" + port ;
529
+ return endpoint .getEndpointUrl ().getStringValue ().startsWith ("opc.tcp://" + host + portAddition + transportEndpoint );
549
530
}
550
531
551
532
/**
0 commit comments