aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/app_dial.c3
-rw-r--r--apps/app_meetme.c4
-rw-r--r--apps/app_while.c5
-rw-r--r--channels/chan_agent.c12
-rw-r--r--channels/chan_h323.c6
-rw-r--r--channels/chan_iax2.c11
-rw-r--r--channels/chan_misdn.c2
-rw-r--r--channels/chan_sip.c29
-rw-r--r--channels/chan_skinny.c2
-rw-r--r--include/asterisk/astobj2.h1
-rw-r--r--main/asterisk.c14
-rw-r--r--main/astobj2.c15
-rw-r--r--main/manager.c3
-rw-r--r--main/pbx.c2
14 files changed, 90 insertions, 19 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 142fe9f25..ce2bffeb3 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -1583,6 +1583,9 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
/* Again, keep going even if there's an error */
ast_debug(1, "ast call on peer returned %d\n", res);
ast_verb(3, "Couldn't call %s\n", numsubst);
+ if (tc->hangupcause) {
+ chan->hangupcause = tc->hangupcause;
+ }
ast_hangup(tc);
tc = NULL;
ast_free(tmp);
diff --git a/apps/app_meetme.c b/apps/app_meetme.c
index 13f61df00..9f7f3afc3 100644
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -1379,6 +1379,10 @@ static void sla_queue_event_full(enum sla_event_type type,
{
struct sla_event *event;
+ if (sla.thread == AST_PTHREADT_NULL) {
+ return;
+ }
+
if (!(event = ast_calloc(1, sizeof(*event))))
return;
diff --git a/apps/app_while.c b/apps/app_while.c
index 1c61d966e..405e78c3c 100644
--- a/apps/app_while.c
+++ b/apps/app_while.c
@@ -160,11 +160,16 @@ static int _while_exec(struct ast_channel *chan, void *data, int end)
return -1;
}
+#if 0
/* dont want run away loops if the chan isn't even up
this is up for debate since it slows things down a tad ......
+
+ Debate is over... this prevents While/EndWhile from working
+ within the "h" extension. Not good.
*/
if (ast_waitfordigit(chan,1) < 0)
return -1;
+#endif
for (x=0;;x++) {
if (get_index(chan, prefix, x)) {
diff --git a/channels/chan_agent.c b/channels/chan_agent.c
index ebfa11147..de7bb1125 100644
--- a/channels/chan_agent.c
+++ b/channels/chan_agent.c
@@ -657,9 +657,15 @@ static int agent_indicate(struct ast_channel *ast, int condition, const void *da
struct agent_pvt *p = ast->tech_pvt;
int res = -1;
ast_mutex_lock(&p->lock);
- if (p->chan && !ast_check_hangup(p->chan))
- res = p->chan->tech->indicate ? p->chan->tech->indicate(p->chan, condition, data, datalen) : -1;
- else
+ if (p->chan && !ast_check_hangup(p->chan)) {
+ while (ast_channel_trylock(p->chan)) {
+ ast_channel_unlock(ast);
+ usleep(1);
+ ast_channel_lock(ast);
+ }
+ res = p->chan->tech->indicate ? p->chan->tech->indicate(p->chan, condition, data, datalen) : -1;
+ ast_channel_unlock(p->chan);
+ } else
res = 0;
ast_mutex_unlock(&p->lock);
return res;
diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index 26cf3a6b8..c24cbe71c 100644
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -2609,7 +2609,7 @@ static int restart_monitor(void)
pthread_kill(monitor_thread, SIGURG);
} else {
/* Start a new monitor */
- if (ast_pthread_create_detached_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
+ if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
monitor_thread = AST_PTHREADT_NULL;
ast_mutex_unlock(&monlock);
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
@@ -3301,9 +3301,9 @@ static int unload_module(void)
}
if (!ast_mutex_lock(&monlock)) {
if ((monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
- /* this causes a seg, anyone know why? */
- if (monitor_thread != pthread_self())
+ if (monitor_thread != pthread_self()) {
pthread_cancel(monitor_thread);
+ }
pthread_kill(monitor_thread, SIGURG);
pthread_join(monitor_thread, NULL);
}
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 2c2e11c52..107df395b 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -1664,12 +1664,21 @@ static int __find_callno(unsigned short callno, unsigned short dcallno, struct s
/* This will occur on the first response to a message that we initiated,
* such as a PING. */
+ if (dcallno) {
+ ast_mutex_lock(&iaxsl[dcallno]);
+ }
if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
iaxs[dcallno]->peercallno = callno;
res = dcallno;
store_by_peercallno(iaxs[dcallno]);
+ if (!res || !return_locked) {
+ ast_mutex_unlock(&iaxsl[dcallno]);
+ }
return res;
}
+ if (dcallno) {
+ ast_mutex_unlock(&iaxsl[dcallno]);
+ }
#ifdef IAX_OLD_FIND
/* If we get here, we SHOULD NOT find a call structure for this
@@ -6977,7 +6986,7 @@ static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, i
/* Make sure our call still exists, an INVAL at the right point may make it go away */
if (!iaxs[callno]) {
- res = 0;
+ res = -1;
goto return_unref;
}
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index 15cdb7ce9..123971327 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -2479,7 +2479,7 @@ static int misdn_indication(struct ast_channel *ast, int cond, const void *data,
}
chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc ? p->bc->pid : -1);
- ast_setstate(ast, AST_STATE_RINGING);
+ ast_setstate(ast, AST_STATE_RING);
if ( !p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio )
chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n");
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index adf9ab905..05f63c61a 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -4280,8 +4280,11 @@ static int sip_call(struct ast_channel *ast, char *dest, int timeout)
res = update_call_counter(p, INC_CALL_RINGING);
- if (res == -1)
+ if (res == -1) {
return res;
+ } else {
+ ast->hangupcause = AST_CAUSE_USER_BUSY;
+ }
p->callingpres = ast->cid.cid_pres;
p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec);
@@ -15266,7 +15269,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, char *rest, str
break;
case 200: /* 200 OK */
if (!r) {
- ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
+ ast_log(LOG_WARNING, "Got 200 OK on REGISTER, but there isn't a registry entry for '%s' (we probably already got the OK)\n", S_OR(p->peername, p->username));
p->needdestroy = 1;
return 0;
}
@@ -15445,6 +15448,20 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
Fix assigned to Rizzo :-)
*/
/* check_via_response(p, req); */
+
+ /* RFC 3261 Section 15 specifies that if we receive a 408 or 481
+ * in response to a BYE, then we should end the current dialog
+ * and session. There is no mention in the spec of other 4XX responses,
+ * but it is known that at least one phone manufacturer potentially
+ * will send a 404 in response to a BYE, so we'll be liberal in what
+ * we accept and end the dialog and session if we receive any 4XX
+ * response to a BYE.
+ */
+ if (resp >= 400 && resp < 500 && sipmethod == SIP_BYE) {
+ p->needdestroy = 1;
+ return;
+ }
+
if (p->relatedpeer && p->method == SIP_OPTIONS) {
/* We don't really care what the response is, just that it replied back.
Well, as long as it's not a 100 response... since we might
@@ -20706,6 +20723,14 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno);
peer->maxms = 0;
}
+ if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) {
+ /* This would otherwise cause a network storm, where the
+ * qualify response refreshes the peer from the database,
+ * which in turn causes another qualify to be sent, ad
+ * infinitum. */
+ ast_log(LOG_WARNING, "Qualify is incompatible with dynamic uncached realtime. Please either turn rtcachefriends on or turn qualify off on peer '%s'\n", peer->name);
+ peer->maxms = 0;
+ }
} else if (!strcasecmp(v->name, "qualifyfreq")) {
int i;
if (sscanf(v->value, "%d", &i) == 1)
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index f415ad6ca..ae6cc573d 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -5747,7 +5747,7 @@ static void *accept_thread(void *ignore)
sessions = s;
ast_mutex_unlock(&sessionlock);
- if (ast_pthread_create_detached(&tcp_thread, NULL, skinny_session, s)) {
+ if (ast_pthread_create(&tcp_thread, NULL, skinny_session, s)) {
destroy_session(s);
}
}
diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h
index bb63496ca..322e4732c 100644
--- a/include/asterisk/astobj2.h
+++ b/include/asterisk/astobj2.h
@@ -211,6 +211,7 @@ int ao2_unlock(void *a);
#define ao2_unlock(a) _ao2_unlock(a, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
int _ao2_unlock(void *a, const char *file, const char *func, int line, const char *var);
#endif
+int ao2_trylock(void *user_data);
/*!
*
diff --git a/main/asterisk.c b/main/asterisk.c
index 81c4c73b7..b8a95064d 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -3028,11 +3028,6 @@ int main(int argc, char *argv[])
if (ast_opt_console && !option_verbose)
ast_verbose("[ Booting...\n");
- if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
- ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
- ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
- }
-
/* For remote connections, change the name of the remote connection.
* We do this for the benefit of init scripts (which need to know if/when
* the main asterisk process has died yet). */
@@ -3043,8 +3038,10 @@ int main(int argc, char *argv[])
}
}
- if (ast_opt_console && !option_verbose)
+ if (ast_opt_console && !option_verbose) {
ast_verbose("[ Reading Master Configuration ]\n");
+ }
+
ast_readconfig();
if (ast_opt_remote && remotesock != NULL)
@@ -3053,6 +3050,11 @@ int main(int argc, char *argv[])
if (!ast_language_is_prefix && !ast_opt_remote)
ast_log(LOG_WARNING, "The 'languageprefix' option in asterisk.conf is deprecated; in a future release it will be removed, and your sound files will need to be organized in the 'new style' language layout.\n");
+ if (ast_opt_always_fork && (ast_opt_remote || ast_opt_console)) {
+ ast_log(LOG_WARNING, "'alwaysfork' is not compatible with console or remote console mode; ignored\n");
+ ast_clear_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK);
+ }
+
if (ast_opt_dump_core) {
struct rlimit l;
memset(&l, 0, sizeof(l));
diff --git a/main/astobj2.c b/main/astobj2.c
index 77f0f2962..212b64ed9 100644
--- a/main/astobj2.c
+++ b/main/astobj2.c
@@ -170,6 +170,21 @@ int _ao2_unlock(void *user_data, const char *file, const char *func, int line, c
#endif
}
+int ao2_trylock(void *user_data)
+{
+ struct astobj2 *p = INTERNAL_OBJ(user_data);
+ int ret;
+
+ if (p == NULL)
+ return -1;
+ ret = ast_mutex_trylock(&p->priv_data.lock);
+#ifdef AO2_DEBUG
+ if (!ret)
+ ast_atomic_fetchadd_int(&ao2.total_locked, 1);
+#endif
+ return ret;
+}
+
/*
* The argument is a pointer to the user portion.
*/
diff --git a/main/manager.c b/main/manager.c
index e0ab9a16b..0076f64f3 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -2059,7 +2059,8 @@ static int action_command(struct mansession *s, const struct message *m)
/*! \brief helper function for originate */
struct fast_originate_helper {
char tech[AST_MAX_EXTENSION];
- char data[AST_MAX_EXTENSION];
+ /*! data can contain a channel name, extension number, username, password, etc. */
+ char data[512];
int timeout;
int format; /*!< Codecs used for a call */
char app[AST_MAX_APP];
diff --git a/main/pbx.c b/main/pbx.c
index 4c8f23caf..3a78612b3 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -6795,7 +6795,7 @@ int ast_add_extension2(struct ast_context *con,
}
res = 0; /* some compilers will think it is uninitialized otherwise */
for (e = con->root; e; el = e, e = e->next) { /* scan the extension list */
- res = ext_cmp(e->exten, extension);
+ res = ext_cmp(e->exten, tmp->exten);
if (res == 0) { /* extension match, now look at cidmatch */
if (!e->matchcid && !tmp->matchcid)
res = 0;