Skip to content

Commit 8573325

Browse files
Merge pull request wolfSSL#487 from gasbytes/timeout-dtls-examples
Added OS-level timeout support for the DTLS I/O callbacks examples
2 parents 702d54c + 7daf133 commit 8573325

File tree

2 files changed

+66
-29
lines changed

2 files changed

+66
-29
lines changed

dtls/client-dtls-callback.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,35 @@ int my_IORecv(WOLFSSL* ssl, char* buff, int sz, void* ctx)
6767
int recvd;
6868
struct sockaddr addr;
6969
socklen_t addrSz = sizeof(addr);
70+
int dtls_timeout;
7071

7172
printf("my_IORecv fd %d, buf %d\n", shared->sd, sz);
7273

74+
/* Get current DTLS handshake timeout. */
75+
dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
76+
printf("my_IORecv timeout %d\n", dtls_timeout);
77+
78+
/* If we are performing the DTLS handshake, and we are in blocking mode, we
79+
* set a socket timeout at OS level. */
80+
if (!wolfSSL_is_init_finished(ssl)) {
81+
/* Still in handshake: set the OS timeout */
82+
if (dtls_timeout > 0) {
83+
struct timeval tv;
84+
tv.tv_sec = dtls_timeout;
85+
tv.tv_usec = 0;
86+
if (setsockopt(shared->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
87+
fprintf(stderr, "setsockopt failed\n");
88+
return WOLFSSL_CBIO_ERR_GENERAL;
89+
}
90+
}
91+
} else {
92+
struct timeval tv = {0, 0};
93+
if (setsockopt(shared->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
94+
fprintf(stderr, "setsockopt failed\n");
95+
return WOLFSSL_CBIO_ERR_GENERAL;
96+
}
97+
}
98+
7399
/* Receive datagram */
74100
recvd = recvfrom(shared->sd, buff, sz, 0, &addr, &addrSz);
75101
if (recvd == -1) {

dtls/server-dtls-callback.c

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -59,33 +59,43 @@ typedef struct SharedDtls {
5959
struct sockaddr_in cliAddr; /* server sockaddr */
6060
socklen_t cliSz; /* length of servAddr */
6161
byte rxBuf[DTLS_MTU];
62-
word32 rxSz;
6362
} SharedDtls;
6463

6564

6665
int my_IORecv(WOLFSSL* ssl, char* buff, int sz, void* ctx)
6766
{
6867
SharedDtls* shared = (SharedDtls*)ctx;
6968
int recvd;
70-
struct sockaddr addr;
71-
socklen_t addrSz = sizeof(addr);
69+
int dtls_timeout;
7270

7371
printf("Server Recv fd %d, buf %d\n", shared->sd, sz);
7472

75-
/* handle "peek" rx data */
76-
if (shared->rxSz > 0) {
77-
recvd = shared->rxSz;
78-
if (recvd > sz)
79-
recvd = sz;
80-
memcpy(buff, shared->rxBuf, recvd);
81-
shared->rxSz -= recvd;
82-
memcpy(shared->rxBuf, &shared->rxBuf[recvd], shared->rxSz);
83-
}
84-
else {
85-
/* Receive datagram */
86-
recvd = recvfrom(shared->sd, buff, sz, 0, &addr, &addrSz);
73+
dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
74+
75+
/* If we are performing the DTLS handshake, and we are in blocking mode, we
76+
* set a socket timeout at OS level. */
77+
if (!wolfSSL_is_init_finished(ssl)) {
78+
/* Still in handshake: set the OS timeout */
79+
if (dtls_timeout > 0) {
80+
struct timeval tv;
81+
tv.tv_sec = dtls_timeout;
82+
tv.tv_usec = 0;
83+
if (setsockopt(shared->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
84+
fprintf(stderr, "setsockopt failed\n");
85+
return WOLFSSL_CBIO_ERR_GENERAL;
86+
}
87+
}
88+
} else {
89+
struct timeval tv = {0, 0};
90+
if (setsockopt(shared->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
91+
fprintf(stderr, "setsockopt failed\n");
92+
return WOLFSSL_CBIO_ERR_GENERAL;
93+
}
8794
}
8895

96+
/* Receive datagram and store client's address */
97+
recvd = recvfrom(shared->sd, buff, sz, 0, (struct sockaddr*)&shared->cliAddr, &shared->cliSz);
98+
8999
if (recvd == -1) {
90100
/* error encountered. Be responsible and report it in wolfSSL terms */
91101

@@ -284,20 +294,21 @@ int main(int argc, char** argv)
284294
shared.sd = listenfd;
285295
shared.cliSz = sizeof(shared.cliAddr);
286296

287-
ret = (int)recvfrom(listenfd, (char*)shared.rxBuf, sizeof(shared.rxBuf), 0,
288-
(struct sockaddr*)&shared.cliAddr, &shared.cliSz);
289-
if (ret < 0) {
290-
printf("No clients in queue, enter idle state\n");
291-
continue;
292-
}
293-
else if (ret > 0) {
294-
shared.rxSz = ret;
295-
ret = 0;
296-
printf("Connected!\n");
297-
}
298-
else {
299-
printf("Recvfrom failed %d.\n", errno);
300-
break;
297+
/*
298+
* Wait until the socket is readable
299+
* and wait until we actually have data waiting to be read.
300+
* */
301+
{
302+
fd_set readfds;
303+
FD_ZERO(&readfds);
304+
FD_SET(listenfd, &readfds);
305+
306+
/* No timeout, so wait indefinitely */
307+
int sel_ret = select(listenfd + 1, &readfds, NULL, NULL, NULL);
308+
if (sel_ret < 0) {
309+
perror("select");
310+
goto exit;
311+
}
301312
}
302313

303314
/* Create the WOLFSSL Object */

0 commit comments

Comments
 (0)