use of com.datastax.oss.driver.internal.core.metadata.SniEndPoint in project java-driver by datastax.
the class CloudConfigFactory method getEndPoints.
@NonNull
protected List<EndPoint> getEndPoints(@NonNull JsonNode proxyMetadata, @NonNull InetSocketAddress sniProxyAddress) {
JsonNode contactInfo = getContactInfo(proxyMetadata);
if (contactInfo.has("contact_points")) {
List<EndPoint> endPoints = new ArrayList<>();
JsonNode hostIdsJson = contactInfo.get("contact_points");
for (int i = 0; i < hostIdsJson.size(); i++) {
endPoints.add(new SniEndPoint(sniProxyAddress, hostIdsJson.get(i).asText()));
}
return endPoints;
} else {
throw new IllegalStateException("Invalid proxy metadata: missing field contact_points");
}
}
use of com.datastax.oss.driver.internal.core.metadata.SniEndPoint in project java-driver by datastax.
the class SniSslEngineFactory method newSslEngine.
@NonNull
@Override
public SSLEngine newSslEngine(@NonNull EndPoint remoteEndpoint) {
if (!(remoteEndpoint instanceof SniEndPoint)) {
throw new IllegalArgumentException(String.format("Configuration error: can only use %s with SNI end points", this.getClass().getSimpleName()));
}
SniEndPoint sniEndPoint = (SniEndPoint) remoteEndpoint;
InetSocketAddress address = sniEndPoint.resolve();
String sniServerName = sniEndPoint.getServerName();
// When hostname verification is enabled (with setEndpointIdentificationAlgorithm), the SSL
// engine will try to match the server's certificate against the SNI host name; if that doesn't
// work, it will fall back to the "advisory peer host" passed to createSSLEngine.
//
// In our case, the first check will never succeed because our SNI host name is not the DNS name
// (we use the Cassandra host_id instead). So we *must* set the advisory peer information.
//
// However if we use the address as-is, this leads to another issue: the advisory peer
// information is also used to cache SSL sessions internally. All of our nodes share the same
// proxy address, so the JDK tries to reuse SSL sessions across nodes. But it doesn't update the
// SNI host name every time, so it ends up opening connections to the wrong node.
//
// To avoid that, we create a unique "fake" port for every node. We still get session reuse for
// a given node, but not across nodes. This is safe because the advisory port is only used for
// session caching.
SSLEngine engine = sslContext.createSSLEngine(address.getHostName(), getFakePort(sniServerName));
engine.setUseClientMode(true);
SSLParameters parameters = engine.getSSLParameters();
parameters.setServerNames(ImmutableList.of(new SNIHostName(sniServerName)));
parameters.setEndpointIdentificationAlgorithm("HTTPS");
engine.setSSLParameters(parameters);
return engine;
}
Aggregations