Hi, I may be misunderstanding the intended error contract.
The README says every Error returned by handle_packet, handle_timeout, send_application_data, or close is fatal and that the Dtls instance should always be dropped:
https://github.com/algesten/dimpl/blob/37f950984af1d0c2f86ef21b940c672fb27cd7c7/README.md#error-handling
However, Error::HandshakePending says callers should buffer the data and retry once the handshake advances:
|
/// Application data cannot be sent because the handshake is not yet complete. |
|
/// |
|
/// For auto-sense instances this means the version has not yet been |
|
/// resolved. Callers should buffer the data and retry once the |
|
/// handshake advances. |
|
HandshakePending, |
send_application_data repeats that guidance, and both it and close return HandshakePending from the pending branch before invoking the protocol-specific send or close logic:
|
/// Send application data over the established DTLS session. |
|
/// |
|
/// Returns [`Error::HandshakePending`] if the DTLS version has not |
|
/// yet been resolved (auto-sense pending). Callers should buffer |
|
/// the data externally and retry after the handshake progresses. |
|
pub fn send_application_data(&mut self, data: &[u8]) -> Result<(), Error> { |
|
// unwrap is ok, we only have an Option to deal with pending auto. |
|
let inner = self.inner.as_mut().unwrap(); |
|
|
|
if inner.is_pending() { |
|
return Err(Error::HandshakePending); |
|
} |
|
|
|
match inner { |
|
Inner::Client12(client) => client.send_application_data(data), |
|
Inner::Server12(server) => server.send_application_data(data), |
|
Inner::Client13(client) => client.send_application_data(data), |
|
Inner::Server13(server) => server.send_application_data(data), |
|
Inner::ClientPending(_) => Err(Error::HandshakePending), |
|
} |
|
} |
|
|
|
/// Initiate graceful shutdown by sending a `close_notify` alert. |
|
/// |
|
/// **Connected** (`AwaitApplicationData`): queues a `close_notify` alert; |
|
/// the next [`poll_output`](Self::poll_output) cycle yields it as |
|
/// [`Output::Packet`]. |
|
/// |
|
/// **Handshake in progress**: aborts immediately without sending an |
|
/// alert (no authenticated channel exists). Subsequent calls to |
|
/// [`send_application_data`](Self::send_application_data) will return |
|
/// an error. |
|
/// |
|
/// **Pending** (version not yet resolved): returns |
|
/// [`Error::HandshakePending`]. Callers who want to discard a pending |
|
/// connection can simply drop the [`Dtls`] value. |
|
/// |
|
/// The alert is not retransmitted (per RFC 6347 §4.2.7 / RFC 9147 §5.10). |
|
pub fn close(&mut self) -> Result<(), Error> { |
|
let inner = self.inner.as_mut().unwrap(); |
|
|
|
if inner.is_pending() { |
|
return Err(Error::HandshakePending); |
|
} |
|
|
|
match inner { |
|
Inner::Client12(client) => client.close(), |
|
Inner::Server12(server) => server.close(), |
|
Inner::Client13(client) => client.close(), |
|
Inner::Server13(server) => server.close(), |
|
Inner::ClientPending(_) => Err(Error::HandshakePending), |
|
} |
Does this mean HandshakePending is recoverable and should be documented as an exception to the README’s fatal-error rule?
Hi, I may be misunderstanding the intended error contract.
The README says every
Errorreturned byhandle_packet,handle_timeout,send_application_data, orcloseis fatal and that theDtlsinstance should always be dropped:https://github.com/algesten/dimpl/blob/37f950984af1d0c2f86ef21b940c672fb27cd7c7/README.md#error-handling
However,
Error::HandshakePendingsays callers should buffer the data and retry once the handshake advances:dimpl/src/error.rs
Lines 46 to 51 in 37f9509
send_application_datarepeats that guidance, and both it andclosereturnHandshakePendingfrom the pending branch before invoking the protocol-specific send or close logic:dimpl/src/lib.rs
Lines 816 to 867 in 37f9509
Does this mean
HandshakePendingis recoverable and should be documented as an exception to the README’s fatal-error rule?