<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-mgw/+/18913">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  dexter: Looks good to me, but someone else must approve
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">refactor: use msgb to receive, pass and send RTP packets<br><br>Instead of numerous arguments (buf, len and context data), use a msgb, like<br>most other osmo programs do, with a msb->cb pointing at a context data struct.<br><br>This opens the future for adding/stripping IuUP header data from the msgb<br>easily.<br><br>(Checked to pass current ttcn3-mgw-tests.)<br><br>Change-Id: I3af40b63bc49f8636d4e7ea2f8f83bb67f6619ee<br>---<br>M include/osmocom/mgcp/mgcp_codec.h<br>M include/osmocom/mgcp/mgcp_endp.h<br>M include/osmocom/mgcp/mgcp_internal.h<br>M src/libosmo-mgcp/mgcp_codec.c<br>M src/libosmo-mgcp/mgcp_network.c<br>M src/libosmo-mgcp/mgcp_osmux.c<br>M tests/mgcp/mgcp_test.c<br>7 files changed, 244 insertions(+), 220 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/mgcp/mgcp_codec.h b/include/osmocom/mgcp/mgcp_codec.h</span><br><span>index 3ead60a..caeecb0 100644</span><br><span>--- a/include/osmocom/mgcp/mgcp_codec.h</span><br><span>+++ b/include/osmocom/mgcp/mgcp_codec.h</span><br><span>@@ -5,3 +5,5 @@</span><br><span> int mgcp_codec_add(struct mgcp_conn_rtp *conn, int payload_type, const char *audio_name, const struct mgcp_codec_param *param);</span><br><span> int mgcp_codec_decide(struct mgcp_conn_rtp *conn);</span><br><span> int mgcp_codec_pt_translate(struct mgcp_conn_rtp *conn_src, struct mgcp_conn_rtp *conn_dst, int payload_type);</span><br><span style="color: hsl(120, 100%, 40%);">+const struct mgcp_rtp_codec *mgcp_codec_pt_find_by_subtype_name(struct mgcp_conn_rtp *conn,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                         const char *subtype_name, unsigned int match_nr);</span><br><span>diff --git a/include/osmocom/mgcp/mgcp_endp.h b/include/osmocom/mgcp/mgcp_endp.h</span><br><span>index 879947b..c16ea4b 100644</span><br><span>--- a/include/osmocom/mgcp/mgcp_endp.h</span><br><span>+++ b/include/osmocom/mgcp/mgcp_endp.h</span><br><span>@@ -23,8 +23,11 @@</span><br><span> </span><br><span> #pragma once</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct sockaddr_in;</span><br><span> struct mgcp_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+struct mgcp_conn_rtp;</span><br><span> struct mgcp_endpoint;</span><br><span> </span><br><span> /* Number of E1 subslots (different variants, not all useable at the same time) */</span><br><span>@@ -35,11 +38,19 @@</span><br><span>      endp ? endp->name : "none", \</span><br><span>      ## args)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Callback type for RTP dispatcher functions</span><br><span style="color: hsl(0, 100%, 40%);">-   (e.g mgcp_dispatch_rtp_bridge_cb, see below) */</span><br><span style="color: hsl(0, 100%, 40%);">-typedef int (*mgcp_dispatch_rtp_cb) (int proto, struct sockaddr_in *addr,</span><br><span style="color: hsl(0, 100%, 40%);">-                              char *buf, unsigned int buf_size,</span><br><span style="color: hsl(0, 100%, 40%);">-                               struct mgcp_conn *conn);</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_rtp_msg_ctx {</span><br><span style="color: hsl(120, 100%, 40%);">+      int proto;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct mgcp_conn_rtp *conn_src;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct sockaddr_in *from_addr;</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%);">+#define OSMO_RTP_MSG_CTX(MSGB) ((struct osmo_rtp_msg_ctx*)(MSGB)->cb)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_static_assert(sizeof(((struct msgb*)0)->cb) >= sizeof(struct osmo_rtp_msg_ctx), osmo_rtp_msg_ctx_fits_in_msgb_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Callback type for RTP dispatcher functions (e.g mgcp_dispatch_rtp_bridge_cb, see below).</span><br><span style="color: hsl(120, 100%, 40%);">+ * The OSMO_RTP_MSG_CTX() should be set appropriately on the msg. */</span><br><span style="color: hsl(120, 100%, 40%);">+typedef int (*mgcp_dispatch_rtp_cb) (struct msgb *msg);</span><br><span> </span><br><span> /* Callback type for endpoint specific cleanup actions. This function</span><br><span>  * is automatically executed when a connection is freed (see mgcp_conn_free()</span><br><span>diff --git a/include/osmocom/mgcp/mgcp_internal.h b/include/osmocom/mgcp/mgcp_internal.h</span><br><span>index ec3ce31..3d7224e 100644</span><br><span>--- a/include/osmocom/mgcp/mgcp_internal.h</span><br><span>+++ b/include/osmocom/mgcp/mgcp_internal.h</span><br><span>@@ -32,6 +32,18 @@</span><br><span> </span><br><span> #define CI_UNUSED 0</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* FIXME: This this is only needed to compile the currently</span><br><span style="color: hsl(120, 100%, 40%);">+ * broken OSMUX support. Remove when fixed */</span><br><span style="color: hsl(120, 100%, 40%);">+#define CONN_ID_BTS "0"</span><br><span style="color: hsl(120, 100%, 40%);">+#define CONN_ID_NET "1"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOG_CONN(conn, level, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+       LOGP(DRTP, level, "(%s I:%s) " fmt, \</span><br><span style="color: hsl(120, 100%, 40%);">+            (conn)->endp ? (conn)->endp->name : "none", (conn)->id, ## args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOG_CONN_RTP(conn_rtp, level, fmt, args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+  LOG_CONN((conn_rtp)->conn, level, fmt, ## args)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct mgcp_rtp_stream_state {</span><br><span>       uint32_t ssrc;</span><br><span>       uint16_t last_seq;</span><br><span>@@ -208,14 +220,12 @@</span><br><span> };</span><br><span> </span><br><span> int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct sockaddr_in *addr,</span><br><span style="color: hsl(0, 100%, 40%);">-       char *buf, int rc, struct mgcp_conn_rtp *conn_src,</span><br><span style="color: hsl(120, 100%, 40%);">+            struct msgb *msg, struct mgcp_conn_rtp *conn_src,</span><br><span>            struct mgcp_conn_rtp *conn_dst);</span><br><span> int mgcp_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn);</span><br><span style="color: hsl(0, 100%, 40%);">-int mgcp_dispatch_rtp_bridge_cb(int proto, struct sockaddr_in *addr, char *buf,</span><br><span style="color: hsl(0, 100%, 40%);">-                           unsigned int buf_size, struct mgcp_conn *conn);</span><br><span style="color: hsl(120, 100%, 40%);">+int mgcp_dispatch_rtp_bridge_cb(struct msgb *msg);</span><br><span> void mgcp_cleanup_rtp_bridge_cb(struct mgcp_endpoint *endp, struct mgcp_conn *conn);</span><br><span style="color: hsl(0, 100%, 40%);">-int mgcp_dispatch_e1_bridge_cb(int proto, struct sockaddr_in *addr, char *buf,</span><br><span style="color: hsl(0, 100%, 40%);">-                               unsigned int buf_size, struct mgcp_conn *conn);</span><br><span style="color: hsl(120, 100%, 40%);">+int mgcp_dispatch_e1_bridge_cb(struct msgb *msg);</span><br><span> void mgcp_cleanup_e1_bridge_cb(struct mgcp_endpoint *endp, struct mgcp_conn *conn);</span><br><span> int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port,</span><br><span>                       struct mgcp_conn_rtp *conn);</span><br><span>@@ -282,3 +292,7 @@</span><br><span> </span><br><span> void mgcp_get_local_addr(char *addr, struct mgcp_conn_rtp *conn);</span><br><span> void mgcp_conn_watchdog_kick(struct mgcp_conn *conn);</span><br><span style="color: hsl(120, 100%, 40%);">+void mgcp_patch_and_count(struct mgcp_endpoint *endp,</span><br><span style="color: hsl(120, 100%, 40%);">+                          struct mgcp_rtp_state *state,</span><br><span style="color: hsl(120, 100%, 40%);">+                         struct mgcp_rtp_end *rtp_end,</span><br><span style="color: hsl(120, 100%, 40%);">+                         struct sockaddr_in *addr, struct msgb *msg);</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_codec.c b/src/libosmo-mgcp/mgcp_codec.c</span><br><span>index 9ac5fbb..58079c6 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_codec.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_codec.c</span><br><span>@@ -432,3 +432,28 @@</span><br><span> </span><br><span>   return codec_dst->payload_type;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Find the payload type number configured for a specific codec by SDP.</span><br><span style="color: hsl(120, 100%, 40%);">+ * For example, IuUP gets assigned a payload type number, and the endpoint needs to translate that to the number</span><br><span style="color: hsl(120, 100%, 40%);">+ * assigned to "AMR" on the other conn (by a=rtpmap:N).</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param conn  The side of an endpoint to get the payload type number for (to translate the payload type number to).</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param subtype_name  SDP codec name without parameters (e.g. "AMR").</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param match_nr  Index for the match found, first being match_nr == 0. Iterate all matches by calling multiple times</span><br><span style="color: hsl(120, 100%, 40%);">+ *                  with incrementing match_nr.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return codec definition for that conn matching the subtype_name, or NULL if no such match_nr is found.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+const struct mgcp_rtp_codec *mgcp_codec_pt_find_by_subtype_name(struct mgcp_conn_rtp *conn,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                             const char *subtype_name, unsigned int match_nr)</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%);">+        for (i = 0; i < conn->end.codecs_assigned; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!strcmp(conn->end.codecs[i].subtype_name, subtype_name)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (match_nr) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               match_nr--;</span><br><span style="color: hsl(120, 100%, 40%);">+                           continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span style="color: hsl(120, 100%, 40%);">+                     return &conn->end.codecs[i];</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%);">+     return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_network.c b/src/libosmo-mgcp/mgcp_network.c</span><br><span>index a0714c1..155ed20 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_network.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_network.c</span><br><span>@@ -53,7 +53,7 @@</span><br><span> #define RTP_MAX_MISORDER        100</span><br><span> #define RTP_BUF_SIZE             4096</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum {</span><br><span style="color: hsl(120, 100%, 40%);">+enum rtp_proto {</span><br><span>     MGCP_PROTO_RTP,</span><br><span>      MGCP_PROTO_RTCP,</span><br><span> };</span><br><span>@@ -74,6 +74,8 @@</span><br><span>   rtpconn_rate_ctr_add(conn_rtp, endp, id, 1);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int rx_rtp(struct msgb *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Determine the local rtp bind IP-address.</span><br><span>  *  \param[out] addr caller provided memory to store the resulting IP-Address.</span><br><span>  *  \param[in] endp mgcp endpoint, that holds a copy of the VTY parameters.</span><br><span>@@ -486,16 +488,19 @@</span><br><span>  * Patch the payload type of an RTP packet so that it uses the payload type</span><br><span>  * that is valid for the destination connection (conn_dst) */</span><br><span> static int mgcp_patch_pt(struct mgcp_conn_rtp *conn_src,</span><br><span style="color: hsl(0, 100%, 40%);">-                       struct mgcp_conn_rtp *conn_dst, char *data, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+                  struct mgcp_conn_rtp *conn_dst, struct msgb *msg)</span><br><span> {</span><br><span>      struct rtp_hdr *rtp_hdr;</span><br><span>     uint8_t pt_in;</span><br><span>       int pt_out;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (len < sizeof(struct rtp_hdr))</span><br><span style="color: hsl(120, 100%, 40%);">+  if (msgb_length(msg) < sizeof(struct rtp_hdr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOG_CONN_RTP(conn_src, LOGL_ERROR, "RTP packet too short (%u < %zu)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                       msgb_length(msg), sizeof(struct rtp_hdr));</span><br><span>              return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   rtp_hdr = (struct rtp_hdr *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+     rtp_hdr = (struct rtp_hdr *)msgb_data(msg);</span><br><span> </span><br><span>      pt_in = rtp_hdr->payload_type;</span><br><span>    pt_out = mgcp_codec_pt_translate(conn_src, conn_dst, pt_in);</span><br><span>@@ -515,7 +520,7 @@</span><br><span> void mgcp_patch_and_count(struct mgcp_endpoint *endp,</span><br><span>                    struct mgcp_rtp_state *state,</span><br><span>                        struct mgcp_rtp_end *rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct sockaddr_in *addr, char *data, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+                        struct sockaddr_in *addr, struct msgb *msg)</span><br><span> {</span><br><span>   uint32_t arrival_time;</span><br><span>       int32_t transit;</span><br><span>@@ -523,11 +528,12 @@</span><br><span>     uint32_t timestamp, ssrc;</span><br><span>    struct rtp_hdr *rtp_hdr;</span><br><span>     int payload = rtp_end->codec->payload_type;</span><br><span style="color: hsl(120, 100%, 40%);">+     unsigned int len = msgb_length(msg);</span><br><span> </span><br><span>     if (len < sizeof(*rtp_hdr))</span><br><span>               return;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     rtp_hdr = (struct rtp_hdr *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+     rtp_hdr = (struct rtp_hdr *)msgb_data(msg);</span><br><span>  seq = ntohs(rtp_hdr->sequence);</span><br><span>   timestamp = ntohl(rtp_hdr->timestamp);</span><br><span>    arrival_time = get_current_ts(rtp_end->codec->rate);</span><br><span>@@ -660,32 +666,26 @@</span><br><span>  * function is used to convert between RFC 5993 and TS 101318, which we normally</span><br><span>  * use.</span><br><span>  * Return 0 on sucess, negative on errors like invalid data length. */</span><br><span style="color: hsl(0, 100%, 40%);">-static int rfc5993_hr_convert(struct mgcp_endpoint *endp, char *data, int *len)</span><br><span style="color: hsl(120, 100%, 40%);">+static int rfc5993_hr_convert(struct mgcp_endpoint *endp, struct msgb *msg)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    /* NOTE: *data has an overall length of RTP_BUF_SIZE, so there is</span><br><span style="color: hsl(0, 100%, 40%);">-        * plenty of space available to store the slightly larger, converted</span><br><span style="color: hsl(0, 100%, 40%);">-     * data */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>   struct rtp_hdr *rtp_hdr;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (*len < sizeof(struct rtp_hdr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+       if (msgb_length(msg) < sizeof(struct rtp_hdr)) {</span><br><span>          LOGPENDP(endp, DRTP, LOGL_ERROR, "AMR RTP packet too short (%d < %zu)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   *len, sizeof(struct rtp_hdr));</span><br><span style="color: hsl(120, 100%, 40%);">+                        msgb_length(msg), sizeof(struct rtp_hdr));</span><br><span>          return -EINVAL;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   rtp_hdr = (struct rtp_hdr *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+     rtp_hdr = (struct rtp_hdr *)msgb_data(msg);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (*len == GSM_HR_BYTES + sizeof(struct rtp_hdr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+  if (msgb_length(msg) == GSM_HR_BYTES + sizeof(struct rtp_hdr)) {</span><br><span>             /* TS 101318 encoding => RFC 5993 encoding */</span><br><span style="color: hsl(120, 100%, 40%);">+              msgb_put(msg, 1);</span><br><span>            memmove(rtp_hdr->data + 1, rtp_hdr->data, GSM_HR_BYTES);</span><br><span>               rtp_hdr->data[0] = 0x00;</span><br><span style="color: hsl(0, 100%, 40%);">-             (*len) += 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    } else if (*len == GSM_HR_BYTES + sizeof(struct rtp_hdr) + 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+       } else if (msgb_length(msg) == GSM_HR_BYTES + sizeof(struct rtp_hdr) + 1) {</span><br><span>          /* RFC 5993 encoding => TS 101318 encoding */</span><br><span>             memmove(rtp_hdr->data, rtp_hdr->data + 1, GSM_HR_BYTES);</span><br><span style="color: hsl(0, 100%, 40%);">-          (*len) -= 1;</span><br><span style="color: hsl(120, 100%, 40%);">+          msgb_trim(msg, msgb_length(msg) - 1);</span><br><span>        } else {</span><br><span>             /* It is possible that multiple payloads occur in one RTP</span><br><span>             * packet. This is not supported yet. */</span><br><span>@@ -700,25 +700,24 @@</span><br><span>  * efficient encoding scheme where all fields are packed together one after</span><br><span>  * another and an octet aligned mode where all fields are aligned to octet</span><br><span>  * boundaries. This function is used to convert between the two modes */</span><br><span style="color: hsl(0, 100%, 40%);">-static int amr_oa_bwe_convert(struct mgcp_endpoint *endp, char *data, int *len,</span><br><span style="color: hsl(120, 100%, 40%);">+static int amr_oa_bwe_convert(struct mgcp_endpoint *endp, struct msgb *msg,</span><br><span>                              bool target_is_oa)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   /* NOTE: *data has an overall length of RTP_BUF_SIZE, so there is</span><br><span style="color: hsl(120, 100%, 40%);">+     /* NOTE: the msgb has an allocated length of RTP_BUF_SIZE, so there is</span><br><span>        * plenty of space available to store the slightly larger, converted</span><br><span>          * data */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>   struct rtp_hdr *rtp_hdr;</span><br><span>     unsigned int payload_len;</span><br><span>    int rc;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     if (*len < sizeof(struct rtp_hdr)) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGPENDP(endp, DRTP, LOGL_ERROR, "AMR RTP packet too short (%d < %zu)\n", *len, sizeof(struct rtp_hdr));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (msgb_length(msg) < sizeof(struct rtp_hdr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGPENDP(endp, DRTP, LOGL_ERROR, "AMR RTP packet too short (%d < %zu)\n", msgb_length(msg), sizeof(struct rtp_hdr));</span><br><span>            return -EINVAL;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   rtp_hdr = (struct rtp_hdr *)data;</span><br><span style="color: hsl(120, 100%, 40%);">+     rtp_hdr = (struct rtp_hdr *)msgb_data(msg);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- payload_len = *len - sizeof(struct rtp_hdr);</span><br><span style="color: hsl(120, 100%, 40%);">+  payload_len = msgb_length(msg) - sizeof(struct rtp_hdr);</span><br><span> </span><br><span>         if (osmo_amr_is_oa(rtp_hdr->data, payload_len)) {</span><br><span>                 if (!target_is_oa)</span><br><span>@@ -746,9 +745,7 @@</span><br><span>             return -EINVAL;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   *len = rc + sizeof(struct rtp_hdr);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     return msgb_trim(msg, rc + sizeof(struct rtp_hdr));</span><br><span> }</span><br><span> </span><br><span> /* Check if a conversion between octet-aligned and bandwith-efficient mode is</span><br><span>@@ -786,15 +783,14 @@</span><br><span> </span><br><span> /* Forward data to a debug tap. This is debug function that is intended for</span><br><span>  * debugging the voice traffic with tools like gstreamer */</span><br><span style="color: hsl(0, 100%, 40%);">-static void forward_data(int fd, struct mgcp_rtp_tap *tap, const char *buf,</span><br><span style="color: hsl(0, 100%, 40%);">-                       int len)</span><br><span style="color: hsl(120, 100%, 40%);">+static void forward_data(int fd, struct mgcp_rtp_tap *tap, struct msgb *msg)</span><br><span> {</span><br><span>         int rc;</span><br><span> </span><br><span>  if (!tap->enabled)</span><br><span>                return;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     rc = sendto(fd, buf, len, 0, (struct sockaddr *)&tap->forward,</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = sendto(fd, msgb_data(msg), msgb_length(msg), 0, (struct sockaddr *)&tap->forward,</span><br><span>                    sizeof(tap->forward));</span><br><span> </span><br><span>    if (rc < 0)</span><br><span>@@ -812,7 +808,7 @@</span><br><span>  *  \param[in] conn_dst associated destination connection.</span><br><span>  *  \returns 0 on success, -1 on ERROR. */</span><br><span> int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct sockaddr_in *addr,</span><br><span style="color: hsl(0, 100%, 40%);">-           char *buf, int len, struct mgcp_conn_rtp *conn_src,</span><br><span style="color: hsl(120, 100%, 40%);">+           struct msgb *msg, struct mgcp_conn_rtp *conn_src,</span><br><span>            struct mgcp_conn_rtp *conn_dst)</span><br><span> {</span><br><span>   /*! When no destination connection is available (e.g. when only one</span><br><span>@@ -824,6 +820,7 @@</span><br><span>    struct mgcp_rtp_state *rtp_state;</span><br><span>    char *dest_name;</span><br><span>     int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       int len;</span><br><span> </span><br><span>         OSMO_ASSERT(conn_src);</span><br><span>       OSMO_ASSERT(conn_dst);</span><br><span>@@ -847,7 +844,7 @@</span><br><span>          * should not occur if transcoding is consequently avoided. Until</span><br><span>     * we have transcoding support in osmo-mgw we can not resolve this. */</span><br><span>       if (is_rtp) {</span><br><span style="color: hsl(0, 100%, 40%);">-           rc = mgcp_patch_pt(conn_src, conn_dst, buf, len);</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = mgcp_patch_pt(conn_src, conn_dst, msg);</span><br><span>                 if (rc < 0) {</span><br><span>                     LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span>                              "can not patch PT because no suitable egress codec was found.\n");</span><br><span>@@ -872,21 +869,21 @@</span><br><span>        } else if (is_rtp) {</span><br><span>                 int cont;</span><br><span>            int nbytes = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-         int buflen = len;</span><br><span style="color: hsl(120, 100%, 40%);">+             int buflen = msgb_length(msg);</span><br><span>               do {</span><br><span>                         /* Run transcoder */</span><br><span>                         cont = endp->cfg->rtp_processing_cb(endp, rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                            buf, &buflen,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     (char*)msgb_data(msg), &buflen,</span><br><span>                                                          RTP_BUF_SIZE);</span><br><span>                   if (cont < 0)</span><br><span>                             break;</span><br><span> </span><br><span>                   if (addr)</span><br><span>                            mgcp_patch_and_count(endp, rtp_state, rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">-                                               addr, buf, buflen);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                   addr, msg);</span><br><span> </span><br><span>                         if (amr_oa_bwe_convert_indicated(conn_dst->end.codec)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                             rc = amr_oa_bwe_convert(endp, buf, &buflen,</span><br><span style="color: hsl(120, 100%, 40%);">+                               rc = amr_oa_bwe_convert(endp, msg,</span><br><span>                                                   conn_dst->end.codec->param.amr_octet_aligned);</span><br><span>                                 if (rc < 0) {</span><br><span>                                     LOGPENDP(endp, DRTP, LOGL_ERROR,</span><br><span>@@ -897,7 +894,7 @@</span><br><span>                       else if (rtp_end->rfc5993_hr_convert</span><br><span>                          && strcmp(conn_src->end.codec->subtype_name,</span><br><span>                                     "GSM-HR-08") == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                            rc = rfc5993_hr_convert(endp, buf, &buflen);</span><br><span style="color: hsl(120, 100%, 40%);">+                              rc = rfc5993_hr_convert(endp, msg);</span><br><span>                          if (rc < 0) {</span><br><span>                                     LOGPENDP(endp, DRTP, LOGL_ERROR, "Error while converting to GSM-HR-08\n");</span><br><span>                                         break;</span><br><span>@@ -913,7 +910,7 @@</span><br><span> </span><br><span>                     /* Forward a copy of the RTP data to a debug ip/port */</span><br><span>                      forward_data(rtp_end->rtp.fd, &conn_src->tap_out,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  buf, buflen);</span><br><span style="color: hsl(120, 100%, 40%);">+                                 msg);</span><br><span> </span><br><span>                       /* FIXME: HACK HACK HACK. See OS#2459.</span><br><span>                        * The ip.access nano3G needs the first RTP payload's first two bytes to read hex</span><br><span>@@ -922,7 +919,7 @@</span><br><span>                   */</span><br><span>                  if (!rtp_state->patched_first_rtp_payload</span><br><span>                             && conn_src->conn->mode == MGCP_CONN_LOOPBACK) {</span><br><span style="color: hsl(0, 100%, 40%);">-                              uint8_t *data = (uint8_t *) & buf[12];</span><br><span style="color: hsl(120, 100%, 40%);">+                            uint8_t *data = msgb_data(msg) + 12;</span><br><span>                                 if (data[0] == 0xe0) {</span><br><span>                                       data[0] = 0xe4;</span><br><span>                                      data[1] = 0x00;</span><br><span>@@ -933,9 +930,8 @@</span><br><span>                                }</span><br><span>                    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                   len = mgcp_udp_send(rtp_end->rtp.fd,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     &rtp_end->addr,</span><br><span style="color: hsl(0, 100%, 40%);">-                                          rtp_end->rtp_port, buf, buflen);</span><br><span style="color: hsl(120, 100%, 40%);">+                       len = mgcp_udp_send(rtp_end->rtp.fd, &rtp_end->addr, rtp_end->rtp_port,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      (char*)msgb_data(msg), msgb_length(msg));</span><br><span> </span><br><span>                    if (len <= 0)</span><br><span>                             return len;</span><br><span>@@ -956,7 +952,7 @@</span><br><span> </span><br><span>                len = mgcp_udp_send(rtp_end->rtcp.fd,</span><br><span>                                 &rtp_end->addr,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  rtp_end->rtcp_port, buf, len);</span><br><span style="color: hsl(120, 100%, 40%);">+                             rtp_end->rtcp_port, (char*)msgb_data(msg), msgb_length(msg));</span><br><span> </span><br><span>             rtpconn_rate_ctr_inc(conn_dst, endp, RTP_PACKETS_TX_CTR);</span><br><span>            rtpconn_rate_ctr_add(conn_dst, endp, RTP_OCTETS_TX_CTR, len);</span><br><span>@@ -967,45 +963,6 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Helper function for mgcp_recv(),</span><br><span style="color: hsl(0, 100%, 40%);">-   Receive one RTP Packet + Originating address from file descriptor */</span><br><span style="color: hsl(0, 100%, 40%);">-static int receive_from(struct mgcp_endpoint *endp, int fd,</span><br><span style="color: hsl(0, 100%, 40%);">-                 struct sockaddr_in *addr, char *buf, int bufsize)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- socklen_t slen = sizeof(*addr);</span><br><span style="color: hsl(0, 100%, 40%);">- struct sockaddr_in addr_sink;</span><br><span style="color: hsl(0, 100%, 40%);">-   char buf_sink[RTP_BUF_SIZE];</span><br><span style="color: hsl(0, 100%, 40%);">-    bool tossed = false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!addr)</span><br><span style="color: hsl(0, 100%, 40%);">-              addr = &addr_sink;</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!buf) {</span><br><span style="color: hsl(0, 100%, 40%);">-             tossed = true;</span><br><span style="color: hsl(0, 100%, 40%);">-          buf = buf_sink;</span><br><span style="color: hsl(0, 100%, 40%);">-         bufsize = sizeof(buf_sink);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = recvfrom(fd, buf, bufsize, 0, (struct sockaddr *)addr, &slen);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-             "receiving %u bytes length packet from %s:%u ...\n",</span><br><span style="color: hsl(0, 100%, 40%);">-          rc, inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGPENDP(endp, DRTP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-                         "failed to receive packet, errno: %d/%s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   errno, strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">-               return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (tossed) {</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGPENDP(endp, DRTP, LOGL_ERROR, "packet tossed\n");</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* Check if the origin (addr) matches the address/port data of the RTP</span><br><span>  * connections. */</span><br><span> static int check_rtp_origin(struct mgcp_conn_rtp *conn,</span><br><span>@@ -1098,7 +1055,7 @@</span><br><span> </span><br><span> /* Do some basic checks to make sure that the RTCP packets we are going to</span><br><span>  * process are not complete garbage */</span><br><span style="color: hsl(0, 100%, 40%);">-static int check_rtcp(char *buf, unsigned int buf_size)</span><br><span style="color: hsl(120, 100%, 40%);">+static int check_rtcp(struct mgcp_conn_rtp *conn_src, struct msgb *msg)</span><br><span> {</span><br><span>      struct rtcp_hdr *hdr;</span><br><span>        unsigned int len;</span><br><span>@@ -1106,33 +1063,43 @@</span><br><span> </span><br><span>      /* RTPC packets that are just a header without data do not make</span><br><span>       * any sense. */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (buf_size < sizeof(struct rtcp_hdr))</span><br><span style="color: hsl(120, 100%, 40%);">+    if (msgb_length(msg) < sizeof(struct rtcp_hdr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          LOG_CONN_RTP(conn_src, LOGL_ERROR, "RTCP packet too short (%u < %zu)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      msgb_length(msg), sizeof(struct rtcp_hdr));</span><br><span>             return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span> </span><br><span>        /* Make sure that the length of the received packet does not exceed</span><br><span>   * the available buffer size */</span><br><span style="color: hsl(0, 100%, 40%);">- hdr = (struct rtcp_hdr *)buf;</span><br><span style="color: hsl(120, 100%, 40%);">+ hdr = (struct rtcp_hdr *)msgb_data(msg);</span><br><span>     len = (osmo_ntohs(hdr->length) + 1) * 4;</span><br><span style="color: hsl(0, 100%, 40%);">-     if (len > buf_size)</span><br><span style="color: hsl(120, 100%, 40%);">+        if (len > msgb_length(msg)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOG_CONN_RTP(conn_src, LOGL_ERROR, "RTCP header length exceeds packet size (%u > %u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      len, msgb_length(msg));</span><br><span>                 return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span> </span><br><span>        /* Make sure we accept only packets that have a proper packet type set</span><br><span>        * See also: http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml */</span><br><span>  type = hdr->type;</span><br><span style="color: hsl(0, 100%, 40%);">-    if ((type < 192 || type > 195) && (type < 200 || type > 213))</span><br><span style="color: hsl(120, 100%, 40%);">+     if ((type < 192 || type > 195) && (type < 200 || type > 213)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOG_CONN_RTP(conn_src, LOGL_ERROR, "RTCP header: invalid type: %u\n", type);</span><br><span>               return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span> </span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span> /* Do some basic checks to make sure that the RTP packets we are going to</span><br><span>  * process are not complete garbage */</span><br><span style="color: hsl(0, 100%, 40%);">-static int check_rtp(char *buf, unsigned int buf_size)</span><br><span style="color: hsl(120, 100%, 40%);">+static int check_rtp(struct mgcp_conn_rtp *conn_src, struct msgb *msg)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    /* RTP packets that are just a header without data do not make</span><br><span style="color: hsl(0, 100%, 40%);">-   * any sense. */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (buf_size < sizeof(struct rtp_hdr))</span><br><span style="color: hsl(0, 100%, 40%);">-               return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t min_size = sizeof(struct rtp_hdr);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (msgb_length(msg) < min_size) {</span><br><span style="color: hsl(120, 100%, 40%);">+         LOG_CONN_RTP(conn_src, LOGL_ERROR, "RTP packet too short (%u < %zu)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                       msgb_length(msg), min_size);</span><br><span style="color: hsl(120, 100%, 40%);">+             return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span> </span><br><span>        /* FIXME: Add more checks, the reason why we do not check more than</span><br><span>   * the length is because we currently handle IUUP packets as RTP</span><br><span>@@ -1143,86 +1110,15 @@</span><br><span>   return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Receive RTP data from a specified source connection and dispatch it to a</span><br><span style="color: hsl(0, 100%, 40%);">- * destination connection. */</span><br><span style="color: hsl(0, 100%, 40%);">-static int mgcp_recv(int *proto, struct sockaddr_in *addr, char *buf,</span><br><span style="color: hsl(0, 100%, 40%);">-              unsigned int buf_size, struct osmo_fd *fd)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct mgcp_endpoint *endp;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct mgcp_conn_rtp *conn;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct mgcp_trunk *trunk;</span><br><span style="color: hsl(0, 100%, 40%);">-       int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- conn = (struct mgcp_conn_rtp*) fd->data;</span><br><span style="color: hsl(0, 100%, 40%);">-     endp = conn->conn->endp;</span><br><span style="color: hsl(0, 100%, 40%);">-  trunk = endp->trunk;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPCONN(conn->conn, DRTP, LOGL_DEBUG, "receiving RTP/RTCP packet...\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  rc = receive_from(endp, fd->fd, addr, buf, buf_size);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (rc <= 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* FIXME: The way how we detect the protocol looks odd. We should look</span><br><span style="color: hsl(0, 100%, 40%);">-   * into the packet header. Also we should introduce a packet type</span><br><span style="color: hsl(0, 100%, 40%);">-        * MGCP_PROTO_IUUP because currently we handle IUUP packets like RTP</span><br><span style="color: hsl(0, 100%, 40%);">-     * packets which is problematic. */</span><br><span style="color: hsl(0, 100%, 40%);">-     *proto = fd == &conn->end.rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (*proto == MGCP_PROTO_RTP) {</span><br><span style="color: hsl(0, 100%, 40%);">-         if (check_rtp(buf, rc) < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGPCONN(conn->conn, DRTP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-                                "invalid RTP packet received -- packet tossed\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                   return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (*proto == MGCP_PROTO_RTCP) {</span><br><span style="color: hsl(0, 100%, 40%);">-         if (check_rtcp(buf, rc) < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGPCONN(conn->conn, DRTP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-                                "invalid RTCP packet received -- packet tossed\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                  return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       LOGPCONN(conn->conn, DRTP, LOGL_DEBUG, "");</span><br><span style="color: hsl(0, 100%, 40%);">-        LOGPC(DRTP, LOGL_DEBUG, "receiving from %s %s %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-        conn->conn->name, inet_ntoa(addr->sin_addr),</span><br><span style="color: hsl(0, 100%, 40%);">-           ntohs(addr->sin_port));</span><br><span style="color: hsl(0, 100%, 40%);">-        LOGPENDP(endp, DRTP, LOGL_DEBUG, "conn:%s\n", mgcp_conn_dump(conn->conn));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Check if the origin of the RTP packet seems plausible */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (trunk->rtp_accept_all == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-            if (check_rtp_origin(conn, addr) != 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                  return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Filter out dummy message */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (rc == 1 && buf[0] == MGCP_DUMMY_LOAD) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGPCONN(conn->conn, DRTP, LOGL_NOTICE,</span><br><span style="color: hsl(0, 100%, 40%);">-                       "dummy message received\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGPCONN(conn->conn, DRTP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-                        "packet tossed\n");</span><br><span style="color: hsl(0, 100%, 40%);">-          return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Increment RX statistics */</span><br><span style="color: hsl(0, 100%, 40%);">-   rtpconn_rate_ctr_inc(conn, endp, RTP_PACKETS_RX_CTR);</span><br><span style="color: hsl(0, 100%, 40%);">-   rtpconn_rate_ctr_add(conn, endp, RTP_OCTETS_RX_CTR, rc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Forward a copy of the RTP data to a debug ip/port */</span><br><span style="color: hsl(0, 100%, 40%);">- forward_data(fd->fd, &conn->tap_in, buf, rc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* Send RTP data. Possible options are standard RTP packet</span><br><span>  * transmission or trsmission via an osmux connection */</span><br><span style="color: hsl(0, 100%, 40%);">-static int mgcp_send_rtp(int proto, struct sockaddr_in *addr, char *buf,</span><br><span style="color: hsl(0, 100%, 40%);">-                    unsigned int buf_size,</span><br><span style="color: hsl(0, 100%, 40%);">-                  struct mgcp_conn_rtp *conn_src,</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct mgcp_conn_rtp *conn_dst)</span><br><span style="color: hsl(120, 100%, 40%);">+static int mgcp_send_rtp(struct mgcp_conn_rtp *conn_dst, struct msgb *msg)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       struct mgcp_endpoint *endp;</span><br><span style="color: hsl(0, 100%, 40%);">-     endp = conn_src->conn->endp;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  enum rtp_proto proto = mc->proto;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct mgcp_conn_rtp *conn_src = mc->conn_src;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct sockaddr_in *from_addr = mc->from_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct mgcp_endpoint *endp = conn_src->conn->endp;</span><br><span> </span><br><span>         LOGPENDP(endp, DRTP, LOGL_DEBUG, "destin conn:%s\n",</span><br><span>                mgcp_conn_dump(conn_dst->conn));</span><br><span>@@ -1241,13 +1137,13 @@</span><br><span>                        "endpoint type is MGCP_RTP_DEFAULT, "</span><br><span>                      "using mgcp_send() to forward data directly\n");</span><br><span>          return mgcp_send(endp, proto == MGCP_PROTO_RTP,</span><br><span style="color: hsl(0, 100%, 40%);">-                          addr, buf, buf_size, conn_src, conn_dst);</span><br><span style="color: hsl(120, 100%, 40%);">+                             from_addr, msg, conn_src, conn_dst);</span><br><span>        case MGCP_OSMUX_BSC_NAT:</span><br><span>     case MGCP_OSMUX_BSC:</span><br><span>                 LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span>                      "endpoint type is MGCP_OSMUX_BSC_NAT, "</span><br><span>                    "using osmux_xfrm_to_osmux() to forward data through OSMUX\n");</span><br><span style="color: hsl(0, 100%, 40%);">-              return osmux_xfrm_to_osmux(buf, buf_size, conn_dst);</span><br><span style="color: hsl(120, 100%, 40%);">+          return osmux_xfrm_to_osmux((char*)msgb_data(msg), msgb_length(msg), conn_dst);</span><br><span>       }</span><br><span> </span><br><span>        /* If the data has not been handled/forwarded until here, it will</span><br><span>@@ -1265,10 +1161,13 @@</span><br><span>  *  \param[in] buf_size size data length of buf.</span><br><span>  *  \param[in] conn originating connection.</span><br><span>  *  \returns 0 on success, -1 on ERROR. */</span><br><span style="color: hsl(0, 100%, 40%);">-int mgcp_dispatch_rtp_bridge_cb(int proto, struct sockaddr_in *addr, char *buf,</span><br><span style="color: hsl(0, 100%, 40%);">-                             unsigned int buf_size, struct mgcp_conn *conn)</span><br><span style="color: hsl(120, 100%, 40%);">+int mgcp_dispatch_rtp_bridge_cb(struct msgb *msg)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  struct mgcp_conn_rtp *conn_src = mc->conn_src;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct mgcp_conn *conn = conn_src->conn;</span><br><span>  struct mgcp_conn *conn_dst;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct sockaddr_in *from_addr = mc->from_addr;</span><br><span> </span><br><span>        /*! NOTE: This callback function implements the endpoint specific</span><br><span>     *  dispatch behaviour of an rtp bridge/proxy endpoint. It is assumed</span><br><span>@@ -1287,11 +1186,10 @@</span><br><span>               * address data from the UDP packet header to patch the</span><br><span>               * outgoing address in connection on the fly */</span><br><span>              if (conn->u.rtp.end.rtp_port == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 conn->u.rtp.end.addr = addr->sin_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-                    conn->u.rtp.end.rtp_port = addr->sin_port;</span><br><span style="color: hsl(120, 100%, 40%);">+                      conn->u.rtp.end.addr = from_addr->sin_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+                     conn->u.rtp.end.rtp_port = from_addr->sin_port;</span><br><span>                }</span><br><span style="color: hsl(0, 100%, 40%);">-               return mgcp_send_rtp(proto, addr, buf,</span><br><span style="color: hsl(0, 100%, 40%);">-                               buf_size, &conn->u.rtp, &conn->u.rtp);</span><br><span style="color: hsl(120, 100%, 40%);">+             return mgcp_send_rtp(conn_src, msg);</span><br><span>         }</span><br><span> </span><br><span>        /* Find a destination connection. */</span><br><span>@@ -1323,9 +1221,7 @@</span><br><span>         }</span><br><span> </span><br><span>        /* Dispatch RTP packet to destination RTP connection */</span><br><span style="color: hsl(0, 100%, 40%);">- return mgcp_send_rtp(proto, addr, buf,</span><br><span style="color: hsl(0, 100%, 40%);">-                       buf_size, &conn->u.rtp, &conn_dst->u.rtp);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+ return mgcp_send_rtp(&conn_dst->u.rtp, msg);</span><br><span> }</span><br><span> </span><br><span> /*! dispatch incoming RTP packet to E1 subslot, handle RTCP packets locally.</span><br><span>@@ -1335,9 +1231,12 @@</span><br><span>  *  \param[in] buf_size size data length of buf.</span><br><span>  *  \param[in] conn originating connection.</span><br><span>  *  \returns 0 on success, -1 on ERROR. */</span><br><span style="color: hsl(0, 100%, 40%);">-int mgcp_dispatch_e1_bridge_cb(int proto, struct sockaddr_in *addr, char *buf,</span><br><span style="color: hsl(0, 100%, 40%);">-                            unsigned int buf_size, struct mgcp_conn *conn)</span><br><span style="color: hsl(120, 100%, 40%);">+int mgcp_dispatch_e1_bridge_cb(struct msgb *msg)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  struct mgcp_conn_rtp *conn_src = mc->conn_src;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct mgcp_conn *conn = conn_src->conn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        /* FIXME: integrate E1 support from libsomoabis, also implement</span><br><span>       * handling for RTCP packets, which can not converted to E1. */</span><br><span>      LOGPCONN(conn, DRTP, LOGL_FATAL,</span><br><span>@@ -1372,6 +1271,11 @@</span><br><span>             "cannot dispatch! E1 support is not implemented yet!\n");</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static bool is_dummy_msg(enum rtp_proto proto, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    return msgb_length(msg) == 1 && msgb_data(msg)[0] == MGCP_DUMMY_LOAD;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Handle incoming RTP data from NET */</span><br><span> static int rtp_data_net(struct osmo_fd *fd, unsigned int what)</span><br><span> {</span><br><span>@@ -1385,23 +1289,83 @@</span><br><span>       struct mgcp_conn_rtp *conn_src;</span><br><span>      struct mgcp_endpoint *endp;</span><br><span>  struct sockaddr_in addr;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        char buf[RTP_BUF_SIZE];</span><br><span style="color: hsl(0, 100%, 40%);">- int proto;</span><br><span style="color: hsl(0, 100%, 40%);">-      int len;</span><br><span style="color: hsl(120, 100%, 40%);">+      socklen_t slen = sizeof(addr);</span><br><span style="color: hsl(120, 100%, 40%);">+        int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+      enum rtp_proto proto;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_rtp_msg_ctx *mc;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct msgb *msg = msgb_alloc(RTP_BUF_SIZE, "RTP-rx");</span><br><span style="color: hsl(120, 100%, 40%);">+      int rc;</span><br><span> </span><br><span>  conn_src = (struct mgcp_conn_rtp *)fd->data;</span><br><span>      OSMO_ASSERT(conn_src);</span><br><span>       endp = conn_src->conn->endp;</span><br><span>   OSMO_ASSERT(endp);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  LOGPENDP(endp, DRTP, LOGL_DEBUG, "source conn:%s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-           mgcp_conn_dump(conn_src->conn));</span><br><span style="color: hsl(120, 100%, 40%);">+  proto = (fd == &conn_src->end.rtp)? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        /* Receive packet */</span><br><span style="color: hsl(0, 100%, 40%);">-    len = mgcp_recv(&proto, &addr, buf, sizeof(buf), fd);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (len < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    ret = recvfrom(fd->fd, msgb_data(msg), msg->data_len, 0, (struct sockaddr *)&addr, &slen);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (ret <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOG_CONN_RTP(conn_src, LOGL_ERROR, "recvfrom error: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                rc = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+              goto out;</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%);">+   msgb_put(msg, ret);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG_CONN_RTP(conn_src, LOGL_DEBUG, "%s: rx %u bytes from %s:%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+               proto == MGCP_PROTO_RTP ? "RTP" : "RTPC",</span><br><span style="color: hsl(120, 100%, 40%);">+                 msgb_length(msg), inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if ((proto == MGCP_PROTO_RTP && check_rtp(conn_src, msg))</span><br><span style="color: hsl(120, 100%, 40%);">+         || (proto == MGCP_PROTO_RTCP && check_rtcp(conn_src, msg))) {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Logging happened in the two check_ functions */</span><br><span style="color: hsl(120, 100%, 40%);">+            rc = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+              goto out;</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%);">+   if (is_dummy_msg(proto, msg)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOG_CONN_RTP(conn_src, LOGL_DEBUG, "rx dummy packet (dropped)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+               goto out;</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%);">+   /* Since the msgb remains owned and freed by this function, the msg ctx data struct can just be on the stack and</span><br><span style="color: hsl(120, 100%, 40%);">+       * needs not be allocated with the msgb. */</span><br><span style="color: hsl(120, 100%, 40%);">+   mc = OSMO_RTP_MSG_CTX(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+   *mc = (struct osmo_rtp_msg_ctx){</span><br><span style="color: hsl(120, 100%, 40%);">+              .proto = proto,</span><br><span style="color: hsl(120, 100%, 40%);">+               .conn_src = conn_src,</span><br><span style="color: hsl(120, 100%, 40%);">+         .from_addr = &addr,</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+    LOG_CONN_RTP(conn_src, LOGL_DEBUG, "msg ctx: %d %p %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                mc->proto, mc->conn_src,</span><br><span style="color: hsl(120, 100%, 40%);">+                osmo_hexdump((void*)mc->from_addr, sizeof(struct sockaddr_in)));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Increment RX statistics */</span><br><span style="color: hsl(120, 100%, 40%);">+ rate_ctr_inc(&conn_src->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR]);</span><br><span style="color: hsl(120, 100%, 40%);">+   rate_ctr_add(&conn_src->rate_ctr_group->ctr[RTP_OCTETS_RX_CTR], msgb_length(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+  /* FIXME: count RTP and RTCP separately, also count IuUP payload-less separately */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Forward a copy of the RTP data to a debug ip/port */</span><br><span style="color: hsl(120, 100%, 40%);">+       forward_data(fd->fd, &conn_src->tap_in, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = rx_rtp(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+out:</span><br><span style="color: hsl(120, 100%, 40%);">+     msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       return rc;</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 int rx_rtp(struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  struct mgcp_conn_rtp *conn_src = mc->conn_src;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct sockaddr_in *from_addr = mc->from_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct mgcp_conn *conn = conn_src->conn;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct mgcp_trunk *trunk = conn->endp->trunk;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOG_CONN_RTP(conn_src, LOGL_DEBUG, "rx_rtp(%u bytes)\n", msgb_length(msg));</span><br><span> </span><br><span>    mgcp_conn_watchdog_kick(conn_src->conn);</span><br><span> </span><br><span>@@ -1410,17 +1374,20 @@</span><br><span>     * define, then we check if the incoming payload matches that</span><br><span>         * expectation. */</span><br><span>   if (amr_oa_bwe_convert_indicated(conn_src->end.codec)) {</span><br><span style="color: hsl(0, 100%, 40%);">-             int oa = amr_oa_check(buf, len);</span><br><span style="color: hsl(120, 100%, 40%);">+              int oa = amr_oa_check((char*)msgb_data(msg), msgb_length(msg));</span><br><span>              if (oa < 0)</span><br><span>                       return -1;</span><br><span>           if (((bool)oa) != conn_src->end.codec->param.amr_octet_aligned)</span><br><span>                        return -1;</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Check if the origin of the RTP packet seems plausible */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!trunk->rtp_accept_all && check_rtp_origin(conn_src, from_addr))</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         /* Execute endpoint specific implementation that handles the</span><br><span>          * dispatching of the RTP data */</span><br><span style="color: hsl(0, 100%, 40%);">-       return endp->type->dispatch_rtp_cb(proto, &addr, buf, len,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       conn_src->conn);</span><br><span style="color: hsl(120, 100%, 40%);">+        return conn->endp->type->dispatch_rtp_cb(msg);</span><br><span> }</span><br><span> </span><br><span> /*! set IP Type of Service parameter.</span><br><span>diff --git a/src/libosmo-mgcp/mgcp_osmux.c b/src/libosmo-mgcp/mgcp_osmux.c</span><br><span>index ceae087..85e33e0 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_osmux.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_osmux.c</span><br><span>@@ -236,13 +236,15 @@</span><br><span> {</span><br><span>      struct mgcp_conn_rtp *conn = data;</span><br><span>   struct mgcp_endpoint *endp = conn->conn->endp;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct sockaddr_in addr = {</span><br><span style="color: hsl(0, 100%, 40%);">-             .sin_addr = conn->end.addr,</span><br><span style="color: hsl(0, 100%, 40%);">-          .sin_port = conn->end.rtp_port,</span><br><span style="color: hsl(0, 100%, 40%);">-      }; /* FIXME: not set/used in cb */</span><br><span style="color: hsl(120, 100%, 40%);">+    struct sockaddr_in addr = { /* FIXME: do we know the source address?? */ };</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_rtp_msg_ctx *mc = OSMO_RTP_MSG_CTX(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  *mc = (struct osmo_rtp_msg_ctx){</span><br><span style="color: hsl(120, 100%, 40%);">+              .proto = MGCP_PROTO_RTP,</span><br><span style="color: hsl(120, 100%, 40%);">+              .conn_src = conn,</span><br><span style="color: hsl(120, 100%, 40%);">+             .from_addr = &addr,</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  endp->type->dispatch_rtp_cb(MGCP_PROTO_RTP, &addr, (char *)msg->data, msg->len, conn->conn);</span><br><span style="color: hsl(120, 100%, 40%);">+       endp->type->dispatch_rtp_cb(msg);</span><br><span>      msgb_free(msg);</span><br><span> }</span><br><span> </span><br><span>diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c</span><br><span>index 66f79b0..458f6c9 100644</span><br><span>--- a/tests/mgcp/mgcp_test.c</span><br><span>+++ b/tests/mgcp/mgcp_test.c</span><br><span>@@ -29,6 +29,7 @@</span><br><span> #include <osmocom/mgcp/mgcp_trunk.h></span><br><span> #include <osmocom/mgcp/mgcp_sdp.h></span><br><span> #include <osmocom/mgcp/mgcp_codec.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/mgcp/mgcp_internal.h></span><br><span> </span><br><span> #include <osmocom/core/application.h></span><br><span> #include <osmocom/core/talloc.h></span><br><span>@@ -1261,7 +1262,7 @@</span><br><span> void mgcp_patch_and_count(struct mgcp_endpoint *endp,</span><br><span>                         struct mgcp_rtp_state *state,</span><br><span>                        struct mgcp_rtp_end *rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">-                   struct sockaddr_in *addr, char *data, int len);</span><br><span style="color: hsl(120, 100%, 40%);">+                       struct sockaddr_in *addr, struct msgb *msg);</span><br><span> </span><br><span> static void test_packet_error_detection(int patch_ssrc, int patch_ts)</span><br><span> {</span><br><span>@@ -1274,7 +1275,6 @@</span><br><span>     struct mgcp_rtp_state state;</span><br><span>         struct mgcp_rtp_end *rtp;</span><br><span>    struct sockaddr_in addr = { 0 };</span><br><span style="color: hsl(0, 100%, 40%);">-        char buffer[4096];</span><br><span>   uint32_t last_ssrc = 0;</span><br><span>      uint32_t last_timestamp = 0;</span><br><span>         uint32_t last_seqno = 0;</span><br><span>@@ -1323,16 +1323,17 @@</span><br><span> </span><br><span>       for (i = 0; i < ARRAY_SIZE(test_rtp_packets1); ++i) {</span><br><span>             struct rtp_packet_info *info = test_rtp_packets1 + i;</span><br><span style="color: hsl(120, 100%, 40%);">+         struct msgb *msg = msgb_alloc(4096, __func__);</span><br><span> </span><br><span>           force_monotonic_time_us = round(1000000.0 * info->txtime);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-               OSMO_ASSERT(info->len <= sizeof(buffer));</span><br><span style="color: hsl(120, 100%, 40%);">+               OSMO_ASSERT(info->len <= msgb_tailroom(msg));</span><br><span>          OSMO_ASSERT(info->len >= 0);</span><br><span style="color: hsl(0, 100%, 40%);">-              memmove(buffer, info->data, info->len);</span><br><span style="color: hsl(120, 100%, 40%);">+         msg->l3h = msgb_put(msg, info->len);</span><br><span style="color: hsl(120, 100%, 40%);">+            memcpy((char*)msgb_l3(msg), info->data, info->len);</span><br><span>            mgcp_rtp_end_config(&endp, 1, rtp);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-             mgcp_patch_and_count(&endp, &state, rtp, &addr,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  buffer, info->len);</span><br><span style="color: hsl(120, 100%, 40%);">+           mgcp_patch_and_count(&endp, &state, rtp, &addr, msg);</span><br><span> </span><br><span>                if (state.out_stream.ssrc != last_ssrc) {</span><br><span>                    printf("Output SSRC changed to %08x\n",</span><br><span>@@ -1359,6 +1360,8 @@</span><br><span>            last_out_ts_err_cnt = state.out_stream.err_ts_ctr->current;</span><br><span>               last_timestamp = state.out_stream.last_timestamp;</span><br><span>            last_seqno = state.out_stream.last_seq;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             msgb_free(msg);</span><br><span>      }</span><br><span> </span><br><span>        force_monotonic_time_us = -1;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-mgw/+/18913">change 18913</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/c/osmo-mgw/+/18913"/><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-Change-Id: I3af40b63bc49f8636d4e7ea2f8f83bb67f6619ee </div>
<div style="display:none"> Gerrit-Change-Number: 18913 </div>
<div style="display:none"> Gerrit-PatchSet: 5 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Assignee: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: daniel <dwillmann@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>