[asterisk-commits] oej: branch oej/grape-sip-timeout-pdd-1.8 r402918 - in /team/oej/grape-sip-ti...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Nov 21 07:10:18 CST 2013
Author: oej
Date: Thu Nov 21 07:10:14 2013
New Revision: 402918
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=402918
Log:
Time for test.
Added:
team/oej/grape-sip-timeout-pdd-1.8/README.grape (with props)
Modified:
team/oej/grape-sip-timeout-pdd-1.8/channels/chan_sip.c
team/oej/grape-sip-timeout-pdd-1.8/channels/sip/include/sip.h
Added: team/oej/grape-sip-timeout-pdd-1.8/README.grape
URL: http://svnview.digium.com/svn/asterisk/team/oej/grape-sip-timeout-pdd-1.8/README.grape?view=auto&rev=402918
==============================================================================
--- team/oej/grape-sip-timeout-pdd-1.8/README.grape (added)
+++ team/oej/grape-sip-timeout-pdd-1.8/README.grape Thu Nov 21 07:10:14 2013
@@ -1,0 +1,22 @@
+Edvina AB
+Olle E. Johansson
+
+Start date: 2013-11-21
+
+
+
+
+
+
+
+
+Grape - implement timer C in Chan_sip
+=====================================
+
+If we call a server and that server just sends 100 trying, we wait forever. This is not good.
+In order to fix this, this branch will implement a timer C that is normally a proxy timer.
+This fires after 3 minutes if there's no provisional response at all received from a device.
+
+When the timer fires, the call attempt is killed..
+
+The timer is set per channel, not per device, initially.
Propchange: team/oej/grape-sip-timeout-pdd-1.8/README.grape
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/grape-sip-timeout-pdd-1.8/README.grape
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/oej/grape-sip-timeout-pdd-1.8/README.grape
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/oej/grape-sip-timeout-pdd-1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/grape-sip-timeout-pdd-1.8/channels/chan_sip.c?view=diff&rev=402918&r1=402917&r2=402918
==============================================================================
--- team/oej/grape-sip-timeout-pdd-1.8/channels/chan_sip.c (original)
+++ team/oej/grape-sip-timeout-pdd-1.8/channels/chan_sip.c Thu Nov 21 07:10:14 2013
@@ -736,6 +736,7 @@
static int global_t1; /*!< T1 time */
static int global_t1min; /*!< T1 roundtrip time minimum */
static int global_timer_b; /*!< Timer B - RFC 3261 Section 17.1.1.2 */
+static int global_timer_c; /*!< Timer C - RFC 3261 Section 16.6 */
static unsigned int global_autoframing; /*!< Turn autoframing on or off. */
static int global_qualifyfreq; /*!< Qualify frequency */
static int global_qualify_gap; /*!< Time between our group of peer pokes */
@@ -1285,6 +1286,7 @@
static void *registry_unref(struct sip_registry *reg, char *tag);
static int update_call_counter(struct sip_pvt *fup, int event);
static int auto_congest(const void *arg);
+static int dialog_proceeding_timeout(const void *arg);
static struct sip_pvt *find_call(struct sip_request *req, struct ast_sockaddr *addr, const int intended_method);
static void free_old_route(struct sip_route *route);
static void list_route(struct sip_route *route);
@@ -4271,6 +4273,9 @@
if (p->timer_b == 0) {
p->timer_b = global_timer_b; /* Set timer B if not set (RFC 3261) */
}
+ if (p->timer_c == 0) {
+ p->timer_c = global_timer_c; /* Set timer C if not set (RFC 3261) */
+ }
ms = p->timer_t1 * 64;
}
if (sip_debug_test_pvt(p)) {
@@ -5756,6 +5761,12 @@
else
dialog->timer_b = 64 * dialog->timer_t1;
+ if (peer->timer_c) {
+ dialog->timer_c = peer->timer_c;
+ } else {
+ dialog->timer_c = global_timer_c;
+ }
+
if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
(ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
dialog->noncodeccapability |= AST_RTP_DTMF;
@@ -5806,6 +5817,7 @@
dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
+ dialog->timer_c = global_timer_c; /* Default SIP transaction timer C (RFC 3261) */
peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
if (peer) {
@@ -5910,6 +5922,30 @@
return 0;
}
+/*! \brief Scheduled congestion on a call when no responses has been received for 3 minutes (or configured)
+ * Only called by the scheduler, must return the reference when done.
+ */
+static int dialog_proceeding_timeout(const void *arg)
+{
+ struct sip_pvt *p = (struct sip_pvt *)arg;
+
+ sip_pvt_lock(p);
+ p->timercid = -1; /* event gone, will not be rescheduled */
+ if (p->owner) {
+ /* XXX fails on possible deadlock */
+ if (!ast_channel_trylock(p->owner)) {
+ append_history(p, "Cong", "Auto-congesting (timer C)");
+ ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+ ast_channel_unlock(p->owner);
+ }
+
+ /* Give the channel a chance to act before we proceed with destruction */
+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ }
+ sip_pvt_unlock(p);
+ dialog_unref(p, "unreffing arg passed into timer C callback (p->timerc)");
+ return 0;
+}
/*! \brief Initiate SIP call from PBX
* used from the dial() application */
@@ -8160,6 +8196,7 @@
p->method = intended_method;
p->initid = -1;
p->waitid = -1;
+ p->timercid = -1;
p->reinviteid = -1;
p->autokillid = -1;
p->request_queue_sched_id = -1;
@@ -8176,6 +8213,7 @@
if (intended_method != SIP_OPTIONS) { /* Peerpoke has it's own system */
p->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
p->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
+ p->timer_c = global_timer_c; /* Default SIP transaction timer B (RFC 3261) */
}
if (!addr) {
@@ -16702,6 +16740,11 @@
p->timer_b = peer->timer_b;
else
p->timer_b = 64 * p->timer_t1;
+ /* Set timer C to control transaction timeouts */
+ if (peer->timer_c)
+ p->timer_c = peer->timer_c;
+ else
+ p->timer_c = global_timer_c;
p->allowtransfer = peer->allowtransfer;
@@ -18257,6 +18300,7 @@
ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
ast_cli(fd, " Timer T1 : %d\n", peer->timer_t1);
ast_cli(fd, " Timer B : %d\n", peer->timer_b);
+ ast_cli(fd, " Timer C : %d\n", peer->timer_c);
ast_cli(fd, " ToHost : %s\n", peer->tohost);
ast_cli(fd, " Addr->IP : %s\n", ast_sockaddr_stringify(&peer->addr));
ast_cli(fd, " Defaddr->IP : %s\n", ast_sockaddr_stringify(&peer->defaddr));
@@ -18533,6 +18577,7 @@
"__sip_autodestruct",
"expire_register",
"auto_congest",
+ "dialog_proceeding_timeout",
"sip_reg_timeout",
"sip_poke_peer_s",
"sip_poke_noanswer",
@@ -18542,6 +18587,7 @@
__sip_autodestruct,
expire_register,
auto_congest,
+ dialog_proceeding_timeout,
sip_reg_timeout,
sip_poke_peer_s,
sip_poke_noanswer,
@@ -18955,6 +19001,7 @@
ast_cli(a->fd, " Timer T1: %d\n", global_t1);
ast_cli(a->fd, " Timer T1 minimum: %d\n", global_t1min);
ast_cli(a->fd, " Timer B: %d\n", global_timer_b);
+ ast_cli(a->fd, " Timer C: %d\n", global_timer_c);
ast_cli(a->fd, " No premature media: %s\n", AST_CLI_YESNO(global_prematuremediafilter));
ast_cli(a->fd, " Max forwards: %d\n", sip_cfg.default_max_forwards);
@@ -20771,8 +20818,27 @@
resp = 183;
/* Any response between 100 and 199 is PROCEEDING */
- if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
+ if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) {
p->invitestate = INV_PROCEEDING;
+ if (p->timercid == -1) {
+ /* Trigger timer C */
+ AST_SCHED_REPLACE_UNREF(p->timercid, sched, p->timer_c, dialog_proceeding_timeout, p,
+ dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"),
+ dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"),
+ dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") );
+ ast_debug(3, "Setting Timer C to %d \n", p->timer_c);
+ }
+ }
+
+ if (resp >= 200) {
+ /* Delete timer C - we have a response */
+ AST_SCHED_DEL_UNREF(sched, dialog->timercid, dialog_unref(dialog, "when you delete the timercid sched, you should dec the refcount for the stored dialog ptr"));
+ ast_debug(3, "Deleting Timer C (response received)\n");
+ } else {
+ /* reset timer C */
+ AST_SCHED_REPLACE_VARIABLE(dialog->timercid, sched, dialog->timer_c, dialog_proceeding_timeout, dialog, 1);
+ ast_debug(3, "Resetting Timer C to %d \n", p->timer_c);
+ }
/* Final response, not 200 ? */
if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
@@ -27986,6 +28052,7 @@
peer->stimer.st_max_se = global_max_se;
peer->timer_t1 = global_t1;
peer->timer_b = global_timer_b;
+ peer->timer_c = global_timer_c;
clear_peer_mailboxes(peer);
peer->disallowed_methods = sip_cfg.disallowed_methods;
peer->transports = default_transports;
@@ -28076,7 +28143,7 @@
int firstpass = 1;
uint16_t port = 0;
int format = 0; /* Ama flags */
- int timerb_set = 0, timert1_set = 0;
+ int timerb_set = 0, timert1_set = 0, timerc_set = 0;
time_t regseconds = 0;
struct ast_flags peerflags[3] = {{(0)}};
struct ast_flags mask[3] = {{(0)}};
@@ -28429,6 +28496,12 @@
peer->timer_b = global_timer_b;
}
timerb_set = 1;
+ } else if (!strcasecmp(v->name, "timerc")) {
+ if ((sscanf(v->value, "%30d", &peer->timer_c) != 1) || (peer->timer_c > 100)) {
+ ast_log(LOG_WARNING, "'%s' is not a valid Timer C time at line %d (above 100, default 180 s). Using configured default %s.\n", v->value, v->lineno, global_timer_c);
+ peer->timer_c = global_timer_c;
+ }
+ timerc_set = 1;
} else if (!strcasecmp(v->name, "setvar")) {
peer->chanvars = add_var(v->value, peer->chanvars);
} else if (!strcasecmp(v->name, "header")) {
@@ -29002,6 +29075,7 @@
global_authfailureevents = FALSE;
global_t1 = DEFAULT_TIMER_T1;
global_timer_b = 64 * DEFAULT_TIMER_T1;
+ global_timer_c = 180; /* 3 minutes per RFC 3261 */
global_t1min = DEFAULT_T1MIN;
global_qualifyfreq = DEFAULT_QUALIFYFREQ;
global_t38_maxdatagram = -1;
@@ -29087,6 +29161,12 @@
ast_log(LOG_WARNING, "Invalid value for timerb ('%s'). Setting to default ('%d').\n", v->value, global_timer_b);
}
timerb_set = 1;
+ } else if (!strcasecmp(v->name, "timerc")) {
+ int tmp = atoi(v->value);
+ if (tmp < 100) {
+ global_timer_c = DEFAULT_TIMER_C;
+ ast_log(LOG_WARNING, "Invalid value (< 100 s) for timerc ('%s'). Setting to default ('%d').\n", v->value, global_timer_c);
+ }
} else if (!strcasecmp(v->name, "t1min")) {
global_t1min = atoi(v->value);
} else if (!strcasecmp(v->name, "transport")) {
@@ -31668,7 +31748,8 @@
MEMBER(sip_peer, maxms, AST_DATA_MILLISECONDS) \
MEMBER(sip_peer, qualifyfreq, AST_DATA_MILLISECONDS) \
MEMBER(sip_peer, timer_t1, AST_DATA_MILLISECONDS) \
- MEMBER(sip_peer, timer_b, AST_DATA_MILLISECONDS)
+ MEMBER(sip_peer, timer_b, AST_DATA_MILLISECONDS) \
+ MEMBER(sip_peer, timer_c, AST_DATA_SECONDS)
AST_DATA_STRUCTURE(sip_peer, DATA_EXPORT_SIP_PEER);
Modified: team/oej/grape-sip-timeout-pdd-1.8/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/grape-sip-timeout-pdd-1.8/channels/sip/include/sip.h?view=diff&rev=402918&r1=402917&r2=402918
==============================================================================
--- team/oej/grape-sip-timeout-pdd-1.8/channels/sip/include/sip.h (original)
+++ team/oej/grape-sip-timeout-pdd-1.8/channels/sip/include/sip.h Thu Nov 21 07:10:14 2013
@@ -1018,6 +1018,7 @@
unsigned short req_secure_signaling:1;/*!< Whether we are required to have secure signaling or not */
int timer_t1; /*!< SIP timer T1, ms rtt */
int timer_b; /*!< SIP timer B, ms */
+ int timer_c; /*!< SIP timer B, ms */
unsigned int sipoptions; /*!< Supported SIP options on the other end */
unsigned int reqsipoptions; /*!< Required SIP options on the other end */
struct ast_codec_pref prefs; /*!< codec prefs */
@@ -1078,6 +1079,7 @@
int initid; /*!< Auto-congest ID if appropriate (scheduler) */
int waitid; /*!< Wait ID for scheduler after 491 or other delays */
+ int timercid; /*!< Scheduler ID for timer C delays */
int reinviteid; /*!< Reinvite in case of provisional, but no final response */
int autokillid; /*!< Auto-kill ID (scheduler) */
int t38id; /*!< T.38 Response ID */
@@ -1271,6 +1273,7 @@
struct sip_st_cfg stimer; /*!< SIP Session-Timers */
int timer_t1; /*!< The maximum T1 value for the peer */
int timer_b; /*!< The maximum timer B (transaction timeouts) */
+ int timer_c; /*!< The timer c (transaction timeouts) */
int fromdomainport; /*!< The From: domain port */
/*XXX Seems like we suddenly have two flags with the same content. Why? To be continued... */
More information about the asterisk-commits
mailing list