-
Notifications
You must be signed in to change notification settings - Fork 835
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DTLS: Add server side stateless and CID QoL API #8224
base: master
Are you sure you want to change the base?
Conversation
julek-wolfssl
commented
Nov 25, 2024
- wolfDTLS_accept_stateless - statelessly listen for incoming connections
- wolfSSL_inject - insert data into WOLFSSL object
- wolfSSL_SSL(Enable|Disable)Read - enable/disable reading from IO
- wolfSSL_get_wfd - get the write side file descriptor
- wolfSSL_dtls_set_pending_peer - set the pending peer that will be upgraded to regular peer when we successfully de-protect a DTLS record
- wolfSSL_dtls_get0_peer - zero copy access to the peer address
- wolfSSL_is_stateful - boolean to check if we have entered stateful processing
- wolfSSL_dtls_cid_get0_rx - zero copy access to the rx cid
- wolfSSL_dtls_cid_get0_tx - zero copy access to the tx cid
- wolfSSL_dtls_cid_parse - extract cid from a datagram/message
023cc55
to
86376db
Compare
9b95077
to
baa7738
Compare
- wolfDTLS_accept_stateless - statelessly listen for incoming connections - wolfSSL_inject - insert data into WOLFSSL object - wolfSSL_SSL(Enable|Disable)Read - enable/disable reading from IO - wolfSSL_get_wfd - get the write side file descriptor - wolfSSL_dtls_set_pending_peer - set the pending peer that will be upgraded to regular peer when we successfully de-protect a DTLS record - wolfSSL_dtls_get0_peer - zero copy access to the peer address - wolfSSL_is_stateful - boolean to check if we have entered stateful processing - wolfSSL_dtls_cid_get0_rx - zero copy access to the rx cid - wolfSSL_dtls_cid_get0_tx - zero copy access to the tx cid - wolfSSL_dtls_cid_parse - extract cid from a datagram/message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a big step in the right direction but there are things unclear. These comments are considering wolfSSL/wolfssl-examples#472 as the user of the changes in this PR.
-
what's the purpose of splitting the fd in write and read?
-
I don't get why we should use the pendingPeer and the example doesn't use it. It looks complicate and there is code that get hit after we copy the pendingPeer to the current Peer that it doesn't look doing nothing other than flipping the processPendingRecord bit.
-
I don't see much gain in using wolfSSL_accept_stateless.
AFAIU it just boils down in a) disabling read so that it can return before reading from the socket and b) to return after a good CH. a) avoids dropping other peer messages that can be received in the EmbedRecvFrom. But, as shown in the example, the server has already to read the messages itself outside of the wolfSSL to do proper demux. I wonder if then this is superfluous.
I would suggest of using a custom internal field like the pendingPeer, but called, as you suggested, currentRecordPeer.
Until the ssl is stateless, this is set on recvfrom, but no filtering happens bc of this.
It's used as the destination of the HRR/HVR and to compute the cookie.
It's not used anywhere else and it's not automatically copied over the other peer.
This way an ssl object can be used to reply to the CHs w/o cookies.
If we got a CH w/ valid cookie we can then leverage our existing goodch callback to set the right peer for sending and continue the connection.
If the application wants to demux, it needs to manage the reading from the socket itself anyway.
Just to recap, my suggestion are:
- In EmbedRecvFrom to set a "peer to send the HRR/HRV" to if we are in a stateless
- Application needs to use ChGoodCB to set the proper peer (is it already like this?)
- Make clear that application needs to manage the read itself if it wants to demux over a single socket
The new APIs (inject, parse_cid) allows the application to manage the connection with a good tradeoff of complexity and control imo.
/*! | ||
\ingroup IO | ||
|
||
\brief |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing doc
\brief Get the ConnectionID used by the other peer. See RFC 9146 and RFC | ||
9147. | ||
|
||
\return WOLFSSL_SUCCESS if ConnectionID was correctly copied, error code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ConnectionID is not copied.
if (msgSz < DTLS_RECORD_HEADER_SZ + cidSz) | ||
return; | ||
/* content type(1) + version(2) + epoch(2) + sequence(6) */ | ||
*cid = msg + ENUM_LEN + VERSION_SZ + OPAQUE16_LEN + OPAQUE16_LEN + | ||
OPAQUE32_LEN; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the calculation of lengths are different between the check and the parsing?
int result = DtlsMsgPoolSend(ssl, 0); | ||
int result; | ||
#ifdef WOLFSSL_DTLS13 | ||
if (IsAtLeastTLSv1_3(ssl->version)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change related to the feature or is a general fix?
|
||
if (ssl->buffers.dtlsCtx.peer.sa != NULL && | ||
ssl->buffers.dtlsCtx.peer.sz == peerSz && | ||
XMEMCMP(ssl->buffers.dtlsCtx.peer.sa, peer, peerSz) == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the correct way to compare sockaddr structure, see sockAddrEqual
if (ssl->buffers.inputBuffer.length - *inOutIdx < | ||
(word32)cidSz + LENGTH_SZ) | ||
return LENGTH_ERROR; | ||
if (cidSz > DTLS_CID_MAX_SIZE || | ||
wolfSSL_dtls_cid_get_rx(ssl, cid, cidSz) != WOLFSSL_SUCCESS) | ||
if (cidSz != DtlsGetCidRxSize(ssl) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this check redundant? we set cidSz to DtlsGetCidRxSize() before
|
||
WOLFSSL_ENTER("wolfSSL_read_internal"); | ||
|
||
if (ssl == NULL || data == NULL || sz <= 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we allow sz == 0?
int wolfSSL_dtls_cid_max_size(void) | ||
{ | ||
return DTLS_CID_MAX_SIZE; | ||
} | ||
|
||
void wolfSSL_dtls_cid_parse(const unsigned char* msg, unsigned int msgSz, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return WOLFSSL_SUCCESS or WOLFSSL_FAILURE.
\sa wolfSSL_dtls_set_peer | ||
\sa wolfSSL_dtls | ||
*/ | ||
int wolfSSL_dtls_get0_peer(WOLFSSL* ssl, const void** peer, unsigned int* peerSz); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't expose the internal cid.
Prefer to add an API to compare to the ssl cid object if afraid of performance loss of copying the cid.
(like wolfSSL_dtls_cid_cmp(WOLFSSL*ssl,byte *cid, int cidSz)
)
baa7738
to
935227a
Compare