summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorDavid Vossel <dvossel@digium.com>2010-08-13 20:05:44 +0000
committerDavid Vossel <dvossel@digium.com>2010-08-13 20:05:44 +0000
commit0f8eaa62998c697ee72c6c3c98bf0c9478de5fb7 (patch)
tree595c0ede600ce5c602d97f7592666d96f3c7e3c4 /channels
parent86142d711f40bb582e0bfea311ec10b93ef7d60a (diff)
Merged revisions 282269 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8 ........ r282269 | dvossel | 2010-08-13 15:03:56 -0500 (Fri, 13 Aug 2010) | 4 lines res_stun_monitor for monitoring network changes behind a NAT device Review: https://reviewboard.asterisk.org/r/854 ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@282270 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_iax2.c71
-rw-r--r--channels/chan_sip.c55
2 files changed, 123 insertions, 3 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index af4cb72e3..37cbf1cfc 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;
@@ -1177,6 +1180,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 +1206,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 +1242,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(&registrations);
+ AST_LIST_TRAVERSE(&registrations, reg, entry) {
+ iax2_do_register(reg);
+ }
+ AST_LIST_UNLOCK(&registrations);
+
+ 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 +1293,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,
@@ -12779,7 +12825,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 +13144,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 +13164,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 +14111,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 +14593,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;
}
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index e24681974..21c7f08f1 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -762,6 +762,9 @@ static int regobjs = 0; /*!< Registry objects */
static struct ast_flags global_flags[3] = {{0}}; /*!< global SIP_ flags */
static int global_t38_maxdatagram; /*!< global T.38 FaxMaxDatagram override */
+static struct ast_event_sub *network_change_event_subscription; /*!< subscription id for network change events */
+static int network_change_event_sched_id = -1;
+
static char used_context[AST_MAX_CONTEXT]; /*!< name of automatically created context for unloading */
AST_MUTEX_DEFINE_STATIC(netlock);
@@ -1334,6 +1337,7 @@ static int sip_poke_peer(struct sip_peer *peer, int force);
static void sip_poke_all_peers(void);
static void sip_peer_hold(struct sip_pvt *p, int hold);
static void mwi_event_cb(const struct ast_event *, void *);
+static void network_change_event_cb(const struct ast_event *, void *);
/*--- Applications, functions, CLI and manager command helpers */
static const char *sip_nat_mode(const struct sip_pvt *p);
@@ -13435,6 +13439,39 @@ static void mwi_event_cb(const struct ast_event *event, void *userdata)
ao2_unlock(peer);
}
+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)
+{
+ network_change_event_sched_id = -1;
+ sip_send_all_registers();
+ sip_send_all_mwi_subscriptions();
+ return 0;
+}
+
+static void network_change_event_cb(const struct ast_event *event, void *userdata)
+{
+ ast_debug(1, "SIP, got a network change event, renewing all SIP registrations.\n");
+ if (network_change_event_sched_id == -1) {
+ network_change_event_sched_id = ast_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
+ }
+}
+
/*! \brief Callback for the devicestate notification (SUBSCRIBE) support subsystem
\note If you add an "hint" priority to the extension in the dial plan,
you will get notifications on device state changes */
@@ -26140,6 +26177,7 @@ static int reload_config(enum channelreloadreason reason)
int auto_sip_domains = FALSE;
struct ast_sockaddr old_bindaddr = bindaddr;
int registry_count = 0, peer_count = 0, timerb_set = 0, timert1_set = 0;
+ int subscribe_network_change = 1;
time_t run_start, run_end;
struct sockaddr_in externaddr_sin;
int bindport = 0;
@@ -26843,11 +26881,25 @@ static int reload_config(enum channelreloadreason reason)
ast_log(LOG_WARNING, "'%s' is not a valid maxforwards value at line %d. Using default.\n", v->value, v->lineno);
sip_cfg.default_max_forwards = DEFAULT_MAX_FORWARDS;
}
+ } 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, "snom_aoc_enabled")) {
ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
}
}
+ if (subscribe_network_change) {
+ network_change_event_subscribe();
+ } else {
+ network_change_event_unsubscribe();
+ }
+
if (global_t1 < global_t1min) {
ast_log(LOG_WARNING, "'t1min' (%d) cannot be greater than 't1timer' (%d). Resetting 't1timer' to the value of 't1min'\n", global_t1min, global_t1);
global_t1 = global_t1min;
@@ -28354,6 +28406,7 @@ static int load_module(void)
sip_register_tests();
+ network_change_event_subscribe();
return AST_MODULE_LOAD_SUCCESS;
}
@@ -28366,6 +28419,8 @@ static int unload_module(void)
struct ast_context *con;
struct ao2_iterator i;
+ network_change_event_unsubscribe();
+
ast_sched_dump(sched);
/* First, take us out of the channel type list */