Skip to content
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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

julek-wolfssl
Copy link
Member

  • 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

- 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
Copy link
Contributor

@rizlik rizlik left a 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.

  1. what's the purpose of splitting the fd in write and read?

  2. 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.

  3. 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
Copy link
Contributor

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConnectionID is not copied.

Comment on lines +1421 to +1434
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;
Copy link
Contributor

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))
Copy link
Contributor

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) {
Copy link
Contributor

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) ||
Copy link
Contributor

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)
Copy link
Contributor

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,
Copy link
Contributor

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);
Copy link
Contributor

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))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants