Review Board 1.7.16


SIP Session-Expires: Set timer to correctly expire at (~2/3) of the expiry interval when not the refresher.

Review Request #2488 - Created May 1, 2013 and submitted

Alec Davis
1.8 to trunk
ASTERISK-21742
Reviewers
asterisk-dev
Asterisk
RFC 4028 Section 10

	if the side not performing refreshes does not receive a
	session refresh request before the session expiration, it SHOULD send
	a BYE to terminate the session, slightly before the session
	expiration.  The minimum of 32 seconds and one third of the session
	interval is RECOMMENDED.

asterisk to phone.
Phone's Session-Expires: 120

[Apr 30 22:49:20] NOTICE[12686][C-00000000]: chan_sip.c:29006 start_session_timer: Session timer started: 104 - 50a7397219b8f47e192f74e81f3b125e@192.168.x.y:5060 88000ms
<<<<<  pull ethernet on phone >>
<<<<<  88 seconds later       >>
[Apr 30 22:50:48] WARNING[12686]: chan_sip.c:29042 proc_session_timer: Session-Timer expired - 50a7397219b8f47e192f74e81f3b125e@192.168.x.y:5060


Phone to Asterisk, No Session-Expires
Asterisk's Session-Expires: 300
[Apr 30 23:47:02] NOTICE[12857][C-00000001]: chan_sip.c:29006 start_session_timer: Session timer started: 99 - 7160947918a9977c@192.168.124.73 150000ms

Diff revision 2 (Latest)

1 2
1 2

  1. branches/11/channels/chan_sip.c: Loading...
  2. branches/11/channels/sip/include/sip.h: Loading...
branches/11/channels/chan_sip.c
Revision 386925 New Change
[20] 21090 lines
[+20] [+] static char *sip_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
21091
			} else {
21091
			} else {
21092
 				ast_cli(a->fd, "  Session-Timer:          %s\n", cur->stimer->st_active ? "Active" : "Inactive");
21092
 				ast_cli(a->fd, "  Session-Timer:          %s\n", cur->stimer->st_active ? "Active" : "Inactive");
21093
 				if (cur->stimer->st_active == TRUE) {
21093
 				if (cur->stimer->st_active == TRUE) {
21094
 					ast_cli(a->fd, "  S-Timer Interval:       %d\n", cur->stimer->st_interval);
21094
 					ast_cli(a->fd, "  S-Timer Interval:       %d\n", cur->stimer->st_interval);
21095
 					ast_cli(a->fd, "  S-Timer Refresher:      %s\n", strefresher2str(cur->stimer->st_ref));
21095
 					ast_cli(a->fd, "  S-Timer Refresher:      %s\n", strefresher2str(cur->stimer->st_ref));
21096
 					ast_cli(a->fd, "  S-Timer Expirys:        %d\n", cur->stimer->st_expirys);

   
21097
 					ast_cli(a->fd, "  S-Timer Sched Id:       %d\n", cur->stimer->st_schedid);
21096
 					ast_cli(a->fd, "  S-Timer Sched Id:       %d\n", cur->stimer->st_schedid);
21098
 					ast_cli(a->fd, "  S-Timer Peer Sts:       %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive");
21097
 					ast_cli(a->fd, "  S-Timer Peer Sts:       %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive");
21099
 					ast_cli(a->fd, "  S-Timer Cached Min-SE:  %d\n", cur->stimer->st_cached_min_se);
21098
 					ast_cli(a->fd, "  S-Timer Cached Min-SE:  %d\n", cur->stimer->st_cached_min_se);
21100
 					ast_cli(a->fd, "  S-Timer Cached SE:      %d\n", cur->stimer->st_cached_max_se);
21099
 					ast_cli(a->fd, "  S-Timer Cached SE:      %d\n", cur->stimer->st_cached_max_se);
21101
 					ast_cli(a->fd, "  S-Timer Cached Ref:     %s\n", strefresherparam2str(cur->stimer->st_cached_ref));
21100
 					ast_cli(a->fd, "  S-Timer Cached Ref:     %s\n", strefresherparam2str(cur->stimer->st_cached_ref));
[+20] [20] 4441 lines
[+20] [+] static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, uint32_t seqno, int *recount, const char *e, int *nounlock)
25543
				p->stimer->st_interval = st_interval;
25542
				p->stimer->st_interval = st_interval;
25544
				p->stimer->st_ref      = tmp_st_ref;
25543
				p->stimer->st_ref      = tmp_st_ref;
25545
			}
25544
			}
25546

    
   
25545

   
25547
			restart_session_timer(p);
25546
			restart_session_timer(p);
25548
			if (p->stimer->st_expirys > 0) {

   
25549
				p->stimer->st_expirys--;

   
25550
			}

   
25551
		}
25547
		}
25552
	}
25548
	}
25553

    
   
25549

   
25554
	if (!req->ignore && p)
25550
	if (!req->ignore && p)
25555
		p->lastinvite = seqno;
25551
		p->lastinvite = seqno;
[+20] [20] 3397 lines
[+20] [+] static void stop_session_timer(struct sip_pvt *p)
28953

    
   
28949

   
28954

    
   
28950

   
28955
/*! \brief Session-Timers: Start session timer */
28951
/*! \brief Session-Timers: Start session timer */
28956
static void start_session_timer(struct sip_pvt *p)
28952
static void start_session_timer(struct sip_pvt *p)
28957
{
28953
{

    
   
28954
	unsigned int timeout_ms;

    
   
28955

   
28958
	if (!p->stimer) {
28956
	if (!p->stimer) {
28959
		ast_log(LOG_WARNING, "Null stimer in start_session_timer - %s\n", p->callid);
28957
		ast_log(LOG_WARNING, "Null stimer in start_session_timer - %s\n", p->callid);
28960
		return;
28958
		return;
28961
	}
28959
	}
28962

    
   
28960

   
28963
	if (p->stimer->st_schedid > -1) {
28961
	if (p->stimer->st_schedid > -1) {
28964
		/* in the event a timer is already going, stop it */
28962
		/* in the event a timer is already going, stop it */
28965
		ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
28963
		ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
28966
		AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
28964
		AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
28967
			dialog_unref(p, "unref stimer->st_schedid from dialog"));
28965
			dialog_unref(p, "unref stimer->st_schedid from dialog"));
28968
	}
28966
	}
28969

    
   
28967

   
28970
	p->stimer->st_schedid  = ast_sched_add(sched, p->stimer->st_interval * 1000 / 2, proc_session_timer, 
28968
	/*

    
   
28969
	 * RFC 4028 Section 10

    
   
28970
	 * If the side not performing refreshes does not receive a

    
   
28971
	 * session refresh request before the session expiration, it SHOULD send

    
   
28972
	 * a BYE to terminate the session, slightly before the session

    
   
28973
	 * expiration.  The minimum of 32 seconds and one third of the session

    
   
28974
	 * interval is RECOMMENDED.

    
   
28975
	 */

    
   
28976

   

    
   
28977
	timeout_ms = (1000 * p->stimer->st_interval);

    
   
28978
	if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US) {

    
   
28979
		timeout_ms /= 2;

    
   
28980
	} else if (timeout_ms / 3 < 32000 ) {

    
   
28981
		timeout_ms -= (timeout_ms / 3);

    
   
28982
	} else {

    
   
28983
		timeout_ms -= 32000;

    
   
28984
	}

    
   
28985

   

    
   
28986
	p->stimer->st_schedid = ast_sched_add(sched, timeout_ms, proc_session_timer,
28971
			dialog_ref(p, "adding session timer ref"));
28987
			dialog_ref(p, "adding session timer ref"));

    
   
28988

   
28972
	if (p->stimer->st_schedid < 0) {
28989
	if (p->stimer->st_schedid < 0) {
28973
		dialog_unref(p, "removing session timer ref");
28990
		dialog_unref(p, "removing session timer ref");
28974
		ast_log(LOG_ERROR, "ast_sched_add failed - %s\n", p->callid);
28991
		ast_log(LOG_ERROR, "ast_sched_add failed - %s\n", p->callid);
28975
	} else {
28992
	} else {
28976
		p->stimer->st_active = TRUE;
28993
		p->stimer->st_active = TRUE;
28977
		ast_debug(2, "Session timer started: %d - %s\n", p->stimer->st_schedid, p->callid);
28994
		ast_debug(2, "Session timer started: %d - %s %ums\n", p->stimer->st_schedid, p->callid, timeout_ms);
28978
	}
28995
	}
28979
}
28996
}
28980

    
   
28997

   
28981

    
   
28998

   
28982
/*! \brief Session-Timers: Process session refresh timeout event */
28999
/*! \brief Session-Timers: Process session refresh timeout event */
[+20] [20] 23 lines
[+20] [+] static int proc_session_timer(const void *vp)
29006
			transmit_reinvite_with_sdp(p, TRUE, TRUE);
29023
			transmit_reinvite_with_sdp(p, TRUE, TRUE);
29007
		} else {
29024
		} else {
29008
			transmit_reinvite_with_sdp(p, FALSE, TRUE);
29025
			transmit_reinvite_with_sdp(p, FALSE, TRUE);
29009
		}
29026
		}
29010
	} else {
29027
	} else {
29011
		p->stimer->st_expirys++;

   
29012
		if (p->stimer->st_expirys >= 2) {

   
29013
			if (p->stimer->quit_flag) {
29028
		if (p->stimer->quit_flag) {
29014
				goto return_unref;
29029
			goto return_unref;
29015
			}
29030
		}
29016
			ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid);
29031
		ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid);
29017
			sip_pvt_lock(p);
29032
		sip_pvt_lock(p);
[+20] [20] 9 lines
[+20] static int proc_session_timer(const void *vp)
29027
			manager_event(EVENT_FLAG_CALL, "SessionTimeout", "Source: SIPSessionTimer\r\n"
29042
		manager_event(EVENT_FLAG_CALL, "SessionTimeout", "Source: SIPSessionTimer\r\n"
29028
					"Channel: %s\r\nUniqueid: %s\r\n", ast_channel_name(p->owner), ast_channel_uniqueid(p->owner));
29043
				"Channel: %s\r\nUniqueid: %s\r\n", ast_channel_name(p->owner), ast_channel_uniqueid(p->owner));
29029
			ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
29044
		ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
29030
			ast_channel_unlock(p->owner);
29045
		ast_channel_unlock(p->owner);
29031
			sip_pvt_unlock(p);
29046
		sip_pvt_unlock(p);
29032
		} else {

   
29033
			res = 1;

   
29034
		}

   
29035
	}
29047
	}
29036

    
   
29048

   
29037
return_unref:
29049
return_unref:
29038
	if (!res) {
29050
	if (!res) {
29039
		/* An error occurred.  Stop session timer processing */
29051
		/* An error occurred.  Stop session timer processing */
[+20] [20] 5619 lines
branches/11/channels/sip/include/sip.h
Revision 386925 New Change
 
  1. branches/11/channels/chan_sip.c: Loading...
  2. branches/11/channels/sip/include/sip.h: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.