Example #1
0
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;
}
Example #2
0
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;
}