mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 11:17:29 +02:00
DTLS Nonblocking Updates
Add command line option to the example server to fake a write block on a specified DTLS sequence number in epoch 0.
This commit is contained in:
@ -115,6 +115,138 @@ static void err_sys_ex(int out, const char* msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
|
||||||
|
/* Translates return codes returned from
|
||||||
|
* send() and recv() if need be.
|
||||||
|
*/
|
||||||
|
static WC_INLINE int TranslateReturnCode(int old, int sd)
|
||||||
|
{
|
||||||
|
(void)sd;
|
||||||
|
|
||||||
|
#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
|
||||||
|
if (old == 0) {
|
||||||
|
errno = SOCKET_EWOULDBLOCK;
|
||||||
|
return -1; /* convert to BSD style wouldblock as error */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old < 0) {
|
||||||
|
errno = RTCS_geterror(sd);
|
||||||
|
if (errno == RTCSERR_TCP_CONN_CLOSING)
|
||||||
|
return 0; /* convert to BSD style closing */
|
||||||
|
if (errno == RTCSERR_TCP_CONN_RLSD)
|
||||||
|
errno = SOCKET_ECONNRESET;
|
||||||
|
if (errno == RTCSERR_TCP_TIMED_OUT)
|
||||||
|
errno = SOCKET_EAGAIN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WC_INLINE int wolfSSL_LastError(void)
|
||||||
|
{
|
||||||
|
#ifdef USE_WINDOWS_API
|
||||||
|
return WSAGetLastError();
|
||||||
|
#elif defined(EBSNET)
|
||||||
|
return xn_getlasterror();
|
||||||
|
#else
|
||||||
|
return errno;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wolfSSL Sock Addr */
|
||||||
|
struct WOLFSSL_TEST_SOCKADDR {
|
||||||
|
unsigned int sz; /* sockaddr size */
|
||||||
|
SOCKADDR_IN_T sa; /* pointer to the sockaddr_in or sockaddr_in6 */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct WOLFSSL_TEST_DTLS_CTX {
|
||||||
|
struct WOLFSSL_TEST_SOCKADDR peer;
|
||||||
|
int rfd;
|
||||||
|
int wfd;
|
||||||
|
int failOnce;
|
||||||
|
word32 blockSeq;
|
||||||
|
} WOLFSSL_TEST_DTLS_CTX;
|
||||||
|
|
||||||
|
|
||||||
|
static WC_INLINE int PeekSeq(const char* buf, word32* seq)
|
||||||
|
{
|
||||||
|
const char* c = buf + 3;
|
||||||
|
|
||||||
|
if ((c[0] | c[1] | c[2] | c[3]) == 0) {
|
||||||
|
*seq = (c[4] << 24) | (c[5] << 16) | (c[6] << 8) | c[7];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The send embedded callback
|
||||||
|
* return : nb bytes sent, or error
|
||||||
|
*/
|
||||||
|
static int TestEmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
|
||||||
|
{
|
||||||
|
WOLFSSL_TEST_DTLS_CTX* dtlsCtx = (WOLFSSL_TEST_DTLS_CTX*)ctx;
|
||||||
|
int sd = dtlsCtx->wfd;
|
||||||
|
int sent;
|
||||||
|
int len = sz;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
(void)ssl;
|
||||||
|
|
||||||
|
WOLFSSL_ENTER("TestEmbedSendTo()");
|
||||||
|
|
||||||
|
if (dtlsCtx->failOnce) {
|
||||||
|
word32 seq = 0;
|
||||||
|
|
||||||
|
if (PeekSeq(buf, &seq) && seq == dtlsCtx->blockSeq) {
|
||||||
|
dtlsCtx->failOnce = 0;
|
||||||
|
WOLFSSL_MSG("Forcing WANT_WRITE");
|
||||||
|
return WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sent = (int)sendto(sd, &buf[sz - len], len, 0,
|
||||||
|
(const SOCKADDR*)&dtlsCtx->peer.sa,
|
||||||
|
dtlsCtx->peer.sz);
|
||||||
|
|
||||||
|
sent = TranslateReturnCode(sent, sd);
|
||||||
|
|
||||||
|
if (sent < 0) {
|
||||||
|
err = wolfSSL_LastError();
|
||||||
|
WOLFSSL_MSG("Embed Send To error");
|
||||||
|
|
||||||
|
if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
|
||||||
|
WOLFSSL_MSG("\tWould Block");
|
||||||
|
return WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||||
|
}
|
||||||
|
else if (err == SOCKET_ECONNRESET) {
|
||||||
|
WOLFSSL_MSG("\tConnection reset");
|
||||||
|
return WOLFSSL_CBIO_ERR_CONN_RST;
|
||||||
|
}
|
||||||
|
else if (err == SOCKET_EINTR) {
|
||||||
|
WOLFSSL_MSG("\tSocket interrupted");
|
||||||
|
return WOLFSSL_CBIO_ERR_ISR;
|
||||||
|
}
|
||||||
|
else if (err == SOCKET_EPIPE) {
|
||||||
|
WOLFSSL_MSG("\tSocket EPIPE");
|
||||||
|
return WOLFSSL_CBIO_ERR_CONN_CLOSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WOLFSSL_MSG("\tGeneral error");
|
||||||
|
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* WOLFSSL_DTLS */
|
||||||
|
|
||||||
|
|
||||||
static int NonBlockingSSL_Accept(SSL* ssl)
|
static int NonBlockingSSL_Accept(SSL* ssl)
|
||||||
{
|
{
|
||||||
#ifndef WOLFSSL_CALLBACKS
|
#ifndef WOLFSSL_CALLBACKS
|
||||||
@ -687,6 +819,9 @@ static void Usage(void)
|
|||||||
!defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
|
!defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
|
||||||
printf("-2 Disable DH Prime check\n");
|
printf("-2 Disable DH Prime check\n");
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
printf("-4 <seq> DTLS fake would-block for message seq\n");
|
||||||
|
#endif
|
||||||
#ifdef WOLFSSL_MULTICAST
|
#ifdef WOLFSSL_MULTICAST
|
||||||
printf("%s", msg[++msgId]); /* -3 */
|
printf("%s", msg[++msgId]); /* -3 */
|
||||||
#endif
|
#endif
|
||||||
@ -728,6 +863,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
|||||||
int dtlsUDP = 0;
|
int dtlsUDP = 0;
|
||||||
int dtlsSCTP = 0;
|
int dtlsSCTP = 0;
|
||||||
int doMcast = 0;
|
int doMcast = 0;
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
int doBlockSeq = 0;
|
||||||
|
WOLFSSL_TEST_DTLS_CTX dtlsCtx;
|
||||||
|
#endif
|
||||||
int needDH = 0;
|
int needDH = 0;
|
||||||
int useNtruKey = 0;
|
int useNtruKey = 0;
|
||||||
int nonBlocking = 0;
|
int nonBlocking = 0;
|
||||||
@ -872,7 +1011,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
|||||||
while ((ch = mygetopt(argc, argv, "?"
|
while ((ch = mygetopt(argc, argv, "?"
|
||||||
"abc:defgijk:l:mnop:q:rstuv:wxy"
|
"abc:defgijk:l:mnop:q:rstuv:wxy"
|
||||||
"A:B:C:D:E:GH:IJKL:MNO:PQR:S:TUVYZ:"
|
"A:B:C:D:E:GH:IJKL:MNO:PQR:S:TUVYZ:"
|
||||||
"01:23:")) != -1) {
|
"01:23:4:")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '?' :
|
case '?' :
|
||||||
if(myoptarg!=NULL) {
|
if(myoptarg!=NULL) {
|
||||||
@ -1228,6 +1367,14 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '4' :
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
XMEMSET(&dtlsCtx, 0, sizeof(dtlsCtx));
|
||||||
|
doBlockSeq = 1;
|
||||||
|
dtlsCtx.blockSeq = atoi(myoptarg);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Usage();
|
Usage();
|
||||||
XEXIT_T(MY_EX_USAGE);
|
XEXIT_T(MY_EX_USAGE);
|
||||||
@ -1607,6 +1754,14 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (doDTLS && dtlsUDP) {
|
||||||
|
#ifdef WOLFSSL_DTLS
|
||||||
|
if (doBlockSeq) {
|
||||||
|
wolfSSL_CTX_SetIOSend(ctx, TestEmbedSendTo);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PK_CALLBACKS
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
if (pkCallbacks)
|
if (pkCallbacks)
|
||||||
SetupPkCallbacks(ctx);
|
SetupPkCallbacks(ctx);
|
||||||
@ -1816,13 +1971,23 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
|||||||
/* For DTLS, peek at the next datagram so we can get the client's
|
/* For DTLS, peek at the next datagram so we can get the client's
|
||||||
* address and set it into the ssl object later to generate the
|
* address and set it into the ssl object later to generate the
|
||||||
* cookie. */
|
* cookie. */
|
||||||
n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
|
n = (int)recvfrom(clientfd, (char*)b, sizeof(b), MSG_PEEK,
|
||||||
(struct sockaddr*)&cliaddr, &len);
|
(struct sockaddr*)&cliaddr, &len);
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
err_sys_ex(runWithErrors, "recvfrom failed");
|
err_sys_ex(runWithErrors, "recvfrom failed");
|
||||||
|
|
||||||
|
if (doBlockSeq) {
|
||||||
|
XMEMCPY(&dtlsCtx.peer.sa, &cliaddr, len);
|
||||||
|
dtlsCtx.peer.sz = len;
|
||||||
|
dtlsCtx.wfd = clientfd;
|
||||||
|
dtlsCtx.failOnce = 1;
|
||||||
|
|
||||||
|
wolfSSL_SetIOWriteCtx(ssl, &dtlsCtx);
|
||||||
|
}
|
||||||
|
else {
|
||||||
wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
|
wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL
|
if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL
|
||||||
|| needDH == 1) {
|
|| needDH == 1) {
|
||||||
|
Reference in New Issue
Block a user