static void ns_write_to_socket(struct ns_connection *conn) { struct iobuf *io = &conn->send_iobuf; int n = 0; #ifdef NS_ENABLE_SSL if (conn->ssl != NULL) { n = SSL_write(conn->ssl, io->buf, io->len); if (n <= 0) { int ssl_err = ns_ssl_err(conn, n); if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) { return; /* Call us again */ } else { conn->flags |= NSF_CLOSE_IMMEDIATELY; } } } else #endif { n = (int) send(conn->sock, io->buf, io->len, 0); } DBG(("%p %lu -> %d bytes", conn, conn->flags, n)); ns_call(conn, NS_SEND, &n); if (ns_is_error(n)) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } else if (n > 0) { iobuf_remove(io, n); } }
static void ns_read_from_socket(struct ns_connection *conn) { char buf[NS_READ_BUFFER_SIZE]; int n = 0; if (conn->flags & NSF_CONNECTING) { int ok = 1, ret; (void) ret; socklen_t len = sizeof(ok); ret = getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, (char *) &ok, &len); #ifdef NS_ENABLE_SSL if (ret == 0 && ok == 0 && conn->ssl != NULL) { ns_ssl_begin(conn); } #endif DBG(("%p connect ok=%d", conn, ok)); if (ok != 0) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } else { conn->flags &= ~NSF_CONNECTING; } ns_call(conn, NS_CONNECT, &ok); return; } #ifdef NS_ENABLE_SSL if (conn->ssl != NULL) { if (conn->flags & NSF_SSL_HANDSHAKE_DONE) { /* SSL library may have more bytes ready to read then we ask to read. * Therefore, read in a loop until we read everything. Without the loop, * we skip to the next select() cycle which can just timeout. */ while ((n = SSL_read(conn->ssl, buf, sizeof(buf))) > 0) { DBG(("%p %d bytes <- %d (SSL)", conn, n, conn->sock)); mbuf_append(&conn->recv_mbuf, buf, n); ns_call(conn, NS_RECV, &n); } ns_ssl_err(conn, n); } else { ns_ssl_begin(conn); return; } } else #endif { while ((n = (int) NS_RECV_FUNC( conn->sock, buf, recv_avail_size(conn, sizeof(buf)), 0)) > 0) { DBG(("%p %d bytes (PLAIN) <- %d", conn, n, conn->sock)); mbuf_append(&conn->recv_mbuf, buf, n); ns_call(conn, NS_RECV, &n); } } if (ns_is_error(n)) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } }
static void ns_write_to_socket(struct ns_connection *conn) { struct mbuf *io = &conn->send_mbuf; int n = 0; assert(io->len > 0); #ifdef NS_ENABLE_SSL if (conn->ssl != NULL) { if (conn->flags & NSF_SSL_HANDSHAKE_DONE) { n = SSL_write(conn->ssl, io->buf, io->len); if (n <= 0) { int ssl_err = ns_ssl_err(conn, n); if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) { return; /* Call us again */ } else { conn->flags |= NSF_CLOSE_IMMEDIATELY; } } else { /* Successful SSL operation, clear off SSL wait flags */ conn->flags &= ~(NSF_WANT_READ | NSF_WANT_WRITE); } } else { ns_ssl_begin(conn); return; } } else #endif { n = (int) NS_SEND_FUNC(conn->sock, io->buf, io->len, 0); } DBG(("%p %d bytes -> %d", conn, n, conn->sock)); if (ns_is_error(n)) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } else if (n > 0) { #ifndef NS_DISABLE_FILESYSTEM /* LCOV_EXCL_START */ if (conn->mgr->hexdump_file != NULL) { ns_hexdump_connection(conn, conn->mgr->hexdump_file, n, NS_SEND); } /* LCOV_EXCL_STOP */ #endif mbuf_remove(io, n); } ns_call(conn, NS_SEND, &n); }
static void ns_ssl_begin(struct ns_connection *nc) { int server_side = nc->listener != NULL; int res = server_side ? SSL_accept(nc->ssl) : SSL_connect(nc->ssl); if (res == 1) { nc->flags |= NSF_SSL_HANDSHAKE_DONE; nc->flags &= ~(NSF_WANT_READ | NSF_WANT_WRITE); if (server_side) { union socket_address sa; socklen_t sa_len = sizeof(sa); /* In case port was set to 0, get the real port number */ (void) getsockname(nc->sock, &sa.sa, &sa_len); ns_call(nc, NS_ACCEPT, &sa); } } else { int ssl_err = ns_ssl_err(nc, res); if (ssl_err != SSL_ERROR_WANT_READ && ssl_err != SSL_ERROR_WANT_WRITE) { nc->flags |= NSF_CLOSE_IMMEDIATELY; } } }
static void ns_read_from_socket(struct ns_connection *conn) { char buf[NS_READ_BUFFER_SIZE]; int n = 0; if (conn->flags & NSF_CONNECTING) { int ok = 1, ret; socklen_t len = sizeof(ok); ret = getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, (char *) &ok, &len); #ifdef NS_ENABLE_SSL if (ret == 0 && ok == 0 && conn->ssl != NULL) { int res = SSL_connect(conn->ssl); int ssl_err = ns_ssl_err(conn, res); if (res == 1) { conn->flags |= NSF_SSL_HANDSHAKE_DONE; } else if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) { return; /* Call us again */ } else { ok = 1; } } #endif conn->flags &= ~NSF_CONNECTING; DBG(("%p ok=%d", conn, ok)); if (ok != 0) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } ns_call(conn, NS_CONNECT, &ok); return; } #ifdef NS_ENABLE_SSL if (conn->ssl != NULL) { if (conn->flags & NSF_SSL_HANDSHAKE_DONE) { /* SSL library may have more bytes ready to read then we ask to read. * Therefore, read in a loop until we read everything. Without the loop, * we skip to the next select() cycle which can just timeout. */ while ((n = SSL_read(conn->ssl, buf, sizeof(buf))) > 0) { DBG(("%p %lu <- %d bytes (SSL)", conn, conn->flags, n)); iobuf_append(&conn->recv_iobuf, buf, n); ns_call(conn, NS_RECV, &n); } ns_ssl_err(conn, n); } else { int res = SSL_accept(conn->ssl); int ssl_err = ns_ssl_err(conn, res); if (res == 1) { conn->flags |= NSF_SSL_HANDSHAKE_DONE; } else if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) { return; /* Call us again */ } else { conn->flags |= NSF_CLOSE_IMMEDIATELY; } return; } } else #endif { while ((n = (int) recv(conn->sock, buf, sizeof(buf), 0)) > 0) { DBG(("%p %lu <- %d bytes (PLAIN)", conn, conn->flags, n)); iobuf_append(&conn->recv_iobuf, buf, n); ns_call(conn, NS_RECV, &n); } } if (ns_is_error(n)) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } }