diff options
author | root <root@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-03-31 19:04:28 +0000 |
---|---|---|
committer | root <root@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-03-31 19:04:28 +0000 |
commit | 2f64cbbdcd552881537897ca80ec255f1a7ad5b2 (patch) | |
tree | fdcff4a039f20eb3dcea588ed8ac46426272e1bc | |
parent | e40118fd759cc84814a8df3784856ac9761afa44 (diff) |
automerge commit
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2-netsec@16770 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r-- | channels/chan_iax2.c | 33 | ||||
-rw-r--r-- | pbx.c | 27 |
2 files changed, 34 insertions, 26 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 2412ca9a1..c497f30d6 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -8781,6 +8781,18 @@ static int set_config(char *config_file, int reload) /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ v = v->next; } + + if (defaultsockfd < 0) { + if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { + ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); + } else { + if (option_verbose > 1) + ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); + defaultsockfd = ast_netsock_sockfd(ns); + ast_netsock_unref(ns); + } + } + if (min_reg_expire > max_reg_expire) { ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", min_reg_expire, max_reg_expire, max_reg_expire); @@ -9542,9 +9554,6 @@ int load_module(void) struct iax2_registry *reg; struct iax2_peer *peer; - struct ast_netsock *ns; - struct sockaddr_in sin; - ast_custom_function_register(&iaxpeer_function); iax_set_output(iax_debug_output); @@ -9553,10 +9562,6 @@ int load_module(void) jb_setoutput(jb_error_output, jb_warning_output, NULL); #endif - sin.sin_family = AF_INET; - sin.sin_port = htons(IAX_DEFAULT_PORTNO); - sin.sin_addr.s_addr = INADDR_ANY; - #ifdef IAX_TRUNKING #ifdef ZT_TIMERACK timingfd = open("/dev/zap/timer", O_RDWR); @@ -9609,19 +9614,7 @@ int load_module(void) if (ast_register_switch(&iax2_switch)) ast_log(LOG_ERROR, "Unable to register IAX switch\n"); - - if (defaultsockfd < 0) { - if (!(ns = ast_netsock_bindaddr(netsock, io, &sin, tos, socket_read, NULL))) { - ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); - return -1; - } else { - if (option_verbose > 1) - ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", IAX_DEFAULT_PORTNO); - defaultsockfd = ast_netsock_sockfd(ns); - ast_netsock_unref(ns); - } - } - + res = start_network_thread(); if (!res) { if (option_verbose > 1) @@ -514,6 +514,12 @@ AST_MUTEX_DEFINE_STATIC(applock); /* Lock for the application list */ struct ast_switch *switches = NULL; AST_MUTEX_DEFINE_STATIC(switchlock); /* Lock for switches */ +/* WARNING: + When holding this lock, do _not_ do anything that will cause conlock + to be taken, unless you _already_ hold it. The ast_merge_contexts_and_delete + function will take the locks in conlock/hintlock order, so any other + paths that require both locks must also take them in that order. +*/ AST_MUTEX_DEFINE_STATIC(hintlock); /* Lock for extension state notifys */ static int stateid = 1; struct ast_hint *hints = NULL; @@ -3696,9 +3702,20 @@ void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char int length; struct ast_state_cb *thiscb, *prevcb; - /* preserve all watchers for hints associated with this registrar */ AST_LIST_HEAD_INIT(&store); + + /* it is very important that this function hold the hintlock _and_ the conlock + during its operation; not only do we need to ensure that the list of contexts + and extensions does not change, but also that no hint callbacks (watchers) are + added or removed during the merge/delete process + + in addition, the locks _must_ be taken in this order, because there are already + other code paths that use this order + */ + ast_mutex_lock(&conlock); ast_mutex_lock(&hintlock); + + /* preserve all watchers for hints associated with this registrar */ for (hint = hints; hint; hint = hint->next) { if (hint->callbacks && !strcmp(registrar, hint->exten->parent->registrar)) { length = strlen(hint->exten->exten) + strlen(hint->exten->parent->name) + 2 + sizeof(*this); @@ -3717,10 +3734,8 @@ void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char AST_LIST_INSERT_HEAD(&store, this, list); } } - ast_mutex_unlock(&hintlock); tmp = *extcontexts; - ast_mutex_lock(&conlock); if (registrar) { __ast_context_destroy(NULL,registrar); while (tmp) { @@ -3740,7 +3755,6 @@ void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *extcontexts = NULL; } else ast_log(LOG_WARNING, "Requested contexts didn't get merged\n"); - ast_mutex_unlock(&conlock); /* restore the watchers for hints that can be found; notify those that cannot be restored @@ -3748,7 +3762,6 @@ void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char while ((this = AST_LIST_REMOVE_HEAD(&store, list))) { exten = ast_hint_extension(NULL, this->context, this->exten); /* Find the hint in the list of hints */ - ast_mutex_lock(&hintlock); for (hint = hints; hint; hint = hint->next) { if (hint->exten == exten) break; @@ -3771,10 +3784,12 @@ void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char hint->callbacks = this->callbacks; hint->laststate = this->laststate; } - ast_mutex_unlock(&hintlock); free(this); } + ast_mutex_unlock(&hintlock); + ast_mutex_unlock(&conlock); + return; } |