/* The send embedded callback * return : nb bytes sended * -1 : other errors (unexpected) * -2 : want write * -3 : connexion reset * -4 : interrupt * -5 : pipe error / connection closed */ int EmbedSend(char *buf, int sz, void *ctx) { int socket = *(int*)ctx; int sent; int len = sz; sent = SEND_FUNCTION(socket, &buf[sz - len], len, 0); if (sent == -1) { if (LastError() == SOCKET_EWOULDBLOCK || LastError() == SOCKET_EAGAIN) return -2; else if (LastError() == SOCKET_ECONNRESET) return -3; else if (LastError() == SOCKET_EINTR) return -4; else if (LastError() == SOCKET_EPIPE) return -5; else return -1; } return sent; }
/* The send embedded callback * return : nb bytes sent, or error */ int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) { int sd = *(int*)ctx; int sent; int len = sz; int err; sent = (int)SEND_FUNCTION(sd, &buf[sz - len], len, ssl->wflags); sent = TranslateReturnCode(sent, sd); if (sent < 0) { err = LastError(); WOLFSSL_MSG("Embed Send error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { WOLFSSL_MSG(" Would Block"); return WOLFSSL_CBIO_ERR_WANT_WRITE; } 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_EPIPE) { WOLFSSL_MSG(" Socket EPIPE"); return WOLFSSL_CBIO_ERR_CONN_CLOSE; } else { WOLFSSL_MSG(" General error"); return WOLFSSL_CBIO_ERR_GENERAL; } } return sent; }
/* The send embedded callback * return : nb bytes sent, or error */ int EmbedSend(char *buf, int sz, void *ctx) { int sd = *(int*)ctx; int sent; int len = sz; int err; sent = SEND_FUNCTION(sd, &buf[sz - len], len, 0); if (sent < 0) { err = LastError(); CYASSL_MSG("Embed Send error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { CYASSL_MSG(" Would Block"); return IO_ERR_WANT_WRITE; } else if (err == SOCKET_ECONNRESET) { CYASSL_MSG(" Connection reset"); return IO_ERR_CONN_RST; } else if (err == SOCKET_EINTR) { CYASSL_MSG(" Socket interrupted"); return IO_ERR_ISR; } else if (err == SOCKET_EPIPE) { CYASSL_MSG(" Socket EPIPE"); return IO_ERR_CONN_CLOSE; } else { CYASSL_MSG(" General error"); return IO_ERR_GENERAL; } } return sent; }
int EmbedOcspLookup(void* ctx, const char* url, int urlSz, byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf) { SOCKET_T sfd = 0; word16 port; int ret = -1; #ifdef WOLFSSL_SMALL_STACK char* path; char* domainName; #else char path[80]; char domainName[80]; #endif #ifdef WOLFSSL_SMALL_STACK path = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (path == NULL) return -1; domainName = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (domainName == NULL) { XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER); return -1; } #endif (void)ctx; if (ocspReqBuf == NULL || ocspReqSz == 0) { WOLFSSL_MSG("OCSP request is required for lookup"); } else if (ocspRespBuf == NULL) { WOLFSSL_MSG("Cannot save OCSP response"); } else if (decode_url(url, urlSz, domainName, path, &port) < 0) { WOLFSSL_MSG("Unable to decode OCSP URL"); } else { /* Note, the library uses the EmbedOcspRespFree() callback to * free this buffer. */ int httpBufSz = SCRATCH_BUFFER_SIZE; byte* httpBuf = (byte*)XMALLOC(httpBufSz, NULL, DYNAMIC_TYPE_OCSP); if (httpBuf == NULL) { WOLFSSL_MSG("Unable to create OCSP response buffer"); } else { httpBufSz = build_http_request(domainName, path, ocspReqSz, httpBuf, httpBufSz); if ((tcp_connect(&sfd, domainName, port) != 0) || (sfd <= 0)) { WOLFSSL_MSG("OCSP Responder connection failed"); } else if ((int)SEND_FUNCTION(sfd, (char*)httpBuf, httpBufSz, 0) != httpBufSz) { WOLFSSL_MSG("OCSP http request failed"); } else if ((int)SEND_FUNCTION(sfd, (char*)ocspReqBuf, ocspReqSz, 0) != ocspReqSz) { WOLFSSL_MSG("OCSP ocsp request failed"); } else { ret = process_http_response(sfd, ocspRespBuf, httpBuf, SCRATCH_BUFFER_SIZE); } CLOSE_FUNCTION(sfd); XFREE(httpBuf, NULL, DYNAMIC_TYPE_OCSP); } } #ifdef WOLFSSL_SMALL_STACK XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(domainName, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; }
/* The send embedded callback * return : nb bytes sent, or error */ int EmbedSend(CYASSL* ssl, char *buf, int sz, void *ctx) { int sd = *(int*)ctx; int sent; int len = sz; int err; uint32_t timeout = 500; socklen_t sizeOfTimeOut = sizeof(timeout); int result = setsockopt (sd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeOfTimeOut); if (result<0) { logOffNominal("setsockopt SO_SNDTIMEO failed(%d).",result); return CYASSL_CBIO_ERR_GENERAL; } CYASSL_ENTER("EmbedSend"); CYASSL_DEBUG("EmbedSend - lwip_send ssl=%08x sd=%08x, buf=%08x len=%u flags=%x", (unsigned)ssl, (unsigned)sd, (unsigned)&buf[sz - len], len, ssl->wflags); sent = (int)SEND_FUNCTION(sd, &buf[sz - len], len, ssl->wflags); CYASSL_DEBUG("EmbedSend - lwip_send ssl=%08x sd=%08x, buf=%08x len=%u flags=%x returned=%d", (unsigned)ssl, (unsigned)sd, (unsigned)&buf[sz - len], len, ssl->wflags, sent); if (sent < 0) { err = LastError(); CYASSL_MSG("Embed Send error"); if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) { CYASSL_MSG(" Would Block"); return CYASSL_CBIO_ERR_WANT_WRITE; } else if (err == SOCKET_ECONNRESET) { CYASSL_MSG(" Connection reset"); return CYASSL_CBIO_ERR_CONN_RST; } else if (err == SOCKET_EINTR) { CYASSL_MSG(" Socket interrupted"); return CYASSL_CBIO_ERR_ISR; } else if (err == SOCKET_EPIPE) { CYASSL_MSG(" Socket EPIPE"); return CYASSL_CBIO_ERR_CONN_CLOSE; } else { CYASSL_MSG(" General error"); return CYASSL_CBIO_ERR_GENERAL; } } socklen_t getSizeOfTimeOut = sizeof(timeout); timeout = 0xdeadbeef; result = getsockopt (sd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, &getSizeOfTimeOut); if (result<0) logFatal("getsockopt SO_SNDTIMEO failed."); if (timeout != 500) logFatal("getsockopt SO_SNDTIMEO did not read what we wrote %u %u.", getSizeOfTimeOut, timeout); CYASSL_LEAVE("EmbedSend", sent); return sent; }