summaryrefslogtreecommitdiff
path: root/leakcheck/thread-crash.py
blob: a1ebbdd194a33e1d8d274a6a5de5407f8eaa1f0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# Copyright (C) Jean-Paul Calderone
# See LICENSE for details.
#
# Stress tester for thread-related bugs in ssl_Connection_send and
# ssl_Connection_recv in src/ssl/connection.c for usage of a single
# Connection object simultaneously in multiple threads.  In 0.7 and earlier,
# this will somewhat reliably cause Python to abort with a "tstate mix-up"
# almost immediately, due to the incorrect sharing between threads of the
# `tstate` field of the connection object.


from socket import socket
from threading import Thread

from OpenSSL.SSL import Connection, Context, TLSv1_METHOD

def send(conn):
    while 1:
        for i in xrange(1024 * 32):
            conn.send('x')
        print 'Sent 32KB on', hex(id(conn))


def recv(conn):
    while 1:
        for i in xrange(1024 * 64):
            conn.recv(1)
        print 'Received 64KB on', hex(id(conn))


def main():
    port = socket()
    port.bind(('', 0))
    port.listen(5)

    client = socket()
    client.setblocking(False)
    client.connect_ex(port.getsockname())
    client.setblocking(True)

    server = port.accept()[0]

    clientCtx = Context(TLSv1_METHOD)
    clientCtx.set_cipher_list('ALL:ADH')
    clientCtx.load_tmp_dh('dhparam.pem')

    sslClient = Connection(clientCtx, client)
    sslClient.set_connect_state()

    serverCtx = Context(TLSv1_METHOD)
    serverCtx.set_cipher_list('ALL:ADH')
    serverCtx.load_tmp_dh('dhparam.pem')

    sslServer = Connection(serverCtx, server)
    sslServer.set_accept_state()

    t1 = Thread(target=send, args=(sslClient,))
    t2 = Thread(target=send, args=(sslServer,))
    t3 = Thread(target=recv, args=(sslClient,))
    t4 = Thread(target=recv, args=(sslServer,))

    t1.start()
    t2.start()
    t3.start()
    t4.start()
    t1.join()
    t2.join()
    t3.join()
    t4.join()

main()