[asterisk-commits] mjordan: tag 10.0.0-rc4 r347806 - in /tags/10.0.0-rc4: ./ channels/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Dec 8 16:30:43 CST 2011
Author: mjordan
Date: Thu Dec 8 16:30:39 2011
New Revision: 347806
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=347806
Log:
Checking in merge of r346050, r347068, r346856, r347532, r345830
Modified:
tags/10.0.0-rc4/ (props changed)
tags/10.0.0-rc4/.version
tags/10.0.0-rc4/ChangeLog
tags/10.0.0-rc4/channels/chan_sip.c
Propchange: tags/10.0.0-rc4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Dec 8 16:30:39 2011
@@ -1,1 +1,1 @@
-/branches/10:344493,344557,345064
+/branches/10:344493,344557,345064,345830,346040,346856,347068,347532
Modified: tags/10.0.0-rc4/.version
URL: http://svnview.digium.com/svn/asterisk/tags/10.0.0-rc4/.version?view=diff&rev=347806&r1=347805&r2=347806
==============================================================================
--- tags/10.0.0-rc4/.version (original)
+++ tags/10.0.0-rc4/.version Thu Dec 8 16:30:39 2011
@@ -1,1 +1,1 @@
-10.0.0-rc3
+10.0.0-rc4
Modified: tags/10.0.0-rc4/ChangeLog
URL: http://svnview.digium.com/svn/asterisk/tags/10.0.0-rc4/ChangeLog?view=diff&rev=347806&r1=347805&r2=347806
==============================================================================
--- tags/10.0.0-rc4/ChangeLog (original)
+++ tags/10.0.0-rc4/ChangeLog Thu Dec 8 16:30:39 2011
@@ -1,3 +1,36 @@
+2011-12-08 Asterisk Development Team <asteriskteam at digium.com>
+
+ * Asterisk 10.0.0-rc4 Released.
+
+ * Don't crash on INFO automon request with no channel
+
+ AST-2011-014. When automon was enabled in features.conf, it was possible
+ to crash Asterisk by sending an INFO request if no channel had been
+ created yet.
+
+ (closes issue ASTERISK-18805)
+
+ Merged revisions 347530 from http://svn.asterisk.org/svn/asterisk/branches/1.6.2
+
+ Merged revisions 347531 from http://svn.asterisk.org/svn/asterisk/branches/1.8
+
+
+ * Fixed crash from orphaned MWI subscriptions in chan_sip
+
+ This patch resolves the issue where MWI subscriptions are orphaned
+ by subsequent SIP SUBSCRIBE messages. When a peer is removed, either
+ by pruning realtime SIP peers or by unloading / loading chan_sip, the
+ MWI subscriptions that were orphaned would still be on the event engine
+ list of valid subscriptions but have a pointer to a peer that no longer
+ was valid. When an MWI event would occur, this would cause a seg fault.
+
+ (closes issue ASTERISK-18663)
+ Reported by: Ross Beer
+ Tested by: Ross Beer, Matt Jordan
+ Review: https://reviewboard.asterisk.org/r/1610/
+
+ Merged revisions 347058 from http://svn.asterisk.org/svn/asterisk/branches/1.8
+
2011-11-23 Asterisk Development Team <asteriskteam at digium.com>
* Asterisk 10.0.0-rc3 Released.
Modified: tags/10.0.0-rc4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/tags/10.0.0-rc4/channels/chan_sip.c?view=diff&rev=347806&r1=347805&r2=347806
==============================================================================
--- tags/10.0.0-rc4/channels/chan_sip.c (original)
+++ tags/10.0.0-rc4/channels/chan_sip.c Thu Dec 8 16:30:39 2011
@@ -18994,11 +18994,18 @@
per device. I don't want incoming callers to record calls in my
pbx.
*/
- /* first, get the feature string, if it exists */
+
struct ast_call_feature *feat;
int j;
struct ast_frame f = { AST_FRAME_DTMF, };
+ if (!p->owner) { /* not a PBX call */
+ transmit_response(p, "481 Call leg/transaction does not exist", req);
+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ return;
+ }
+
+ /* first, get the feature string, if it exists */
ast_rdlock_call_features();
feat = ast_find_call_feature("automon");
if (!feat || ast_strlen_zero(feat->exten)) {
@@ -24142,25 +24149,17 @@
{
struct sip_pvt *pvt;
int res;
- char *uri, *host;
+ char *to_uri, *to_host, *to_user;
struct sip_peer *peer_ptr;
if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_MESSAGE, NULL))) {
return -1;
}
- uri = ast_strdupa(to);
- if (!strncasecmp(uri, "sip:", 4)) {
- uri += 4;
- } else if (!strncasecmp(uri, "sips:", 5)) {
- uri += 5;
- }
- host = ast_strdupa(uri);
- if (strchr(host, '@')) {
- strsep(&host, "@");
- }
-
- if (ast_strlen_zero(host)) {
+ to_uri = ast_strdupa(to);
+ parse_uri(to_uri, "sip:,sips:", &to_user, NULL, &to_host, NULL);
+
+ if (ast_strlen_zero(to_host)) {
ast_log(LOG_WARNING, "MESSAGE(to) is invalid for SIP - '%s'\n", to);
dialog_unlink_all(pvt);
dialog_unref(pvt, "MESSAGE(to) is invalid for SIP");
@@ -24194,15 +24193,16 @@
sip_pvt_lock(pvt);
/* Look up the host to contact */
- if (create_addr(pvt, host, NULL, TRUE, NULL)) {
+ if (create_addr(pvt, to_host, NULL, TRUE, NULL)) {
sip_pvt_unlock(pvt);
dialog_unlink_all(pvt);
dialog_unref(pvt, "create_addr failed sending a MESSAGE");
return -1;
}
- /* Set the tohost to the full URI provided */
- ast_string_field_set(pvt, tohost, uri);
+ if (!ast_strlen_zero(to_user)) {
+ ast_string_field_set(pvt, username, to_user);
+ }
ast_sip_ouraddrfor(&pvt->sa, &pvt->ourip, pvt);
ast_set_flag(&pvt->flags[0], SIP_OUTGOING);
@@ -24723,11 +24723,21 @@
return handler_result;
}
+/*! \internal \brief Subscribe to MWI events for the specified peer
+ * \note The peer cannot be locked during this method. sip_send_mwi_peer will
+ * attempt to lock the peer after the event subscription lock is held; if the peer is locked during
+ * this method then we will attempt to lock the event subscription lock but after the peer, creating
+ * a locking inversion.
+ */
static void add_peer_mwi_subs(struct sip_peer *peer)
{
struct sip_mailbox *mailbox;
AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
+ if (mailbox->event_sub) {
+ ast_event_unsubscribe(mailbox->event_sub);
+ }
+
mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "SIP mbox event", peer,
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
@@ -24881,7 +24891,7 @@
/* if an authentication response was sent, we are done here */
if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */
return 0;
- if (res < 0) {
+ if (res != AUTH_SUCCESSFUL) {
if (res == AUTH_FAKE_AUTH) {
ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE);
@@ -24895,17 +24905,17 @@
}
}
- /* At this point, authpeer cannot be NULL. Remember we hold a reference,
- * so we must release it when done.
- * XXX must remove all the checks for authpeer == NULL.
+ /* At this point, we hold a reference to authpeer (if not NULL). It
+ * must be released when done.
*/
/* Check if this device is allowed to subscribe at all */
if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
transmit_response(p, "403 Forbidden (policy)", req);
pvt_set_needdestroy(p, "subscription not allowed");
- if (authpeer)
+ if (authpeer) {
sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 1)");
+ }
return 0;
}
@@ -24925,8 +24935,9 @@
transmit_response(p, "404 Not Found", req);
}
pvt_set_needdestroy(p, "subscription target not found");
- if (authpeer)
+ if (authpeer) {
sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 2)");
+ }
return 0;
}
@@ -24940,9 +24951,6 @@
int start = 0;
enum subscriptiontype subscribed = NONE;
const char *unknown_acceptheader = NULL;
-
- if (authpeer) /* We do not need the authpeer any more */
- authpeer = sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 2)");
/* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
accept = __get_header(req, "Accept", &start);
@@ -24981,6 +24989,9 @@
p->subscribecontext,
p->subscribeuri);
pvt_set_needdestroy(p, "no Accept header");
+ if (authpeer) {
+ sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 2)");
+ }
return 0;
}
/* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
@@ -25005,6 +25016,9 @@
p->subscribecontext,
p->subscribeuri);
pvt_set_needdestroy(p, "unrecognized format");
+ if (authpeer) {
+ sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 2)");
+ }
return 0;
} else {
p->subscribed = subscribed;
@@ -25027,8 +25041,9 @@
transmit_response(p, "406 Not Acceptable", req);
ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
pvt_set_needdestroy(p, "unknown format");
- if (authpeer)
+ if (authpeer) {
sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 3)");
+ }
return 0;
}
/* Looks like they actually want a mailbox status
@@ -25037,11 +25052,17 @@
In most devices, this is configurable to the voicemailmain extension you use
*/
if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) {
- transmit_response(p, "404 Not found (no mailbox)", req);
+ if (!authpeer) {
+ transmit_response(p, "404 Not found", req);
+ } else {
+ transmit_response(p, "404 Not found (no mailbox)", req);
+ ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", S_OR(authpeer->name, ""));
+ }
pvt_set_needdestroy(p, "received 404 response");
- ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", S_OR(authpeer->name, ""));
- if (authpeer)
- sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 4)");
+
+ if (authpeer) {
+ sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 3)");
+ }
return 0;
}
@@ -25051,18 +25072,21 @@
add_peer_mwi_subs(authpeer);
ao2_lock(p);
}
- if (authpeer->mwipvt && authpeer->mwipvt != p) { /* Destroy old PVT if this is a new one */
+ if (authpeer->mwipvt != p) { /* Destroy old PVT if this is a new one */
/* We only allow one subscription per peer */
- dialog_unlink_all(authpeer->mwipvt);
- authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt");
- /* sip_destroy(authpeer->mwipvt); */
- }
- if (authpeer->mwipvt)
- dialog_unref(authpeer->mwipvt, "Unref previously stored mwipvt dialog pointer");
- authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p"); /* Link from peer to pvt UH- should this be dialog_ref()? */
- if (p->relatedpeer)
- sip_unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr");
- p->relatedpeer = sip_ref_peer(authpeer, "setting dialog's relatedpeer pointer"); /* already refcounted...Link from pvt to peer UH- should this be dialog_ref()? */
+ if (authpeer->mwipvt) {
+ dialog_unlink_all(authpeer->mwipvt);
+ authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt");
+ }
+ authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p");
+ }
+
+ if (p->relatedpeer != authpeer) {
+ if (p->relatedpeer) {
+ sip_unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr");
+ }
+ p->relatedpeer = sip_ref_peer(authpeer, "setting dialog's relatedpeer pointer");
+ }
/* Do not release authpeer here */
} else if (!strcmp(event, "call-completion")) {
handle_cc_subscribe(p, req);
@@ -25070,14 +25094,10 @@
transmit_response(p, "489 Bad Event", req);
ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", event);
pvt_set_needdestroy(p, "unknown event package");
- if (authpeer)
+ if (authpeer) {
sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 5)");
+ }
return 0;
- }
-
- /* At this point, if we have an authpeer we should unref it. */
- if (authpeer) {
- authpeer = sip_unref_peer(authpeer, "unref pointer into (*authpeer)");
}
/* Add subscription for extension state from the PBX core */
@@ -25104,6 +25124,9 @@
"with Expire header less that 'minexpire' limit. Received \"Expire: %d\" min is %d\n",
p->exten, p->context, p->expiry, min_expiry);
pvt_set_needdestroy(p, "Expires is less that the min expires allowed.");
+ if (authpeer) {
+ sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 6)");
+ }
return 0;
}
@@ -25139,6 +25162,9 @@
ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_sockaddr_stringify(&p->sa));
transmit_response(p, "404 Not found", req);
pvt_set_needdestroy(p, "no extension for SUBSCRIBE");
+ if (authpeer) {
+ sip_unref_peer(authpeer, "sip_unref_peer, from handle_request_subscribe (authpeer 6)");
+ }
return 0;
}
ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
@@ -25153,6 +25179,10 @@
if (!p->expiry) {
pvt_set_needdestroy(p, "forcing expiration");
}
+ }
+
+ if (authpeer) {
+ sip_unref_peer(authpeer, "unref pointer into (*authpeer)");
}
return 1;
}
@@ -25871,7 +25901,7 @@
*/
static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only)
{
- /* Called with peerl lock, but releases it */
+ /* Called with peer lock, but releases it */
struct sip_pvt *p;
int newmsgs = 0, oldmsgs = 0;
const char *vmexten = NULL;
More information about the asterisk-commits
mailing list