static void client_run(CLI *c) { int error; #ifndef USE_FORK enter_critical_section(CRIT_CLIENTS); /* for multi-cpu machines */ ++num_clients; leave_critical_section(CRIT_CLIENTS); #endif c->remote_fd.fd=-1; c->fd=-1; c->ssl=NULL; c->sock_bytes=c->ssl_bytes=0; c->fds=s_poll_alloc(); c->connect_addr.num=0; c->connect_addr.addr=NULL; error=setjmp(c->err); if(!error) client_try(c); s_log(LOG_NOTICE, "Connection %s: %d byte(s) sent to SSL, %d byte(s) sent to socket", error==1 ? "reset" : "closed", c->ssl_bytes, c->sock_bytes); /* cleanup temporary (e.g. IDENT) socket */ if(c->fd>=0) closesocket(c->fd); c->fd=-1; /* cleanup SSL */ if(c->ssl) { /* SSL initialized */ SSL_set_shutdown(c->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); SSL_free(c->ssl); c->ssl=NULL; ERR_remove_state(0); } /* cleanup remote socket */ if(c->remote_fd.fd>=0) { /* remote socket initialized */ if(error==1 && c->remote_fd.is_socket) /* reset */ reset(c->remote_fd.fd, "linger (remote)"); closesocket(c->remote_fd.fd); s_log(LOG_DEBUG, "Remote socket (FD=%d) closed", c->remote_fd.fd); c->remote_fd.fd=-1; } /* cleanup local socket */ if(c->local_rfd.fd>=0) { /* local socket initialized */ if(c->local_rfd.fd==c->local_wfd.fd) { if(error==1 && c->local_rfd.is_socket) reset(c->local_rfd.fd, "linger (local)"); closesocket(c->local_rfd.fd); s_log(LOG_DEBUG, "Local socket (FD=%d) closed", c->local_rfd.fd); } else { /* stdin/stdout */ if(error==1 && c->local_rfd.is_socket) reset(c->local_rfd.fd, "linger (local_rfd)"); if(error==1 && c->local_wfd.is_socket) reset(c->local_wfd.fd, "linger (local_wfd)"); } c->local_rfd.fd=c->local_wfd.fd=-1; } #ifdef USE_FORK /* display child return code if it managed to arrive on time */ /* otherwise it will be retrieved by the init process and ignored */ if(c->opt->option.program) /* 'exec' specified */ child_status(); /* null SIGCHLD handler was used */ s_log(LOG_DEBUG, "Service [%s] finished", c->opt->servname); #else enter_critical_section(CRIT_CLIENTS); /* for multi-cpu machines */ s_log(LOG_DEBUG, "Service [%s] finished (%d left)", c->opt->servname, --num_clients); leave_critical_section(CRIT_CLIENTS); #endif /* free remaining memory structures */ if(c->connect_addr.addr) str_free(c->connect_addr.addr); s_poll_free(c->fds); c->fds=NULL; }
static void client_run(CLI * c) { int error; c->remote_fd.fd = -1; c->fd = -1; c->ssl = NULL; c->sock_bytes = c->ssl_bytes = 0; c->fds = s_poll_alloc(); c->connect_addr.num = 0; c->connect_addr.addr = NULL; error = setjmp(c->err); if (!error) client_try(c); s_log(LOG_NOTICE, "Connection %s: %d byte(s) sent to SSL, %d byte(s) sent to socket", error == 1 ? "reset" : "closed", c->ssl_bytes, c->sock_bytes); if (c->fd >= 0) closesocket(c->fd); c->fd = -1; if (c->ssl) { SSL_set_shutdown(c->ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); SSL_free(c->ssl); c->ssl = NULL; ERR_remove_state(0); } if (c->remote_fd.fd >= 0) { if (error == 1 && c->remote_fd.is_socket) reset(c->remote_fd.fd, "linger (remote)"); closesocket(c->remote_fd.fd); s_log(LOG_DEBUG, "Remote socket (FD=%d) closed", c->remote_fd.fd); c->remote_fd.fd = -1; } if (c->local_rfd.fd >= 0) { if (c->local_rfd.fd == c->local_wfd.fd) { if (error == 1 && c->local_rfd.is_socket) reset(c->local_rfd.fd, "linger (local)"); closesocket(c->local_rfd.fd); s_log(LOG_DEBUG, "Local socket (FD=%d) closed", c->local_rfd.fd); } else { if (error == 1 && c->local_rfd.is_socket) reset(c->local_rfd.fd, "linger (local_rfd)"); if (error == 1 && c->local_wfd.is_socket) reset(c->local_wfd.fd, "linger (local_wfd)"); } c->local_rfd.fd = c->local_wfd.fd = -1; } s_log(LOG_DEBUG, "Service [%s] finished", c->opt->servname); if (c->connect_addr.addr) str_free(c->connect_addr.addr); s_poll_free(c->fds); c->fds = NULL; }