Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1184,9 +1184,9 @@ public enum DefaultDriverOption implements DriverOption {
* system_views.clients} on Cassandra 4.1+) so operators can inspect driver settings while
* investigating incidents. It describes the effective configuration of the driver's default
* execution profile (connection/socket settings, timeouts, retry/reconnection/
* speculative-execution/load-balancing policies, connection pooling, query defaults, and TLS).
* Only the control connection sends it, since it describes the whole session. When {@code false},
* {@code DRIVER_CONFIG} is not sent.
* speculative-execution/load-balancing policies, connection pooling, and query defaults), plus
* the effective TLS state of the control connection carrying it. Only the control connection
* sends it. When {@code false}, {@code DRIVER_CONFIG} is not sent.
*
* <p>This option governs {@code DRIVER_CONFIG} only. The {@code SESSION_ID} startup option, which
* lets the server group all of a session's connections, is an innate driver behavior: it is sent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.datastax.oss.driver.api.core.metadata.EndPoint;
import com.datastax.oss.driver.api.core.type.codec.TypeCodecs;
import com.datastax.oss.driver.internal.core.DefaultProtocolFeature;
import com.datastax.oss.driver.internal.core.context.DriverConfigReporter.TlsInfo;
import com.datastax.oss.driver.internal.core.context.InternalDriverContext;
import com.datastax.oss.driver.internal.core.protocol.BytesToSegmentDecoder;
import com.datastax.oss.driver.internal.core.protocol.FrameDecoder;
Expand Down Expand Up @@ -62,8 +63,10 @@
import com.datastax.oss.protocol.internal.response.Supported;
import com.datastax.oss.protocol.internal.response.result.Rows;
import com.datastax.oss.protocol.internal.response.result.SetKeyspace;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.ssl.SslHandler;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -192,12 +195,14 @@ Message getRequest() {
case STARTUP:
Map<String, String> startupOptions = new HashMap<>(context.getStartupOptions());
featureStore.populateStartupOptions(startupOptions);
// The DRIVER_CONFIG blob describes the whole session, so only the control connection
// carries it (options.reportConfig); the other connections are correlated to it by the
// SESSION_ID that every connection already carries from context.getStartupOptions().
// No-op when driver config reporting is disabled.
// Most of DRIVER_CONFIG describes the whole session; its TLS group describes the control
// connection carrying it. Other connections are correlated to it by the SESSION_ID that
// every connection already carries from context.getStartupOptions(). No-op when driver
// config reporting is disabled.
if (options.reportConfig) {
context.getDriverConfigReporter().populateControlConnectionOptions(startupOptions);
context
.getDriverConfigReporter()
.populateControlConnectionOptions(startupOptions, currentTlsInfo());
}
return request = new Startup(startupOptions);
case GET_CLUSTER_NAME:
Expand All @@ -213,6 +218,21 @@ Message getRequest() {
}
}

private TlsInfo currentTlsInfo() {
try {
return tlsInfo(channel);
} catch (RuntimeException e) {
// Configuration reporting is best-effort and must never prevent a connection. TLS presence
// is still assumed because the failure came while inspecting its handler, but the schema
// permits hostname-verification to be omitted when unknown.
LOG.warn(
"[{}] Could not inspect hostname verification on the active SSL engine; omitting it",
logPrefix,
e);
return TlsInfo.enabledWithUnknownHostnameVerification();
}
}

@Override
void send() {
stepNumber++;
Expand Down Expand Up @@ -416,6 +436,21 @@ public String toString() {
}
}

static TlsInfo tlsInfo(Channel channel) {
// SslHandlerFactory always returns SslHandler, and this reads the pipeline after
// NettyOptions.afterChannelInitialized() has had a chance to add, replace, remove, or
// reconfigure it. A hook that implements encryption with a handler unrelated to SslHandler
// cannot be identified generically and is therefore reported as TLS-disabled.
SslHandler sslHandler = channel.pipeline().get(SslHandler.class);
if (sslHandler == null) {
return TlsInfo.disabled();
}
String endpointIdentificationAlgorithm =
sslHandler.engine().getSSLParameters().getEndpointIdentificationAlgorithm();
return TlsInfo.enabled(
endpointIdentificationAlgorithm != null && !endpointIdentificationAlgorithm.isEmpty());
}

/**
* Conditionally rebuilds pipeline.
*
Expand Down
Loading
Loading