[asterisk-commits] file: branch file/strictrtp r99340 - in /team/file/strictrtp: configs/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 22 10:39:38 CST 2008


Author: file
Date: Mon Jan 21 10:56:07 2008
New Revision: 99340

URL: http://svn.digium.com/view/asterisk?view=rev&rev=99340
Log:
Add in actual strict RTP protection code. This will learn the remote address and drop RTP packets that did not come from it if enabled.

Modified:
    team/file/strictrtp/configs/rtp.conf.sample
    team/file/strictrtp/main/rtp.c

Change Statistics:
 team/file/strictrtp/configs/rtp.conf.sample |    4 ++
 team/file/strictrtp/main/rtp.c              |   32 ++++++++++++++++
 2 files changed, 36 insertions(+)

Modified: team/file/strictrtp/configs/rtp.conf.sample
URL: http://svn.digium.com/view/asterisk/team/file/strictrtp/configs/rtp.conf.sample?view=diff&rev=99340&r1=99339&r2=99340
==============================================================================
--- team/file/strictrtp/configs/rtp.conf.sample (original)
+++ team/file/strictrtp/configs/rtp.conf.sample Mon Jan 21 10:56:07 2008
@@ -20,3 +20,7 @@
 ;dtmftimeout=3000
 ; rtcpinterval = 5000 	; Milliseconds between rtcp reports 
 			;(min 500, max 60000, default 5000)
+;
+; Enable strict RTP protection. This will drop RTP packets that
+; do not come from the source of the RTP stream.
+; strictrtp=yes

Modified: team/file/strictrtp/main/rtp.c
URL: http://svn.digium.com/view/asterisk/team/file/strictrtp/main/rtp.c?view=diff&rev=99340&r1=99339&r2=99340
==============================================================================
--- team/file/strictrtp/main/rtp.c (original)
+++ team/file/strictrtp/main/rtp.c Mon Jan 21 10:56:07 2008
@@ -78,6 +78,13 @@
 #ifdef SO_NO_CHECK
 static int nochecksums;
 #endif
+static int strictrtp;
+
+enum strict_rtp_state {
+	STRICT_RTP_OPEN = 0, /*! No RTP packets should be dropped, all sources accepted */
+	STRICT_RTP_LEARN,    /*! Accept next packet as source */
+	STRICT_RTP_CLOSED,   /*! Drop all RTP packets not coming from source that was learned */
+};
 
 /* Uncomment this to enable more intense native bridging, but note: this is currently buggy */
 /* #define P2P_INTENSE */
@@ -165,6 +172,9 @@
 	struct ast_rtcp *rtcp;
 	struct ast_codec_pref pref;
 	struct ast_rtp *bridged;        /*!< Who we are Packet bridged to */
+
+	enum strict_rtp_state strict_rtp_state; /*!< Current state that strict RTP protection is in */
+	struct sockaddr_in strict_rtp_address;  /*!< Remote address information for strict RTP purposes */
 };
 
 /* Forward declarations */
@@ -1391,6 +1401,21 @@
 	res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
 					0, (struct sockaddr *)&sin, &len);
 
+	/* If strict RTP protection is enabled see if we need to learn this address or if the packet should be dropped */
+	if (rtp->strict_rtp_state == STRICT_RTP_LEARN) {
+		/* Copy over address that this packet was received on */
+		memcpy(&rtp->strict_rtp_address, &sin, sizeof(rtp->strict_rtp_address));
+		/* Now move over to actually protecting the RTP port */
+		rtp->strict_rtp_state = STRICT_RTP_CLOSED;
+		ast_debug(1, "Learned remote address is %s:%d for strict RTP purposes, now protecting the port.\n", ast_inet_ntoa(rtp->strict_rtp_address.sin_addr), ntohs(rtp->strict_rtp_address.sin_port));
+	} else if (rtp->strict_rtp_state == STRICT_RTP_CLOSED) {
+		/* If the address we previously learned doesn't match the address this packet came in on simply drop it */
+		if ((rtp->strict_rtp_address.sin_addr.s_addr != sin.sin_addr.s_addr) || (rtp->strict_rtp_address.sin_port != sin.sin_port)) {
+			ast_debug(1, "Received RTP packet from %s:%d, dropping due to strict RTP protection. Expected it to be from %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), ast_inet_ntoa(rtp->strict_rtp_address.sin_addr), ntohs(rtp->strict_rtp_address.sin_port));
+			return &ast_null_frame;
+		}
+	}
+
 	rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
 	if (res < 0) {
 		if (errno == EBADF)
@@ -2191,6 +2216,7 @@
 	rtp->ssrc = ast_random();
 	rtp->seqno = ast_random() & 0xffff;
 	ast_set_flag(rtp, FLAG_HAS_DTMF);
+	rtp->strict_rtp_state = (strictrtp ? STRICT_RTP_LEARN : STRICT_RTP_OPEN);
 
 	return;
 }
@@ -2312,6 +2338,9 @@
 		rtp->rtcp->them.sin_addr = them->sin_addr;
 	}
 	rtp->rxseqno = 0;
+	/* If strict RTP protection is enabled switch back to the learn state so we don't drop packets from above */
+	if (strictrtp)
+		rtp->strict_rtp_state = STRICT_RTP_LEARN;
 }
 
 int ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
@@ -4068,6 +4097,9 @@
 				dtmftimeout = DEFAULT_DTMF_TIMEOUT;
 			};
 		}
+		if ((s = ast_variable_retrieve(cfg, "general", "strictrtp"))) {
+			strictrtp = ast_true(s);
+		}
 		ast_config_destroy(cfg);
 	}
 	if (rtpstart >= rtpend) {




More information about the asterisk-commits mailing list