pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-mgw/+/29465 )


Change subject: osmux: Support local CID != remote CID
......................................................................

osmux: Support local CID != remote CID

So far the implementation only allowed the remote CID being the same as
the one dynamically implemented internally.

Related: SYS#6138
Change-Id: I6b03eabc0305580c9788c529bec7dda9044a008f
---
M include/osmocom/mgcp/mgcp_conn.h
M include/osmocom/mgcp/osmux.h
M src/libosmo-mgcp/mgcp_conn.c
M src/libosmo-mgcp/mgcp_osmux.c
M src/libosmo-mgcp/mgcp_protocol.c
5 files changed, 66 insertions(+), 63 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/65/29465/1

diff --git a/include/osmocom/mgcp/mgcp_conn.h b/include/osmocom/mgcp/mgcp_conn.h
index 14ddfbb..9ffa7dc 100644
--- a/include/osmocom/mgcp/mgcp_conn.h
+++ b/include/osmocom/mgcp/mgcp_conn.h
@@ -80,10 +80,14 @@
        struct {
                /* Osmux state: disabled, activating, active */
                enum osmux_state state;
-               /* Is cid holding valid data? is it allocated from pool? */
-               bool cid_allocated;
-               /* Allocated Osmux circuit ID for this conn */
-               uint8_t cid;
+               /* Is local_cid holding valid data? is it allocated from pool? 
*/
+               bool local_cid_allocated;
+               /* Allocated local Osmux circuit ID for this conn */
+               uint8_t local_cid;
+               /* Is remote_cid holding valid data? was it already received 
from client? */
+               bool remote_cid_present;
+               /* Received remote Osmux circuit ID for this conn */
+               uint8_t remote_cid;
                /* handle to batch messages, shared (refcounted) among several 
conns */
                struct osmux_in_handle *in;
                /* handle to unbatch messages, one allocated and owned per conn 
*/
diff --git a/include/osmocom/mgcp/osmux.h b/include/osmocom/mgcp/osmux.h
index 26c1bdf..1a99e6d 100644
--- a/include/osmocom/mgcp/osmux.h
+++ b/include/osmocom/mgcp/osmux.h
@@ -17,8 +17,8 @@
 int osmux_enable_conn(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn,
                      const struct osmo_sockaddr *addr);
 void conn_osmux_disable(struct mgcp_conn_rtp *conn);
-int conn_osmux_allocate_cid(struct mgcp_conn_rtp *conn, int osmux_cid);
-void conn_osmux_release_cid(struct mgcp_conn_rtp *conn);
+int conn_osmux_allocate_local_cid(struct mgcp_conn_rtp *conn);
+void conn_osmux_release_local_cid(struct mgcp_conn_rtp *conn);
 int osmux_xfrm_to_osmux(char *buf, int buf_len, struct mgcp_conn_rtp *conn);
 int osmux_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn);

diff --git a/src/libosmo-mgcp/mgcp_conn.c b/src/libosmo-mgcp/mgcp_conn.c
index d963a56..cc309a3 100644
--- a/src/libosmo-mgcp/mgcp_conn.c
+++ b/src/libosmo-mgcp/mgcp_conn.c
@@ -95,8 +95,10 @@
        static atomic_uint rate_ctr_index = 0;

        conn_rtp->type = MGCP_RTP_DEFAULT;
-       conn_rtp->osmux.cid_allocated = false;
-       conn_rtp->osmux.cid = 0;
+       conn_rtp->osmux.local_cid_allocated = false;
+       conn_rtp->osmux.local_cid = 0;
+       conn_rtp->osmux.remote_cid_present = false;
+       conn_rtp->osmux.remote_cid = 0;

        /* backpointer to the generic part of the connection */
        conn->u.rtp.conn = conn;
diff --git a/src/libosmo-mgcp/mgcp_osmux.c b/src/libosmo-mgcp/mgcp_osmux.c
index 83a96fe..72152c7 100644
--- a/src/libosmo-mgcp/mgcp_osmux.c
+++ b/src/libosmo-mgcp/mgcp_osmux.c
@@ -210,7 +210,7 @@

        if (conn->osmux.state != OSMUX_STATE_ENABLED) {
                LOGPCONN(conn->conn, DOSMUX, LOGL_INFO, "forwarding RTP to 
Osmux conn not yet enabled, dropping (cid=%d)\n",
-               conn->osmux.cid);
+               conn->osmux.remote_cid);
                rtpconn_rate_ctr_inc(conn, conn->conn->endp, 
OSMUX_DROPPED_AMR_PAYLOADS_CTR);
                return -1;
        }
@@ -222,7 +222,7 @@
        memcpy(msg->data, buf, buf_len);
        msgb_put(msg, buf_len);

-       while ((ret = osmux_xfrm_input(conn->osmux.in, msg, conn->osmux.cid)) > 
0) {
+       while ((ret = osmux_xfrm_input(conn->osmux.in, msg, 
conn->osmux.remote_cid)) > 0) {
                /* batch full, build and deliver it */
                osmux_xfrm_input_deliver(conn->osmux.in);
        }
@@ -231,7 +231,7 @@

 /* Lookup the endpoint that corresponds to the specified address (port) */
 static struct mgcp_conn_rtp*
-osmux_conn_lookup(struct mgcp_trunk *trunk, uint8_t cid, const struct 
osmo_sockaddr *rem_addr)
+osmux_conn_lookup(struct mgcp_trunk *trunk, uint8_t local_cid, const struct 
osmo_sockaddr *rem_addr)
 {
        struct mgcp_endpoint *endp;
        struct mgcp_conn *conn = NULL;
@@ -252,13 +252,13 @@

                        /* FIXME: Match remote address! */

-                       if (conn_rtp->osmux.cid == cid)
+                       if (conn_rtp->osmux.local_cid == local_cid)
                                return conn_rtp;
                }
        }

-       LOGP(DOSMUX, LOGL_ERROR, "Cannot find osmux conn with rem_addr=%s 
cid=%d\n",
-            osmo_sockaddr_to_str(rem_addr), cid);
+       LOGP(DOSMUX, LOGL_ERROR, "Cannot find osmux conn with rem_addr=%s 
local_cid=%d\n",
+            osmo_sockaddr_to_str(rem_addr), local_cid);

        return NULL;
 }
@@ -327,7 +327,8 @@
                LOGPCONN(conn->conn, DOSMUX, LOGL_INFO,
                         "Osmux %s CID %u towards %s is now enabled\n",
                         sending ? "sent" : "received",
-                        conn->osmux.cid, osmo_sockaddr_to_str(&rem_addr));
+                        sending ? conn->osmux.remote_cid : 
conn->osmux.local_cid,
+                        osmo_sockaddr_to_str(&rem_addr));
                return 0;
        case OSMUX_STATE_ENABLED:
                return 0;
@@ -517,16 +518,16 @@
                        mgcp_conn_dump(conn->conn));
                return -1;
        }
-       if (osmux_xfrm_input_open_circuit(conn->osmux.in, conn->osmux.cid, 
osmux_dummy) < 0) {
+       if (osmux_xfrm_input_open_circuit(conn->osmux.in, 
conn->osmux.remote_cid, osmux_dummy) < 0) {
                LOGPCONN(conn->conn, DOSMUX, LOGL_ERROR,
                        "Cannot open osmux circuit %u for conn:%s\n",
-                    conn->osmux.cid, mgcp_conn_dump(conn->conn));
+                    conn->osmux.remote_cid, mgcp_conn_dump(conn->conn));
                return -1;
        }

        conn->osmux.out = osmux_xfrm_output_alloc(conn->conn);
        osmux_xfrm_output_set_rtp_ssrc(conn->osmux.out,
-                                      (conn->osmux.cid * rtp_ssrc_winlen) +
+                                      (conn->osmux.remote_cid * 
rtp_ssrc_winlen) +
                                       (random() % rtp_ssrc_winlen));
        osmux_xfrm_output_set_rtp_pl_type(conn->osmux.out, 
conn->end.codec->payload_type);
        osmux_xfrm_output_set_tx_cb(conn->osmux.out,
@@ -547,7 +548,7 @@
        OSMO_ASSERT(conn->osmux.state != OSMUX_STATE_DISABLED);

        LOGPCONN(conn->conn, DOSMUX, LOGL_INFO,
-               "Releasing connection using Osmux CID %u\n", conn->osmux.cid);
+               "Releasing connection using local Osmux CID %u\n", 
conn->osmux.local_cid);

        struct rate_ctr_group *all_osmux_stats = 
conn->conn->endp->trunk->ratectr.all_osmux_conn_stats;
        rate_ctr_inc(rate_ctr_group_get_ctr(all_osmux_stats, 
OSMUX_NUM_CONNECTIONS));
@@ -557,53 +558,44 @@
                osmux_xfrm_output_set_tx_cb(conn->osmux.out, NULL, NULL);
                TALLOC_FREE(conn->osmux.out);

-               osmux_xfrm_input_close_circuit(conn->osmux.in, conn->osmux.cid);
+               osmux_xfrm_input_close_circuit(conn->osmux.in, 
conn->osmux.remote_cid);
                conn->osmux.state = OSMUX_STATE_DISABLED;
                osmux_handle_put(conn->osmux.in);
+               conn->osmux.remote_cid = 0;
+               conn->osmux.remote_cid_present = false;

                rate_ctr_group_free(conn->osmux.ctrg);
                conn->osmux.ctrg = NULL;
        }
-       conn_osmux_release_cid(conn);
+       conn_osmux_release_local_cid(conn);
 }

 /*! relase OSXMUX cid, that had been allocated to this connection.
  *  \param[in] conn connection with OSMUX cid to release */
-void conn_osmux_release_cid(struct mgcp_conn_rtp *conn)
+void conn_osmux_release_local_cid(struct mgcp_conn_rtp *conn)
 {
-       if (conn->osmux.cid_allocated)
-               osmux_cid_pool_put(conn->osmux.cid);
-       conn->osmux.cid = 0;
-       conn->osmux.cid_allocated = false;
+       if (conn->osmux.local_cid_allocated)
+               osmux_cid_pool_put(conn->osmux.local_cid);
+       conn->osmux.local_cid = 0;
+       conn->osmux.local_cid_allocated = false;
 }

-/*! allocate OSXMUX cid to connection.
- *  \param[in] conn connection for which we allocate the OSMUX cid
- * \param[in] osmux_cid OSMUX cid to allocate. -1 Means take next available 
one.
- * \returns Allocated OSMUX cid, -1 on error (no free  cids avail, or selected 
one is already taken).
+/*! allocate local OSMUX cid to connection.
+ *  \param[in] conn connection for which we allocate the local OSMUX cid
+ * \returns Allocated OSMUX cid, -1 on error (no free CIDs avail).
  */
-int conn_osmux_allocate_cid(struct mgcp_conn_rtp *conn, int osmux_cid)
+int conn_osmux_allocate_local_cid(struct mgcp_conn_rtp *conn)
 {
-       if (osmux_cid != -1 && osmux_cid_pool_allocated((uint8_t) osmux_cid)) {
+       OSMO_ASSERT(conn->osmux.local_cid_allocated == false);
+       int osmux_cid = osmux_cid_pool_get_next();
+       if (osmux_cid == -1) {
                LOGPCONN(conn->conn, DOSMUX, LOGL_INFO,
-                        "Osmux CID %d already allocated!\n",
-                        osmux_cid);
+                        "no available local Osmux CID to allocate!\n");
                return -1;
        }

-       if (osmux_cid == -1) {
-               osmux_cid = osmux_cid_pool_get_next();
-               if (osmux_cid == -1) {
-                       LOGPCONN(conn->conn, DOSMUX, LOGL_INFO,
-                                "no available Osmux CID to allocate!\n");
-                       return -1;
-               }
-       } else {
-               osmux_cid_pool_get(osmux_cid);
-       }
-
-       conn->osmux.cid = (uint8_t) osmux_cid;
-       conn->osmux.cid_allocated = true;
+       conn->osmux.local_cid = (uint8_t) osmux_cid;
+       conn->osmux.local_cid_allocated = true;
        conn->type = MGCP_OSMUX_BSC;
        return osmux_cid;
 }
@@ -640,12 +632,12 @@
        memset(osmuxh, 0, buf_len);
        osmuxh->ft = OSMUX_FT_DUMMY;
        osmuxh->amr_ft = AMR_FT_0;
-       osmuxh->circuit_id = conn->osmux.cid;
+       osmuxh->circuit_id = conn->osmux.remote_cid;

        LOGPCONN(conn->conn, DOSMUX, LOGL_DEBUG,
                 "sending OSMUX dummy load to %s:%u CID %u\n",
                 osmo_sockaddr_ntop(&conn->end.addr.u.sa, ipbuf),
-                ntohs(conn->end.rtp_port), conn->osmux.cid);
+                ntohs(conn->end.rtp_port), conn->osmux.remote_cid);

        return mgcp_udp_send(osmux_fd.fd, &conn->end.addr,
                             conn->end.rtp_port, (char*)osmuxh, buf_len);
diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c
index 7f31cfd..506de34 100644
--- a/src/libosmo-mgcp/mgcp_protocol.c
+++ b/src/libosmo-mgcp/mgcp_protocol.c
@@ -301,7 +301,7 @@

        /* Attach optional OSMUX parameters */
        if (mgcp_conn_rtp_is_osmux(conn)) {
-               rc = msgb_printf(sdp, MGCP_X_OSMO_OSMUX_HEADER " %u\r\n", 
conn->osmux.cid);
+               rc = msgb_printf(sdp, MGCP_X_OSMO_OSMUX_HEADER " %u\r\n", 
conn->osmux.local_cid);
                if (rc < 0)
                        goto error;
        }
@@ -846,7 +846,7 @@
        const char *callid = NULL;
        const char *mode = NULL;
        char *line;
-       int have_sdp = 0, osmux_cid = -2;
+       int have_sdp = 0, remote_osmux_cid = -2;
        struct mgcp_conn_rtp *conn = NULL;
        struct mgcp_conn *_conn = NULL;
        char conn_name[512];
@@ -895,7 +895,7 @@
                                /* If osmux is disabled, just skip setting it 
up */
                                if (rq->endp->trunk->cfg->osmux_use == 
OSMUX_USAGE_OFF)
                                        break;
-                               osmux_cid = mgcp_osmux_setup(endp, line);
+                               remote_osmux_cid = mgcp_osmux_setup(endp, line);
                                break;
                        }

@@ -1001,12 +1001,17 @@
        /* Annotate Osmux circuit ID and set it to negotiating state until this
         * is fully set up from the dummy load. */
        conn->osmux.state = OSMUX_STATE_DISABLED;
-       if (osmux_cid >= -1) { /* -1 is wilcard, alloc next avail CID */
+       /* If X-Osmux (remote CID) was received (-1 is wilcard), alloc next 
avail CID as local CID */
+       if (remote_osmux_cid >= -1) {
                conn->osmux.state = OSMUX_STATE_ACTIVATING;
-               if (conn_osmux_allocate_cid(conn, osmux_cid) == -1) {
+               if (conn_osmux_allocate_local_cid(conn) == -1) {
                        rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, 
MGCP_CRCX_FAIL_NO_OSMUX));
                        goto error2;
                }
+               if (remote_osmux_cid >= 0) {
+                       conn->osmux.remote_cid_present = true;
+                       conn->osmux.remote_cid = remote_osmux_cid;
+               }
        } else if (endp->trunk->cfg->osmux_use == OSMUX_USAGE_ONLY) {
                LOGPCONN(_conn, DLMGCP, LOGL_ERROR,
                         "CRCX: osmux only and no osmux offered\n");
@@ -1118,7 +1123,7 @@
        const char *mode = NULL;
        struct mgcp_conn_rtp *conn = NULL;
         const char *conn_id = NULL;
-       int osmux_cid = -2;
+       int remote_osmux_cid = -2;
        int rc;

        LOGPENDP(endp, DLMGCP, LOGL_NOTICE, "MDCX: modifying existing 
connection ...\n");
@@ -1176,7 +1181,7 @@
                                /* If osmux is disabled, just skip setting it 
up */
                                if (endp->trunk->cfg->osmux_use == 
OSMUX_USAGE_OFF)
                                        break;
-                               osmux_cid = mgcp_osmux_setup(endp, line);
+                               remote_osmux_cid = mgcp_osmux_setup(endp, line);
                                break;
                        }
                        /* Ignore unknown X-headers */
@@ -1253,23 +1258,23 @@
        }

        if (mgcp_conn_rtp_is_osmux(conn)) {
-               OSMO_ASSERT(conn->osmux.cid_allocated);
-               if (osmux_cid < -1) {
+               OSMO_ASSERT(conn->osmux.local_cid_allocated);
+               if (remote_osmux_cid < -1) {
                        LOGPCONN(conn->conn, DLMGCP, LOGL_ERROR,
                                 "MDCX: Failed to parse Osmux CID!\n");
                        goto error3;
-               } else if (osmux_cid == -1) {
+               } else if (remote_osmux_cid == -1) {
                        LOGPCONN(conn->conn, DLMGCP, LOGL_ERROR,
                                 "MDCX: wilcard in MDCX is not supported!\n");
                        goto error3;
-               } else if (osmux_cid != (int) conn->osmux.cid) {
+               } else if (conn->osmux.remote_cid_present &&
+                          remote_osmux_cid != (int) conn->osmux.remote_cid) {
                        LOGPCONN(conn->conn, DLMGCP, LOGL_ERROR,
                                 "MDCX: changing already allocated CID is not 
supported!\n");
                        goto error3;
                }
-               /* TODO: In the future (when we have recvCID!=sendCID), we need 
to
-                  tell Osmux code that osmux_cid is to be used as sendCID for
-                  that conn. */
+               conn->osmux.remote_cid_present = true;
+               conn->osmux.remote_cid = remote_osmux_cid;
        }

        /* MDCX may have provided a new remote address, which means we may need

--
To view, visit https://gerrit.osmocom.org/c/osmo-mgw/+/29465
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-mgw
Gerrit-Branch: master
Gerrit-Change-Id: I6b03eabc0305580c9788c529bec7dda9044a008f
Gerrit-Change-Number: 29465
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-MessageType: newchange

Reply via email to