]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merge patches for 1.8.11-cert6
authorMatthew Jordan <mjordan@digium.com>
Fri, 24 Aug 2012 13:55:18 +0000 (13:55 +0000)
committerMatthew Jordan <mjordan@digium.com>
Fri, 24 Aug 2012 13:55:18 +0000 (13:55 +0000)
This includes the following
 * r369351 for AST-883
 * r368807 for AST-884
 * r356604, r356650, r364203 for AST-890
 * r370618 for AST-896
 * r370205, r370273, r370360 for AST-916
 * r371469 for AST-932

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

channels/chan_sip.c
channels/sip/include/sip.h
configs/sip.conf.sample
main/cel.c
main/channel.c
main/xmldoc.c

index bd80394ec1005e864da3867dd95e9966c3181de2..456d5fa7e7f0eaa1daef65803fc682ae25c0d03a 100644 (file)
@@ -9034,6 +9034,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
                int video = FALSE;
                int image = FALSE;
                int text = FALSE;
+               int processed_crypto = FALSE;
                char protocol[5] = {0,};
                int x;
 
@@ -9208,28 +9209,34 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
                        case 'a':
                                /* Audio specific scanning */
                                if (audio) {
-                                       if (process_sdp_a_sendonly(value, &sendonly))
+                                       if (process_sdp_a_sendonly(value, &sendonly)) {
                                                processed = TRUE;
-                                       else if (process_crypto(p, p->rtp, &p->srtp, value))
+                                       } else if (!processed_crypto && process_crypto(p, p->rtp, &p->srtp, value)) {
+                                               processed_crypto = TRUE;
                                                processed = TRUE;
-                                       else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
+                                       } else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) {
                                                processed = TRUE;
+                                       }
                                }
                                /* Video specific scanning */
                                else if (video) {
-                                       if (process_sdp_a_sendonly(value, &vsendonly))
+                                       if (process_sdp_a_sendonly(value, &vsendonly)) {
                                                processed = TRUE;
-                                       else if (process_crypto(p, p->vrtp, &p->vsrtp, value))
+                                       } else if (!processed_crypto && process_crypto(p, p->vrtp, &p->vsrtp, value)) {
+                                               processed_crypto = TRUE;
                                                processed = TRUE;
-                                       else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
+                                       } else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) {
                                                processed = TRUE;
+                                       }
                                }
                                /* Text (T.140) specific scanning */
                                else if (text) {
-                                       if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
+                                       if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) {
                                                processed = TRUE;
-                                       else if (process_crypto(p, p->trtp, &p->tsrtp, value))
+                                       } else if (!processed_crypto && process_crypto(p, p->trtp, &p->tsrtp, value)) {
+                                               processed_crypto = TRUE;
                                                processed = TRUE;
+                                       }
                                }
                                /* Image (T.38 FAX) specific scanning */
                                else if (image) {
@@ -16251,11 +16258,12 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
                        }
                        if (!ast_strlen_zero(peer->cid_name))
                                ast_string_field_set(p, cid_name, peer->cid_name);
-                       if (!ast_strlen_zero(peer->cid_tag))
-                               ast_string_field_set(p, cid_tag, peer->cid_tag);
                        if (peer->callingpres)
                                p->callingpres = peer->callingpres;
                }
+               if (!ast_strlen_zero(peer->cid_tag)) {
+                       ast_string_field_set(p, cid_tag, peer->cid_tag);
+               }
                ast_string_field_set(p, fullcontact, peer->fullcontact);
 
                if (!ast_strlen_zero(peer->context)) {
@@ -27318,6 +27326,10 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask
                                } else if (!strcasecmp(word, "nonat")) {
                                        ast_set_flag(&flags[0], SIP_DIRECT_MEDIA);
                                        ast_clear_flag(&flags[0], SIP_DIRECT_MEDIA_NAT);
+                               } else if (!strcasecmp(word, "outgoing")) {
+                                       ast_set_flag(&flags[0], SIP_DIRECT_MEDIA);
+                                       ast_set_flag(&mask[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING);
+                                       ast_set_flag(&flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING);
                                } else {
                                        ast_log(LOG_WARNING, "Unknown directmedia mode '%s' on line %d\n", v->value, v->lineno);
                                }
@@ -29747,6 +29759,18 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i
                p->redircodecs = codecs;
                changed = 1;
        }
+
+       if (ast_test_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING) && !p->outgoing_call) {
+               /* We only wish to withhold sending the initial direct media reinvite on the incoming dialog.
+                * Further direct media reinvites beyond the initial should be sent. In order to allow further
+                * direct media reinvites to be sent, we clear this flag.
+                */
+               ast_clear_flag(&p->flags[2], SIP_PAGE3_DIRECT_MEDIA_OUTGOING);
+               sip_pvt_unlock(p);
+               ast_channel_unlock(chan);
+               return 0;
+       }
+
        if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
                if (chan->_state != AST_STATE_UP) {     /* We are in early state */
                        if (p->do_history)
@@ -30115,12 +30139,6 @@ static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struc
                }
        }
 
-       /* For now, when we receive an INVITE just take the first successful crypto line */
-       if ((*srtp)->crypto && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
-               ast_debug(3, "We've already processed a crypto attribute, skipping '%s'\n", a);
-               return FALSE;
-       }
-
        if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) {
                return FALSE;
        }
index f839cf0b0fc3d0c024be24d3c2722f96bc8e7f0b..a5b9686fe5535e3a75629e266dd91a23e18e9cb1 100644 (file)
 
 
 #define SIP_PAGE3_SNOM_AOC               (1 << 0)  /*!< DPG: Allow snom aoc messages */
+#define SIP_PAGE3_DIRECT_MEDIA_OUTGOING  (1 << 1)  /*!< DP: Only send direct media reinvites on outgoing calls */
 
 #define SIP_PAGE3_FLAGS_TO_COPY \
-       (SIP_PAGE3_SNOM_AOC)
+       (SIP_PAGE3_SNOM_AOC | SIP_PAGE3_DIRECT_MEDIA_OUTGOING)
 
 /*@}*/
 
index a10c224a9d448b233612fea84c96d917746feb0e..a461b01c2c37036ebe64938874c3aca2cd1e4f6b 100644 (file)
@@ -889,6 +889,13 @@ srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
                                 ; instead of INVITE. This can be combined with 'nonat', as
                                 ; 'directmedia=update,nonat'. It implies 'yes'.
 
+;directmedia=outgoing           ; When sending directmedia reinvites, do not send an immediate
+                                ; reinvite on an incoming call leg. This option is useful when
+                                ; peered with another SIP user agent that is known to send
+                                ; immediate direct media reinvites upon call establishment. Setting
+                                ; the option in this situation helps to prevent potential glares.
+                                ; Setting this option implies 'yes'.
+
 ;directrtpsetup=yes             ; Enable the new experimental direct RTP setup. This sets up
                                 ; the call directly with media peer-2-peer without re-invites.
                                 ; Will not work for video and cases where the callee sends
index 35e851b03c86fe38bf71384ed7b5e20017a13e20..4bedc34737eb89dd5105890b6875c9499688ac17 100644 (file)
@@ -398,6 +398,14 @@ void ast_cel_check_retire_linkedid(struct ast_channel *chan)
        }
 }
 
+/* Note that no 'chan_fixup' function is provided for this datastore type,
+ * because the channels that will use it will never be involved in masquerades.
+ */
+static const struct ast_datastore_info fabricated_channel_datastore = {
+       .type = "CEL fabricated channel",
+       .destroy = ast_free_ptr,
+};
+
 struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event *event)
 {
        struct varshead *headp;
@@ -407,6 +415,8 @@ struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event
        struct ast_cel_event_record record = {
                .version = AST_CEL_EVENT_RECORD_VERSION,
        };
+       struct ast_datastore *datastore;
+       char *app_data;
 
        /* do not call ast_channel_alloc because this is not really a real channel */
        if (!(tchan = ast_dummy_channel_alloc())) {
@@ -469,10 +479,42 @@ struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event
                AST_LIST_INSERT_HEAD(headp, newvariable, entries);
        }
 
-       tchan->appl = ast_strdup(record.application_name);
-       tchan->data = ast_strdup(record.application_data);
        tchan->amaflags = record.amaflag;
 
+       /* We need to store an 'application name' and 'application
+        * data' on the channel for logging purposes, but the channel
+        * structure only provides a place to store pointers, and it
+        * expects these pointers to be pointing to data that does not
+        * need to be freed. This means that the channel's destructor
+        * does not attempt to free any storage that these pointers
+        * point to. However, we can't provide data in that form directly for
+        * these structure members. In order to ensure that these data
+        * elements have a lifetime that matches the channel's
+        * lifetime, we'll put them in a datastore attached to the
+        * channel, and set's the channel's pointers to point into the
+        * datastore.  The datastore will then be automatically destroyed
+        * when the channel is destroyed.
+        */
+
+       if (!(datastore = ast_datastore_alloc(&fabricated_channel_datastore, NULL))) {
+               ast_channel_unref(tchan);
+               return NULL;
+       }
+
+       if (!(app_data = ast_malloc(strlen(record.application_name) + strlen(record.application_data) + 2))) {
+               ast_datastore_free(datastore);
+               ast_channel_unref(tchan);
+               return NULL;
+       }
+
+       tchan->appl = app_data;
+       tchan->data = app_data + strlen(record.application_name) + 1;
+
+       strcpy((char *) tchan->appl, record.application_name);
+       strcpy((char *) tchan->data, record.application_data);
+       datastore->data = app_data;
+       ast_channel_datastore_add(tchan, datastore);
+
        return tchan;
 }
 
index f00c400345c9332a3c5733bffd95b8be26d112e9..90fdeabe559968a1f3f43042e4772f614e6232bd 100644 (file)
@@ -2484,6 +2484,13 @@ static void ast_dummy_channel_destructor(void *obj)
        struct ast_channel *chan = obj;
        struct ast_var_t *vardata;
        struct varshead *headp;
+       struct ast_datastore *datastore;
+
+       /* Get rid of each of the data stores on the channel */
+       while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) {
+               /* Free the data store */
+               ast_datastore_free(datastore);
+       }
 
        headp = &chan->varshead;
 
index 239e867ed48c060806ad237756fb03287cc7df71..38b15cb519d5db3fb05f713b84e0bf8f6cefadb1 100644 (file)
@@ -1784,14 +1784,16 @@ static struct ast_str *xmldoc_get_formatted(struct ast_xml_node *node, int raw_o
 {
        struct ast_xml_node *tmp;
        const char *notcleanret, *tmpstr;
-       struct ast_str *ret = ast_str_create(128);
+       struct ast_str *ret;
 
        if (raw_output) {
+               /* xmldoc_string_cleanup will allocate the ret object */
                notcleanret = ast_xml_get_text(node);
                tmpstr = notcleanret;
                xmldoc_string_cleanup(ast_skip_blanks(notcleanret), &ret, 0);
                ast_xml_free_text(tmpstr);
        } else {
+               ret = ast_str_create(128);
                for (tmp = ast_xml_node_get_children(node); tmp; tmp = ast_xml_node_get_next(tmp)) {
                        /* if found, parse a <para> element. */
                        if (xmldoc_parse_para(tmp, "", "\n", &ret)) {