Added OS-level timeout support for the DTLS I/O callbacks examples
parent
702d54ca18
commit
7daf133366
|
@ -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) {
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue