Skip to content

Commit

Permalink
chore: pull helio add test for tls deadlock (#3111)
Browse files Browse the repository at this point in the history
* pull helio
* add test that covers tls deadlock
  • Loading branch information
kostasrim authored Jun 3, 2024
1 parent 4a1831c commit 3924fca
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/core/segment_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace dfly {

/**
* @brief Tightly coupled with mi_malloc 2.x implementation.
* Fetches 4MB segment pointers from the allocated pointers.
* Fetches 4MiB segment pointers from the allocated pointers.
* Provides own indexing of small pointers to real address space using the segment ptrs/
*/

Expand Down
48 changes: 48 additions & 0 deletions tests/dragonfly/connection_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import pytest
import asyncio
import time
import socket
import random
import ssl
from redis import asyncio as aioredis
from redis.exceptions import ConnectionError as redis_conn_error, ResponseError
import async_timeout
Expand Down Expand Up @@ -756,3 +759,48 @@ async def client_pause():

assert not all.done()
await all


async def test_tls_when_read_write_is_interleaved(
with_ca_tls_server_args, with_ca_tls_client_args, df_local_factory
):
"""
This test covers a deadlock bug in helio and TlsSocket when a client connection renegotiated a
handshake without reading its pending data from the socket.
This is a weak test case and from our local experiments it deadlocked 30% of the test runs
"""
server: DflyInstance = df_local_factory.create(
port=1211, **with_ca_tls_server_args, proactor_threads=1
)
server.start()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

ssl_key = with_ca_tls_client_args["ssl_keyfile"]
ssl_cert = with_ca_tls_client_args["ssl_certfile"]
ssl_ca_cert = with_ca_tls_client_args["ssl_ca_certs"]
ssl_sock = ssl.wrap_socket(
s,
keyfile=ssl_key,
certfile=ssl_cert,
ca_certs=ssl_ca_cert,
ssl_version=ssl.PROTOCOL_TLSv1_2,
)
ssl_sock.connect(("127.0.0.1", server.port))

tmp = "f" * 1000
message = f"SET foo {tmp}\r\n".encode()
ssl_sock.send(message)

for i in range(0, 100000):
res = random.randint(1, 4)
message = b""
for j in range(0, res):
message = message + b"GET foo\r\n"
ssl_sock.send(message)
ssl_sock.do_handshake()

# This deadlocks
client = aioredis.Redis(port=server.port, **with_ca_tls_client_args)
await client.execute_command("GET foo")
await client.close()

0 comments on commit 3924fca

Please sign in to comment.