[asterisk-commits] file: branch 1.4 r48472 - in /branches/1.4: include/asterisk/rtp.h main/rtp.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Dec 14 10:36:12 MST 2006


Author: file
Date: Thu Dec 14 11:36:12 2006
New Revision: 48472

URL: http://svn.digium.com/view/asterisk?view=rev&rev=48472
Log:
Payload values on the RTP structure can change AFTER a bridge has started. This comes from the packet handling of the SIP response when indication that it was answered has been sent. Therefore we need to protect this data with a lock when we read/write. (issue #8232 reported by tgrman)

Modified:
    branches/1.4/include/asterisk/rtp.h
    branches/1.4/main/rtp.c

Modified: branches/1.4/include/asterisk/rtp.h
URL: http://svn.digium.com/view/asterisk/branches/1.4/include/asterisk/rtp.h?view=diff&rev=48472&r1=48471&r2=48472
==============================================================================
--- branches/1.4/include/asterisk/rtp.h (original)
+++ branches/1.4/include/asterisk/rtp.h Thu Dec 14 11:36:12 2006
@@ -156,7 +156,7 @@
 void ast_rtp_pt_default(struct ast_rtp* rtp);
 
 /*! \brief Copy payload types between RTP structures */
-void ast_rtp_pt_copy(struct ast_rtp *dest, const struct ast_rtp *src);
+void ast_rtp_pt_copy(struct ast_rtp *dest, struct ast_rtp *src);
 
 void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt);
 void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,

Modified: branches/1.4/main/rtp.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/main/rtp.c?view=diff&rev=48472&r1=48471&r2=48472
==============================================================================
--- branches/1.4/main/rtp.c (original)
+++ branches/1.4/main/rtp.c Thu Dec 14 11:36:12 2006
@@ -160,10 +160,13 @@
 	struct io_context *io;
 	void *data;
 	ast_rtp_callback callback;
+
+	ast_mutex_t payload_lock;
 	struct rtpPayloadType current_RTP_PT[MAX_RTP_PT];
 	int rtp_lookup_code_cache_isAstFormat; /*!< a cache for the result of rtp_lookup_code(): */
 	int rtp_lookup_code_cache_code;
 	int rtp_lookup_code_cache_result;
+
 	struct ast_rtcp *rtcp;
 	struct ast_codec_pref pref;
 	struct ast_rtp *bridged;        /*!< Who we are Packet bridged to */
@@ -1355,8 +1358,11 @@
 void ast_rtp_pt_clear(struct ast_rtp* rtp) 
 {
 	int i;
+
 	if (!rtp)
 		return;
+
+	ast_mutex_lock(&rtp->payload_lock);
 
 	for (i = 0; i < MAX_RTP_PT; ++i) {
 		rtp->current_RTP_PT[i].isAstFormat = 0;
@@ -1366,11 +1372,15 @@
 	rtp->rtp_lookup_code_cache_isAstFormat = 0;
 	rtp->rtp_lookup_code_cache_code = 0;
 	rtp->rtp_lookup_code_cache_result = 0;
+
+	ast_mutex_unlock(&rtp->payload_lock);
 }
 
 void ast_rtp_pt_default(struct ast_rtp* rtp) 
 {
 	int i;
+
+	ast_mutex_lock(&rtp->payload_lock);
 
 	/* Initialize to default payload types */
 	for (i = 0; i < MAX_RTP_PT; ++i) {
@@ -1381,11 +1391,16 @@
 	rtp->rtp_lookup_code_cache_isAstFormat = 0;
 	rtp->rtp_lookup_code_cache_code = 0;
 	rtp->rtp_lookup_code_cache_result = 0;
-}
-
-void ast_rtp_pt_copy(struct ast_rtp *dest, const struct ast_rtp *src)
+
+	ast_mutex_unlock(&rtp->payload_lock);
+}
+
+void ast_rtp_pt_copy(struct ast_rtp *dest, struct ast_rtp *src)
 {
 	unsigned int i;
+
+	ast_mutex_lock(&dest->payload_lock);
+	ast_mutex_lock(&src->payload_lock);
 
 	for (i=0; i < MAX_RTP_PT; ++i) {
 		dest->current_RTP_PT[i].isAstFormat = 
@@ -1396,6 +1411,9 @@
 	dest->rtp_lookup_code_cache_isAstFormat = 0;
 	dest->rtp_lookup_code_cache_code = 0;
 	dest->rtp_lookup_code_cache_result = 0;
+
+	ast_mutex_unlock(&src->payload_lock);
+	ast_mutex_unlock(&dest->payload_lock);
 }
 
 /*! \brief Get channel driver interface structure */
@@ -1561,11 +1579,12 @@
  */
 void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) 
 {
-	if (pt < 0 || pt > MAX_RTP_PT) 
+	if (pt < 0 || pt > MAX_RTP_PT || static_RTP_PT[pt].code == 0) 
 		return; /* bogus payload type */
 
-	if (static_RTP_PT[pt].code != 0) 
-		rtp->current_RTP_PT[pt] = static_RTP_PT[pt];
+	ast_mutex_lock(&rtp->payload_lock);
+	rtp->current_RTP_PT[pt] = static_RTP_PT[pt];
+	ast_mutex_unlock(&rtp->payload_lock);
 } 
 
 /*! \brief Make a note of a RTP payload type (with MIME type) that was seen in
@@ -1579,6 +1598,8 @@
 
 	if (pt < 0 || pt > MAX_RTP_PT) 
 		return; /* bogus payload type */
+	
+	ast_mutex_lock(&rtp->payload_lock);
 
 	for (i = 0; i < sizeof(mimeTypes)/sizeof(mimeTypes[0]); ++i) {
 		if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 &&
@@ -1588,17 +1609,24 @@
 			    mimeTypes[i].payloadType.isAstFormat &&
 			    (options & AST_RTP_OPT_G726_NONSTANDARD))
 				rtp->current_RTP_PT[pt].code = AST_FORMAT_G726_AAL2;
-			return;
-		}
-	}
+			break;
+		}
+	}
+
+	ast_mutex_unlock(&rtp->payload_lock);
+
+	return;
 } 
 
 /*! \brief Return the union of all of the codecs that were set by rtp_set...() calls 
  * They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */
 void ast_rtp_get_current_formats(struct ast_rtp* rtp,
-			     int* astFormats, int* nonAstFormats) {
+				 int* astFormats, int* nonAstFormats)
+{
 	int pt;
-
+	
+	ast_mutex_lock(&rtp->payload_lock);
+	
 	*astFormats = *nonAstFormats = 0;
 	for (pt = 0; pt < MAX_RTP_PT; ++pt) {
 		if (rtp->current_RTP_PT[pt].isAstFormat) {
@@ -1607,6 +1635,10 @@
 			*nonAstFormats |= rtp->current_RTP_PT[pt].code;
 		}
 	}
+	
+	ast_mutex_unlock(&rtp->payload_lock);
+	
+	return;
 }
 
 struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt) 
@@ -1614,28 +1646,35 @@
 	struct rtpPayloadType result;
 
 	result.isAstFormat = result.code = 0;
+
 	if (pt < 0 || pt > MAX_RTP_PT) 
 		return result; /* bogus payload type */
 
 	/* Start with negotiated codecs */
+	ast_mutex_lock(&rtp->payload_lock);
 	result = rtp->current_RTP_PT[pt];
+	ast_mutex_unlock(&rtp->payload_lock);
 
 	/* If it doesn't exist, check our static RTP type list, just in case */
 	if (!result.code) 
 		result = static_RTP_PT[pt];
+
 	return result;
 }
 
 /*! \brief Looks up an RTP code out of our *static* outbound list */
-int ast_rtp_lookup_code(struct ast_rtp* rtp, const int isAstFormat, const int code) {
-
-	int pt;
+int ast_rtp_lookup_code(struct ast_rtp* rtp, const int isAstFormat, const int code)
+{
+	int pt = 0;
+
+	ast_mutex_lock(&rtp->payload_lock);
 
 	if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat &&
 		code == rtp->rtp_lookup_code_cache_code) {
-
 		/* Use our cached mapping, to avoid the overhead of the loop below */
-		return rtp->rtp_lookup_code_cache_result;
+		pt = rtp->rtp_lookup_code_cache_result;
+		ast_mutex_unlock(&rtp->payload_lock);
+		return pt;
 	}
 
 	/* Check the dynamic list first */
@@ -1644,6 +1683,7 @@
 			rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
 			rtp->rtp_lookup_code_cache_code = code;
 			rtp->rtp_lookup_code_cache_result = pt;
+			ast_mutex_unlock(&rtp->payload_lock);
 			return pt;
 		}
 	}
@@ -1654,9 +1694,13 @@
 			rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
   			rtp->rtp_lookup_code_cache_code = code;
 			rtp->rtp_lookup_code_cache_result = pt;
+			ast_mutex_unlock(&rtp->payload_lock);
 			return pt;
 		}
 	}
+
+	ast_mutex_unlock(&rtp->payload_lock);
+
 	return -1;
 }
 
@@ -1765,6 +1809,9 @@
 	
 	if (!(rtp = ast_calloc(1, sizeof(*rtp))))
 		return NULL;
+
+	ast_mutex_init(&rtp->payload_lock);
+
 	rtp->them.sin_family = AF_INET;
 	rtp->us.sin_family = AF_INET;
 	rtp->s = rtp_socket();
@@ -1985,6 +2032,9 @@
 		free(rtp->rtcp);
 		rtp->rtcp=NULL;
 	}
+
+	ast_mutex_destroy(&rtp->payload_lock);
+
 	free(rtp);
 }
 



More information about the asterisk-commits mailing list