Improvements to prevent high CPU spinning on read waits (use tcp_select).
parent
a6642b56d2
commit
0721ab9e6d
|
@ -33,13 +33,58 @@
|
|||
/* wolfSSL */
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <wolfssl/wolfio.h>
|
||||
|
||||
#define DEFAULT_PORT 11111
|
||||
|
||||
#define CONNECT_WAIT_MS 2
|
||||
|
||||
#define CONNECT_WAIT_SEC 2
|
||||
#define SELECT_WAIT_SEC 1
|
||||
#define CERT_FILE "../certs/ca-cert.pem"
|
||||
|
||||
enum {
|
||||
TEST_SELECT_FAIL,
|
||||
TEST_TIMEOUT,
|
||||
TEST_RECV_READY,
|
||||
TEST_SEND_READY,
|
||||
TEST_ERROR_READY
|
||||
};
|
||||
|
||||
static int tcp_select(SOCKET_T socketfd, int to_sec, int rx)
|
||||
{
|
||||
fd_set fds, errfds;
|
||||
fd_set* recvfds = NULL;
|
||||
fd_set* sendfds = NULL;
|
||||
SOCKET_T nfds = socketfd + 1;
|
||||
struct timeval timeout;
|
||||
int result;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(socketfd, &fds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(socketfd, &errfds);
|
||||
|
||||
if (rx)
|
||||
recvfds = &fds;
|
||||
else
|
||||
sendfds = &fds;
|
||||
|
||||
result = select(nfds, recvfds, sendfds, &errfds, &timeout);
|
||||
|
||||
if (result == 0)
|
||||
return TEST_TIMEOUT;
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(socketfd, &fds)) {
|
||||
if (rx)
|
||||
return TEST_RECV_READY;
|
||||
else
|
||||
return TEST_SEND_READY;
|
||||
}
|
||||
else if (FD_ISSET(socketfd, &errfds))
|
||||
return TEST_ERROR_READY;
|
||||
}
|
||||
|
||||
return TEST_SELECT_FAIL;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret, err;
|
||||
|
@ -65,7 +110,7 @@ int main(int argc, char** argv)
|
|||
|
||||
/* Initialize wolfSSL */
|
||||
wolfSSL_Init();
|
||||
|
||||
//wolfSSL_Debugging_ON();
|
||||
|
||||
|
||||
/* Create a socket that uses an internet IPv4 address,
|
||||
|
@ -85,7 +130,6 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) {
|
||||
fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
|
||||
|
@ -102,7 +146,6 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize the server address struct with zeros */
|
||||
memset(&servAddr, 0, sizeof(servAddr));
|
||||
|
||||
|
@ -122,11 +165,13 @@ int main(int argc, char** argv)
|
|||
while (connect(sockfd, (struct sockaddr*) &servAddr, sizeof(servAddr))
|
||||
== -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
/* no error, just non-blocking. Carry on. */
|
||||
/* non-blocking connect, wait for read activity on socket */
|
||||
tcp_select(sockfd, CONNECT_WAIT_SEC, 1);
|
||||
continue;
|
||||
} else if(errno == EINPROGRESS || errno == EALREADY)
|
||||
}
|
||||
else if (errno == EINPROGRESS || errno == EALREADY) {
|
||||
break;
|
||||
/* just keep looping until a connection is made */
|
||||
}
|
||||
fprintf(stderr, "ERROR: failed to connect %d\n\n", errno);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
|
@ -148,11 +193,13 @@ int main(int argc, char** argv)
|
|||
/* Connect to wolfSSL on the server side */
|
||||
do {
|
||||
ret = wolfSSL_connect(ssl);
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
if (err == WOLFSSL_ERROR_WANT_READ)
|
||||
tcp_select(sockfd, SELECT_WAIT_SEC, 1);
|
||||
} while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
|
||||
|
||||
if (ret != WOLFSSL_SUCCESS){
|
||||
fprintf(stderr, "ERROR: failed to connect to wolfSSL\n");
|
||||
fprintf(stderr, "ERROR %d: failed to connect to wolfSSL %d\n", err, ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -196,9 +243,9 @@ int main(int argc, char** argv)
|
|||
/* send close notify */
|
||||
do {
|
||||
ret = wolfSSL_shutdown(ssl);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
err = wolfSSL_get_error(ssl, 0);
|
||||
if (err == WOLFSSL_ERROR_WANT_READ)
|
||||
tcp_select(sockfd, SELECT_WAIT_SEC, 1);
|
||||
} while (ret == WOLFSSL_ERROR_WANT_READ ||
|
||||
ret == WOLFSSL_ERROR_WANT_WRITE);
|
||||
printf("Shutdown complete\n");
|
||||
|
|
|
@ -37,8 +37,7 @@
|
|||
#include <wolfssl/wolfio.h>
|
||||
|
||||
#define DEFAULT_PORT 11111
|
||||
|
||||
#define CONNECT_WAIT_MS 2
|
||||
#define SELECT_WAIT_SEC 1
|
||||
|
||||
#define CERT_FILE "../certs/server-cert.pem"
|
||||
#define KEY_FILE "../certs/server-key.pem"
|
||||
|
@ -51,9 +50,8 @@ enum {
|
|||
TEST_ERROR_READY
|
||||
};
|
||||
|
||||
static int tcp_select(SOCKET_T socketfd, int to_sec)
|
||||
static int tcp_select(SOCKET_T socketfd, int to_sec, int rx)
|
||||
{
|
||||
int rx = 1;
|
||||
fd_set fds, errfds;
|
||||
fd_set* recvfds = NULL;
|
||||
fd_set* sendfds = NULL;
|
||||
|
@ -82,7 +80,7 @@ static int tcp_select(SOCKET_T socketfd, int to_sec)
|
|||
else
|
||||
return TEST_SEND_READY;
|
||||
}
|
||||
else if(FD_ISSET(socketfd, &errfds))
|
||||
else if (FD_ISSET(socketfd, &errfds))
|
||||
return TEST_ERROR_READY;
|
||||
}
|
||||
|
||||
|
@ -111,7 +109,7 @@ int main()
|
|||
|
||||
/* Initialize wolfSSL */
|
||||
wolfSSL_Init();
|
||||
|
||||
//wolfSSL_Debugging_ON();
|
||||
|
||||
|
||||
/* Create a socket that uses an internet IPv4 address,
|
||||
|
@ -182,8 +180,6 @@ int main()
|
|||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Continue to accept clients until shutdown is issued */
|
||||
while (!shutdown) {
|
||||
printf("Waiting for a connection...\n");
|
||||
|
@ -192,11 +188,11 @@ int main()
|
|||
while ((connd = accept(sockfd, (struct sockaddr*)&clientAddr, &size))
|
||||
== -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
/* no error, just non-blocking. Carry on. */
|
||||
tcp_select(sockfd, CONNECT_WAIT_MS);
|
||||
/* non-blocking, wait for read activity on socket */
|
||||
tcp_select(sockfd, SELECT_WAIT_SEC, 1);
|
||||
continue;
|
||||
}
|
||||
else if(errno == EINPROGRESS || errno == EALREADY) {
|
||||
else if (errno == EINPROGRESS || errno == EALREADY) {
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "ERROR: failed to accept the connection\n\n");
|
||||
|
@ -223,10 +219,11 @@ int main()
|
|||
do {
|
||||
ret = wolfSSL_accept(ssl);
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
if (err == WOLFSSL_ERROR_WANT_READ)
|
||||
tcp_select(sockfd, SELECT_WAIT_SEC, 1);
|
||||
} while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
fprintf(stderr, "wolfSSL_accept error = %d\n",
|
||||
wolfSSL_get_error(ssl, ret));
|
||||
fprintf(stderr, "wolfSSL_accept error %d (%d)\n", err, ret);
|
||||
goto exit;
|
||||
}
|
||||
printf("client connected successfully\n");
|
||||
|
@ -237,6 +234,9 @@ int main()
|
|||
do {
|
||||
ret = wolfSSL_read(ssl, buff, sizeof(buff)-1);
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
|
||||
if (err == WOLFSSL_ERROR_WANT_READ)
|
||||
tcp_select(sockfd, SELECT_WAIT_SEC, 1);
|
||||
}
|
||||
while (err == WOLFSSL_ERROR_WANT_READ);
|
||||
if (ret < 0) {
|
||||
|
@ -264,6 +264,7 @@ int main()
|
|||
do {
|
||||
ret = wolfSSL_write(ssl, reply, len);
|
||||
err = wolfSSL_get_error(ssl, ret);
|
||||
sleep(1);
|
||||
}
|
||||
while (err == WOLFSSL_ERROR_WANT_WRITE);
|
||||
if (ret < 0) {
|
||||
|
@ -275,11 +276,14 @@ int main()
|
|||
do {
|
||||
ret = wolfSSL_shutdown(ssl);
|
||||
err = wolfSSL_get_error(ssl, 0);
|
||||
if (err == WOLFSSL_ERROR_WANT_READ)
|
||||
tcp_select(sockfd, SELECT_WAIT_SEC, 1);
|
||||
} while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
|
||||
|
||||
/* Cleanup after this connection */
|
||||
wolfSSL_free(ssl); /* Free the wolfSSL object */
|
||||
close(connd); /* Close the connection to the client */
|
||||
connd = SOCKET_INVALID;
|
||||
}
|
||||
|
||||
printf("Shutdown complete\n");
|
||||
|
|
Loading…
Reference in New Issue