int ssl_aio_stream::__sock_read(void *ctx, unsigned char *buf, size_t len) { #ifdef HAS_POLARSSL ssl_aio_stream* cli = (ssl_aio_stream*) ctx; ACL_VSTREAM* stream = cli->get_vstream(); acl_assert(stream); int ret, errnum; if ((ret = acl_socket_read(ACL_VSTREAM_SOCK(stream), buf, len, 0, stream, NULL)) < 0) { errnum = acl_last_error(); if (errnum == ACL_EINTR) return POLARSSL_ERR_NET_WANT_READ; else if (errnum == ACL_EWOULDBLOCK) return POLARSSL_ERR_NET_WANT_READ; #if ACL_EWOULDBLOCK != ACL_EAGAIN else if (errnum == ACL_EAGAIN) return POLARSSL_ERR_NET_WANT_READ; #endif else if (errnum == ACL_ECONNRESET || errno == EPIPE) return POLARSSL_ERR_NET_CONN_RESET; else return POLARSSL_ERR_NET_RECV_FAILED; } return ret; #else (void) ctx; (void) buf; (void) len; return -1; #endif }
int polarssl_io::sock_read(void *ctx, unsigned char *buf, size_t len) { #ifdef HAS_POLARSSL polarssl_io* io = (polarssl_io*) ctx; int ret, timeout = 120; ACL_VSTREAM* vs = io->stream_->get_vstream(); ACL_SOCKET fd = ACL_VSTREAM_SOCK(vs); ret = acl_socket_read(fd, buf, len, timeout, vs, NULL); if (ret < 0) { int errnum = acl_last_error(); if (ret == ACL_EINTR || ret == ACL_EWOULDBLOCK #if ACL_EWOULDBLOCK != ACL_EAGAIN || ret == ACL_EAGAIN #endif ) return POLARSSL_ERR_NET_WANT_READ; else if (errnum == ACL_ECONNRESET || errno == EPIPE) return POLARSSL_ERR_NET_CONN_RESET; else return POLARSSL_ERR_NET_RECV_FAILED; } return ret; #else (void) ctx; (void) buf; (void) len; logger_error("HAS_POLARSSL not defined!"); return -1; #endif }
static int network_biopair_interop(ACL_SOCKET fd, int timeout, BIO *network_bio) { const char *myname = "network_biopair_interop"; int want_write; int num_write; int write_pos; int from_bio; int want_read; int num_read; int to_bio; char buffer[NETLAYER_BUFFERSIZE]; /* * To avoid deadlock, write all pending data to the network before * attempting to read from the network. */ while ((want_write = (int) BIO_ctrl_pending(network_bio)) > 0) { if (want_write > (int) sizeof(buffer)) want_write = (int) sizeof(buffer); from_bio = BIO_read(network_bio, buffer, want_write); /* * Write the complete buffer contents to the network. */ for (write_pos = 0; write_pos < from_bio; /* see below */ ) { if (timeout > 0 && acl_write_wait(fd, timeout) < 0) return (-1); num_write = acl_socket_write(fd, buffer + write_pos, from_bio - write_pos, 0, 0, 0); if (num_write <= 0) { if ((num_write < 0) && (timeout > 0) && (errno == ACL_EAGAIN || errno == ACL_EINTR)) { acl_msg_warn("%s: write() returns EAGAIN on a writable file descriptor!", myname); acl_msg_warn("%s: pausing to avoid going into a tight select/write loop!", myname); sleep(1); } else { acl_msg_warn("%s: error writing %d bytes to the network: %s", myname, from_bio - write_pos, acl_last_serror()); return (-1); } } else { write_pos += num_write; } } } /* * Read data from the network into the BIO pair. */ while ((want_read = (int) BIO_ctrl_get_read_request(network_bio)) > 0) { if (want_read > (int) sizeof(buffer)) want_read = (int) sizeof(buffer); if (timeout > 0 && acl_read_wait(fd, timeout) < 0) return (-1); num_read = acl_socket_read(fd, buffer, want_read, 0, 0, 0); if (num_read == 0) /* FIX 200412 Cannot return a zero read count. */ return (-1); if (num_read < 0) { if ((num_read < 0) && (timeout > 0) && (errno == ACL_EAGAIN || errno == ACL_EINTR)) { acl_msg_warn("%s: read() returns EAGAIN on a readable file descriptor!", myname); acl_msg_warn("%s: pausing to avoid going into a tight select/write loop!", myname); sleep(1); } else { acl_msg_warn("%s: error reading %d bytes from the network: %s", myname, want_read, acl_last_serror()); return (-1); } } else { to_bio = BIO_write(network_bio, buffer, num_read); if (to_bio != num_read) acl_msg_panic("%s: BIO_write error: to_bio != num_read", myname); } } return (0); }