int my_IORecv(WOLFSSL* ssl, char* buff, int sz, void* ctx) { SharedDtls* shared = (SharedDtls*)ctx; int recvd; struct sockaddr addr; socklen_t addrSz = sizeof(addr); printf("my_IORecv fd %d, buf %d\n", shared->sd, sz); /* Receive datagram */ recvd = recvfrom(shared->sd, buff, sz, 0, &addr, &addrSz); if (recvd == -1) { /* error encountered. Be responsible and report it in wolfSSL terms */ fprintf(stderr, "IO RECEIVE ERROR: %d\n", errno); switch (errno) { #if EAGAIN != EWOULDBLOCK case EAGAIN: /* EAGAIN == EWOULDBLOCK on some systems, but not others */ #endif case EWOULDBLOCK: if (!wolfSSL_dtls(ssl) || wolfSSL_get_using_nonblock(ssl)) { fprintf(stderr, "would block\n"); return WOLFSSL_CBIO_ERR_WANT_READ; } else { fprintf(stderr, "socket timeout\n"); return WOLFSSL_CBIO_ERR_TIMEOUT; } case ECONNRESET: fprintf(stderr, "connection reset\n"); return WOLFSSL_CBIO_ERR_CONN_RST; case EINTR: fprintf(stderr, "socket interrupted\n"); cleanup = 1; return WOLFSSL_CBIO_ERR_GENERAL; /* NOTE: Don't return WOLFSSL_CBIO_ERR_ISR. It keeps trying to recv */ case ECONNREFUSED: fprintf(stderr, "connection refused\n"); return WOLFSSL_CBIO_ERR_WANT_READ; case ECONNABORTED: fprintf(stderr, "connection aborted\n"); return WOLFSSL_CBIO_ERR_CONN_CLOSE; default: fprintf(stderr, "general error\n"); return WOLFSSL_CBIO_ERR_GENERAL; } } else if (recvd == 0) { printf("Connection closed\n"); return WOLFSSL_CBIO_ERR_CONN_CLOSE; } /* successful receive */ printf("my_IORecv: received %d bytes from %d\n", recvd, shared->sd); return recvd; }
/* * function with specific parameters : inbetween process of receiving msg * based from embeded receive in src/io.c */ int CbIORecv(WOLFSSL *ssl, char *buf, int sz, void *ctx) { int recvd; int sd = *(int*)ctx; recvd = recv(sd, buf, sz, 0); if (recvd < 0) { if (errno == SOCKET_EWOULDBLOCK || errno == SOCKET_EAGAIN) { if (!wolfSSL_dtls(ssl) || wolfSSL_get_using_nonblock(ssl)) { printf(" Would block\n"); return WOLFSSL_CBIO_ERR_WANT_READ; } else { printf("Socket timeout\n"); return WOLFSSL_CBIO_ERR_TIMEOUT; } } else if (errno == SOCKET_ECONNRESET) { printf("Connection reset\n"); return WOLFSSL_CBIO_ERR_CONN_RST; } else if (errno == SOCKET_EINTR) { printf("Socket interrupted\n"); return WOLFSSL_CBIO_ERR_ISR; } else if (errno == SOCKET_ECONNREFUSED) { printf("Connection refused\n"); return WOLFSSL_CBIO_ERR_WANT_READ; } else if (errno == SOCKET_ECONNABORTED) { printf("Connection aborted\n"); return WOLFSSL_CBIO_ERR_CONN_CLOSE; } else { printf("General error\n"); return WOLFSSL_CBIO_ERR_GENERAL; } } else if (recvd == 0) { printf("Embed receive connection closed\n"); return WOLFSSL_CBIO_ERR_CONN_CLOSE; } printf("Received %d bytes\n", sz); return recvd; }
/* 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; }