Index: include/asterisk/rtp.h
===================================================================
--- include/asterisk/rtp.h	(revision 82568)
+++ include/asterisk/rtp.h	(working copy)
@@ -118,6 +118,17 @@
 struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode);
 
 /*!
+ * \brief Initializate a RTP session with a remote party.
+ *
+ * \param sched
+ * \param io
+ * \param rtcpenable
+ * \param callbackmode
+ * \returns A representation (structure) of an RTP session.
+ */
+struct ast_rtp *ast_remote_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode);
+
+/*!
  * \brief Initializate a RTP session using an in_addr structure.
  *
  * This fuction gets called by ast_rtp_new().
@@ -127,10 +138,15 @@
  * \param rtcpenable
  * \param callbackmode
  * \param in
+ * \param remotemode
  * \returns A representation (structure) of an RTP session.
  */
+struct ast_rtp *_ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr in, int remotemode);
+
 struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr in);
 
+struct ast_rtp *ast_remote_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr in);
+
 void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them);
 
 /* Copies from rtp to them and returns 1 if there was a change or 0 if it was already the same */
Index: main/rtp.c
===================================================================
--- main/rtp.c	(revision 82568)
+++ main/rtp.c	(working copy)
@@ -81,6 +81,8 @@
 
 static int rtpstart;			/*!< First port for RTP sessions (set in rtp.conf) */
 static int rtpend;			/*!< Last port for RTP sessions (set in rtp.conf) */
+static int remotertpstart;			/*!< First port for Remote RTP sessions (set in rtp.conf) */
+static int remotertpend;			/*!< Last port for Remote RTP sessions (set in rtp.conf) */
 static int rtpdebug;			/*!< Are we debugging? */
 static int rtcpdebug;			/*!< Are we debugging RTCP? */
 static int rtcpstats;			/*!< Are we debugging RTCP? */
@@ -2183,9 +2185,11 @@
 	return;
 }
 
-struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr)
+struct ast_rtp *_ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr, int remotemode)
 {
 	struct ast_rtp *rtp;
+	int start = remotemode ? remotertpstart : rtpstart;
+	int end = remotemode ? remotertpend : rtpend;
 	int x;
 	int startplace;
 	
@@ -2210,7 +2214,7 @@
 	 * next one, cannot be enforced in presence of a NAT box because the
 	 * mapping is not under our control.
 	 */
-	x = (ast_random() % (rtpend-rtpstart)) + rtpstart;
+	x = (ast_random() % (end-start)) + start;
 	x = x & ~1;		/* make it an even number */
 	startplace = x;		/* remember the starting point */
 	/* this is constant across the loop */
@@ -2251,8 +2255,8 @@
 		 * If we reach the starting point, then declare failure.
 		 */
 		x += 2;
-		if (x > rtpend)
-			x = (rtpstart + 1) & ~1;
+		if (x > end)
+			x = (start + 1) & ~1;
 		if (x == startplace) {
 			ast_log(LOG_ERROR, "No RTP ports remaining. Can't setup media stream for this call.\n");
 			goto fail;
@@ -2278,6 +2282,16 @@
 	return NULL;
 }
 
+struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr)
+{
+	return _ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, addr, 0);
+}
+
+struct ast_rtp *ast_remote_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr)
+{
+	return _ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, addr, 1);
+}
+
 struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode)
 {
 	struct in_addr ia;
@@ -2286,6 +2300,14 @@
 	return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia);
 }
 
+struct ast_rtp *ast_remote_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode)
+{
+	struct in_addr ia;
+
+	memset(&ia, 0, sizeof(ia));
+	return ast_remote_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia);
+}
+
 int ast_rtp_setqos(struct ast_rtp *rtp, int tos, int cos)
 {
 	return ast_netsock_set_qos(rtp->s, tos, cos);
@@ -4008,6 +4030,8 @@
 
 	rtpstart = 5000;
 	rtpend = 31000;
+	remotertpstart = rtpstart;
+	remotertpend = rtpend;
 	dtmftimeout = DEFAULT_DTMF_TIMEOUT;
 	if (cfg) {
 		if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
@@ -4024,6 +4048,20 @@
 			if (rtpend > 65535)
 				rtpend = 65535;
 		}
+		if ((s = ast_variable_retrieve(cfg, "general", "remotertpstart"))) {
+			remotertpstart = atoi(s);
+			if (remotertpstart < 1024)
+				remotertpstart = 1024;
+			if (remotertpstart > 65535)
+				remotertpstart = 65535;
+		}
+		if ((s = ast_variable_retrieve(cfg, "general", "remotertpend"))) {
+			remotertpend = atoi(s);
+			if (remotertpend < 1024)
+				remotertpend = 1024;
+			if (remotertpend > 65535)
+				remotertpend = 65535;
+		}
 		if ((s = ast_variable_retrieve(cfg, "general", "rtcpinterval"))) {
 			rtcpinterval = atoi(s);
 			if (rtcpinterval == 0)
@@ -4060,6 +4098,12 @@
 		rtpend = 31000;
 	}
 	ast_verb(2, "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend);
+	if (remotertpstart >= remotertpend) {
+		ast_log(LOG_WARNING, "Unreasonable values for Remote RTP start/end port in rtp.conf\n");
+		remotertpstart = rtpstart;
+		remotertpend = rtpend;
+	}
+	ast_verb(2, "Remote RTP Allocating from port range %d -> %d\n", remotertpstart, remotertpend);
 	return 0;
 }
 
