]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fix bad channel application data reference.
authorMark Michelson <mmichelson@digium.com>
Tue, 11 Sep 2012 15:30:37 +0000 (15:30 +0000)
committerMark Michelson <mmichelson@digium.com>
Tue, 11 Sep 2012 15:30:37 +0000 (15:30 +0000)
When channels get bridged due to an AMI bridge action
or a DTMF attended transfer, the two channels that
get bridged have their application data pointing to
the other channel's name. This means that if one channel
is hung up but the other moves on, it means that the
channel that moves on will have its application data
pointing at freed memory.

(issue ASTERISK-20335)
Reported by: aragon
........

Merged revisions 372840 from http://svn.asterisk.org/svn/asterisk/branches/1.8

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@372841 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/features.c

index d8c641c5bf13bc29aad36256c29c5714b44a51b1..4cdde6fdedabaafa266bfc65eb26c6a6ea7c3d81 100644 (file)
@@ -945,6 +945,33 @@ static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
        struct ast_channel *transferee, const char *type, struct ast_format_cap *cap, void *data,
        int timeout, int *outstate, const char *language);
 
+static const struct ast_datastore_info channel_app_data_datastore = {
+       .type = "Channel appdata datastore",
+       .destroy = ast_free_ptr,
+};
+
+static int set_chan_app_data(struct ast_channel *chan, const char *src_app_data)
+{
+       struct ast_datastore *datastore;
+       char *dst_app_data;
+
+       datastore = ast_datastore_alloc(&channel_app_data_datastore, NULL);
+       if (!datastore) {
+               return -1;
+       }
+
+       dst_app_data = ast_malloc(strlen(src_app_data) + 1);
+       if (!dst_app_data) {
+               ast_datastore_free(datastore);
+               return -1;
+       }
+
+       chan->data = strcpy(dst_app_data, src_app_data);
+       datastore->data = dst_app_data;
+       ast_channel_datastore_add(chan, datastore);
+       return 0;
+}
+
 /*!
  * \brief bridge the call 
  * \param data thread bridge.
@@ -958,9 +985,13 @@ static void *bridge_call_thread(void *data)
        struct ast_bridge_thread_obj *tobj = data;
 
        tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
-       tobj->chan->data = tobj->peer->name;
+       if (set_chan_app_data(tobj->chan, tobj->peer->name)) {
+               tobj->chan->data = "(Empty)";
+       }
        tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
-       tobj->peer->data = tobj->chan->name;
+       if (set_chan_app_data(tobj->peer, tobj->chan->name)) {
+               tobj->peer->data = "(Empty)";
+       }
 
        ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);