Added OS-level timeout support for the DTLS I/O callbacks examples

pull/487/head
Reda Chouk 2025-02-14 11:46:42 +01:00
parent 702d54ca18
commit 7daf133366
2 changed files with 66 additions and 29 deletions

View File

@ -67,9 +67,35 @@ int my_IORecv(WOLFSSL* ssl, char* buff, int sz, void* ctx)
int recvd; int recvd;
struct sockaddr addr; struct sockaddr addr;
socklen_t addrSz = sizeof(addr); socklen_t addrSz = sizeof(addr);
int dtls_timeout;
printf("my_IORecv fd %d, buf %d\n", shared->sd, sz); printf("my_IORecv fd %d, buf %d\n", shared->sd, sz);
/* Get current DTLS handshake timeout. */
dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
printf("my_IORecv timeout %d\n", dtls_timeout);
/* If we are performing the DTLS handshake, and we are in blocking mode, we
* set a socket timeout at OS level. */
if (!wolfSSL_is_init_finished(ssl)) {
/* Still in handshake: set the OS timeout */
if (dtls_timeout > 0) {
struct timeval tv;
tv.tv_sec = dtls_timeout;
tv.tv_usec = 0;
if (setsockopt(shared->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
fprintf(stderr, "setsockopt failed\n");
return WOLFSSL_CBIO_ERR_GENERAL;
}
}
} else {
struct timeval tv = {0, 0};
if (setsockopt(shared->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
fprintf(stderr, "setsockopt failed\n");
return WOLFSSL_CBIO_ERR_GENERAL;
}
}
/* Receive datagram */ /* Receive datagram */
recvd = recvfrom(shared->sd, buff, sz, 0, &addr, &addrSz); recvd = recvfrom(shared->sd, buff, sz, 0, &addr, &addrSz);
if (recvd == -1) { if (recvd == -1) {

View File

@ -59,7 +59,6 @@ typedef struct SharedDtls {
struct sockaddr_in cliAddr; /* server sockaddr */ struct sockaddr_in cliAddr; /* server sockaddr */
socklen_t cliSz; /* length of servAddr */ socklen_t cliSz; /* length of servAddr */
byte rxBuf[DTLS_MTU]; byte rxBuf[DTLS_MTU];
word32 rxSz;
} SharedDtls; } SharedDtls;
@ -67,25 +66,36 @@ int my_IORecv(WOLFSSL* ssl, char* buff, int sz, void* ctx)
{ {
SharedDtls* shared = (SharedDtls*)ctx; SharedDtls* shared = (SharedDtls*)ctx;
int recvd; int recvd;
struct sockaddr addr; int dtls_timeout;
socklen_t addrSz = sizeof(addr);
printf("Server Recv fd %d, buf %d\n", shared->sd, sz); printf("Server Recv fd %d, buf %d\n", shared->sd, sz);
/* handle "peek" rx data */ dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
if (shared->rxSz > 0) {
recvd = shared->rxSz; /* If we are performing the DTLS handshake, and we are in blocking mode, we
if (recvd > sz) * set a socket timeout at OS level. */
recvd = sz; if (!wolfSSL_is_init_finished(ssl)) {
memcpy(buff, shared->rxBuf, recvd); /* Still in handshake: set the OS timeout */
shared->rxSz -= recvd; if (dtls_timeout > 0) {
memcpy(shared->rxBuf, &shared->rxBuf[recvd], shared->rxSz); struct timeval tv;
} tv.tv_sec = dtls_timeout;
else { tv.tv_usec = 0;
/* Receive datagram */ if (setsockopt(shared->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
recvd = recvfrom(shared->sd, buff, sz, 0, &addr, &addrSz); fprintf(stderr, "setsockopt failed\n");
return WOLFSSL_CBIO_ERR_GENERAL;
}
}
} else {
struct timeval tv = {0, 0};
if (setsockopt(shared->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
fprintf(stderr, "setsockopt failed\n");
return WOLFSSL_CBIO_ERR_GENERAL;
}
} }
/* Receive datagram and store client's address */
recvd = recvfrom(shared->sd, buff, sz, 0, (struct sockaddr*)&shared->cliAddr, &shared->cliSz);
if (recvd == -1) { if (recvd == -1) {
/* error encountered. Be responsible and report it in wolfSSL terms */ /* error encountered. Be responsible and report it in wolfSSL terms */
@ -284,20 +294,21 @@ int main(int argc, char** argv)
shared.sd = listenfd; shared.sd = listenfd;
shared.cliSz = sizeof(shared.cliAddr); shared.cliSz = sizeof(shared.cliAddr);
ret = (int)recvfrom(listenfd, (char*)shared.rxBuf, sizeof(shared.rxBuf), 0, /*
(struct sockaddr*)&shared.cliAddr, &shared.cliSz); * Wait until the socket is readable
if (ret < 0) { * and wait until we actually have data waiting to be read.
printf("No clients in queue, enter idle state\n"); * */
continue; {
} fd_set readfds;
else if (ret > 0) { FD_ZERO(&readfds);
shared.rxSz = ret; FD_SET(listenfd, &readfds);
ret = 0;
printf("Connected!\n"); /* No timeout, so wait indefinitely */
} int sel_ret = select(listenfd + 1, &readfds, NULL, NULL, NULL);
else { if (sel_ret < 0) {
printf("Recvfrom failed %d.\n", errno); perror("select");
break; goto exit;
}
} }
/* Create the WOLFSSL Object */ /* Create the WOLFSSL Object */