|
9 | 9 | import gc
|
10 | 10 | import select
|
11 | 11 | import sys
|
| 12 | +import time |
12 | 13 | import uuid
|
13 | 14 | from errno import (
|
14 | 15 | EAFNOSUPPORT,
|
@@ -4369,10 +4370,11 @@ class TestDTLS:
|
4369 | 4370 | # new versions of OpenSSL, this is unnecessary, but harmless, because the
|
4370 | 4371 | # DTLS state machine treats it like a network hiccup that duplicated a
|
4371 | 4372 | # packet, which DTLS is robust against.
|
4372 |
| - def test_it_works_at_all(self): |
4373 |
| - # arbitrary number larger than any conceivable handshake volley |
4374 |
| - LARGE_BUFFER = 65536 |
4375 | 4373 |
|
| 4374 | + # Arbitrary number larger than any conceivable handshake volley. |
| 4375 | + LARGE_BUFFER = 65536 |
| 4376 | + |
| 4377 | + def test_it_works_at_all(self): |
4376 | 4378 | s_ctx = Context(DTLS_METHOD)
|
4377 | 4379 |
|
4378 | 4380 | def generate_cookie(ssl):
|
@@ -4403,7 +4405,7 @@ def verify_cookie(ssl, cookie):
|
4403 | 4405 |
|
4404 | 4406 | def pump_membio(label, source, sink):
|
4405 | 4407 | try:
|
4406 |
| - chunk = source.bio_read(LARGE_BUFFER) |
| 4408 | + chunk = source.bio_read(self.LARGE_BUFFER) |
4407 | 4409 | except WantReadError:
|
4408 | 4410 | return False
|
4409 | 4411 | # I'm not sure this check is needed, but I'm not sure it's *not*
|
@@ -4483,3 +4485,39 @@ def pump():
|
4483 | 4485 | assert 0 < c.get_cleartext_mtu() < 500
|
4484 | 4486 | except NotImplementedError: # OpenSSL 1.1.0 and earlier
|
4485 | 4487 | pass
|
| 4488 | + |
| 4489 | + def test_timeout(self, monkeypatch): |
| 4490 | + c_ctx = Context(DTLS_METHOD) |
| 4491 | + c = Connection(c_ctx) |
| 4492 | + |
| 4493 | + # No timeout before the handshake starts. |
| 4494 | + assert c.DTLSv1_get_timeout() is None |
| 4495 | + assert c.DTLSv1_handle_timeout() is False |
| 4496 | + |
| 4497 | + # Start handshake and check there is data to send. |
| 4498 | + c.set_connect_state() |
| 4499 | + try: |
| 4500 | + c.do_handshake() |
| 4501 | + except SSL.WantReadError: |
| 4502 | + pass |
| 4503 | + assert c.bio_read(self.LARGE_BUFFER) |
| 4504 | + |
| 4505 | + # There should now be an active timeout. |
| 4506 | + seconds = c.DTLSv1_get_timeout() |
| 4507 | + assert seconds is not None |
| 4508 | + |
| 4509 | + # Handle the timeout and check there is data to send. |
| 4510 | + time.sleep(seconds) |
| 4511 | + assert c.DTLSv1_handle_timeout() is True |
| 4512 | + assert c.bio_read(self.LARGE_BUFFER) |
| 4513 | + |
| 4514 | + # After the maximum number of allowed timeouts is reached, |
| 4515 | + # DTLSv1_handle_timeout will return -1. |
| 4516 | + # |
| 4517 | + # Testing this directly is prohibitively time consuming as the timeout |
| 4518 | + # duration is doubled on each retry, so the best we can do is to mock |
| 4519 | + # this condition. |
| 4520 | + monkeypatch.setattr(_lib, "DTLSv1_handle_timeout", lambda x: -1) |
| 4521 | + |
| 4522 | + with pytest.raises(Error): |
| 4523 | + c.DTLSv1_handle_timeout() |
0 commit comments