From 793182ea7db7f85ac8aa1983c1854b13ee33606b Mon Sep 17 00:00:00 2001 From: Jeremy McNamara Date: Thu, 19 May 2005 16:17:08 +0000 Subject: Fix memory leak, avoid uncessary abuse of memory and formatting tweaks. Bug #4282 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5739 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_h323.c | 122 ++++++++++++++++++++++----------------------- channels/h323/ast_h323.cpp | 28 +++-------- channels/h323/chan_h323.h | 11 ++-- 3 files changed, 71 insertions(+), 90 deletions(-) (limited to 'channels') diff --git a/channels/chan_h323.c b/channels/chan_h323.c index 8ef90c4cc..67cd9050d 100755 --- a/channels/chan_h323.c +++ b/channels/chan_h323.c @@ -1240,7 +1240,7 @@ int progress(unsigned call_reference, const char *token, int inband) * * Returns 1 on success */ -call_options_t *setup_incoming_call(call_details_t cd) +call_options_t *setup_incoming_call(call_details_t *cd) { struct oh323_pvt *pvt; struct oh323_user *user = NULL; @@ -1248,10 +1248,10 @@ call_options_t *setup_incoming_call(call_details_t cd) char iabuf[INET_ADDRSTRLEN]; if (h323debug) - ast_log(LOG_DEBUG, "Setting up incoming call for %s\n", cd.call_token); + ast_log(LOG_DEBUG, "Setting up incoming call for %s\n", cd->call_token); /* allocate the call*/ - pvt = oh323_alloc(cd.call_reference); + pvt = oh323_alloc(cd->call_reference); if (!pvt) { ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n"); @@ -1259,12 +1259,8 @@ call_options_t *setup_incoming_call(call_details_t cd) } /* Populate the call details in the private structure */ - pvt->cd.call_token = strdup(cd.call_token); - pvt->cd.call_source_aliases = strdup(cd.call_source_aliases); - pvt->cd.call_dest_alias = strdup(cd.call_dest_alias); - pvt->cd.call_source_name = strdup(cd.call_source_name); - pvt->cd.call_source_e164 = strdup(cd.call_source_e164); - pvt->cd.call_dest_e164 = strdup(cd.call_dest_e164); + memcpy(&pvt->cd, cd, sizeof(pvt->cd)); + memcpy(&pvt->options, &global_options, sizeof(pvt->options)); if (h323debug) { ast_verbose(VERBOSE_PREFIX_3 "Setting up Call\n"); @@ -1276,14 +1272,14 @@ call_options_t *setup_incoming_call(call_details_t cd) } /* Decide if we are allowing Gatekeeper routed calls*/ - if ((!strcasecmp(cd.sourceIp, gatekeeper)) && (gkroute == -1) && (usingGk)) { - if (!ast_strlen_zero(cd.call_dest_e164)) { - strncpy(pvt->exten, cd.call_dest_e164, sizeof(pvt->exten) - 1); + if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && (usingGk)) { + if (!ast_strlen_zero(cd->call_dest_e164)) { + strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1); strncpy(pvt->context, default_context, sizeof(pvt->context) - 1); } else { - alias = find_alias(cd.call_dest_alias); + alias = find_alias(cd->call_dest_alias); if (!alias) { - ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd.call_dest_alias); + ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias); return NULL; } strncpy(pvt->exten, alias->name, sizeof(pvt->exten) - 1); @@ -1292,26 +1288,27 @@ call_options_t *setup_incoming_call(call_details_t cd) } else { /* Either this call is not from the Gatekeeper or we are not allowing gk routed calls */ - user = find_user(&cd); + user = find_user(cd); if (!user) { if (!ast_strlen_zero(pvt->cd.call_dest_e164)) { - strncpy(pvt->exten, cd.call_dest_e164, sizeof(pvt->exten) - 1); + strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1); } else { - strncpy(pvt->exten, cd.call_dest_alias, sizeof(pvt->exten) - 1); + strncpy(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten) - 1); } if (ast_strlen_zero(default_context)) { ast_log(LOG_ERROR, "Call from '%s' rejected due to no default context\n", pvt->cd.call_source_aliases); return NULL; } strncpy(pvt->context, default_context, sizeof(pvt->context) - 1); - ast_log(LOG_DEBUG, "Sending %s to context [%s]\n", cd.call_source_aliases, pvt->context); + ast_log(LOG_DEBUG, "Sending %s to context [%s]\n", cd->call_source_aliases, pvt->context); + /* XXX: Is it really required??? */ memset(&pvt->options, 0, sizeof(pvt->options)); - } else { + } else { if (user->host) { - if (strcasecmp(cd.sourceIp, ast_inet_ntoa(iabuf, sizeof(iabuf), user->addr.sin_addr))) { + if (strcasecmp(cd->sourceIp, ast_inet_ntoa(iabuf, sizeof(iabuf), user->addr.sin_addr))) { if (ast_strlen_zero(user->context)) { if (ast_strlen_zero(default_context)) { - ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd.sourceIp); + ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp); return NULL; } strncpy(pvt->context, default_context, sizeof(pvt->context) - 1); @@ -1320,8 +1317,8 @@ call_options_t *setup_incoming_call(call_details_t cd) } pvt->exten[0] = 'i'; pvt->exten[1] = '\0'; - ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd.sourceIp); - return NULL; + ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp); + return NULL; /* XXX: Hmmm... Why to setup context if we drop connection immediately??? */ } } strncpy(pvt->context, user->context, sizeof(pvt->context) - 1); @@ -1329,9 +1326,9 @@ call_options_t *setup_incoming_call(call_details_t cd) pvt->nat = user->nat; memcpy(&pvt->options, &user->options, sizeof(pvt->options)); if (!ast_strlen_zero(pvt->cd.call_dest_e164)) { - strncpy(pvt->exten, cd.call_dest_e164, sizeof(pvt->exten) - 1); + strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1); } else { - strncpy(pvt->exten, cd.call_dest_alias, sizeof(pvt->exten) - 1); + strncpy(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten) - 1); } if (!ast_strlen_zero(user->accountcode)) { strncpy(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode) - 1); @@ -1380,8 +1377,11 @@ static int answer_call(unsigned call_reference, const char *token) * * Returns 1 on success */ -int setup_outgoing_call(call_details_t cd) -{ +int setup_outgoing_call(call_details_t *cd) +{ + /* Use argument here or free it immediately */ + cleanup_call_details(cd); + return 1; } @@ -1391,8 +1391,8 @@ int setup_outgoing_call(call_details_t cd) */ void chan_ringing(unsigned call_reference, const char *token) { - struct ast_channel *c = NULL; - struct oh323_pvt *pvt; + struct ast_channel *c = NULL; + struct oh323_pvt *pvt; if (h323debug) ast_log(LOG_DEBUG, "Ringing on %s\n", token); @@ -1401,55 +1401,53 @@ void chan_ringing(unsigned call_reference, const char *token) if (!pvt) { ast_log(LOG_ERROR, "Something is wrong: ringing\n"); } - if (!pvt->owner) { - ast_mutex_unlock(&pvt->lock); - ast_log(LOG_ERROR, "Channel has no owner\n"); - return; - } - ast_mutex_lock(&pvt->owner->lock); - c = pvt->owner; - ast_setstate(c, AST_STATE_RINGING); - ast_queue_control(c, AST_CONTROL_RINGING); - ast_mutex_unlock(&pvt->owner->lock); - ast_mutex_unlock(&pvt->lock); - return; + if (!pvt->owner) { + ast_mutex_unlock(&pvt->lock); + ast_log(LOG_ERROR, "Channel has no owner\n"); + return; + } + ast_mutex_lock(&pvt->owner->lock); + c = pvt->owner; + ast_setstate(c, AST_STATE_RINGING); + ast_queue_control(c, AST_CONTROL_RINGING); + ast_mutex_unlock(&pvt->owner->lock); + ast_mutex_unlock(&pvt->lock); + return; } /** * Call-back function to cleanup communication * Returns nothing, */ -static void cleanup_connection(call_details_t cd) +static void cleanup_connection(unsigned call_reference, const char *call_token) { struct oh323_pvt *pvt; - struct ast_rtp *rtp = NULL; - ast_log(LOG_DEBUG, "Cleaning connection to %s\n", cd.call_token); + ast_log(LOG_DEBUG, "Cleaning connection to %s\n", call_token); while (1) { - pvt = find_call_locked(cd.call_reference, cd.call_token); + pvt = find_call_locked(call_reference, call_token); if (!pvt) { if (h323debug) - ast_log(LOG_DEBUG, "No connection for %s\n", cd.call_token); + ast_log(LOG_DEBUG, "No connection for %s\n", call_token); return; } if (!pvt->owner || !ast_mutex_trylock(&pvt->owner->lock)) break; #if 1 #ifdef DEBUG_THREADS - ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s, locked at %ld/%d by %s (%s:%d)\n", cd.call_token, pvt->owner->lock.thread, pvt->owner->lock.reentrancy, pvt->owner->lock.func, pvt->owner->lock.file, pvt->owner->lock.lineno); + ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s, locked at %ld/%d by %s (%s:%d)\n", call_token, pvt->owner->lock.thread, pvt->owner->lock.reentrancy, pvt->owner->lock.func, pvt->owner->lock.file, pvt->owner->lock.lineno); #else - ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", cd.call_token); + ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token); #endif #endif ast_mutex_unlock(&pvt->lock); usleep(1); } if (pvt->rtp) { - rtp = pvt->rtp; - pvt->rtp = NULL; /* Immediately stop RTP */ - ast_rtp_destroy(rtp); + ast_rtp_destroy(pvt->rtp); + pvt->rtp = NULL; } /* Free dsp used for in-band DTMF detection */ if (pvt->vad) { @@ -1466,7 +1464,7 @@ static void cleanup_connection(call_details_t cd) } ast_mutex_unlock(&pvt->lock); if (h323debug) - ast_log(LOG_DEBUG, "Connection to %s cleaned\n", cd.call_token); + ast_log(LOG_DEBUG, "Connection to %s cleaned\n", call_token); return; } @@ -1520,17 +1518,17 @@ static void *do_monitor(void *data) struct oh323_pvt *oh323 = NULL; for(;;) { - /* Check for a reload request */ - ast_mutex_lock(&h323_reload_lock); - reloading = h323_reloading; - h323_reloading = 0; - ast_mutex_unlock(&h323_reload_lock); - if (reloading) { - if (option_verbose > 0) { - ast_verbose(VERBOSE_PREFIX_1 "Reloading H.323\n"); + /* Check for a reload request */ + ast_mutex_lock(&h323_reload_lock); + reloading = h323_reloading; + h323_reloading = 0; + ast_mutex_unlock(&h323_reload_lock); + if (reloading) { + if (option_verbose > 0) { + ast_verbose(VERBOSE_PREFIX_1 "Reloading H.323\n"); } - h323_do_reload(); - } + h323_do_reload(); + } /* Check for interfaces needing to be killed */ ast_mutex_lock(&iflock); restartsearch: diff --git a/channels/h323/ast_h323.cpp b/channels/h323/ast_h323.cpp index c4eeb0587..2e59c8f43 100755 --- a/channels/h323/ast_h323.cpp +++ b/channels/h323/ast_h323.cpp @@ -434,23 +434,8 @@ void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection, const */ void MyH323EndPoint::OnConnectionCleared(H323Connection & connection, const PString & clearedCallToken) { - PString remoteName; - call_details_t cd; - PIPSocket::Address Ip; - WORD sourcePort; + PString remoteName = connection.GetRemotePartyName(); - remoteName = connection.GetRemotePartyName(); - cd.call_reference = connection.GetCallReference(); - cd.call_token = strdup((const char *)clearedCallToken); - cd.call_source_aliases = strdup((const char *)connection.GetRemotePartyName()); - connection.GetSignallingChannel()->GetRemoteAddress().GetIpAndPort(Ip, sourcePort); - cd.sourceIp = strdup((const char *)Ip.AsString()); - - /* Convert complex strings */ - char *s; - if ((s = strchr(cd.call_source_aliases, ' ')) != NULL) { - *s = '\0'; - } switch (connection.GetCallEndReason()) { case H323Connection::EndedByCallForwarded: if (h323debug) { @@ -549,7 +534,7 @@ void MyH323EndPoint::OnConnectionCleared(H323Connection & connection, const PStr } } /* Invoke the PBX application registered callback */ - on_connection_cleared(cd); + on_connection_cleared(connection.GetCallReference(), clearedCallToken); return; } @@ -743,6 +728,7 @@ BOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU) *s1 = '\0'; } + memset(&cd, 0, sizeof(cd)); cd.call_reference = GetCallReference(); cd.call_token = strdup((const char *)GetCallToken()); cd.call_source_aliases = strdup((const char *)sourceAliases); @@ -755,7 +741,7 @@ BOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU) cd.sourceIp = strdup((const char *)Ip.AsString()); /* Notify Asterisk of the request */ - call_options_t *res = on_incoming_call(cd); + call_options_t *res = on_incoming_call(&cd); if (!res) { if (h323debug) { @@ -815,16 +801,16 @@ BOOL MyH323Connection::OnSendSignalSetup(H323SignalPDU & setupPDU) if ((s1 = strchr(destAliases, '\t')) != NULL) { *s1 = '\0'; } + + memset(&cd, 0, sizeof(cd)); cd.call_reference = GetCallReference(); - Lock(); cd.call_token = strdup((const char *)GetCallToken()); - Unlock(); cd.call_source_aliases = strdup((const char *)sourceAliases); cd.call_dest_alias = strdup((const char *)destAliases); cd.call_source_e164 = strdup((const char *)sourceE164); cd.call_dest_e164 = strdup((const char *)destE164); - int res = on_outgoing_call(cd); + int res = on_outgoing_call(&cd); if (!res) { if (h323debug) { cout << "\t-- Call Failed" << endl; diff --git a/channels/h323/chan_h323.h b/channels/h323/chan_h323.h index 520dda3f4..aeb88b876 100755 --- a/channels/h323/chan_h323.h +++ b/channels/h323/chan_h323.h @@ -36,7 +36,7 @@ typedef struct call_options { int noFastStart; int noH245Tunneling; int noSilenceSuppression; - unsigned int port; +/* unsigned int port; */ int progress_setup; int progress_alert; int progress_audio; @@ -132,12 +132,12 @@ extern progress_cb on_progress; /* This is a callback prototype function, called upon an incoming call happens. */ -typedef call_options_t *(*setup_incoming_cb)(call_details_t); +typedef call_options_t *(*setup_incoming_cb)(call_details_t *); extern setup_incoming_cb on_incoming_call; /* This is a callback prototype function, called upon an outbound call. */ -typedef int (*setup_outbound_cb)(call_details_t); +typedef int (*setup_outbound_cb)(call_details_t *); extern setup_outbound_cb on_outgoing_call; /* This is a callback prototype function, called when @@ -152,7 +152,7 @@ extern con_established_cb on_connection_established; /* This is a callback prototype function, called when OnConnectionCleared callback is invoked */ -typedef void (*clear_con_cb)(call_details_t); +typedef void (*clear_con_cb)(unsigned, const char *); extern clear_con_cb on_connection_cleared; /* This is a callback prototype function, called when @@ -231,6 +231,3 @@ extern "C" { #ifdef __cplusplus } #endif - - - -- cgit v1.2.3