<p>Benjamin Keith Ford has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/10246">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_rtp_asterisk.c: Add "seqno" strictrtp option<br><br>When networks experience disruptions, there can be large gaps of time<br>between receiving packets. When strictrtp is enabled, this created<br>issues where a flood of packets could come in and be seen as an attack.<br>Another option - seqno - has been added to the strictrtp option that<br>ignores the time interval and goes strictly by sequence number for<br>validity.<br><br>Change-Id: I8a42b8d193673899c8fc22fe7f98ea87df89be71<br>---<br>M CHANGES<br>M configs/samples/rtp.conf.sample<br>M res/res_rtp_asterisk.c<br>3 files changed, 63 insertions(+), 21 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/46/10246/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/CHANGES b/CHANGES</span><br><span>index 0398781..45c964e 100644</span><br><span>--- a/CHANGES</span><br><span>+++ b/CHANGES</span><br><span>@@ -9,6 +9,17 @@</span><br><span> ==============================================================================</span><br><span> </span><br><span> ------------------------------------------------------------------------------</span><br><span style="color: hsl(120, 100%, 40%);">+--- Functionality changes from Asterisk 13.23.0 to Asterisk 13.24.0 ----------</span><br><span style="color: hsl(120, 100%, 40%);">+------------------------------------------------------------------------------</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+res_rtp_asterisk</span><br><span style="color: hsl(120, 100%, 40%);">+------------------</span><br><span style="color: hsl(120, 100%, 40%);">+ * The existing strictrtp option in rtp.conf has a new choice availabe, called</span><br><span style="color: hsl(120, 100%, 40%);">+ 'seqno', which behaves the same way as setting strictrtp to 'yes', but will</span><br><span style="color: hsl(120, 100%, 40%);">+ ignore the time interval during learning so that bursts of packets can still</span><br><span style="color: hsl(120, 100%, 40%);">+ trigger learning our source.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+------------------------------------------------------------------------------</span><br><span> --- Functionality changes from Asterisk 13.22.0 to Asterisk 13.23.0 ----------</span><br><span> ------------------------------------------------------------------------------</span><br><span> </span><br><span>diff --git a/configs/samples/rtp.conf.sample b/configs/samples/rtp.conf.sample</span><br><span>index de9d590..26a70d2 100644</span><br><span>--- a/configs/samples/rtp.conf.sample</span><br><span>+++ b/configs/samples/rtp.conf.sample</span><br><span>@@ -31,6 +31,10 @@</span><br><span> ; seconds after starting learning mode. Once learning mode completes the</span><br><span> ; current stream is locked in and cannot change until the next</span><br><span> ; renegotiation.</span><br><span style="color: hsl(120, 100%, 40%);">+; Valid options are "no" to disable strictrtp, "yes" to enable strictrtp,</span><br><span style="color: hsl(120, 100%, 40%);">+; and "seqno", which does the same thing as strictrtp=yes, but only checks</span><br><span style="color: hsl(120, 100%, 40%);">+; to make sure the sequence number is correct rather than checking the time</span><br><span style="color: hsl(120, 100%, 40%);">+; interval as well.</span><br><span> ; This option is enabled by default.</span><br><span> ; strictrtp=yes</span><br><span> ;</span><br><span>diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c</span><br><span>index e562627..9641df7 100644</span><br><span>--- a/res/res_rtp_asterisk.c</span><br><span>+++ b/res/res_rtp_asterisk.c</span><br><span>@@ -149,6 +149,12 @@</span><br><span> STRICT_RTP_CLOSED, /*! Drop all RTP packets not coming from source that was learned */</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+enum strict_rtp_mode {</span><br><span style="color: hsl(120, 100%, 40%);">+ STRICT_RTP_NO = 0, /*! Don't adhere to any strict RTP rules */</span><br><span style="color: hsl(120, 100%, 40%);">+ STRICT_RTP_YES, /*! Strict RTP that restricts packets based on time and sequence number */</span><br><span style="color: hsl(120, 100%, 40%);">+ STRICT_RTP_SEQNO, /*! Strict RTP that restricts packets based on sequence number */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*!</span><br><span> * \brief Strict RTP learning timeout time in milliseconds</span><br><span> *</span><br><span>@@ -158,7 +164,7 @@</span><br><span> */</span><br><span> #define STRICT_RTP_LEARN_TIMEOUT 5000</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define DEFAULT_STRICT_RTP -1 /*!< Enabled */</span><br><span style="color: hsl(120, 100%, 40%);">+#define DEFAULT_STRICT_RTP STRICT_RTP_YES /*!< Enabled by default */</span><br><span> #define DEFAULT_ICESUPPORT 1</span><br><span> </span><br><span> extern struct ast_srtp_res *res_srtp;</span><br><span>@@ -182,6 +188,11 @@</span><br><span> static int strictrtp = DEFAULT_STRICT_RTP; /*!< Only accept RTP frames from a defined source. If we receive an indication of a changing source, enter learning mode. */</span><br><span> static int learning_min_sequential = DEFAULT_LEARNING_MIN_SEQUENTIAL; /*!< Number of sequential RTP frames needed from a single source during learning mode to accept new source. */</span><br><span> static int learning_min_duration = DEFAULT_LEARNING_MIN_DURATION; /*!< Lowest acceptable timeout between the first and the last sequential RTP frame. */</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef TEST_FRAMEWORK</span><br><span style="color: hsl(120, 100%, 40%);">+static int strict_rtp_test_event = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+static int strict_rtp_test_event = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span> #ifdef HAVE_PJPROJECT</span><br><span> static int icesupport = DEFAULT_ICESUPPORT;</span><br><span> static struct sockaddr_in stunaddr;</span><br><span>@@ -2834,27 +2845,30 @@</span><br><span> info->received = ast_tvnow();</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- switch (info->stream_type) {</span><br><span style="color: hsl(0, 100%, 40%);">- case AST_MEDIA_TYPE_UNKNOWN:</span><br><span style="color: hsl(0, 100%, 40%);">- case AST_MEDIA_TYPE_AUDIO:</span><br><span style="color: hsl(0, 100%, 40%);">- /*</span><br><span style="color: hsl(0, 100%, 40%);">- * Protect against packet floods by checking that we</span><br><span style="color: hsl(0, 100%, 40%);">- * received the packet sequence in at least the minimum</span><br><span style="color: hsl(0, 100%, 40%);">- * allowed time.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_tvzero(info->received)) {</span><br><span style="color: hsl(0, 100%, 40%);">- info->received = ast_tvnow();</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!info->packets</span><br><span style="color: hsl(0, 100%, 40%);">- && ast_tvdiff_ms(ast_tvnow(), info->received) < learning_min_duration) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Packet flood; reset */</span><br><span style="color: hsl(0, 100%, 40%);">- info->packets = learning_min_sequential - 1;</span><br><span style="color: hsl(0, 100%, 40%);">- info->received = ast_tvnow();</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Only check time if strictrtp is set to yes. Otherwise, we only needed to check seqno */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strictrtp == STRICT_RTP_YES) {</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (info->stream_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case AST_MEDIA_TYPE_UNKNOWN:</span><br><span style="color: hsl(120, 100%, 40%);">+ case AST_MEDIA_TYPE_AUDIO:</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Protect against packet floods by checking that we</span><br><span style="color: hsl(120, 100%, 40%);">+ * received the packet sequence in at least the minimum</span><br><span style="color: hsl(120, 100%, 40%);">+ * allowed time.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_tvzero(info->received)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ info->received = ast_tvnow();</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!info->packets</span><br><span style="color: hsl(120, 100%, 40%);">+ && ast_tvdiff_ms(ast_tvnow(), info->received) < learning_min_duration) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Packet flood; reset */</span><br><span style="color: hsl(120, 100%, 40%);">+ info->packets = learning_min_sequential - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ info->received = ast_tvnow();</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case AST_MEDIA_TYPE_VIDEO:</span><br><span style="color: hsl(120, 100%, 40%);">+ case AST_MEDIA_TYPE_IMAGE:</span><br><span style="color: hsl(120, 100%, 40%);">+ case AST_MEDIA_TYPE_TEXT:</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case AST_MEDIA_TYPE_VIDEO:</span><br><span style="color: hsl(0, 100%, 40%);">- case AST_MEDIA_TYPE_IMAGE:</span><br><span style="color: hsl(0, 100%, 40%);">- case AST_MEDIA_TYPE_TEXT:</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span> }</span><br><span> </span><br><span> info->max_seq = seq;</span><br><span>@@ -5431,6 +5445,8 @@</span><br><span> && STRICT_RTP_LEARN_TIMEOUT < ast_tvdiff_ms(ast_tvnow(), rtp->rtp_source_learn.start)) {</span><br><span> ast_verb(4, "%p -- Strict RTP learning complete - Locking on source address %s\n",</span><br><span> rtp, ast_sockaddr_stringify(&rtp->strict_rtp_address));</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_test_suite_event_notify("STRICT_RTP_LEARN", "Source: %s",</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sockaddr_stringify(&rtp->strict_rtp_address));</span><br><span> rtp->strict_rtp_state = STRICT_RTP_CLOSED;</span><br><span> } else {</span><br><span> struct ast_sockaddr target_address;</span><br><span>@@ -5517,6 +5533,11 @@</span><br><span> }</span><br><span> ast_debug(1, "%p -- Received RTP packet from %s, dropping due to strict RTP protection.\n",</span><br><span> rtp, ast_sockaddr_stringify(&addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strict_rtp_test_event) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_test_suite_event_notify("STRICT_RTP_CLOSED", "Source: %s",</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sockaddr_stringify(&addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ strict_rtp_test_event = 0; /* Only run this event once to prevent possible spam */</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> return &ast_null_frame;</span><br><span> case STRICT_RTP_OPEN:</span><br><span> break;</span><br><span>@@ -6652,6 +6673,12 @@</span><br><span> }</span><br><span> if ((s = ast_variable_retrieve(cfg, "general", "strictrtp"))) {</span><br><span> strictrtp = ast_true(s);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcasecmp(s, "seqno")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ strictrtp = STRICT_RTP_SEQNO;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (strictrtp == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Stick to enum values for consistency */</span><br><span style="color: hsl(120, 100%, 40%);">+ strictrtp = STRICT_RTP_YES;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> if ((s = ast_variable_retrieve(cfg, "general", "probation"))) {</span><br><span> if ((sscanf(s, "%d", &learning_min_sequential) != 1) || learning_min_sequential <= 1) {</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10246">change 10246</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/10246"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I8a42b8d193673899c8fc22fe7f98ea87df89be71 </div>
<div style="display:none"> Gerrit-Change-Number: 10246 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Benjamin Keith Ford <bford@digium.com> </div>