[asterisk-commits] mjordan: branch certified-1.8.15 r375590 - in /certified/branches/1.8.15: ./ ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Nov 2 10:28:04 CDT 2012


Author: mjordan
Date: Fri Nov  2 10:27:56 2012
New Revision: 375590

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=375590
Log:
Multiple revisions 372709,373165,373532,373652,374456

........
  r372709 | mjordan | 2012-09-08 20:19:21 -0500 (Sat, 08 Sep 2012) | 38 lines
  
  Only re-create an SRTP session when needed; respond with correct crypto policy
  
  In r356604, SRTP handling was fixed to accomodate multiple crypto keys in an
  SDP offer and the ability to re-create an SRTP session when the crypto keys
  changed.  In certain circumstances - most notably when a phone is put on
  hold after having been bridged for a significant amount of time - the act
  of re-creating the SRTP session causes problems for certain models of phones.
  The patch committed in r356604 always re-created the SRTP session regardless
  of whether or not the cryptographic keys changed.  Since this is technically
  not necessary, this patch modifies the behavior to only re-create the SRTP
  session if Asterisk detects that the remote key has changed.  This allows
  models of phones that do not handle the SRTP session changing to continue
  to work, while also providing the behavior needed for those phones that do
  re-negotiate cryptographic keys.
  
  In addition, in Asterisk 1.8 only, it was found that phones that offer
  AES_CM_128_HMAC_SHA1_32 will end up with no audio if the phone is the
  initiator of the call.  The phone will send an INVITE request specifying
  that AES_CM_128_HMAC_SHA1_32 be used for the cryptographic policy; Asterisk
  will set its policy to that value.  Unfortunately, when the call is Answered
  and a 200 OK is sent back to the UA, the policy sent in the response's SDP
  will be the hard coded value AES_CM_128_HMAC_SHA1_80.  This potentially
  results in Asterisk using the INVITE request's policy of
  AES_CM_128_HMAC_SHA1_32, while the phone uses Asterisk's response of
  AES_CM_128_HMAC_SHA1_80.  Hilarity ensues as both endpoints think the other
  is crazy.
  
  This patch fixes that by caching the policy from the request and responding
  with it.  Note that this is not a problem in Asterisk 10 and later, as the
  ability to configure the policy was added in that version.
  
  (issue ASTERISK-20194)
  Reported by: Nicolo Mazzon
  Tested by: Nicolo Mazzon
  
  Review: https://reviewboard.asterisk.org/r/2099
........
  r373165 | file | 2012-09-19 11:02:18 -0500 (Wed, 19 Sep 2012) | 10 lines
  
  Fix a regression where direct media was not permitted for calls using SIP INFO DTMF.
  
  A change was committed to fix direct media ACL support. This change wrongly assumed that
  only a single channel technology structure exists for chan_sip. This is in fact false as
  a second exists for calls using SIP INFO DTMF. The code which performs direct media ACL
  checking now checks for both the non-INFO DTMF and INFO DTMF channel technology structures.
  
  (closes issue ASTERISK-20409)
  Reported by: michele cicciotti privatewave
........
  r373532 | file | 2012-09-24 19:09:46 -0500 (Mon, 24 Sep 2012) | 5 lines
  
  Add missing checks that I neglected. The SIP technology and SIP info technology should be considered equal.
  
  (closes issue ASTERISK-20409)
  Reported by: michele cicciotti privatewave
........
  r373652 | twilson | 2012-09-25 12:21:19 -0500 (Tue, 25 Sep 2012) | 18 lines
  
  Properly handle UAC/UAS roles for SIP session timers
  
  The SIP session timer mechanism contains a mandatory 'refresher' parameter
  (included in the Session-Expires header) which is used in the session timer
  offer/answer signaling within a SIP Invite dialog. It looks like asterisk is
  interpreting the uac resp. uas role only as the initial role of client and
  server (caller is uac, callee is uas). The standard rfc 4028 however assigns
  the client role to the ((RE)-Invite) requester, the server role to the
  ((RE)-Invite) responder.
  
  This patch has Asterisk track the actual refresher as "us" or "them" as opposed
  to relying on just the configured "uas" or "uac" properties.
  
  (closes issue AST-922)
  Reported by: Thomas Airmont
  
  Review: https://reviewboard.asterisk.org/r/2118/
........
  r374456 | file | 2012-10-04 12:39:18 -0500 (Thu, 04 Oct 2012) | 14 lines
  
  Fix a regression from direct media ACLs where the directrtpsetup option no longer works.
  
  A check was added for direct media ACLs that immediately forbid remote bridging if there
  was no bridged channel. This caused directrtpsetup to no longer function as it needs this
  information before bridging actually occurs.
  
  Logic has now been adjusted so if there is no bridged channel a remote bridge will still
  be attempted.
  
  (closes issue ASTERISK-20511)
  Reported by: kristoff
  
  Review: https://reviewboard.asterisk.org/r/2146/
........

Merged revisions 372709,373165,373532,373652,374456 from http://svn.asterisk.org/svn/asterisk/branches/1.8

Modified:
    certified/branches/1.8.15/   (props changed)
    certified/branches/1.8.15/channels/chan_sip.c
    certified/branches/1.8.15/channels/sip/include/sip.h
    certified/branches/1.8.15/channels/sip/sdp_crypto.c
    certified/branches/1.8.15/configs/sip.conf.sample

Propchange: certified/branches/1.8.15/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Modified: certified/branches/1.8.15/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/certified/branches/1.8.15/channels/chan_sip.c?view=diff&rev=375590&r1=375589&r2=375590
==============================================================================
--- certified/branches/1.8.15/channels/chan_sip.c (original)
+++ certified/branches/1.8.15/channels/chan_sip.c Fri Nov  2 10:27:56 2012
@@ -758,7 +758,7 @@
 static int global_qualify_peers;        /*!< Number of peers to poke at a given time */
 
 static enum st_mode global_st_mode;           /*!< Mode of operation for Session-Timers           */
-static enum st_refresher global_st_refresher; /*!< Session-Timer refresher                        */
+static enum st_refresher_param global_st_refresher; /*!< Session-Timer refresher                        */
 static int global_min_se;                     /*!< Lowest threshold for session refresh interval  */
 static int global_max_se;                     /*!< Highest threshold for session refresh interval */
 
@@ -1602,8 +1602,8 @@
 static void stop_session_timer(struct sip_pvt *p);
 static void start_session_timer(struct sip_pvt *p);
 static void restart_session_timer(struct sip_pvt *p);
-static const char *strefresher2str(enum st_refresher r);
-static int parse_session_expires(const char *p_hdrval, int *const p_interval, enum st_refresher *const p_ref);
+static const char *strefresherparam2str(enum st_refresher r);
+static int parse_session_expires(const char *p_hdrval, int *const p_interval, enum st_refresher_param *const p_ref);
 static int parse_minse(const char *p_hdrval, int *const p_interval);
 static int st_get_se(struct sip_pvt *, int max);
 static enum st_refresher st_get_refresher(struct sip_pvt *);
@@ -10451,7 +10451,7 @@
 	if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE) {
 		char se_hdr[256];
 		snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval,
-			strefresher2str(p->stimer->st_ref));
+			p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uas" : "uac");
 		add_header(resp, "Session-Expires", se_hdr);
 	}
 
@@ -10623,7 +10623,7 @@
 	    && sipmethod == SIP_INVITE) {
 		char se_hdr[256];
 		snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval,
-			strefresher2str(p->stimer->st_ref));
+			p->stimer->st_ref == SESSION_TIMER_REFRESHER_US ? "uac" : "uas");
 		add_header(req, "Session-Expires", se_hdr);
 		snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE));
 		add_header(req, "Min-SE", se_hdr);
@@ -16880,23 +16880,34 @@
 }
 
 /* Session-Timer Refreshers */
+static const struct _map_x_s strefresher_params[] = {
+        { SESSION_TIMER_REFRESHER_PARAM_UNKNOWN, "unknown" },
+        { SESSION_TIMER_REFRESHER_PARAM_UAC,     "uac"     },
+        { SESSION_TIMER_REFRESHER_PARAM_UAS,     "uas"     },
+        { -1,                                NULL  },
+};
+
 static const struct _map_x_s strefreshers[] = {
-        { SESSION_TIMER_REFRESHER_AUTO,     "auto"},
-        { SESSION_TIMER_REFRESHER_UAC,      "uac"},
-        { SESSION_TIMER_REFRESHER_UAS,      "uas"},
-        { -1,                               NULL},
+        { SESSION_TIMER_REFRESHER_AUTO, "auto" },
+        { SESSION_TIMER_REFRESHER_US,   "us"   },
+        { SESSION_TIMER_REFRESHER_THEM, "them" },
+        { -1,                           NULL   },
 };
 
+static const char *strefresherparam2str(enum st_refresher r)
+{
+	return map_x_s(strefresher_params, r, "Unknown");
+}
+
+static enum st_refresher str2strefresherparam(const char *s)
+{
+	return map_s_x(strefresher_params, s, -1);
+}
+
 static const char *strefresher2str(enum st_refresher r)
 {
 	return map_x_s(strefreshers, r, "Unknown");
 }
-
-static enum st_refresher str2strefresher(const char *s)
-{
-	return map_s_x(strefreshers, s, -1);
-}
-
 
 static int peer_status(struct sip_peer *peer, char *status, int statuslen)
 {
@@ -18042,7 +18053,7 @@
 		}
 
 		ast_cli(fd, "  Sess-Timers  : %s\n", stmode2str(peer->stimer.st_mode_oper));
-		ast_cli(fd, "  Sess-Refresh : %s\n", strefresher2str(peer->stimer.st_ref));
+		ast_cli(fd, "  Sess-Refresh : %s\n", strefresherparam2str(peer->stimer.st_ref));
 		ast_cli(fd, "  Sess-Expires : %d secs\n", peer->stimer.st_max_se);
 		ast_cli(fd, "  Min-Sess     : %d secs\n", peer->stimer.st_min_se);
 		ast_cli(fd, "  RTP Engine   : %s\n", peer->engine);
@@ -18099,7 +18110,7 @@
 		astman_append(s, "SIP-T.38EC: %s\r\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
 		astman_append(s, "SIP-T.38MaxDtgrm: %d\r\n", peer->t38_maxdatagram);
 		astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper));
-		astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresher2str(peer->stimer.st_ref));
+		astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresherparam2str(peer->stimer.st_ref));
 		astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se);
 		astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se);
 		astman_append(s, "SIP-RTP-Engine: %s\r\n", peer->engine);
@@ -18239,7 +18250,7 @@
 		ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
 		ast_cli(a->fd, "  ACL          : %s\n", AST_CLI_YESNO(user->ha != NULL));
  		ast_cli(a->fd, "  Sess-Timers  : %s\n", stmode2str(user->stimer.st_mode_oper));
- 		ast_cli(a->fd, "  Sess-Refresh : %s\n", strefresher2str(user->stimer.st_ref));
+ 		ast_cli(a->fd, "  Sess-Refresh : %s\n", strefresherparam2str(user->stimer.st_ref));
  		ast_cli(a->fd, "  Sess-Expires : %d secs\n", user->stimer.st_max_se);
  		ast_cli(a->fd, "  Sess-Min-SE  : %d secs\n", user->stimer.st_min_se);
 		ast_cli(a->fd, "  RTP Engine   : %s\n", user->engine);
@@ -18682,7 +18693,7 @@
 	ast_cli(a->fd, "  Outb. proxy:            %s %s\n", ast_strlen_zero(sip_cfg.outboundproxy.name) ? "<not set>" : sip_cfg.outboundproxy.name,
 							sip_cfg.outboundproxy.force ? "(forced)" : "");
 	ast_cli(a->fd, "  Session Timers:         %s\n", stmode2str(global_st_mode));
-	ast_cli(a->fd, "  Session Refresher:      %s\n", strefresher2str (global_st_refresher));
+	ast_cli(a->fd, "  Session Refresher:      %s\n", strefresherparam2str(global_st_refresher));
 	ast_cli(a->fd, "  Session Expires:        %d secs\n", global_max_se);
 	ast_cli(a->fd, "  Session Min-SE:         %d secs\n", global_min_se);
  	ast_cli(a->fd, "  Timer T1:               %d\n", global_t1);
@@ -19114,7 +19125,7 @@
  					ast_cli(a->fd, "  S-Timer Peer Sts:       %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive");
  					ast_cli(a->fd, "  S-Timer Cached Min-SE:  %d\n", cur->stimer->st_cached_min_se);
  					ast_cli(a->fd, "  S-Timer Cached SE:      %d\n", cur->stimer->st_cached_max_se);
- 					ast_cli(a->fd, "  S-Timer Cached Ref:     %s\n", strefresher2str(cur->stimer->st_cached_ref));
+ 					ast_cli(a->fd, "  S-Timer Cached Ref:     %s\n", strefresherparam2str(cur->stimer->st_cached_ref));
  					ast_cli(a->fd, "  S-Timer Cached Mode:    %s\n", stmode2str(cur->stimer->st_cached_mode));
  				}
 			}
@@ -20754,15 +20765,18 @@
 			p_hdrval = (char*)get_header(req, "Session-Expires");
 			if (!ast_strlen_zero(p_hdrval)) {
 				/* UAS supports Session-Timers */
-				enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO;
+				enum st_refresher_param st_ref_param;
 				int tmp_st_interval = 0;
-				rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &tmp_st_ref);
+				rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &st_ref_param);
 				if (rtn != 0) {
 					ast_set_flag(&p->flags[0], SIP_PENDINGBYE);	
 				}
-				if (tmp_st_ref == SESSION_TIMER_REFRESHER_UAC ||
-					tmp_st_ref == SESSION_TIMER_REFRESHER_UAS) {
-					p->stimer->st_ref = tmp_st_ref;
+				if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) {
+				   p->stimer->st_ref = SESSION_TIMER_REFRESHER_US;
+				} else if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAS) {
+					p->stimer->st_ref = SESSION_TIMER_REFRESHER_THEM;
+				} else {
+					ast_log(LOG_WARNING, "Unknown refresher on %s\n", p->callid);
 				}
 				if (tmp_st_interval) {
 					p->stimer->st_interval = tmp_st_interval;
@@ -20773,7 +20787,7 @@
 			} else {
 				/* UAS doesn't support Session-Timers */
 				if (st_get_mode(p, 0) == SESSION_TIMER_MODE_ORIGINATE) {
-					p->stimer->st_ref = SESSION_TIMER_REFRESHER_UAC;
+					p->stimer->st_ref = SESSION_TIMER_REFRESHER_US;
 					p->stimer->st_active_peer_ua = FALSE;
 					start_session_timer(p);
 				}
@@ -22787,7 +22801,7 @@
 	int uac_min_se = -1;            /* UAC's Min-SE in integer format                           */
 	int st_active = FALSE;          /* Session-Timer on/off boolean                             */
 	int st_interval = 0;            /* Session-Timer negotiated refresh interval                */
-	enum st_refresher st_ref;       /* Session-Timer session refresher                          */
+	enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO; /* Session-Timer refresher     */
 	int dlg_min_se = -1;
 	struct {
 		char exten[AST_MAX_EXTENSION];
@@ -22795,7 +22809,6 @@
 	} pickup = {
 			.exten = "",
 	};
-	st_ref = SESSION_TIMER_REFRESHER_AUTO;
 
 	/* Find out what they support */
 	if (!p->sipoptions) {
@@ -23322,6 +23335,8 @@
 
 	/* Session-Timers */
 	if ((p->sipoptions & SIP_OPT_TIMER) && !ast_strlen_zero(get_header(req, "Session-Expires"))) {
+		enum st_refresher_param st_ref_param;
+
 		/* The UAC has requested session-timers for this session. Negotiate
 		the session refresh interval and who will be the refresher */
 		ast_debug(2, "Incoming INVITE with 'timer' option supported and \"Session-Expires\" header.\n");
@@ -23332,7 +23347,8 @@
 
 		/* Parse the Session-Expires header */
 		p_uac_se_hdr = get_header(req, "Session-Expires");
-		rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref);
+		rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref_param);
+		tmp_st_ref = (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US;
 		if (rtn != 0) {
 			transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req);
 			p->invitestate = INV_COMPLETED;
@@ -23374,8 +23390,8 @@
 
 			p->stimer->st_active_peer_ua = TRUE;
 			st_active = TRUE;
-			if (st_ref == SESSION_TIMER_REFRESHER_AUTO) {
-				st_ref = st_get_refresher(p);
+			if (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UNKNOWN) {
+				tmp_st_ref = st_get_refresher(p);
 			}
 
 			if (uac_max_se > 0) {
@@ -23416,7 +23432,7 @@
 		case SESSION_TIMER_MODE_ORIGINATE:
 			st_active = TRUE;
 			st_interval = st_get_se(p, TRUE);
-			st_ref = SESSION_TIMER_REFRESHER_UAS;
+			tmp_st_ref = SESSION_TIMER_REFRESHER_US;
 			p->stimer->st_active_peer_ua = FALSE;
 			break;
 
@@ -23428,9 +23444,9 @@
 	if (reinvite == 0) {
 		/* Session-Timers: Start session refresh timer based on negotiation/config */
 		if (st_active == TRUE) {
-			p->stimer->st_active   = TRUE;
+			p->stimer->st_active = TRUE;
 			p->stimer->st_interval = st_interval;
-			p->stimer->st_ref      = st_ref;
+			p->stimer->st_ref = tmp_st_ref;
 			start_session_timer(p);
 		}
 	} else {
@@ -23443,7 +23459,7 @@
 			/* The UAC may be adjusting the session-timers mid-session */
 			if (st_interval > 0) {
 				p->stimer->st_interval = st_interval;
-				p->stimer->st_ref      = st_ref;
+				p->stimer->st_ref      = tmp_st_ref;
 			}
 
 			restart_session_timer(p);
@@ -26660,7 +26676,6 @@
 static int proc_session_timer(const void *vp)
 {
 	struct sip_pvt *p = (struct sip_pvt *) vp;
-	int sendreinv = FALSE;
 	int res = 0;
 
 	if (!p->stimer) {
@@ -26678,23 +26693,7 @@
 		goto return_unref;
 	}
 
-	switch (p->stimer->st_ref) {
-	case SESSION_TIMER_REFRESHER_UAC:
-		if (p->outgoing_call == TRUE) {
-	  		sendreinv = TRUE;
-		}
-		break;
-	case SESSION_TIMER_REFRESHER_UAS:
-		if (p->outgoing_call != TRUE) {
-  			sendreinv = TRUE;
-		}
-		break;
-	default:
-		ast_log(LOG_ERROR, "Unknown session refresher %d\n", p->stimer->st_ref);
-		goto return_unref;
-	}
-
-	if (sendreinv == TRUE) {
+	if (p->stimer->st_ref == SESSION_TIMER_REFRESHER_US) {
 		res = 1;
 		transmit_reinvite_with_sdp(p, FALSE, TRUE);
 	} else {
@@ -26761,7 +26760,7 @@
 
 
 /*! \brief Session-Timers: Function for parsing Session-Expires header */
-int parse_session_expires(const char *p_hdrval, int *const p_interval, enum st_refresher *const p_ref)
+int parse_session_expires(const char *p_hdrval, int *const p_interval, enum st_refresher_param *const p_ref)
 {
 	char *p_token;
 	int  ref_idx;
@@ -26772,7 +26771,7 @@
 		return -1;
 	}
 
-	*p_ref = SESSION_TIMER_REFRESHER_AUTO;
+	*p_ref = SESSION_TIMER_REFRESHER_PARAM_UNKNOWN;
 	*p_interval = 0;
 
 	p_se_hdr = ast_strdupa(p_hdrval);
@@ -26797,10 +26796,10 @@
 			p_se_hdr = ast_skip_blanks(p_se_hdr);
 
 			if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) {
-				*p_ref = SESSION_TIMER_REFRESHER_UAC;
+				*p_ref = SESSION_TIMER_REFRESHER_PARAM_UAC;
 				ast_debug(2, "Refresher: UAC\n");
 			} else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) {
-				*p_ref = SESSION_TIMER_REFRESHER_UAS;
+				*p_ref = SESSION_TIMER_REFRESHER_PARAM_UAS;
 				ast_debug(2, "Refresher: UAS\n");
 			} else {
 				ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr);
@@ -26872,20 +26871,24 @@
 
 
 /*! \brief Get the entity (UAC or UAS) that's acting as the session-timer refresher
+ * \note This is only called when processing an INVITE, so in that case Asterisk is
+ *       always currently the UAS. If this is ever used to process responses, the
+ *       function will have to be changed.
  * \param p pointer to the SIP dialog
 */
 enum st_refresher st_get_refresher(struct sip_pvt *p)
 {
-	if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO)
+	if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) {
 		return p->stimer->st_cached_ref;
+	}
 
 	if (p->relatedpeer) {
-		p->stimer->st_cached_ref = p->relatedpeer->stimer.st_ref;
+		p->stimer->st_cached_ref = (p->relatedpeer->stimer.st_ref == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US;
 		return p->stimer->st_cached_ref;
 	}
 	
-	p->stimer->st_cached_ref = global_st_refresher;
-	return global_st_refresher;
+	p->stimer->st_cached_ref = (global_st_refresher == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US;
+	return p->stimer->st_cached_ref;
 }
 
 
@@ -28320,7 +28323,7 @@
 					peer->stimer.st_min_se = global_min_se;
 				}
 			} else if (!strcasecmp(v->name, "session-refresher")) {
-				int i = (int) str2strefresher(v->value);
+				int i = (int) str2strefresherparam(v->value);
 				if (i < 0) {
 					ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
 					peer->stimer.st_ref = global_st_refresher;
@@ -28816,7 +28819,7 @@
 
 	/* Session-Timers */
 	global_st_mode = SESSION_TIMER_MODE_ACCEPT;
-	global_st_refresher = SESSION_TIMER_REFRESHER_UAS;
+	global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS;
 	global_min_se  = DEFAULT_MIN_SE;
 	global_max_se  = DEFAULT_MAX_SE;
 
@@ -29311,10 +29314,10 @@
 				global_min_se = DEFAULT_MIN_SE;
 			}
 		} else if (!strcasecmp(v->name, "session-refresher")) {
-			int i = (int) str2strefresher(v->value);
+			int i = (int) str2strefresherparam(v->value);
 			if (i < 0) {
 				ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
-				global_st_refresher = SESSION_TIMER_REFRESHER_UAS;
+				global_st_refresher = SESSION_TIMER_REFRESHER_PARAM_UAS;
 			} else {
 				global_st_refresher = i;
 			}
@@ -29733,7 +29736,8 @@
 
 	if (!(opp_chan = ast_bridged_channel(chan))) {
 		return NULL;
-	} else if ((opp_chan->tech != &sip_tech) || (!(opp = opp_chan->tech_pvt))) {
+	} else if (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
+		   (!(opp = opp_chan->tech_pvt))) {
 		return NULL;
 	}
 
@@ -29809,21 +29813,22 @@
 		return AST_RTP_GLUE_RESULT_FORBID;
 	}
 
-	if (!(opp_chan = ast_bridged_channel(chan))) {
+	if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
+						       (!(opp = opp_chan->tech_pvt)))) {
 		return AST_RTP_GLUE_RESULT_FORBID;
-	} else if ((opp_chan->tech != &sip_tech) || (!(opp = opp_chan->tech_pvt))) {
-		return AST_RTP_GLUE_RESULT_FORBID;
 	}
 
 	sip_pvt_lock(p);
-	while (sip_pvt_trylock(opp)) {
+	while (opp && sip_pvt_trylock(opp)) {
 		sip_pvt_unlock(p);
 		usleep(1);
 		sip_pvt_lock(p);
 	}
 
 	if (!(p->rtp)) {
-		sip_pvt_unlock(opp);
+		if (opp) {
+			sip_pvt_unlock(opp);
+		}
 		sip_pvt_unlock(p);
 		return AST_RTP_GLUE_RESULT_FORBID;
 	}
@@ -29833,7 +29838,7 @@
 
 	if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
 		res = AST_RTP_GLUE_RESULT_REMOTE;
-		if (!apply_directmedia_ha(p, opp, "audio")) {
+		if (opp && !apply_directmedia_ha(p, opp, "audio")) {
 			res = AST_RTP_GLUE_RESULT_FORBID;
 		}
 	} else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
@@ -29842,7 +29847,9 @@
 		res = AST_RTP_GLUE_RESULT_FORBID;
 	}
 
-	sip_pvt_unlock(opp);
+	if (opp) {
+		sip_pvt_unlock(opp);
+	}
 
 	if (p->srtp) {
 		res = AST_RTP_GLUE_RESULT_FORBID;
@@ -29864,21 +29871,22 @@
 		return AST_RTP_GLUE_RESULT_FORBID;
 	}
 
-	if (!(opp_chan = ast_bridged_channel(chan))) {
+	if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
+						       (!(opp = opp_chan->tech_pvt)))) {
 		return AST_RTP_GLUE_RESULT_FORBID;
-	} else if ((opp_chan->tech != &sip_tech) || (!(opp = opp_chan->tech_pvt))) {
-		return AST_RTP_GLUE_RESULT_FORBID;
 	}
 
 	sip_pvt_lock(p);
-	while (sip_pvt_trylock(opp)) {
+	while (opp && sip_pvt_trylock(opp)) {
 		sip_pvt_unlock(p);
 		usleep(1);
 		sip_pvt_lock(p);
 	}
 
 	if (!(p->vrtp)) {
-		sip_pvt_unlock(opp);
+		if (opp) {
+			sip_pvt_unlock(opp);
+		}
 		sip_pvt_unlock(p);
 		return AST_RTP_GLUE_RESULT_FORBID;
 	}
@@ -29888,12 +29896,14 @@
 
 	if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
 		res = AST_RTP_GLUE_RESULT_REMOTE;
-		if (!apply_directmedia_ha(p, opp, "video")) {
+		if (opp && !apply_directmedia_ha(p, opp, "video")) {
 			res = AST_RTP_GLUE_RESULT_FORBID;
 		}
 	}
 
-	sip_pvt_unlock(opp);
+	if (opp) {
+		sip_pvt_unlock(opp);
+	}
 	sip_pvt_unlock(p);
 
 	return res;
@@ -29910,21 +29920,22 @@
 		return AST_RTP_GLUE_RESULT_FORBID;
 	}
 
-	if (!(opp_chan = ast_bridged_channel(chan))) {
+	if ((opp_chan = ast_bridged_channel(chan)) && (((opp_chan->tech != &sip_tech) && (opp_chan->tech != &sip_tech_info)) ||
+						       (!(opp = opp_chan->tech_pvt)))) {
 		return AST_RTP_GLUE_RESULT_FORBID;
-	} else if ((opp_chan->tech != &sip_tech) || (!(opp = opp_chan->tech_pvt))) {
-		return AST_RTP_GLUE_RESULT_FORBID;
 	}
 
 	sip_pvt_lock(p);
-	while (sip_pvt_trylock(opp)) {
+	while (opp && sip_pvt_trylock(opp)) {
 		sip_pvt_unlock(p);
 		usleep(1);
 		sip_pvt_lock(p);
 	}
 
 	if (!(p->trtp)) {
-		sip_pvt_unlock(opp);
+		if (opp) {
+			sip_pvt_unlock(opp);
+		}
 		sip_pvt_unlock(p);
 		return AST_RTP_GLUE_RESULT_FORBID;
 	}
@@ -29934,12 +29945,14 @@
 
 	if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
 		res = AST_RTP_GLUE_RESULT_REMOTE;
-		if (!apply_directmedia_ha(p, opp, "text")) {
+		if (opp && !apply_directmedia_ha(p, opp, "text")) {
 			res = AST_RTP_GLUE_RESULT_FORBID;
 		}
 	}
 
-	sip_pvt_unlock(opp);
+	if (opp) {
+		sip_pvt_unlock(opp);
+	}
 	sip_pvt_unlock(p);
 
 	return res;

Modified: certified/branches/1.8.15/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/certified/branches/1.8.15/channels/sip/include/sip.h?view=diff&rev=375590&r1=375589&r2=375590
==============================================================================
--- certified/branches/1.8.15/channels/sip/include/sip.h (original)
+++ certified/branches/1.8.15/channels/sip/include/sip.h Fri Nov  2 10:27:56 2012
@@ -525,9 +525,15 @@
 
 /*! \brief The entity playing the refresher role for Session-Timers */
 enum st_refresher {
-        SESSION_TIMER_REFRESHER_AUTO,    /*!< Negotiated                      */
-        SESSION_TIMER_REFRESHER_UAC,     /*!< Session is refreshed by the UAC */
-        SESSION_TIMER_REFRESHER_UAS      /*!< Session is refreshed by the UAS */
+        SESSION_TIMER_REFRESHER_AUTO, /*!< Negotiated                      */
+        SESSION_TIMER_REFRESHER_US,   /*!< Initially prefer session refresh by Asterisk */
+        SESSION_TIMER_REFRESHER_THEM, /*!< Initially prefer session refresh by the other side */
+};
+
+enum st_refresher_param {
+	SESSION_TIMER_REFRESHER_PARAM_UNKNOWN,
+	SESSION_TIMER_REFRESHER_PARAM_UAC,
+	SESSION_TIMER_REFRESHER_PARAM_UAS,
 };
 
 /*! \brief Define some implemented SIP transports
@@ -901,14 +907,14 @@
 struct sip_st_dlg {
 	int st_active;                     /*!< Session-Timers on/off */
 	int st_interval;                   /*!< Session-Timers negotiated session refresh interval */
+	enum st_refresher st_ref;          /*!< Session-Timers cached refresher */
 	int st_schedid;                    /*!< Session-Timers ast_sched scheduler id */
-	enum st_refresher st_ref;          /*!< Session-Timers session refresher */
 	int st_expirys;                    /*!< Session-Timers number of expirys */
 	int st_active_peer_ua;             /*!< Session-Timers on/off in peer UA */
 	int st_cached_min_se;              /*!< Session-Timers cached Min-SE */
 	int st_cached_max_se;              /*!< Session-Timers cached Session-Expires */
 	enum st_mode st_cached_mode;       /*!< Session-Timers cached M.O. */
-	enum st_refresher st_cached_ref;   /*!< Session-Timers cached refresher */
+	enum st_refresher st_cached_ref;   /*!< Session-Timers session refresher */
 	unsigned char quit_flag:1;         /*!< Stop trying to lock; just quit */
 };
 
@@ -917,10 +923,10 @@
  *   of SIP Session-Timers feature on a per user/peer basis.
  */
 struct sip_st_cfg {
-	enum st_mode st_mode_oper;    /*!< Mode of operation for Session-Timers           */
-	enum st_refresher st_ref;     /*!< Session-Timer refresher                        */
-	int st_min_se;                /*!< Lowest threshold for session refresh interval  */
-	int st_max_se;                /*!< Highest threshold for session refresh interval */
+	enum st_mode st_mode_oper;      /*!< Mode of operation for Session-Timers           */
+	enum st_refresher_param st_ref; /*!< Session-Timer refresher                        */
+	int st_min_se;                  /*!< Lowest threshold for session refresh interval  */
+	int st_max_se;                  /*!< Highest threshold for session refresh interval */
 };
 
 /*! \brief Structure for remembering offered media in an INVITE, to make sure we reply

Modified: certified/branches/1.8.15/channels/sip/sdp_crypto.c
URL: http://svnview.digium.com/svn/asterisk/certified/branches/1.8.15/channels/sip/sdp_crypto.c?view=diff&rev=375590&r1=375589&r2=375590
==============================================================================
--- certified/branches/1.8.15/channels/sip/sdp_crypto.c (original)
+++ certified/branches/1.8.15/channels/sip/sdp_crypto.c Fri Nov  2 10:27:56 2012
@@ -49,6 +49,8 @@
 	char *a_crypto;
 	unsigned char local_key[SRTP_MASTER_LEN];
 	char local_key64[SRTP_MASTER_LEN64];
+	unsigned char remote_key[SRTP_MASTER_LEN];
+	char suite[64];
 };
 
 static int set_crypto_policy(struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, unsigned long ssrc, int inbound);
@@ -257,11 +259,19 @@
 		return -1;
 	}
 
-
 	if ((key_len = ast_base64decode(remote_key, key_salt, sizeof(remote_key))) != SRTP_MASTER_LEN) {
-		ast_log(LOG_WARNING, "SRTP sdescriptions key %d != %d\n", key_len, SRTP_MASTER_LEN);
-		return -1;
-	}
+		ast_log(LOG_WARNING, "SRTP descriptions key %d != %d\n", key_len, SRTP_MASTER_LEN);
+		return -1;
+	}
+
+	if (!memcmp(p->remote_key, remote_key, sizeof(p->remote_key))) {
+		ast_debug(1, "SRTP remote key unchanged; maintaining current policy\n");
+		return 0;
+	}
+
+	/* Set the accepted policy and remote key */
+	ast_copy_string(p->suite, suite, sizeof(p->suite));
+	memcpy(p->remote_key, remote_key, sizeof(p->remote_key));
 
 	if (sdp_crypto_activate(p, suite_val, remote_key, rtp) < 0) {
 		return -1;
@@ -280,13 +290,17 @@
 int sdp_crypto_offer(struct sdp_crypto *p)
 {
 	char crypto_buf[128];
-	const char *crypto_suite = "AES_CM_128_HMAC_SHA1_80"; /* Crypto offer */
+
+	if (ast_strlen_zero(p->suite)) {
+		/* Default crypto offer */
+		strcpy(p->suite, "AES_CM_128_HMAC_SHA1_80");
+	}
 
 	if (p->a_crypto) {
 		ast_free(p->a_crypto);
 	}
 
-	if (snprintf(crypto_buf, sizeof(crypto_buf), "a=crypto:1 %s inline:%s\r\n",  crypto_suite, p->local_key64) < 1) {
+	if (snprintf(crypto_buf, sizeof(crypto_buf), "a=crypto:1 %s inline:%s\r\n",  p->suite, p->local_key64) < 1) {
 		return -1;
 	}
 

Modified: certified/branches/1.8.15/configs/sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/certified/branches/1.8.15/configs/sip.conf.sample?view=diff&rev=375590&r1=375589&r2=375590
==============================================================================
--- certified/branches/1.8.15/configs/sip.conf.sample (original)
+++ certified/branches/1.8.15/configs/sip.conf.sample Fri Nov  2 10:27:56 2012
@@ -560,11 +560,20 @@
 ; * session-expires   - Maximum session refresh interval in seconds. Defaults to 1800 secs.
 ; * session-minse     - Minimum session refresh interval in seconds. Defualts to 90 secs.
 ; * session-refresher - The session refresher (uac|uas). Defaults to 'uas'.
+;                            uac - Default to the caller initially refreshing when possible
+;                            uas - Default to the callee initially refreshing when possible
+;
+; Note that, due to recommendations in RFC 4028, Asterisk will always honor the other
+; endpoint's preference for who will handle refreshes. Asterisk will never override the
+; preferences of the other endpoint. Doing so could result in Asterisk and the endpoint
+; fighting over who sends the refreshes. This holds true for the initiation of session
+; timers and subsequent re-INVITE requests whether Asterisk is the caller or callee, or
+; whether Asterisk is currently the refresher or not.
 ;
 ;session-timers=originate
 ;session-expires=600
 ;session-minse=90
-;session-refresher=uas
+;session-refresher=uac
 ;
 ;--------------------------- SIP DEBUGGING ---------------------------------------------------
 ;sipdebug = yes                 ; Turn on SIP debugging by default, from




More information about the asterisk-commits mailing list