/**
 * @brief	Destroy and free a generic connection object after executing its protocol-specific destructor; update any statistics accordingly.
 * @param	con		a pointer to the connection to be destroyed.
 * @return	This function returns no value.
 */
void con_destroy(connection_t *con) {

	if (con && !con_decrement_refs(con)) {

		switch (con->server->protocol) {
			case (POP):

				if (con->network.ssl) {
					stats_decrement_by_name("pop.connections.secure");
				}

				stats_decrement_by_name("pop.connections.total");
				pop_session_destroy(con);
				break;
			case (IMAP):
				if (con->network.ssl) {
					stats_decrement_by_name("imap.connections.secure");
				}

				stats_decrement_by_name("imap.connections.total");
				imap_session_destroy(con);
				break;
			case (HTTP):
				if (con->network.ssl) {
					stats_decrement_by_name("http.connections.secure");
				}

				stats_decrement_by_name("http.connections.total");
				http_session_destroy(con);
				break;
			case (SMTP):
				if (con->network.ssl) {
					stats_decrement_by_name("smtp.connections.secure");
				}

				stats_decrement_by_name("smtp.connections.total");
				smtp_session_destroy(con);
				break;
			case (SUBMISSION):
				if (con->network.ssl) {
					stats_decrement_by_name("smtp.connections.secure");
				}

				stats_decrement_by_name("smtp.connections.total");
				smtp_session_destroy(con);
				break;
			case (MOLTEN):
				if (con->network.ssl) {
					stats_decrement_by_name("molten.connections.secure");
				}

				stats_decrement_by_name("molten.connections.total");
				molten_session_destroy(con);
				break;
			default:
				break;
		}

		if (con->network.ssl) {
			ssl_free(con->network.ssl);
		}

		if (con->network.sockd != -1) {
			close(con->network.sockd);
		}

		st_cleanup(con->network.buffer);
		st_cleanup(con->network.reverse.domain);
		mutex_destroy(&(con->lock));
		mm_free(con);
	}

	return;
}
Exemple #2
0
POP_SESSION *pop_set_socket(POP_SESSION *psp, int s, int opt)
{
    if (s < 0) {
	return NULL;
    }

    if (psp == NULL && (psp = pop_session_create()) == NULL) {
	return NULL;
    }

#ifdef WITH_OPENSSL
    if ((psp->bio = BIO_new_socket(s, BIO_NOCLOSE)) == NULL) {
	__pop_set_error_openssl(psp, "BIO_new_socket(): ");
	pop_session_destroy(psp);
	return NULL;
    }

#ifdef ENABLE_SSL
    if (opt & POP_OPT_SSL) {
	SSL_CTX *ctxp;
	BIO *bio_ssl;

	if ((ctxp = SSL_CTX_new(SSLv23_client_method())) == NULL) {
	    __pop_set_error_openssl(psp, "SSL_CTX_new(): ");
	    pop_session_destroy(psp);
	    return NULL;
	}
	if ((bio_ssl = BIO_new_ssl(ctxp, 1)) == NULL) {
	    __pop_set_error_openssl(psp, "BIO_new_ssl(): ");
	    pop_session_destroy(psp);
	    return NULL;
	}
	BIO_push(bio_ssl, psp->bio);
	psp->bio = bio_ssl;
	BIO_do_handshake(psp->bio);
    }
#endif /* ENABLE_SSL */

    {
	BIO *bio_buffer;

	if ((bio_buffer = BIO_new(BIO_f_buffer())) == NULL) {
	    __pop_set_error_openssl(psp, "BIO_new(): ");
	    pop_session_destroy(psp);
	    return NULL;
	}
	BIO_push(bio_buffer, psp->bio);
	psp->bio = bio_buffer;
    }
#else /* WITH_OPENSSL */
    if ((psp->sw = dup(s)) < 0) {
	__pop_set_error_errno(psp, "dup(s): ");
	pop_session_destroy(psp);
	return NULL;
    }
    if ((psp->fw = fdopen(psp->sw, "w")) == NULL) {
	__pop_set_error_errno(psp, "fdopen(fw): ");
	pop_session_destroy(psp);
	return NULL;
    }
    if ((psp->fr = fdopen(s, "r")) == NULL) {
	__pop_set_error_errno(psp, "fdopen(fr): ");
	pop_session_destroy(psp);
	return NULL;
    }
    psp->sr = s;
#endif /* WITH_OPENSSL */

    return psp;
}