diff options
author | bbryant <bbryant@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-09-09 18:51:52 +0000 |
---|---|---|
committer | bbryant <bbryant@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-09-09 18:51:52 +0000 |
commit | 722eb3c4c3cfa1c0cee915c949c5f95199ee24dd (patch) | |
tree | 25683963c5e51bdedd6211cd0ea92a85639505c3 /channels/chan_iax2.c | |
parent | 815b5b09da5e555add7bba3d8fca588e7611248a (diff) |
Merged revisions 285710 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.6.2
........
r285710 | bbryant | 2010-09-09 14:50:13 -0400 (Thu, 09 Sep 2010) | 8 lines
Fixes an issue with dialplan pattern matching where the specificity for pattern ranges and pattern special characters was inconsistent.
(closes issue #16903)
Reported by: Nick_Lewis
Patches:
pbx.c-specificity.patch uploaded by Nick Lewis (license 657)
Tested by: Nick_Lewis
........
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.8@285711 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_iax2.c')
-rw-r--r-- | channels/chan_iax2.c | 114 |
1 files changed, 99 insertions, 15 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 5bb6b2c59..b05adaa1a 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -268,6 +268,9 @@ static char default_parkinglot[AST_MAX_CONTEXT]; static char language[MAX_LANGUAGE] = ""; static char regcontext[AST_MAX_CONTEXT] = ""; +static struct ast_event_sub *network_change_event_subscription; /*!< subscription id for network change events */ +static int network_change_event_sched_id = -1; + static int maxauthreq = 3; static int max_retries = 4; static int ping_time = 21; @@ -355,6 +358,8 @@ static int (*iax2_regfunk)(const char *username, int onoff) = NULL; static struct io_context *io; static struct ast_sched_thread *sched; +#define DONT_RESCHEDULE -2 + static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH; static int iaxdebug = 0; @@ -1177,6 +1182,8 @@ static int iax2_setoption(struct ast_channel *c, int option, void *data, int dat static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen); static int iax2_transfer(struct ast_channel *c, const char *dest); static int iax2_write(struct ast_channel *c, struct ast_frame *f); +static int iax2_sched_add(struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data); + static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now); static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int); static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int); @@ -1201,6 +1208,7 @@ static void build_rand_pad(unsigned char *buf, ssize_t len); static struct callno_entry *get_unused_callno(int trunk, int validated); static int replace_callno(const void *obj); static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry); +static void network_change_event_cb(const struct ast_event *, void *); static const struct ast_channel_tech iax2_tech = { .type = "IAX2", @@ -1236,6 +1244,47 @@ static void mwi_event_cb(const struct ast_event *event, void *userdata) * is time to send MWI, since it is only sent with a REGACK. */ } +static void network_change_event_subscribe(void) +{ + if (!network_change_event_subscription) { + network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, + network_change_event_cb, + "SIP Network Change ", + NULL, + AST_EVENT_IE_END); + } +} + +static void network_change_event_unsubscribe(void) +{ + if (network_change_event_subscription) { + network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); + } +} + +static int network_change_event_sched_cb(const void *data) +{ + struct iax2_registry *reg; + network_change_event_sched_id = -1; + AST_LIST_LOCK(®istrations); + AST_LIST_TRAVERSE(®istrations, reg, entry) { + iax2_do_register(reg); + } + AST_LIST_UNLOCK(®istrations); + + return 0; +} + +static void network_change_event_cb(const struct ast_event *event, void *userdata) +{ + ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n"); + if (network_change_event_sched_id == -1) { + network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL); + } + +} + + /*! \brief Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers */ static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt) @@ -1246,7 +1295,6 @@ static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt) pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); } - static struct ast_datastore_info iax2_variable_datastore_info = { .type = "IAX2_VARIABLE", .duplicate = iax2_dup_variable_datastore, @@ -1427,10 +1475,9 @@ static void __send_ping(const void *data) if (iaxs[callno]) { if (iaxs[callno]->peercallno) { send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); - iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); - } else { - /* I am the schedule, so I'm allowed to do this */ - iaxs[callno]->pingid = -1; + if (iaxs[callno]->pingid != DONT_RESCHEDULE) { + iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); + } } } else { ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); @@ -1441,9 +1488,16 @@ static void __send_ping(const void *data) static int send_ping(const void *data) { + int callno = (long) data; + ast_mutex_lock(&iaxsl[callno]); + if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) { + iaxs[callno]->pingid = -1; + } + ast_mutex_unlock(&iaxsl[callno]); + #ifdef SCHED_MULTITHREADED if (schedule_action(__send_ping, data)) -#endif +#endif __send_ping(data); return 0; @@ -1488,10 +1542,9 @@ static void __send_lagrq(const void *data) if (iaxs[callno]) { if (iaxs[callno]->peercallno) { send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); - iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); - } else { - /* I am the schedule, so I'm allowed to do this */ - iaxs[callno]->lagid = -1; + if (iaxs[callno]->lagid != DONT_RESCHEDULE) { + iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); + } } } else { ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); @@ -1502,11 +1555,17 @@ static void __send_lagrq(const void *data) static int send_lagrq(const void *data) { + int callno = (long) data; + ast_mutex_lock(&iaxsl[callno]); + if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) { + iaxs[callno]->lagid = -1; + } + ast_mutex_unlock(&iaxsl[callno]); + #ifdef SCHED_MULTITHREADED if (schedule_action(__send_lagrq, data)) -#endif +#endif __send_lagrq(data); - return 0; } @@ -1688,7 +1747,9 @@ static void iax2_destroy_helper(struct chan_iax2_pvt *pvt) } /* No more pings or lagrq's */ AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]); + pvt->pingid = DONT_RESCHEDULE; AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]); + pvt->lagid = DONT_RESCHEDULE; ast_sched_thread_del(sched, pvt->autoid); ast_sched_thread_del(sched, pvt->authid); ast_sched_thread_del(sched, pvt->initid); @@ -6986,13 +7047,14 @@ static int manager_iax2_show_registry(struct mansession *s, const struct message astman_append(s, "Event: RegistryEntry\r\n" + "%s" "Host: %s\r\n" "DNSmanager: %s\r\n" "Username: %s\r\n" "Perceived: %s\r\n" "Refresh: %d\r\n" "State: %s\r\n" - "\r\n", host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, + "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); total++; @@ -10428,6 +10490,7 @@ retryowner: /* No authentication required, let them in */ memset(&ied1, 0, sizeof(ied1)); iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); + iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); if (strcmp(iaxs[fr->callno]->exten, "TBD")) { ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); @@ -10893,6 +10956,7 @@ retryowner2: /* Authentication received */ memset(&ied1, 0, sizeof(ied1)); iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); + iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); if (strcmp(iaxs[fr->callno]->exten, "TBD")) { ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); @@ -12779,7 +12843,8 @@ static int set_config(const char *config_file, int reload) int format; int portno = IAX_DEFAULT_PORTNO; int x; - int mtuv; + int mtuv; + int subscribe_network_change = 1; struct iax2_user *user; struct iax2_peer *peer; struct ast_netsock *ns; @@ -13097,6 +13162,14 @@ static int set_config(const char *config_file, int reload) if (add_calltoken_ignore(v->value)) { ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); } + } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { + if (ast_true(v->value)) { + subscribe_network_change = 1; + } else if (ast_false(v->value)) { + subscribe_network_change = 0; + } else { + ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); + } } else if (!strcasecmp(v->name, "shrinkcallerid")) { if (ast_true(v->value)) { ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); @@ -13109,7 +13182,13 @@ static int set_config(const char *config_file, int reload) /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ v = v->next; } - + + if (subscribe_network_change) { + network_change_event_subscribe(); + } else { + network_change_event_unsubscribe(); + } + if (defaultsockfd < 0) { if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); @@ -14050,6 +14129,8 @@ static int __unload_module(void) struct ast_context *con; int x; + network_change_event_unsubscribe(); + ast_manager_unregister("IAXpeers"); ast_manager_unregister("IAXpeerlist"); ast_manager_unregister("IAXnetstats"); @@ -14530,6 +14611,8 @@ static int load_module(void) ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); + network_change_event_subscribe(); + return AST_MODULE_LOAD_SUCCESS; } @@ -14538,4 +14621,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchan .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, + .nonoptreq = "res_crypto", ); |