From 694bebfc54f7896e1ba59faa60ee1008ad6e12b1 Mon Sep 17 00:00:00 2001 From: Henry Case Date: Sun, 28 Jul 2019 20:46:04 +0100 Subject: [PATCH] WIP: Don't exit on SSL error --- src/core.c | 115 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 49 deletions(-) diff --git a/src/core.c b/src/core.c index ff3482d..f7ebb2e 100755 --- a/src/core.c +++ b/src/core.c @@ -1,31 +1,31 @@ /* * Copyright (C) 2000-2007 Hewlett-Packard Company - * + * * This file is part of httperf, a web server performance measurment tool. - * + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. - * + * * In addition, as a special exception, the copyright holders give permission * to link the code of this work with the OpenSSL project's "OpenSSL" library - * (or with modified versions of it that use the same license as the "OpenSSL" + * (or with modified versions of it that use the same license as the "OpenSSL" * library), and distribute linked combinations including the two. You must * obey the GNU General Public License in all respects for all of the code * used other than "OpenSSL". If you modify this file, you may extend this * exception to your version of the file, but you are not obligated to do so. * If you do not wish to do so, delete this exception statement from your * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT + * + * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. - * + * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "config.h" @@ -200,7 +200,7 @@ hash_code(const char *server, size_t server_len, int port) int ch; /* - * Basically the ELF hash algorithm: + * Basically the ELF hash algorithm: */ while ((ch = *cp++) != '\0') { @@ -405,7 +405,7 @@ clear_active(Conn * s, enum IO_DIR dir) } #else fd_set * fdset; - + if (dir == WRITE) fdset = &wrfds; else @@ -459,7 +459,7 @@ set_active(Conn * s, enum IO_DIR dir) } #else fd_set * fdset; - + if (dir == WRITE) fdset = &wrfds; else @@ -564,7 +564,7 @@ do_send(Conn * conn) break; } else { /* - * we're done with this fragment: + * we're done with this fragment: */ nsent -= iovp->iov_len; *iovp = call->req.iov_saved; @@ -575,7 +575,7 @@ do_send(Conn * conn) call->req.iov_index = iovp - call->req.iov; if (call->req.iov_index < NELEMS(call->req.iov)) { /* - * there are more header bytes to write + * there are more header bytes to write */ call->timeout = param.timeout ? timer_now() + param.timeout : 0.0; @@ -584,7 +584,7 @@ do_send(Conn * conn) } /* - * we're done with sending this request + * we're done with sending this request */ conn->sendq = call->sendq_next; if (!conn->sendq) { @@ -600,8 +600,8 @@ do_send(Conn * conn) /* * get ready to receive matching reply (note that we - * implicitly pass on the reference to the call from the sendq - * to the recvq): + * implicitly pass on the reference to the call from the sendq + * to the recvq): */ call->recvq_next = 0; if (!conn->recvq) @@ -640,7 +640,7 @@ recv_done(Call * call) conn->recvq_tail = 0; } /* - * we're done with receiving this request + * we're done with receiving this request */ arg.l = 0; event_signal(EV_CALL_RECV_STOP, (Object *) call, arg); @@ -697,7 +697,7 @@ do_recv(Conn * s) if (DBG > 3) { /* - * dump received data in hex & ascii: + * dump received data in hex & ascii: */ fprintf(stderr, "do_recv.%lu: received reply data:\n", c->id); @@ -718,7 +718,7 @@ do_recv(Conn * s) } /* - * process the replies in this buffer: + * process the replies in this buffer: */ buf_len = nread; @@ -727,7 +727,7 @@ do_recv(Conn * s) c = s->recvq; assert(c); /* - * sets right start time, but doesn't update each packet + * sets right start time, but doesn't update each packet */ if (s->state == S_REPLY_STATUS) { c->timeout = param.timeout + param.think_timeout; @@ -951,7 +951,7 @@ core_init(void) core_add_address(myaddr.sin_addr); /* - * Don't disturb just because a TCP connection closed on us... + * Don't disturb just because a TCP connection closed on us... */ signal(SIGPIPE, SIG_IGN); @@ -974,7 +974,7 @@ core_init(void) fprintf(stderr, "%s: failed to add timer event: %s", prog_name, strerror(errno)); - } + } #else #ifdef HAVE_EPOLL epoll_fd = epoll_create(EPOLL_N_MAX); @@ -995,17 +995,17 @@ core_init(void) #else #ifdef DONT_POLL /* - * This causes select() to take several milliseconds on both Linux/x86 - * and HP-UX 10.20. + * This causes select() to take several milliseconds on both Linux/x86 + * and HP-UX 10.20. */ select_timeout.tv_sec = (u_long) TIMER_INTERVAL; select_timeout.tv_usec = (u_long) (TIMER_INTERVAL * 1e6); #else /* * This causes httperf to become a CPU hog as it polls for - * filedescriptors to become readable/writable. This is OK as long as + * filedescriptors to become readable/writable. This is OK as long as * httperf is the only (interesting) user-level process that executes - * on a machine. + * on a machine. */ select_timeout.tv_sec = 0; select_timeout.tv_usec = 0; @@ -1014,7 +1014,7 @@ core_init(void) #endif /* - * boost open file limit to the max: + * boost open file limit to the max: */ if (getrlimit(RLIMIT_NOFILE, &rlimit) < 0) { fprintf(stderr, @@ -1048,7 +1048,7 @@ core_init(void) #ifdef HAVE_SSL -void +int core_ssl_connect(Conn * s) { Any_Type arg; @@ -1083,13 +1083,13 @@ core_ssl_connect(Conn * s) clear_active(s, READ); set_active(s, WRITE); } - return; + return 0; } fprintf(stderr, "%s: failed to connect to SSL server (err=%d, reason=%d)\n", prog_name, ssl_err, reason); ERR_print_errors_fp(stderr); - exit(-1); + return -1; } s->state = S_CONNECTED; @@ -1114,6 +1114,7 @@ core_ssl_connect(Conn * s) arg.l = 0; event_signal(EV_CONN_CONNECTED, (Object *) s, arg); + return 0; } #endif /* HAVE_SSL */ @@ -1168,7 +1169,7 @@ core_connect(Conn * s) /* * Disable Nagle algorithm so we don't delay needlessly when - * pipelining requests. + * pipelining requests. */ optval = 1; if (setsockopt(sd, SOL_TCP, TCP_NODELAY, &optval, sizeof(optval)) < 0) { @@ -1267,7 +1268,12 @@ core_connect(Conn * s) if (result == 0) { #ifdef HAVE_SSL if (param.use_ssl) - core_ssl_connect(s); + printf("OZAPTF UNKNOWN case\n"); + if (core_ssl_connect(s) == -1) { + // OZAPTF: + conn_failure(s, errno); + return -1; + } else #endif { @@ -1279,7 +1285,7 @@ core_connect(Conn * s) /* * The socket becomes writable only after the connection has * been established. Hence we wait for writability to detect - * connection establishment. + * connection establishment. */ s->state = S_CONNECTING; set_active(s, WRITE); @@ -1325,7 +1331,7 @@ core_send(Conn * conn, Call * call) call->req.iov[IE_HOST].iov_len = 0; } else if (!call->req.iov[IE_HOST].iov_base) { /* - * Default call's hostname to connection's hostname: + * Default call's hostname to connection's hostname: */ call->req.iov[IE_HOST].iov_base = (caddr_t) conn->fqdname; call->req.iov[IE_HOST].iov_len = conn->fqdname_len; @@ -1336,7 +1342,7 @@ core_send(Conn * conn, Call * call) * understand. If we send HTTP/1.1, it doesn't mean that the server * has to speak HTTP/1.1. In other words, sending an HTTP/1.1 header * leaves it up to the server whether it wants to reply with a 1.0 or - * 1.1 reply. + * 1.1 reply. */ switch (call->req.version) { case 0x10000: @@ -1373,7 +1379,7 @@ core_send(Conn * conn, Call * call) call->req.iov_saved = call->req.iov[0]; /* - * insert call into connection's send queue: + * insert call into connection's send queue: */ call_inc_ref(call); call->sendq_next = 0; @@ -1413,7 +1419,7 @@ core_close(Conn * conn) } /* - * first, get rid of all pending calls: + * first, get rid of all pending calls: */ for (call = conn->sendq; call; call = call_next) { call_next = call->sendq_next; @@ -1464,14 +1470,15 @@ core_close(Conn * conn) port_put(conn->myaddr, conn->myport); /* - * A connection that has been closed is not useful anymore, so we give - * up the reference obtained when creating the session. This normally - * initiates destruction of the connection. + * A connection that has been closed is not useful anymore, so we give + * up the reference obtained when creating the session. This normally + * initiates destruction of the connection. */ conn_dec_ref(conn); } #ifdef HAVE_KEVENT +#error "MUST NOT BE USED" void core_loop(void) { @@ -1521,7 +1528,7 @@ core_loop(void) if (ev.filter == EVFILT_READ && conn->recvq) do_recv(conn); } - + conn_dec_ref(conn); break; } @@ -1559,7 +1566,11 @@ core_loop(void) if (conn->state == S_CONNECTING) { #ifdef HAVE_SSL if (param.use_ssl) - core_ssl_connect(conn); + if (core_ssl_connect(conn) == -1) { + event_signal(EV_CONN_TIMEOUT, (Object*)conn, arg); + conn_dec_ref(conn); + continue; + } else #endif if (ep->events & EPOLLOUT) { @@ -1580,6 +1591,9 @@ core_loop(void) close(epoll_fd); } #else + +#error "MUST NOT BE USED" + void core_loop(void) { @@ -1588,7 +1602,7 @@ core_loop(void) fd_mask mask; Any_Type arg; Conn *conn; - + while (running) { struct timeval tv = select_timeout; @@ -1614,7 +1628,7 @@ core_loop(void) while (n > 0) { /* * find the index of the fdmask that has something - * going on: + * going on: */ do { ++i; @@ -1631,7 +1645,7 @@ core_loop(void) --n; is_readable = (FD_ISSET(sd, &readable) && FD_ISSET(sd, &rdfds)); is_writable = (FD_ISSET(sd, &writable) && FD_ISSET(sd, &wrfds)); - + if (is_readable || is_writable) { /* * only handle sockets that @@ -1646,8 +1660,11 @@ core_loop(void) } if (conn->state == S_CONNECTING) { #ifdef HAVE_SSL - if (param.use_ssl) - core_ssl_connect(conn); + if (param.use_ssl) { + core_ssl_connect(conn); + assert(false); /// OZAPTF: ensure this is not used + } + else #endif if (is_writable) { @@ -1662,9 +1679,9 @@ core_loop(void) if (is_readable && conn->recvq) do_recv(conn); } - + conn_dec_ref(conn); - + if (n > 0) timer_tick(); }