mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-08-10 04:31:24 +02:00
With WOLFSSL_RW_THREADED the read path performs no scheduled work, because transmitting from the reader would race the write thread over the output buffer and the sending key schedule, neither of which is covered by a lock. Post-handshake the only remaining consumers are on the write path, and wolfSSL_dtls_retransmit() only helps while the handshake is unfinished. An application that reads without writing therefore never acknowledges a NewSessionTicket, KeyUpdate or connection ID message, and the peer keeps retransmitting what it is waiting to have acknowledged. RFC 9147 relies on those ACKs, so this is a protocol level break rather than a missed optimisation. Add wolfSSL_dtls13_do_scheduled_work() so such an application can send that work from its write thread, and wolfSSL_dtls13_pending_work() so it can tell when there is any. Both entry points ask the same helpers rather than each testing conditions of their own, so they cannot drift into the predicate promising work the pump then declines or silently discards, which would leave a drain loop spinning or mislead the caller about what happened. That covers key updates in particular: none is sent while one of ours is unacknowledged, since DTLS must not have two in flight and Tls13UpdateKeys() drops a locally scheduled one in that state, and a peer request is kept rather than dropped until it can be answered. The predicate also errs towards reporting work when it cannot tell, so a loop surfaces the error rather than stopping silently. Refusing an object is treated as a usage error and leaves ssl->error alone. That field is sticky, since SendData() only clears it for WANT_WRITE, pending async work and the DTLS MAC and decrypt cases, and wolfSSL_write() skips its write-dup drain while it is set, so recording one would disable the very drain a write-dup application depends on. Write-dup pairs are out of scope on both sides. They park the read side's work in the shared WriteDup struct, which only wolfSSL_write() reconciles, so they already have a drain. Completing a key update we started ourselves is out of scope too: that needs the peer's acknowledgement processed, which rotates the sending keys and creates an epoch, and the epoch table has no locking while the read thread mutates it as well. The declaration is gated to match where the definitions live, so a lean build is not promised a symbol it does not get.
The wolfSSL manual is available at: http://www.wolfssl.com/documentation/wolfSSL-Manual.pdf The wolfSSL API guide is available at: https://www.wolfssl.com/doxygen/wolfssl_API.html The wolfCrypt API guide is available at: https://www.wolfssl.com/doxygen/wolfcrypt_API.html