Bound DTLS handshakes with a monotonic deadline - #34
Conversation
eae1aef to
5ecfb71
Compare
|
The wall-clock problem this fixes is worse than the PR body suggests, and I want to record why before anything else.
Before it goes in, one question about how the timing is done.
to = conn.DTLSv1_get_timeout()
if to is not None and to <= 0:
if retransmits >= retries:
break
conn.DTLSv1_handle_timeout()
retransmits += 1The pyOpenSSL floor was raised to 23.1 in This PR keeps that cadence and adds a deadline around it, which gives us two hand-rolled timing schemes in one package. Could I'm raising it now rather than as a follow-up because On ordering. Your stack has this behind #33, but I'd like to do that and land this first. #33 has a confirmed field failure open against it (vmonkey's non-DER leaf) and no consumer in either this repo's bridge or mbillow/localthings today. This PR has users hitting the wall-clock path right now. If #33's parser fix turns around quickly then the order doesn't matter much and I'm happy to take your original sequence. If it takes longer, I don't want the startup-reconnect fix waiting behind a certificate profile nobody is calling yet. Happy to rebase myself if you'd prefer. |
5ecfb71 to
a44930f
Compare
|
That makes sense. I’ve rebased this directly onto current main, so it no longer depends on #33. I also removed the separate fixed-cadence handshake loop. connect() and the diagnostic path now use one shared memory-BIO driver: the application owns the total monotonic deadline, while OpenSSL’s DTLSv1_get_timeout() / DTLSv1_handle_timeout() control flight retransmission. The old 50 ms sleep and flat two-second cadence are gone. Good catch! Let me know if you find anything else |
|
Merged in v0.1.7, thanks. I smoke-tested the whole stack (#34/#35/#33) on a live dryer and oven before merging. Both handshakes completed ~6s after a container recreate, and steady-state polling held at 0 errors with no forced reconnect. The retransmit servicing you added is new behaviour on these devices (the old One minor thing for a follow-up, non-blocking: in |
Problem
connect()measures its handshake budget withtime.time(). A clock step during Home Assistant startup can therefore expire a connection immediately or let it run well past its intended bound. The session also maintains a second, fixed-cadence handshake loop beside the diagnostic probe's OpenSSL-timed loop.Changes
connect(timeout=...), retaining the 12-second default.connect()anddiagnose_dtls_handshake().DTLSv1_get_timeout()/DTLSv1_handle_timeout()schedule retransmissions instead of sleeping 50 ms and retrying on a flat two-second cadence.Expiry continues to use the existing
SessionTimeoutError.Validation
The deterministic timing tests cover malformed values, context and socket setup time, shortened final waits, success at and after expiry, the default timeout, and an OpenSSL-timed retransmission after a dropped flight.
Independence
This is one signed commit,
a44930f, directly on currentmain(b0d51ab/ v0.1.6). It has no dependency on #33. Connection-attempt cancellation remains separate in #35.