Fix memory leak, avoid uncessary abuse of memory and formatting tweaks. Bug #4282
authorJeremy McNamara <jj@nufone.net>
Thu, 19 May 2005 16:17:08 +0000 (16:17 +0000)
committerJeremy McNamara <jj@nufone.net>
Thu, 19 May 2005 16:17:08 +0000 (16:17 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5739 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_h323.c
channels/h323/ast_h323.cpp
channels/h323/chan_h323.h

index 8ef90c4..67cd905 100755 (executable)
@@ -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:         
index c4eeb05..2e59c8f 100755 (executable)
@@ -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;
index 520dda3..aeb88b8 100755 (executable)
@@ -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
-
-
-