<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/9474">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">protocol: reject illegal lco options<br><br>At the moment osmo-mgw will accept multiple lco options. (e.g.<br>p:10, a:PCMU, p:10) If LCO appear multiple times, than the first<br>appearance of will be parsed and used, all following appearances<br>will be ignored. However, having multiple appearances of LCO is<br>illegal and affected requests should be rejected. Also osmo-mgw<br>should reject illegal formatted LCO strings<br><br>- make sure that multiple appearances of LCOs will be rejected<br>- make sure that illegal formated LCOs are rejected<br>- add testcases with garbeled LCO and valid LCO examples<br><br>Change-Id: Iae2fddfa5f2bcfc952f8ab217b3056694e5f7812<br>Closes: OS#3119<br>---<br>M include/osmocom/mgcp/mgcp_internal.h<br>M src/libosmo-mgcp/mgcp_protocol.c<br>M tests/mgcp/mgcp_test.c<br>M tests/mgcp/mgcp_test.ok<br>4 files changed, 244 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/mgcp/mgcp_internal.h b/include/osmocom/mgcp/mgcp_internal.h</span><br><span>index 7a00c98..bff7da0 100644</span><br><span>--- a/include/osmocom/mgcp/mgcp_internal.h</span><br><span>+++ b/include/osmocom/mgcp/mgcp_internal.h</span><br><span>@@ -282,6 +282,8 @@</span><br><span> struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int index);</span><br><span> struct mgcp_trunk_config *mgcp_trunk_num(struct mgcp_config *cfg, int index);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+char *get_lco_identifier(const char *options);</span><br><span style="color: hsl(120, 100%, 40%);">+int check_local_cx_options(void *ctx, const char *options);</span><br><span> void mgcp_rtp_end_config(struct mgcp_endpoint *endp, int expect_ssrc_change,</span><br><span>                        struct mgcp_rtp_end *rtp);</span><br><span> uint32_t mgcp_rtp_packet_duration(struct mgcp_endpoint *endp,</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>index ded1552..21f6cf3 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_protocol.c</span><br><span>@@ -395,6 +395,121 @@</span><br><span>    return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Helper function for check_local_cx_options() to get a pointer of the next</span><br><span style="color: hsl(120, 100%, 40%);">+ *  lco option identifier</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] lco string</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns pointer to the beginning of the LCO identifier, NULL on failure */</span><br><span style="color: hsl(120, 100%, 40%);">+char *get_lco_identifier(const char *options)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   char *ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned int count = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Jump to the end of the lco identifier */</span><br><span style="color: hsl(120, 100%, 40%);">+   ptr = strstr(options, ":");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ptr)</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Walk backwards until the pointer points to the beginning of the</span><br><span style="color: hsl(120, 100%, 40%);">+     * lco identifier. We know that we stand at the beginning when we</span><br><span style="color: hsl(120, 100%, 40%);">+      * are either at the beginning of the memory or see a space or</span><br><span style="color: hsl(120, 100%, 40%);">+         * comma. (this is tolerant, it will accept a:10, b:11 as well as</span><br><span style="color: hsl(120, 100%, 40%);">+      * a:10,b:11) */</span><br><span style="color: hsl(120, 100%, 40%);">+      while (1) {</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Endless loop protection */</span><br><span style="color: hsl(120, 100%, 40%);">+         if (count > 10000)</span><br><span style="color: hsl(120, 100%, 40%);">+                 return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+          else if (ptr < options || *ptr == ' ' || *ptr == ',') {</span><br><span style="color: hsl(120, 100%, 40%);">+                    ptr++;</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             ptr--;</span><br><span style="color: hsl(120, 100%, 40%);">+                count++;</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%);">+   /* Check if we got any result */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (*ptr == ':')</span><br><span style="color: hsl(120, 100%, 40%);">+              return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return ptr;</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%);">+/*! Check the LCO option. This function checks for multiple appearence of LCO</span><br><span style="color: hsl(120, 100%, 40%);">+ *  options, which is illegal</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] ctx talloc context</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] lco string</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success, -1 on failure */</span><br><span style="color: hsl(120, 100%, 40%);">+int check_local_cx_options(void *ctx, const char *options)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        char *options_copy;</span><br><span style="color: hsl(120, 100%, 40%);">+   char *lco_identifier;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *lco_identifier_end;</span><br><span style="color: hsl(120, 100%, 40%);">+     char *next_lco_identifier;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  char **lco_seen;</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int lco_seen_n = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!options)</span><br><span style="color: hsl(120, 100%, 40%);">+         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  lco_seen =</span><br><span style="color: hsl(120, 100%, 40%);">+        (char **)talloc_zero_size(ctx, strlen(options) * sizeof(char *));</span><br><span style="color: hsl(120, 100%, 40%);">+ options_copy = talloc_strdup(ctx, options);</span><br><span style="color: hsl(120, 100%, 40%);">+   lco_identifier = options_copy;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      do {</span><br><span style="color: hsl(120, 100%, 40%);">+          /* Move the lco_identifier pointer to the beginning of the</span><br><span style="color: hsl(120, 100%, 40%);">+             * current lco option identifier */</span><br><span style="color: hsl(120, 100%, 40%);">+           lco_identifier = get_lco_identifier(lco_identifier);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!lco_identifier)</span><br><span style="color: hsl(120, 100%, 40%);">+                  goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* Look ahead to the next LCO option early, since we</span><br><span style="color: hsl(120, 100%, 40%);">+           * will parse destructively */</span><br><span style="color: hsl(120, 100%, 40%);">+                next_lco_identifier = strstr(lco_identifier + 1, ",");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Pinch off the end of the lco field identifier name</span><br><span style="color: hsl(120, 100%, 40%);">+          * and see if we still got something, also check if</span><br><span style="color: hsl(120, 100%, 40%);">+            * there is some value after the colon. */</span><br><span style="color: hsl(120, 100%, 40%);">+            lco_identifier_end = strstr(lco_identifier, ":");</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!lco_identifier_end)</span><br><span style="color: hsl(120, 100%, 40%);">+                      goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+           if (*(lco_identifier_end + 1) == ' '</span><br><span style="color: hsl(120, 100%, 40%);">+              || *(lco_identifier_end + 1) == ','</span><br><span style="color: hsl(120, 100%, 40%);">+                   || *(lco_identifier_end + 1) == '\0')</span><br><span style="color: hsl(120, 100%, 40%);">+                     goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+           *lco_identifier_end = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+           if (strlen(lco_identifier) == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                      goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* Check if we have already seen the current field identifier</span><br><span style="color: hsl(120, 100%, 40%);">+          * before. If yes, we must bail, an LCO must only appear once</span><br><span style="color: hsl(120, 100%, 40%);">+          * in the LCO string */</span><br><span style="color: hsl(120, 100%, 40%);">+               for (i = 0; i < lco_seen_n; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (strcmp(lco_seen[i], lco_identifier) == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                         goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+             lco_seen[lco_seen_n] = lco_identifier;</span><br><span style="color: hsl(120, 100%, 40%);">+                lco_seen_n++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               /* The first identifier must always be found at the beginnning</span><br><span style="color: hsl(120, 100%, 40%);">+                 * of the LCO string */</span><br><span style="color: hsl(120, 100%, 40%);">+               if (lco_seen[0] != options_copy)</span><br><span style="color: hsl(120, 100%, 40%);">+                      goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* Go to the next lco option */</span><br><span style="color: hsl(120, 100%, 40%);">+               lco_identifier = next_lco_identifier;</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (lco_identifier);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   talloc_free(lco_seen);</span><br><span style="color: hsl(120, 100%, 40%);">+        talloc_free(options_copy);</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+error:</span><br><span style="color: hsl(120, 100%, 40%);">+     talloc_free(lco_seen);</span><br><span style="color: hsl(120, 100%, 40%);">+        talloc_free(options_copy);</span><br><span style="color: hsl(120, 100%, 40%);">+    return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Set the LCO from a string (see RFC 3435).</span><br><span>  * The string is stored in the 'string' field. A NULL string is handled exactly</span><br><span>  * like an empty string, the 'string' field is never NULL after this function</span><br><span>@@ -410,9 +525,16 @@</span><br><span>   if (strlen(options) == 0)</span><br><span>            return 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   talloc_free(lco->string);</span><br><span style="color: hsl(0, 100%, 40%);">-    lco->string = talloc_strdup(ctx, options ? options : "");</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Make sure the encoding of the LCO is consistant before we proceed */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (check_local_cx_options(ctx, options) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DLMGCP, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+                   "local CX options: Internal inconsistency in Local Connection Options!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+            return 524;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(lco->string);</span><br><span style="color: hsl(120, 100%, 40%);">+  lco->string = talloc_strdup(ctx, options);</span><br><span style="color: hsl(120, 100%, 40%);">+ </span><br><span>     p_opt = strstr(lco->string, "p:");</span><br><span>      if (p_opt && sscanf(p_opt, "p:%d-%d",</span><br><span>                          &lco->pkt_period_min, &lco->pkt_period_max) == 1)</span><br><span>diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c</span><br><span>index 4dce64c..3fc8bc0 100644</span><br><span>--- a/tests/mgcp/mgcp_test.c</span><br><span>+++ b/tests/mgcp/mgcp_test.c</span><br><span>@@ -1465,6 +1465,108 @@</span><br><span>   .num_cat = ARRAY_SIZE(log_categories),</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void test_get_lco_identifier(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        char *test;</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("Testing get_lco_identifier()\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Normal case at the beginning */</span><br><span style="color: hsl(120, 100%, 40%);">+    test = "p:10, a:PCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("%s -> %s\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  test = "p:10, a:PCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("%s -> %s\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Begin parsing in the middle of the value part of</span><br><span style="color: hsl(120, 100%, 40%);">+    * the previous LCO option value */</span><br><span style="color: hsl(120, 100%, 40%);">+   test = "XXXX, p:10, a:PCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("'%s' -> '%s'\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      test = "XXXX,p:10,a:PCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("'%s' -> '%s'\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      test = "10,a:PCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("'%s' -> '%s'\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      test = "10, a:PCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("'%s' -> '%s'\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      test = "10,a: PCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("'%s' -> '%s'\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      test = "10 ,a: PCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("'%s' -> '%s'\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Begin parsing right at the end of the previous LCO</span><br><span style="color: hsl(120, 100%, 40%);">+  * option value */</span><br><span style="color: hsl(120, 100%, 40%);">+    test = ", a:PCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("'%s' -> '%s'\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      test = " a:PCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("'%s' -> '%s'\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Empty string, result should be (null) */</span><br><span style="color: hsl(120, 100%, 40%);">+   test = "";</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("'%s' -> '%s'\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Missing colons, result should be (null) */</span><br><span style="color: hsl(120, 100%, 40%);">+ test = "p10, aPCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("%s -> %s\n", test, get_lco_identifier(test));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Colon separated from the identifier, result should be (null) */</span><br><span style="color: hsl(120, 100%, 40%);">+    test = "10,a :PCMU";</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("'%s' -> '%s'\n", test, get_lco_identifier(test));</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%);">+static void test_check_local_cx_options(void *ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Legal cases */</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:PCMU") == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(check_local_cx_options(ctx, "a:PCMU") == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(check_local_cx_options(ctx, "a:PCMU, p:10, IN:10") == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(check_local_cx_options(ctx, "one:AAA, two:BB, tree:C") ==</span><br><span style="color: hsl(120, 100%, 40%);">+                   0);</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:PCMU") == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:G726-32") == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_ASSERT(check_local_cx_options(ctx, "p:10-20, b:64") == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(check_local_cx_options(ctx, "b:32-64, e:off") == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:PCMU;G726-32") == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Illegal spaces before and after colon */</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_ASSERT(check_local_cx_options(ctx, "a:PCMU, p :10") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(check_local_cx_options(ctx, "a :PCMU, p:10") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(check_local_cx_options(ctx, "p: 10, a:PCMU") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Check if multiple appearances of LCOs are rejected */</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:PCMU, p:10") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:PCMU, a:PCMU, p:10") ==</span><br><span style="color: hsl(120, 100%, 40%);">+                -1);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(check_local_cx_options(ctx, "p:10, p:10") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Check if empty LCO are rejected */</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(check_local_cx_options(ctx, "p: , a:PCMU") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(check_local_cx_options(ctx, "p: , a: PCMU") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a: PCMU") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(check_local_cx_options(ctx, "p:, a:PCMU") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Garbeled beginning and ends */</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(check_local_cx_options(ctx, ":10, a:10") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(check_local_cx_options(ctx, "10, a:PCMU") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(check_local_cx_options(ctx, ", a:PCMU") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(check_local_cx_options(ctx, " a:PCMU") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_ASSERT(check_local_cx_options(ctx, "a:PCMU,") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_ASSERT(check_local_cx_options(ctx, "a:PCMU, ") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Illegal strings */</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(check_local_cx_options(ctx, " ") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(check_local_cx_options(ctx, "") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(check_local_cx_options(ctx, "AAA") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(check_local_cx_options(ctx, ":,") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(check_local_cx_options(ctx, ",:") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(check_local_cx_options(ctx, ",,,") == -1);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span>        void *ctx = talloc_named_const(NULL, 0, "mgcp_test");</span><br><span>@@ -1486,6 +1588,8 @@</span><br><span>      test_no_cycle();</span><br><span>     test_no_name();</span><br><span>      test_osmux_cid();</span><br><span style="color: hsl(120, 100%, 40%);">+     test_get_lco_identifier();</span><br><span style="color: hsl(120, 100%, 40%);">+    test_check_local_cx_options(ctx);</span><br><span> </span><br><span>        OSMO_ASSERT(talloc_total_size(msgb_ctx) == 0);</span><br><span>       OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1);</span><br><span>diff --git a/tests/mgcp/mgcp_test.ok b/tests/mgcp/mgcp_test.ok</span><br><span>index d2879ad..e293533 100644</span><br><span>--- a/tests/mgcp/mgcp_test.ok</span><br><span>+++ b/tests/mgcp/mgcp_test.ok</span><br><span>@@ -1104,4 +1104,18 @@</span><br><span> checking response:</span><br><span> using message with patched conn_id for comparison</span><br><span> Response matches our expectations.</span><br><span style="color: hsl(120, 100%, 40%);">+Testing get_lco_identifier()</span><br><span style="color: hsl(120, 100%, 40%);">+p:10, a:PCMU -> p:10, a:PCMU</span><br><span style="color: hsl(120, 100%, 40%);">+p:10, a:PCMU -> p:10, a:PCMU</span><br><span style="color: hsl(120, 100%, 40%);">+'XXXX, p:10, a:PCMU' -> 'p:10, a:PCMU'</span><br><span style="color: hsl(120, 100%, 40%);">+'XXXX,p:10,a:PCMU' -> 'p:10,a:PCMU'</span><br><span style="color: hsl(120, 100%, 40%);">+'10,a:PCMU' -> 'a:PCMU'</span><br><span style="color: hsl(120, 100%, 40%);">+'10, a:PCMU' -> 'a:PCMU'</span><br><span style="color: hsl(120, 100%, 40%);">+'10,a: PCMU' -> 'a: PCMU'</span><br><span style="color: hsl(120, 100%, 40%);">+'10 ,a: PCMU' -> 'a: PCMU'</span><br><span style="color: hsl(120, 100%, 40%);">+', a:PCMU' -> 'a:PCMU'</span><br><span style="color: hsl(120, 100%, 40%);">+' a:PCMU' -> 'a:PCMU'</span><br><span style="color: hsl(120, 100%, 40%);">+'' -> '(null)'</span><br><span style="color: hsl(120, 100%, 40%);">+p10, aPCMU -> (null)</span><br><span style="color: hsl(120, 100%, 40%);">+'10,a :PCMU' -> '(null)'</span><br><span> Done</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/9474">change 9474</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.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.osmocom.org/9474"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-mgw </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Iae2fddfa5f2bcfc952f8ab217b3056694e5f7812 </div>
<div style="display:none"> Gerrit-Change-Number: 9474 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>