<p>Benjamin Keith Ford has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/10249">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, 65 insertions(+), 22 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/49/10249/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/CHANGES b/CHANGES</span><br><span>index 0a6db05..6196a6e 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 16.0.0 to Asterisk 16.1.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 15 to Asterisk 16 --------------------</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 c1aa275..249bbcd 100644</span><br><span>--- a/res/res_rtp_asterisk.c</span><br><span>+++ b/res/res_rtp_asterisk.c</span><br><span>@@ -157,6 +157,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>@@ -166,7 +172,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>@@ -190,6 +196,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>@@ -198,6 +209,7 @@</span><br><span> static pj_str_t turnusername;</span><br><span> static pj_str_t turnpassword;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static struct ast_ha *ice_blacklist = NULL;    /*!< Blacklisted ICE networks */</span><br><span> static ast_rwlock_t ice_blacklist_lock = AST_RWLOCK_INIT_VALUE;</span><br><span> </span><br><span>@@ -3154,28 +3166,31 @@</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%);">+             case AST_MEDIA_TYPE_END:</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%);">-       case AST_MEDIA_TYPE_END:</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>@@ -6733,6 +6748,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>@@ -6819,6 +6836,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>@@ -8103,6 +8125,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/10249">change 10249</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/10249"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </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: 10249 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Benjamin Keith Ford <bford@digium.com> </div>