-- i don't really like the way that i fixed the memory leak in connio, however i wanted to get this out to users asap for testing. this fixed a major memory leak for me when tls is used
-- there were a couple of remaining memory leaks in smtpc that have been fixed and i've changed the threadpool size from 5-20 down to 1. The system still seems to deliver mail rapidly and the huge memory usage does not occur any longer.
This commit is contained in:
@@ -156,6 +156,12 @@ typedef struct {
|
||||
unsigned long useCount;
|
||||
} TraceDestination;
|
||||
|
||||
/* this struct is used to pass the new context and the credentials */
|
||||
typedef struct _ssl_context_and_credentials {
|
||||
gnutls_session_t context;
|
||||
gnutls_certificate_credentials_t credentials;
|
||||
} SSL_Context_and_Credentials;
|
||||
|
||||
typedef struct _Connection {
|
||||
IPSOCKET socket;
|
||||
BOOL bSelfManage;
|
||||
@@ -164,6 +170,7 @@ typedef struct _Connection {
|
||||
BOOL enable;
|
||||
|
||||
gnutls_session_t context;
|
||||
gnutls_certificate_credentials_t credentials;
|
||||
} ssl;
|
||||
|
||||
struct sockaddr_in socketAddress;
|
||||
|
||||
+17
-3
@@ -153,14 +153,25 @@ Connection *LookupRemoteMX(RecipStruct *Recipient) {
|
||||
Recipient->Result = DELIVER_TRY_LATER;
|
||||
break;
|
||||
}
|
||||
ConnFree(Result);
|
||||
Result = NULL;
|
||||
continue;
|
||||
}
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (list) {
|
||||
MemFree(list);
|
||||
list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
finish:
|
||||
if (list) {
|
||||
MemFree(list);
|
||||
list = NULL;
|
||||
}
|
||||
XplDnsFreeMxLookup(mx);
|
||||
|
||||
return Result;
|
||||
@@ -597,6 +608,7 @@ ProcessEntry(void *clientp, Connection *conn)
|
||||
// we're responsible for closing this connection
|
||||
ConnClose(Remote.conn, 1);
|
||||
ConnFree(Remote.conn);
|
||||
Remote.conn = NULL;
|
||||
|
||||
/* now handle delivery result codes */
|
||||
switch(CurrentRecip.Result) {
|
||||
@@ -629,8 +641,9 @@ ProcessEntry(void *clientp, Connection *conn)
|
||||
if (Recipients) {
|
||||
BongoArrayFree(Recipients, TRUE);
|
||||
}
|
||||
/* The Queue struct, connection, and QDONE will be cleaned up by
|
||||
* the caller */
|
||||
/* The caller will call the free function specified on agent init
|
||||
* which will free the queue struct. the caller will then free the
|
||||
* connection and do the qdone */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -646,7 +659,8 @@ SMTPAgentServer(void *ignored)
|
||||
|
||||
/* Listen for incoming queue items. Call ProcessEntry with a
|
||||
* SMTPAgentClient allocated for each incoming queue entry. */
|
||||
SMTPAgent.OutgoingThreadPool = BongoThreadPoolNew(AGENT_NAME " Clients", BONGO_QUEUE_AGENT_DEFAULT_STACK_SIZE, minThreads, maxThreads, minSleep);
|
||||
SMTPAgent.OutgoingThreadPool = BongoThreadPoolNew(AGENT_NAME " Clients", BONGO_QUEUE_AGENT_DEFAULT_STACK_SIZE, 0, 1, minSleep);
|
||||
//SMTPAgent.OutgoingThreadPool = BongoThreadPoolNew(AGENT_NAME " Clients", BONGO_QUEUE_AGENT_DEFAULT_STACK_SIZE, minThreads, maxThreads, minSleep);
|
||||
SMTPAgent.nmapOutgoing = BongoQueueConnectionInit(&SMTPAgent.agent, Q_OUTGOING);
|
||||
BongoQueueAgentListenWithClientPool(&SMTPAgent.agent,
|
||||
SMTPAgent.nmapOutgoing,
|
||||
|
||||
+40
-19
@@ -59,43 +59,45 @@ ConnIOGlobals ConnIO;
|
||||
gnutls_dh_params_t dh_params;
|
||||
gnutls_rsa_params_t rsa_params;
|
||||
|
||||
gnutls_session_t
|
||||
__gnutls_new(bongo_ssl_context *context, gnutls_connection_end_t con_end) {
|
||||
gnutls_session_t session;
|
||||
BOOL
|
||||
__gnutls_new(SSL_Context_and_Credentials *new_session, bongo_ssl_context *context, gnutls_connection_end_t con_end) {
|
||||
int ccode;
|
||||
|
||||
ccode = gnutls_init(&session, con_end);
|
||||
new_session->context = NULL;
|
||||
new_session->credentials = NULL;
|
||||
|
||||
ccode = gnutls_init(&new_session->context, con_end);
|
||||
if (ccode) {
|
||||
return(NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (con_end == GNUTLS_SERVER) {
|
||||
ccode = gnutls_set_default_export_priority(session);
|
||||
ccode = gnutls_set_default_export_priority(new_session->context);
|
||||
|
||||
/* store in the credetials loaded earler */
|
||||
ccode = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, context->cert_cred);
|
||||
ccode = gnutls_credentials_set(new_session->context, GNUTLS_CRD_CERTIFICATE, context->cert_cred);
|
||||
|
||||
/* initialize the dh bits */
|
||||
gnutls_dh_set_prime_bits(session, 1024);
|
||||
gnutls_dh_set_prime_bits(new_session->context, 1024);
|
||||
} else {
|
||||
gnutls_certificate_credentials_t xcred = NULL;
|
||||
new_session->credentials = NULL;
|
||||
|
||||
const int cert_type_priority[4] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 };
|
||||
|
||||
/* defaults are ok here */
|
||||
gnutls_set_default_priority (session);
|
||||
gnutls_set_default_priority (new_session->context);
|
||||
|
||||
/* store the priority for x509 or openpgp out there
|
||||
* i doubt that openpgp will be used but perhaps there is a server that supports it */
|
||||
gnutls_certificate_type_set_priority (session, cert_type_priority);
|
||||
gnutls_certificate_allocate_credentials (&xcred);
|
||||
gnutls_certificate_set_x509_trust_file (xcred, XPL_DEFAULT_CERT_PATH, GNUTLS_X509_FMT_PEM);
|
||||
gnutls_certificate_type_set_priority (new_session->context, cert_type_priority);
|
||||
gnutls_certificate_allocate_credentials (&new_session->credentials);
|
||||
gnutls_certificate_set_x509_trust_file (new_session->credentials, XPL_DEFAULT_CERT_PATH, GNUTLS_X509_FMT_PEM);
|
||||
|
||||
/* set the empty credentials in the session */
|
||||
gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
|
||||
gnutls_credentials_set (new_session->context, GNUTLS_CRD_CERTIFICATE, new_session->credentials);
|
||||
}
|
||||
|
||||
return session;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
@@ -349,6 +351,7 @@ __inline static IPSOCKET
|
||||
ConnConnectInternal(Connection *conn, struct sockaddr *saddr, socklen_t slen, bongo_ssl_context *context, TraceDestination *destination, unsigned long timeOut)
|
||||
{
|
||||
int ccode;
|
||||
SSL_Context_and_Credentials ssl_info;
|
||||
|
||||
conn->socket = IPsocket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (conn->socket != -1) {
|
||||
@@ -376,7 +379,10 @@ ConnConnectInternal(Connection *conn, struct sockaddr *saddr, socklen_t slen, bo
|
||||
conn->ssl.enable = FALSE;
|
||||
|
||||
return(conn->socket);
|
||||
} else if ((conn->ssl.context = __gnutls_new(context, GNUTLS_CLIENT)) != NULL) {
|
||||
} else if (__gnutls_new(&ssl_info, context, GNUTLS_CLIENT) != FALSE) {
|
||||
conn->ssl.context = ssl_info.context;
|
||||
conn->ssl.credentials = ssl_info.credentials;
|
||||
|
||||
setsockopt(conn->socket, IPPROTO_TCP, 1, (unsigned char *)&ccode, sizeof(ccode));
|
||||
|
||||
gnutls_transport_set_ptr (conn->ssl.context, (gnutls_transport_ptr_t) conn->socket);
|
||||
@@ -425,8 +431,12 @@ ConnEncrypt(Connection *conn, bongo_ssl_context *context)
|
||||
{
|
||||
int ccode;
|
||||
register Connection *c = conn;
|
||||
SSL_Context_and_Credentials ssl_info;
|
||||
|
||||
if (__gnutls_new(&ssl_info, context, GNUTLS_CLIENT) != FALSE) {
|
||||
c->ssl.context = ssl_info.context;
|
||||
c->ssl.credentials = ssl_info.credentials;
|
||||
|
||||
if ((c->ssl.context = __gnutls_new(context, GNUTLS_CLIENT)) != NULL) {
|
||||
setsockopt(c->socket, IPPROTO_TCP, 1, (unsigned char *)&ccode, sizeof(ccode));
|
||||
|
||||
gnutls_transport_set_ptr(c->ssl.context, (gnutls_transport_ptr_t) c->socket);
|
||||
@@ -438,7 +448,9 @@ ConnEncrypt(Connection *conn, bongo_ssl_context *context)
|
||||
}
|
||||
|
||||
gnutls_deinit(c->ssl.context);
|
||||
gnutls_certificate_free_credentials(c->ssl.credentials);
|
||||
c->ssl.context = NULL;
|
||||
c->ssl.credentials = NULL;
|
||||
}
|
||||
c->ssl.enable = FALSE;
|
||||
|
||||
@@ -450,6 +462,7 @@ ConnNegotiate(Connection *conn, bongo_ssl_context *context)
|
||||
{
|
||||
int ccode;
|
||||
register Connection *c = conn;
|
||||
SSL_Context_and_Credentials ssl_info;
|
||||
|
||||
if (c->ssl.enable == FALSE) {
|
||||
ccode = 1;
|
||||
@@ -458,7 +471,10 @@ ConnNegotiate(Connection *conn, bongo_ssl_context *context)
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if ((c->ssl.context = __gnutls_new(context, GNUTLS_SERVER)) != NULL) {
|
||||
if (__gnutls_new(&ssl_info, context, GNUTLS_SERVER) != FALSE) {
|
||||
c->ssl.context = ssl_info.context;
|
||||
c->ssl.credentials = ssl_info.credentials;
|
||||
|
||||
setsockopt(c->socket, IPPROTO_TCP, 1, (unsigned char *)&ccode, sizeof(ccode));
|
||||
|
||||
gnutls_transport_set_ptr(c->ssl.context, (gnutls_transport_ptr_t) c->socket);
|
||||
@@ -468,9 +484,10 @@ ConnNegotiate(Connection *conn, bongo_ssl_context *context)
|
||||
return(TRUE);
|
||||
}
|
||||
gnutls_deinit(c->ssl.context);
|
||||
gnutls_certificate_free_credentials(c->ssl.credentials);
|
||||
c->ssl.enable = FALSE;
|
||||
c->ssl.context = NULL;
|
||||
|
||||
c->ssl.credentials = NULL;
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
@@ -531,6 +548,10 @@ ConnFree(Connection *Conn)
|
||||
MemFree(c->send.buffer);
|
||||
}
|
||||
|
||||
if (c->ssl.credentials) {
|
||||
gnutls_certificate_free_credentials(c->ssl.credentials);
|
||||
}
|
||||
|
||||
if (c->ssl.context) {
|
||||
gnutls_deinit(c->ssl.context);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,6 @@ typedef struct _ConnIO {
|
||||
|
||||
extern ConnIOGlobals ConnIO;
|
||||
|
||||
gnutls_session_t __gnutls_new(bongo_ssl_context *context, gnutls_connection_end_t con_end);
|
||||
BOOL __gnutls_new(SSL_Context_and_Credentials *new_session, bongo_ssl_context *context, gnutls_connection_end_t con_end);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user