diff options
author | Cory Benfield <lukasaoz@gmail.com> | 2016-11-28 12:17:08 +0000 |
---|---|---|
committer | Hynek Schlawack <hs@ox.cx> | 2016-11-28 13:17:08 +0100 |
commit | e62840e19c5f1640afff1ff4d84df05cda652085 (patch) | |
tree | a5e903d910e8412c1571b17766cc96a0152217ae | |
parent | f189de9becf14840712b01877ebb1f08c26f894c (diff) | |
download | pyopenssl-e62840e19c5f1640afff1ff4d84df05cda652085.tar.gz |
Don't zero memory when we don't have to. (#578)
-rw-r--r-- | CHANGELOG.rst | 4 | ||||
-rw-r--r-- | src/OpenSSL/SSL.py | 15 | ||||
-rw-r--r-- | src/OpenSSL/_util.py | 6 |
3 files changed, 18 insertions, 7 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 19cebf1..56c3c74 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -25,6 +25,10 @@ Changes: - Added ``OpenSSL.X509Store.set_time()`` to set a custom verification time when verifying certificate chains. `#567 <https://github.com/pyca/pyopenssl/pull/567>`_ +- Changed the ``SSL`` module's memory allocation policy to avoid zeroing memory it allocates when unnecessary. + This reduces CPU usage and memory allocation time by an amount proportional to the size of the allocation. + For applications that process a lot of TLS data or that use very lage allocations this can provide considerable performance improvements. + `#578 <https://github.com/pyca/pyopenssl/pull/578>`_ ---- diff --git a/src/OpenSSL/SSL.py b/src/OpenSSL/SSL.py index f92c064..63a0b7e 100644 --- a/src/OpenSSL/SSL.py +++ b/src/OpenSSL/SSL.py @@ -18,6 +18,7 @@ from OpenSSL._util import ( native as _native, path_string as _path_string, text_to_bytes_and_warn as _text_to_bytes_and_warn, + no_zero_allocator as _no_zero_allocator, ) from OpenSSL.crypto import ( @@ -1297,7 +1298,7 @@ class Connection(object): all other flags are ignored. :return: The string read from the Connection """ - buf = _ffi.new("char[]", bufsiz) + buf = _no_zero_allocator("char[]", bufsiz) if flags is not None and flags & socket.MSG_PEEK: result = _lib.SSL_peek(self._ssl, buf, bufsiz) else: @@ -1328,7 +1329,7 @@ class Connection(object): # We need to create a temporary buffer. This is annoying, it would be # better if we could pass memoryviews straight into the SSL_read call, # but right now we can't. Revisit this if CFFI gets that ability. - buf = _ffi.new("char[]", nbytes) + buf = _no_zero_allocator("char[]", nbytes) if flags is not None and flags & socket.MSG_PEEK: result = _lib.SSL_peek(self._ssl, buf, nbytes) else: @@ -1379,7 +1380,7 @@ class Connection(object): if not isinstance(bufsiz, integer_types): raise TypeError("bufsiz must be an integer") - buf = _ffi.new("char[]", bufsiz) + buf = _no_zero_allocator("char[]", bufsiz) result = _lib.BIO_read(self._from_ssl, buf, bufsiz) if result <= 0: self._handle_bio_errors(self._from_ssl, result) @@ -1616,7 +1617,7 @@ class Connection(object): return None length = _lib.SSL_get_server_random(self._ssl, _ffi.NULL, 0) assert length > 0 - outp = _ffi.new("unsigned char[]", length) + outp = _no_zero_allocator("unsigned char[]", length) _lib.SSL_get_server_random(self._ssl, outp, length) return _ffi.buffer(outp, length)[:] @@ -1632,7 +1633,7 @@ class Connection(object): length = _lib.SSL_get_client_random(self._ssl, _ffi.NULL, 0) assert length > 0 - outp = _ffi.new("unsigned char[]", length) + outp = _no_zero_allocator("unsigned char[]", length) _lib.SSL_get_client_random(self._ssl, outp, length) return _ffi.buffer(outp, length)[:] @@ -1648,7 +1649,7 @@ class Connection(object): length = _lib.SSL_SESSION_get_master_key(session, _ffi.NULL, 0) assert length > 0 - outp = _ffi.new("unsigned char[]", length) + outp = _no_zero_allocator("unsigned char[]", length) _lib.SSL_SESSION_get_master_key(session, outp, length) return _ffi.buffer(outp, length)[:] @@ -1788,7 +1789,7 @@ class Connection(object): # No Finished message so far. return None - buf = _ffi.new("char[]", size) + buf = _no_zero_allocator("char[]", size) function(self._ssl, buf, size) return _ffi.buffer(buf, size)[:] diff --git a/src/OpenSSL/_util.py b/src/OpenSSL/_util.py index 48bcbf5..cf8b888 100644 --- a/src/OpenSSL/_util.py +++ b/src/OpenSSL/_util.py @@ -12,6 +12,12 @@ ffi = binding.ffi lib = binding.lib +# This is a special CFFI allocator that does not bother to zero its memory +# after allocation. This has vastly better performance on large allocations and +# so should be used whenever we don't need the memory zeroed out. +no_zero_allocator = ffi.new_allocator(should_clear_after_alloc=False) + + def text(charp): """ Get a native string type representing of the given CFFI ``char*`` object. |