[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