-
Notifications
You must be signed in to change notification settings - Fork 59
Add TLS session resumption via SSLSessionCache #789
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
5d85a32
3cec910
21708f2
fcd1376
5cd68db
2a67558
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,7 +51,8 @@ | |
| from cassandra.connection import (ClientRoutesEndPointFactory, ConnectionException, ConnectionShutdown, | ||
| ConnectionHeartbeat, ProtocolVersionUnsupported, | ||
| EndPoint, DefaultEndPoint, DefaultEndPointFactory, | ||
| SniEndPointFactory, ConnectionBusy, locally_supported_compressions) | ||
| SniEndPointFactory, ConnectionBusy, locally_supported_compressions, | ||
| SSLSessionCache) | ||
| from cassandra.cqltypes import UserType | ||
| import cassandra.cqltypes as types | ||
| from cassandra.encoder import Encoder | ||
|
|
@@ -868,6 +869,51 @@ def default_retry_policy(self, policy): | |
| .. versionadded:: 3.17.0 | ||
| """ | ||
|
|
||
| ssl_session_cache = None | ||
| """ | ||
| A :class:`~cassandra.connection.SSLSessionCache` shared by every | ||
| connection this cluster opens, letting them resume TLS sessions instead of | ||
| performing a full handshake each time. This matters most for the group of | ||
| per-shard connections opened to a node at once, and for reconnections. | ||
|
|
||
| One is created automatically when :attr:`~Cluster.ssl_context` is set. | ||
| That decision is made while the :class:`.Cluster` is being constructed, as | ||
| it is for the other state derived from the TLS configuration, so setting | ||
| ``ssl_context`` afterwards leaves resumption off; assign a cache here | ||
| yourself if you configure TLS that way. | ||
|
|
||
| Pass ``ssl_session_cache=None`` to :class:`.Cluster` to turn resumption | ||
| off, or pass your own instance to size it or to share it between | ||
| clusters:: | ||
|
|
||
| from cassandra.connection import SSLSessionCache | ||
|
|
||
| cluster = Cluster(ssl_context=ssl_context, | ||
| ssl_session_cache=SSLSessionCache(max_size=64)) | ||
|
|
||
| Resumption is available when TLS is configured through | ||
| :attr:`~Cluster.ssl_context` and the reactor establishes TLS with the | ||
| standard library's ``ssl`` module: the ``libev`` and ``asyncore`` reactors, | ||
| which is to say the default one. | ||
|
|
||
| It is not available with the deprecated :attr:`~Cluster.ssl_options`-only | ||
| configuration, because each connection builds its own ``SSLContext`` and a | ||
| session cannot be replayed onto a different one; nor on the ``asyncio`` | ||
| reactor, which performs the handshake inside | ||
| ``loop.create_connection()``, leaving no point at which to restore a | ||
| session. In those cases no cache is created and connections handshake in | ||
| full. | ||
|
|
||
| It equally requires the server to hand out something it will honour later. | ||
| Scylla issues session tickets only when ``enable_session_tickets`` is set | ||
| in its ``client_encryption_options``, which is off by default; without it | ||
| nothing resumes and every connection performs a full handshake, as it would | ||
| have anyway. Over TLS 1.3 the cache then stays empty, while over TLS 1.2 | ||
| such a server still assigns a session id, so the cache may hold an entry it | ||
| will not honour -- offering that costs nothing and the handshake simply | ||
| completes in full. | ||
| """ | ||
|
|
||
| sockopts = None | ||
| """ | ||
| An optional list of tuples which will be used as arguments to | ||
|
|
@@ -1214,7 +1260,8 @@ def __init__(self, | |
| column_encryption_policy=None, | ||
| application_info:Optional[ApplicationInfoBase]=None, | ||
| client_routes_config:Optional[ClientRoutesConfig]=None, | ||
| allow_control_connection_query_fallback:Optional[ControlConnectionQueryFallback]=ControlConnectionQueryFallback.Disabled | ||
| allow_control_connection_query_fallback:Optional[ControlConnectionQueryFallback]=ControlConnectionQueryFallback.Disabled, | ||
| ssl_session_cache=_NOT_SET | ||
| ): | ||
| """ | ||
| ``executor_threads`` defines the number of threads in a pool for handling asynchronous tasks such as | ||
|
|
@@ -1461,6 +1508,21 @@ def __init__(self, | |
|
|
||
| self.ssl_options = ssl_options | ||
| self.ssl_context = ssl_context | ||
|
|
||
| if ssl_session_cache is _NOT_SET: | ||
|
sylwiaszunejko marked this conversation as resolved.
|
||
| # Resume TLS sessions by default, but only where it can work: the | ||
| # session has to be replayed onto the same SSLContext, and the | ||
| # reactor has to give the driver a chance to offer it before the | ||
| # handshake. | ||
| # connection_class is not required to derive from Connection, so | ||
| # treat one that does not report the capability as lacking it. | ||
| resumable = (ssl_context is not None and | ||
| getattr(self.connection_class, | ||
| 'supports_tls_session_resumption', False)) | ||
| self.ssl_session_cache = SSLSessionCache() if resumable else None | ||
|
coderabbitai[bot] marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: Every key embeds the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one is not fixed
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I fixed it, the key now holds |
||
| else: | ||
| self.ssl_session_cache = ssl_session_cache | ||
|
|
||
| self.sockopts = sockopts | ||
| self.cql_version = cql_version | ||
| self.max_schema_agreement_wait = max_schema_agreement_wait | ||
|
|
@@ -1681,6 +1743,7 @@ def _make_connection_kwargs(self, endpoint, kwargs_dict): | |
| kwargs_dict.setdefault('sockopts', self.sockopts) | ||
| kwargs_dict.setdefault('ssl_options', self.ssl_options) | ||
| kwargs_dict.setdefault('ssl_context', self.ssl_context) | ||
| kwargs_dict.setdefault('ssl_session_cache', self.ssl_session_cache) | ||
| kwargs_dict.setdefault('cql_version', self.cql_version) | ||
| kwargs_dict.setdefault('protocol_version', self.protocol_version) | ||
| kwargs_dict.setdefault('user_type_map', self._user_types) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.