/** * @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; }
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; }