--- chan_sip.orig 2013-11-18 07:20:05.000000000 -0700
+++ chan_sip.c 2013-11-16 16:05:15.000000000 -0700
@@ -737,6 +737,7 @@
static int global_timer_b; /*!< Timer B - RFC 3261 Section 17.1.1.2 */
static unsigned int global_autoframing; /*!< Turn autoframing on or off. */
static int global_qualifyfreq; /*!< Qualify frequency */
+static int global_qualifynotok; /*!< Qualify frequency when unreachable */
static int global_qualify_gap; /*!< Time between our group of peer pokes */
static int global_qualify_peers; /*!< Number of peers to poke at a given time */
@@ -4533,6 +4534,7 @@
* bugs 15156 and 15895
*/
if (fc) {
+ if (sip_cfg.peer_rtlastms) {
ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
"port", port, "regseconds", regseconds,
deprecated_username ? "username" : "defaultuser", defaultuser,
@@ -4541,9 +4543,22 @@
} else {
ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
"port", port, "regseconds", regseconds,
+ deprecated_username ? "username" : "defaultuser", defaultuser,
+ "useragent", useragent, fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */
+ }
+ } else {
+ if (sip_cfg.peer_rtlastms) {
+ ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
+ "port", port, "regseconds", regseconds,
"useragent", useragent, "lastms", str_lastms,
deprecated_username ? "username" : "defaultuser", defaultuser,
syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */
+ } else {
+ ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
+ "port", port, "regseconds", regseconds,
+ "useragent", useragent, deprecated_username ? "username" : "defaultuser", defaultuser,
+ syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */
+ }
}
}
@@ -13752,7 +13767,11 @@
if (!sip_cfg.ignore_regexpire) {
if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) {
+ if (!sip_cfg.peer_rtlastms) {
+ ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", "useragent", "", SENTINEL);
+ } else {
ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "regserver", "", "useragent", "", "lastms", "0", SENTINEL);
+ }
} else {
ast_db_del("SIP/Registry", peer->name);
ast_db_del("SIP/PeerMethods", peer->name);
@@ -17656,6 +17675,7 @@
ast_cli(fd, " Useragent : %s\n", peer->useragent);
ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact);
ast_cli(fd, " Qualify Freq : %d ms\n", peer->qualifyfreq);
+ ast_cli(fd, " Qualify NotOK: %d ms\n", peer->qualifynotok);
if (peer->chanvars) {
ast_cli(fd, " Variables :\n");
for (v = peer->chanvars ; v ; v = v->next)
@@ -17755,6 +17775,7 @@
astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact);
astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq);
+ astman_append(s, "QualifyNotOK: %d ms\r\n", peer->qualifynotok);
astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot);
if (peer->chanvars) {
for (v = peer->chanvars ; v ; v = v->next) {
@@ -18218,6 +18239,7 @@
else
ast_cli(a->fd, " SIP realtime: Enabled\n" );
ast_cli(a->fd, " Qualify Freq : %d ms\n", global_qualifyfreq);
+ ast_cli(a->fd, " Qualify NotOK : %d ms\n", global_qualifynotok);
ast_cli(a->fd, " Q.850 Reason header: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_Q850_REASON)));
ast_cli(a->fd, " Store SIP_CAUSE: %s\n", AST_CLI_YESNO(global_store_sip_cause));
ast_cli(a->fd, "\nNetwork QoS Settings:\n");
@@ -18335,6 +18357,7 @@
ast_cli(a->fd, " Realtime Regs: %s\n", AST_CLI_YESNO(realtimeregs));
ast_cli(a->fd, " Cache Friends: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)));
ast_cli(a->fd, " Update: %s\n", AST_CLI_YESNO(sip_cfg.peer_rtupdate));
+ ast_cli(a->fd, " Update Lastms: %s\n", AST_CLI_YESNO(sip_cfg.peer_rtlastms));
ast_cli(a->fd, " Ignore Reg. Expire: %s\n", AST_CLI_YESNO(sip_cfg.ignore_regexpire));
ast_cli(a->fd, " Save sys. name: %s\n", AST_CLI_YESNO(sip_cfg.rtsave_sysname));
ast_cli(a->fd, " Auto Clear: %d (%s)\n", sip_cfg.rtautoclear, ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR) ? "Enabled" : "Disabled");
@@ -20955,7 +20978,7 @@
ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
peer->name, s, pingtime, peer->maxms);
ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
- if (sip_cfg.peer_rtupdate) {
+ if (sip_cfg.peer_rtupdate && sip_cfg.peer_rtlastms) {
ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL);
}
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
@@ -20969,7 +20992,7 @@
/* Try again eventually */
AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
- is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK,
+ is_reachable ? peer->qualifyfreq : peer->qualifynotok,
sip_poke_peer_s, peer,
unref_peer(_data, "removing poke peer ref"),
unref_peer(peer, "removing poke peer ref"),
@@ -26385,7 +26408,7 @@
if (peer->lastms > -1) {
ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms);
- if (sip_cfg.peer_rtupdate) {
+ if (sip_cfg.peer_rtupdate && sip_cfg.peer_rtlastms) {
ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL);
}
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
@@ -26408,7 +26431,7 @@
/* Try again quickly */
AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
- DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer,
+ peer->qualifynotok, sip_poke_peer_s, peer,
unref_peer(_data, "removing poke peer ref"),
unref_peer(peer, "removing poke peer ref"),
ref_peer(peer, "adding poke peer ref"));
@@ -27272,6 +27295,7 @@
peer->autoframing = global_autoframing;
peer->t38_maxdatagram = global_t38_maxdatagram;
peer->qualifyfreq = global_qualifyfreq;
+ peer->qualifynotok = global_qualifynotok;
if (global_callcounter)
peer->call_limit=INT_MAX;
ast_string_field_set(peer, vmexten, default_vmexten);
@@ -27384,7 +27408,7 @@
int firstpass = 1;
uint16_t port = 0;
int format = 0; /* Ama flags */
- int timerb_set = 0, timert1_set = 0;
+ int peer_timert1_set = 0;
time_t regseconds = 0;
struct ast_flags peerflags[3] = {{(0)}};
struct ast_flags mask[3] = {{(0)}};
@@ -27758,17 +27782,16 @@
peer->rtpkeepalive = global_rtpkeepalive;
}
} else if (!strcasecmp(v->name, "timert1")) {
- if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 200) || (peer->timer_t1 < global_t1min)) {
+ if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 50)) {
ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d. Using default.\n", v->value, v->lineno);
- peer->timer_t1 = global_t1min;
+ peer->timer_t1 = global_t1;
}
- timert1_set = 1;
+ peer_timert1_set = 1;
} else if (!strcasecmp(v->name, "timerb")) {
- if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 200)) {
+ if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 3200)) {
ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d. Using default.\n", v->value, v->lineno);
peer->timer_b = global_timer_b;
}
- timerb_set = 1;
} else if (!strcasecmp(v->name, "setvar")) {
peer->chanvars = add_var(v->value, peer->chanvars);
} else if (!strcasecmp(v->name, "header")) {
@@ -27783,6 +27806,14 @@
ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
peer->qualifyfreq = global_qualifyfreq;
}
+ } else if (!strcasecmp(v->name, "qualifynotok")) {
+ int i;
+ if (sscanf(v->value, "%30d", &i) == 1) {
+ peer->qualifynotok = i * 1000;
+ } else {
+ ast_log(LOG_WARNING, "Invalid qualifynotok number '%s' at line %d of %s\n", v->value, v->lineno, config);
+ peer->qualifynotok = global_qualifynotok;
+ }
} else if (!strcasecmp(v->name, "maxcallbitrate")) {
peer->maxcallbitrate = atoi(v->value);
if (peer->maxcallbitrate < 0) {
@@ -27903,20 +27934,16 @@
ast_set_cc_agent_policy(peer->cc_params, AST_CC_AGENT_NEVER);
}
- /* Note that Timer B is dependent upon T1 and MUST NOT be lower
- * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */
+ /* Note that Timer B is dependent upon Timer T1 and MUST NOT be lower
+ * than Timer T1 * 64, according to RFC 3261, Section 17.1.1.2 */
if (peer->timer_b < peer->timer_t1 * 64) {
- if (timerb_set && timert1_set) {
- ast_log(LOG_WARNING, "Timer B has been set lower than recommended for peer %s (%d < 64 * Timer-T1=%d)\n", peer->name, peer->timer_b, peer->timer_t1);
- } else if (timerb_set) {
- if ((peer->timer_t1 = peer->timer_b / 64) < global_t1min) {
- ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", peer->timer_b, peer->timer_t1);
- peer->timer_t1 = global_t1min;
+ if (peer_timert1_set) {
+ ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d), using 64 * timert1. (RFC 3261, 17.1.1.2)\n", peer->timer_b, peer->timer_t1);
peer->timer_b = peer->timer_t1 * 64;
- }
- peer->timer_t1 = peer->timer_b / 64;
} else {
- peer->timer_b = peer->timer_t1 * 64;
+ ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d), using 64 * timert1. (RFC 3261, 17.1.1.2)\n", peer->timer_b, peer->timer_t1);
+ peer->timer_t1 = global_t1;
+ peer->timer_b = global_timer_b;
}
}
@@ -28131,7 +28158,7 @@
struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED };
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 registry_count = 0, peer_count = 0, global_timert1_set = 0;
int subscribe_network_change = 1;
time_t run_start, run_end;
int bindport = 0;
@@ -28299,6 +28326,7 @@
ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for all devices: TRUE */
ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); /* Default for all devices: Yes */
sip_cfg.peer_rtupdate = TRUE;
+ sip_cfg.peer_rtlastms = TRUE;
global_dynamic_exclude_static = 0; /* Exclude static peers */
sip_cfg.tcp_enabled = FALSE;
@@ -28343,6 +28371,7 @@
global_timer_b = 64 * DEFAULT_TIMER_T1;
global_t1min = DEFAULT_T1MIN;
global_qualifyfreq = DEFAULT_QUALIFYFREQ;
+ global_qualifynotok = DEFAULT_FREQ_NOTOK;
global_t38_maxdatagram = -1;
global_shrinkcallerid = 1;
authlimit = DEFAULT_AUTHLIMIT;
@@ -28409,20 +28438,30 @@
sip_cfg.rtsave_sysname = ast_true(v->value);
} else if (!strcasecmp(v->name, "rtupdate")) {
sip_cfg.peer_rtupdate = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "rtlastms")) {
+ sip_cfg.peer_rtlastms = ast_true(v->value);
} else if (!strcasecmp(v->name, "ignoreregexpire")) {
sip_cfg.ignore_regexpire = ast_true(v->value);
} else if (!strcasecmp(v->name, "timert1")) {
/* Defaults to 500ms, but RFC 3261 states that it is recommended
* for the value to be set higher, though a lower value is only
* allowed on private networks unconnected to the Internet. */
+ int tmp = atoi(v->value);
+ if (tmp < 50) {
+ global_t1 = DEFAULT_TIMER_T1;
+ ast_log(LOG_WARNING, "Invalid value for timert1 ('%s'). Setting to default ('%d').\n", v->value, global_t1);
+ } else {
global_t1 = atoi(v->value);
+ }
+ global_timert1_set = 1;
} else if (!strcasecmp(v->name, "timerb")) {
int tmp = atoi(v->value);
- if (tmp < 500) {
+ if (tmp < global_t1 * 64) {
global_timer_b = global_t1 * 64;
- ast_log(LOG_WARNING, "Invalid value for timerb ('%s'). Setting to default ('%d').\n", v->value, global_timer_b);
+ ast_log(LOG_WARNING, "Invalid value for timerb ('%s'). Setting to 64 * timert1 ('%d').\n", v->value, global_timer_b);
+ } else {
+ global_timer_b = atoi(v->value);
}
- timerb_set = 1;
} else if (!strcasecmp(v->name, "t1min")) {
global_t1min = atoi(v->value);
} else if (!strcasecmp(v->name, "transport")) {
@@ -28785,6 +28824,14 @@
ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
global_qualifyfreq = DEFAULT_QUALIFYFREQ;
}
+ } else if (!strcasecmp(v->name, "qualifynotok")) {
+ int i;
+ if (sscanf(v->value, "%30d", &i) == 1) {
+ global_qualifynotok = i * 1000;
+ } else {
+ ast_log(LOG_WARNING, "Invalid qualifynotok number '%s' at line %d of %s\n", v->value, v->lineno, config);
+ global_qualifynotok = DEFAULT_FREQ_NOTOK;
+ }
} else if (!strcasecmp(v->name, "callevents")) {
sip_cfg.callevents = ast_true(v->value);
} else if (!strcasecmp(v->name, "authfailureevents")) {
@@ -28877,22 +28924,16 @@
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;
- }
-
+ /* Note that Timer B is dependent upon Timer T1 and MUST NOT be lower
+ * than Timer T1 * 64, according to RFC 3261, Section 17.1.1.2 */
if (global_timer_b < global_t1 * 64) {
- if (timerb_set && timert1_set) {
- ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1);
- } else if (timerb_set) {
- if ((global_t1 = global_timer_b / 64) < global_t1min) {
- ast_log(LOG_WARNING, "Timer B has been set lower than recommended (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1);
- global_t1 = global_t1min;
+ if (global_timert1_set) {
+ ast_log(LOG_WARNING, "Timer B has been set lower than recommended, using 64 * timert1 (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1);
global_timer_b = global_t1 * 64;
- }
} else {
- global_timer_b = global_t1 * 64;
+ ast_log(LOG_WARNING, "Timer B has been set lower than recommended, using defaults for timert1 and timerb (%d < 64 * timert1=%d). (RFC 3261, 17.1.1.2)\n", global_timer_b, global_t1);
+ global_t1 = DEFAULT_TIMER_T1;
+ global_timer_b = 64 * DEFAULT_TIMER_T1;
}
}
if (!sip_cfg.allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
@@ -30454,6 +30495,7 @@
MEMBER(sip_peer, lastms, AST_DATA_MILLISECONDS) \
MEMBER(sip_peer, maxms, AST_DATA_MILLISECONDS) \
MEMBER(sip_peer, qualifyfreq, AST_DATA_MILLISECONDS) \
+ MEMBER(sip_peer, qualifynotok, AST_DATA_MILLISECONDS) \
MEMBER(sip_peer, timer_t1, AST_DATA_MILLISECONDS) \
MEMBER(sip_peer, timer_b, AST_DATA_MILLISECONDS)