static void NonBlockingSSL_Connect(WOLFSSL* ssl) { #ifndef WOLFSSL_CALLBACKS int ret = wolfSSL_connect(ssl); #else int ret = wolfSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeout); #endif int error = wolfSSL_get_error(ssl, 0); SOCKET_T sockfd = (SOCKET_T)wolfSSL_get_fd(ssl); int select_ret; while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)) { int currTimeout = 1; if (error == SSL_ERROR_WANT_READ) printf("... client would read block\n"); else printf("... client would write block\n"); #ifdef WOLFSSL_DTLS currTimeout = wolfSSL_dtls_get_current_timeout(ssl); #endif select_ret = tcp_select(sockfd, currTimeout); if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_ERROR_READY)) { #ifndef WOLFSSL_CALLBACKS ret = wolfSSL_connect(ssl); #else ret = wolfSSL_connect_ex(ssl,handShakeCB,timeoutCB,timeout); #endif error = wolfSSL_get_error(ssl, 0); } else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) { error = SSL_ERROR_WANT_READ; } #ifdef WOLFSSL_DTLS else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) && wolfSSL_dtls_got_timeout(ssl) >= 0) { error = SSL_ERROR_WANT_READ; } #endif else { error = SSL_FATAL_ERROR; } } if (ret != SSL_SUCCESS) err_sys("SSL_connect failed"); }
/* The receive embedded callback * return : nb bytes read, or error */ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) { WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx; int recvd = 0; int err; int sd = dtlsCtx->fd; int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); struct sockaddr_storage peer; XSOCKLENT peerSz = sizeof(peer); WOLFSSL_ENTER("EmbedReceiveFrom()"); if (!wolfSSL_get_using_nonblock(ssl) && dtls_timeout != 0) { #ifdef SELECT_FUNCTION /* Wait for data on this socket. */ recvd = (int)SELECT_FUNCTION(sd, dtls_timeout); recvd = TranslateReturnCode(recvd, sd); #else #ifdef USE_WINDOWS_API DWORD timeout = dtls_timeout * 1000; #else struct timeval timeout; XMEMSET(&timeout, 0, sizeof(timeout)); timeout.tv_sec = dtls_timeout; #endif if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) != 0) { WOLFSSL_MSG("setsockopt rcvtimeo failed"); } #endif } if (recvd == 0) { /* Clear peer address */ XMEMSET(&peer, 0, sizeof(peer)); recvd = (int)RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags, (struct sockaddr*)&peer, &peerSz); recvd = TranslateReturnCode(recvd, sd); } if (recvd < 0) { err = LastError(); WOLFSSL_MSG("Embed Receive From error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { if (wolfSSL_get_using_nonblock(ssl)) { WOLFSSL_MSG(" Would block"); return WOLFSSL_CBIO_ERR_WANT_READ; } else { WOLFSSL_MSG(" Socket timeout"); return WOLFSSL_CBIO_ERR_TIMEOUT; } } else if (err == SOCKET_ECONNRESET) { WOLFSSL_MSG(" Connection reset"); return WOLFSSL_CBIO_ERR_CONN_RST; } else if (err == SOCKET_EINTR) { WOLFSSL_MSG(" Socket interrupted"); return WOLFSSL_CBIO_ERR_ISR; } else if (err == SOCKET_ECONNREFUSED) { WOLFSSL_MSG(" Connection refused"); return WOLFSSL_CBIO_ERR_WANT_READ; } else { WOLFSSL_MSG(" General error"); return WOLFSSL_CBIO_ERR_GENERAL; } } else { if (dtlsCtx->peer.sz > 0 && peerSz != (XSOCKLENT)dtlsCtx->peer.sz && memcmp(&peer, dtlsCtx->peer.sa, peerSz) != 0) { WOLFSSL_MSG(" Ignored packet from invalid peer"); return WOLFSSL_CBIO_ERR_WANT_READ; } } return recvd; }
/* The receive embedded callback * return : nb bytes read, or error */ int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx) { int recvd = 0; int err; int sd = *(int*)ctx; #ifdef WOLFSSL_DTLS { int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); if (wolfSSL_dtls(ssl) && !wolfSSL_get_using_nonblock(ssl) && dtls_timeout != 0) { #ifdef SELECT_FUNCTION /* Wait for data on this socket. */ recvd = (int)SELECT_FUNCTION(sd, dtls_timeout); recvd = TranslateReturnCode(recvd, sd); #else #ifdef USE_WINDOWS_API DWORD timeout = dtls_timeout * 1000; #else struct timeval timeout; XMEMSET(&timeout, 0, sizeof(timeout)); timeout.tv_sec = dtls_timeout; #endif if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) != 0) { WOLFSSL_MSG("setsockopt rcvtimeo failed"); } #endif } } #endif if (recvd == 0) { recvd = (int)RECV_FUNCTION(sd, buf, sz, ssl->rflags); recvd = TranslateReturnCode(recvd, sd); } if (recvd < 0) { err = LastError(); WOLFSSL_MSG("Embed Receive error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { if (!wolfSSL_dtls(ssl) || wolfSSL_get_using_nonblock(ssl)) { WOLFSSL_MSG(" Would block"); return WOLFSSL_CBIO_ERR_WANT_READ; } else { WOLFSSL_MSG(" Socket timeout"); return WOLFSSL_CBIO_ERR_TIMEOUT; } } else if (err == SOCKET_ECONNRESET) { WOLFSSL_MSG(" Connection reset"); return WOLFSSL_CBIO_ERR_CONN_RST; } else if (err == SOCKET_EINTR) { WOLFSSL_MSG(" Socket interrupted"); return WOLFSSL_CBIO_ERR_ISR; } else if (err == SOCKET_ECONNREFUSED) { WOLFSSL_MSG(" Connection refused"); return WOLFSSL_CBIO_ERR_WANT_READ; } else if (err == SOCKET_ECONNABORTED) { WOLFSSL_MSG(" Connection aborted"); return WOLFSSL_CBIO_ERR_CONN_CLOSE; } else { WOLFSSL_MSG(" General error"); return WOLFSSL_CBIO_ERR_GENERAL; } } else if (recvd == 0) { WOLFSSL_MSG("Embed receive connection closed"); return WOLFSSL_CBIO_ERR_CONN_CLOSE; } return recvd; }