fixeria has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libosmo-sccp/+/35796?usp=email )


Change subject: Implement M3UA-over-TCP (in addition to SCTP)
......................................................................

Implement M3UA-over-TCP (in addition to SCTP)

RFC 4666 section 1.3.1 states that "TCP MAY be used as the underlying
common transport protocol" under certain scenarios.  There is even
IANA-allocated TCP port 2905 for that purpose (see section 1.4.8).

Since TCP is a stream oriented protocol, so we need to handle message
boundaries ourselves by reading the M3UA header to know the PDU length.

Change-Id: I8c76d271472befacbeb998a93bbdc9e8660d9b5d
Related: SYS#5424
---
M examples/sccp_demo_user.c
M include/osmocom/sigtran/osmo_ss7.h
M src/m3ua.c
M src/osmo_ss7_asp.c
M src/osmo_ss7_hmrt.c
M src/osmo_ss7_vty.c
M src/osmo_ss7_xua_srv.c
M src/sccp_scrc.c
M src/ss7_internal.h
M src/xua_rkm.c
M src/xua_snm.c
M tests/vty/ss7_asp_test.vty
12 files changed, 274 insertions(+), 72 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/96/35796/1

diff --git a/examples/sccp_demo_user.c b/examples/sccp_demo_user.c
index a9e470d..a29cf0f 100644
--- a/examples/sccp_demo_user.c
+++ b/examples/sccp_demo_user.c
@@ -113,7 +113,7 @@
                        "             [-r REMOTE_ADDRESS[:REMOTE_PORT]]\n"
                        "             [-L LOCAL_POINT_CODE] [-R 
REMOTE_POINT_CODE]\n"
                        "Options:\n"
-                       "  -p: protocol to use (m3ua, sua, ipa; default is 
ipa)\n"
+                       "  -p: protocol to use (m3ua, m3ua-tcp, sua, ipa; 
default is ipa)\n"
                        "  -c: Run in client mode (default is server mode)\n"
                        "  -C filename  The config file to use\n"
                        "  -l: local IP address and SCTP port (default is %s:%d 
in server mode,\n"
diff --git a/include/osmocom/sigtran/osmo_ss7.h 
b/include/osmocom/sigtran/osmo_ss7.h
index ca7087b..381ca1a 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -279,6 +279,7 @@
        OSMO_SS7_ASP_PROT_SUA,
        OSMO_SS7_ASP_PROT_M3UA_SCTP,
        OSMO_SS7_ASP_PROT_IPA,
+       OSMO_SS7_ASP_PROT_M3UA_TCP,
        _NUM_OSMO_SS7_ASP_PROT
 };

diff --git a/src/m3ua.c b/src/m3ua.c
index 2c2a2a5..9977994 100644
--- a/src/m3ua.c
+++ b/src/m3ua.c
@@ -48,6 +48,10 @@

 #define M3UA_MSGB_SIZE 1500

+#define proto_is_m3ua(proto) \
+       (((proto) == OSMO_SS7_ASP_PROT_M3UA_SCTP) || \
+        ((proto) == OSMO_SS7_ASP_PROT_M3UA_TCP))
+
 /***********************************************************************
  * Protocol Definition (string tables, mandatory IE checking)
  ***********************************************************************/
@@ -478,7 +482,7 @@
 {
        struct msgb *msg = m3ua_to_msg(xua);

-       OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA_SCTP);
+       OSMO_ASSERT(proto_is_m3ua(asp->cfg.proto));

        if (!msg)
                return -1;
@@ -495,7 +499,7 @@
        struct msgb *msg;
        int rc;

-       OSMO_ASSERT(as->cfg.proto == OSMO_SS7_ASP_PROT_M3UA_SCTP);
+       OSMO_ASSERT(proto_is_m3ua(as->cfg.proto));

        /* Add RC for this AS */
        if (as->cfg.routing_key.context)
@@ -693,7 +697,7 @@
        struct xua_msg *xua = NULL, *err = NULL;
        int rc = 0;

-       OSMO_ASSERT(asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA_SCTP);
+       OSMO_ASSERT(proto_is_m3ua(asp->cfg.proto));

        /* caller owns msg memory, we shall neither free it here nor
         * keep references beyond the execution of this function and its
diff --git a/src/osmo_ss7_asp.c b/src/osmo_ss7_asp.c
index ac30b75..b51bc6a 100644
--- a/src/osmo_ss7_asp.c
+++ b/src/osmo_ss7_asp.c
@@ -116,6 +116,7 @@
        { OSMO_SS7_ASP_PROT_NONE,       "none" },
        { OSMO_SS7_ASP_PROT_SUA,        "sua" },
        { OSMO_SS7_ASP_PROT_M3UA_SCTP,  "m3ua" },
+       { OSMO_SS7_ASP_PROT_M3UA_TCP,   "m3ua-tcp" },
        { OSMO_SS7_ASP_PROT_IPA,        "ipa" },
        { 0, NULL }
 };
@@ -131,6 +132,7 @@
 {
        switch (proto) {
        case OSMO_SS7_ASP_PROT_IPA:
+       case OSMO_SS7_ASP_PROT_M3UA_TCP:
                return IPPROTO_TCP;
        case OSMO_SS7_ASP_PROT_SUA:
        case OSMO_SS7_ASP_PROT_M3UA_SCTP:
@@ -143,6 +145,7 @@
        [OSMO_SS7_ASP_PROT_NONE] = 0,
        [OSMO_SS7_ASP_PROT_SUA] = SUA_PORT,
        [OSMO_SS7_ASP_PROT_M3UA_SCTP] = M3UA_PORT,
+       [OSMO_SS7_ASP_PROT_M3UA_TCP] = M3UA_PORT,
        [OSMO_SS7_ASP_PROT_IPA] = 5000,
 };

@@ -566,6 +569,7 @@

 static int xua_cli_read_cb(struct osmo_stream_cli *conn);
 static int ipa_cli_read_cb(struct osmo_stream_cli *conn);
+static int m3ua_tcp_cli_read_cb(struct osmo_stream_cli *conn);
 static int xua_cli_connect_cb(struct osmo_stream_cli *cli);

 int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp)
@@ -604,10 +608,17 @@
                osmo_stream_cli_set_proto(asp->client, 
ss7_asp_proto_to_ip_proto(asp->cfg.proto));
                osmo_stream_cli_set_reconnect_timeout(asp->client, 5);
                osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb);
-               if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA)
+               switch (asp->cfg.proto) {
+               case OSMO_SS7_ASP_PROT_IPA:
                        osmo_stream_cli_set_read_cb(asp->client, 
ipa_cli_read_cb);
-               else
+                       break;
+               case OSMO_SS7_ASP_PROT_M3UA_TCP:
+                       osmo_stream_cli_set_read_cb(asp->client, 
m3ua_tcp_cli_read_cb);
+                       break;
+               default:
                        osmo_stream_cli_set_read_cb(asp->client, 
xua_cli_read_cb);
+                       break;
+               }
                osmo_stream_cli_set_data(asp->client, asp);
                byte = 1; /*AUTH is needed by ASCONF. enable, don't abort 
socket creation if AUTH can't be enabled */
                osmo_stream_cli_set_param(asp->client, 
OSMO_STREAM_CLI_PAR_SCTP_SOCKOPT_AUTH_SUPPORTED, &byte, sizeof(byte));
@@ -838,6 +849,78 @@
        return rc;
 }

+/* netif code tells us we can read something from the socket */
+int ss7_asp_m3ua_tcp_srv_conn_cb(struct osmo_stream_srv *conn)
+{
+       struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn);
+       int fd = osmo_stream_srv_get_fd(conn);
+       struct msgb *msg = asp->pending_msg;
+       const struct xua_common_hdr *hdr;
+       size_t msg_length;
+       int rc;
+
+       OSMO_ASSERT(fd >= 0);
+
+       if (msg == NULL) {
+               msg = m3ua_msgb_alloc(__func__);
+               asp->pending_msg = msg;
+       }
+
+       /* read message header first */
+       if (msg->len < sizeof(*hdr)) {
+               errno = 0;
+               rc = recv(fd, msg->tail, sizeof(*hdr) - msg->len, 0);
+               if (rc <= 0) {
+                       if (errno == EAGAIN || errno == EINTR)
+                               return 0; /* need more data */
+                       osmo_stream_srv_destroy(conn);
+                       asp->pending_msg = NULL;
+                       msgb_free(msg);
+                       return rc;
+               }
+
+               msgb_put(msg, rc);
+               if (msg->len < sizeof(*hdr))
+                       return 0; /* need more data */
+       }
+
+       hdr = (const struct xua_common_hdr *)msg->data;
+       msg_length = ntohl(hdr->msg_length); /* includes sizeof(*hdr) */
+
+       /* read the rest of the message */
+       if (msg->len < msg_length) {
+               errno = 0;
+               rc = recv(fd, msg->tail, msg_length - msg->len, 0);
+               if (rc <= 0) {
+                       if (errno == EAGAIN || errno == EINTR)
+                               return 0; /* need more data */
+                       osmo_stream_srv_destroy(conn);
+                       asp->pending_msg = NULL;
+                       msgb_free(msg);
+                       return rc;
+               }
+
+               msgb_put(msg, rc);
+               if (msg->len < msg_length)
+                       return 0; /* need more data */
+       }
+
+       msg->dst = asp;
+       rate_ctr_inc2(asp->ctrg, SS7_ASP_CTR_PKT_RX_TOTAL);
+
+       /* spoof SCTP Stream ID */
+       if (hdr->msg_class == M3UA_MSGC_XFER)
+               msgb_sctp_stream(msg) = 1;
+       else
+               msgb_sctp_stream(msg) = 0;
+
+       rc = m3ua_rx_msg(asp, msg);
+       asp->pending_msg = NULL;
+       msgb_free(msg);
+
+       return rc;
+}
+
 /* client has established SCTP connection to server */
 static int xua_cli_connect_cb(struct osmo_stream_cli *cli)
 {
@@ -926,6 +1009,78 @@
        return ipa_rx_msg(asp, msg, fd & 0xf);
 }

+/* read call-back for M3UA-over-TCP socket */
+static int m3ua_tcp_cli_read_cb(struct osmo_stream_cli *conn)
+{
+       struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn);
+       int fd = osmo_stream_cli_get_fd(conn);
+       struct msgb *msg = asp->pending_msg;
+       const struct xua_common_hdr *hdr;
+       size_t msg_length;
+       int rc;
+
+       OSMO_ASSERT(fd >= 0);
+
+       if (msg == NULL) {
+               msg = m3ua_msgb_alloc(__func__);
+               asp->pending_msg = msg;
+       }
+
+       /* read message header first */
+       if (msg->len < sizeof(*hdr)) {
+               errno = 0;
+               rc = recv(fd, msg->tail, sizeof(*hdr) - msg->len, 0);
+               if (rc <= 0) {
+                       if (errno == EAGAIN || errno == EINTR)
+                               return 0; /* need more data */
+                       xua_cli_close_and_reconnect(conn);
+                       asp->pending_msg = NULL;
+                       msgb_free(msg);
+                       return rc;
+               }
+
+               msgb_put(msg, rc);
+               if (msg->len < sizeof(*hdr))
+                       return 0; /* need more data */
+       }
+
+       hdr = (const struct xua_common_hdr *)msg->data;
+       msg_length = ntohl(hdr->msg_length); /* includes sizeof(*hdr) */
+
+       /* read the rest of the message */
+       if (msg->len < msg_length) {
+               errno = 0;
+               rc = recv(fd, msg->tail, msg_length - msg->len, 0);
+               if (rc <= 0) {
+                       if (errno == EAGAIN || errno == EINTR)
+                               return 0; /* need more data */
+                       xua_cli_close_and_reconnect(conn);
+                       asp->pending_msg = NULL;
+                       msgb_free(msg);
+                       return rc;
+               }
+
+               msgb_put(msg, rc);
+               if (msg->len < msg_length)
+                       return 0; /* need more data */
+       }
+
+       msg->dst = asp;
+       rate_ctr_inc2(asp->ctrg, SS7_ASP_CTR_PKT_RX_TOTAL);
+
+       /* spoof SCTP Stream ID */
+       if (hdr->msg_class == M3UA_MSGC_XFER)
+               msgb_sctp_stream(msg) = 1;
+       else
+               msgb_sctp_stream(msg) = 0;
+
+       rc = m3ua_rx_msg(asp, msg);
+       asp->pending_msg = NULL;
+       msgb_free(msg);
+
+       return rc;
+}
+
 static int xua_cli_read_cb(struct osmo_stream_cli *conn)
 {
        struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn);
@@ -1033,6 +1188,7 @@
        case OSMO_SS7_ASP_PROT_M3UA_SCTP:
                msgb_sctp_ppid(msg) = M3UA_PPID;
                break;
+       case OSMO_SS7_ASP_PROT_M3UA_TCP:
        case OSMO_SS7_ASP_PROT_IPA:
                break;
        default:
@@ -1096,6 +1252,8 @@
                LOGPASP(asp, DLSS7, LOGL_NOTICE, "Rx IPA for unknown Stream ID 
0x%02x: %s\n",
                        ppid_mux, msgb_hexdump(msg));
                break;
+       case OSMO_SS7_ASP_PROT_M3UA_TCP:
+               OSMO_ASSERT(0); /* shall not happen */
        default:
                LOGPASP(asp, DLSS7, LOGL_NOTICE, "Rx SCTP chunk for unknown 
PPID %u: %s\n",
                        ppid_mux, msgb_hexdump(msg));
@@ -1109,6 +1267,7 @@
 {
        switch (asp->cfg.proto) {
        case OSMO_SS7_ASP_PROT_M3UA_SCTP:
+       case OSMO_SS7_ASP_PROT_M3UA_TCP:
                return DLM3UA;
        case OSMO_SS7_ASP_PROT_SUA:
                return DLSUA;
diff --git a/src/osmo_ss7_hmrt.c b/src/osmo_ss7_hmrt.c
index 76b174b..6c8ad73 100644
--- a/src/osmo_ss7_hmrt.c
+++ b/src/osmo_ss7_hmrt.c
@@ -238,6 +238,7 @@

                        switch (as->cfg.proto) {
                        case OSMO_SS7_ASP_PROT_M3UA_SCTP:
+                       case OSMO_SS7_ASP_PROT_M3UA_TCP:
                                DEBUGP(DLSS7, "rt->dest.as proto is M3UA for 
dpc=%u=%s\n",
                                       dpc, osmo_ss7_pointcode_print(inst, 
dpc));
                                return m3ua_tx_xua_as(as,xua);
diff --git a/src/osmo_ss7_vty.c b/src/osmo_ss7_vty.c
index 5b8269f..eed9874 100644
--- a/src/osmo_ss7_vty.c
+++ b/src/osmo_ss7_vty.c
@@ -55,11 +55,12 @@
 #include <osmocom/netif/sctp.h>
 #endif

-#define XUA_VAR_STR    "(sua|m3ua|ipa)"
+#define XUA_VAR_STR    "(sua|m3ua|m3ua-tcp|ipa)"

 #define XUA_VAR_HELP_STR               \
-       "SCCP User Adaptation\n"         \
-       "MTP3 User Adaptation\n"        \
+       "SCCP User Adaptation\n"        \
+       "MTP3 User Adaptation (SCTP)\n" \
+       "MTP3 User Adaptation (TCP)\n"  \
        "IPA Multiplex (SCCP Lite)\n"

 /* netinet/tcp.h */
@@ -479,7 +480,7 @@
 DEFUN_ATTR(cs7_xua, cs7_xua_cmd,
           "listen " XUA_VAR_STR " <0-65534>",
           "Configure/Enable xUA Listener\n"
-          XUA_VAR_HELP_STR "SCTP Port number\n",
+          XUA_VAR_HELP_STR "SCTP/TCP Port number\n",
           CMD_ATTR_IMMEDIATE)
 {
        struct osmo_ss7_instance *inst = vty->index;
@@ -503,8 +504,8 @@

 DEFUN_ATTR(no_cs7_xua, no_cs7_xua_cmd,
           "no listen " XUA_VAR_STR " <0-65534>",
-          NO_STR "Disable xUA Listener on given SCTP Port\n"
-          XUA_VAR_HELP_STR "SCTP Port number\n",
+          NO_STR "Disable xUA Listener on given SCTP/TCP Port\n"
+          XUA_VAR_HELP_STR "SCTP/TCP Port number\n",
           CMD_ATTR_IMMEDIATE)
 {
        struct osmo_ss7_instance *inst = vty->index;
@@ -665,7 +666,7 @@

 DEFUN(show_cs7_xua, show_cs7_xua_cmd,
       "show cs7 "XUA_VAR_STR" [<0-65534>]",
-      SHOW_STR CS7_STR XUA_VAR_HELP_STR "Port Number")
+      SHOW_STR CS7_STR XUA_VAR_HELP_STR "SCTP/TCP Port Number")
 {
        struct osmo_ss7_instance *inst;
        struct osmo_xua_server *xs;
@@ -713,8 +714,8 @@
           "asp NAME <0-65535> <0-65535> " XUA_VAR_STR,
           "Configure Application Server Process\n"
           "Name of ASP\n"
-          "Remote SCTP port number\n"
-          "Local SCTP port number\n"
+          "Remote SCTP/TCP port number\n"
+          "Local SCTP/TCP port number\n"
           XUA_VAR_HELP_STR,
           CMD_ATTR_NODE_EXIT)
 {
@@ -787,7 +788,7 @@

        if (!ss7_asp_is_started(asp))
                return CMD_SUCCESS;
-       if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA)
+       if (ss7_asp_proto_to_ip_proto(asp->cfg.proto) != IPPROTO_SCTP)
                return CMD_SUCCESS;
        /* The SCTP socket is already created. */

@@ -833,7 +834,7 @@
        }

        if (ss7_asp_is_started(asp)) {
-               if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA) {
+               if (ss7_asp_proto_to_ip_proto(asp->cfg.proto) == IPPROTO_SCTP) {
                        if ((rc = ss7_asp_apply_drop_local_address(asp, idx)) < 
0) {
                                vty_out(vty, "%% Failed removing local address 
'%s' from existing socket%s", argv[0], VTY_NEWLINE);
                                return CMD_WARNING;
@@ -869,17 +870,15 @@

        if (!ss7_asp_is_started(asp))
                return CMD_SUCCESS;
-       if (asp->cfg.proto == OSMO_SS7_ASP_PROT_IPA)
+       if (ss7_asp_proto_to_ip_proto(asp->cfg.proto) != IPPROTO_SCTP)
                return CMD_SUCCESS;

        /* The SCTP socket is already created, dynamically apply the new 
primary if it changed: */
-       if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA && ss7_asp_is_started(asp)) 
{
-               if ((rc = ss7_asp_apply_primary_address(asp)) < 0) {
-                       /* Failed, rollback changes: */
-                       asp->cfg.remote.idx_primary = old_idx_primary;
-                       vty_out(vty, "%% Failed applying primary on host 
'%s'%s", argv[0], VTY_NEWLINE);
-                       return CMD_WARNING;
-               }
+       if ((rc = ss7_asp_apply_primary_address(asp)) < 0) {
+               /* Failed, rollback changes: */
+               asp->cfg.remote.idx_primary = old_idx_primary;
+               vty_out(vty, "%% Failed applying primary on host '%s'%s", 
argv[0], VTY_NEWLINE);
+               return CMD_WARNING;
        }
        return CMD_SUCCESS;
 }
@@ -1202,7 +1201,7 @@
                osmo_ss7_asp_peer_snprintf(buf_rem, sizeof(buf_rem), 
&asp->cfg.remote);
        }

-       vty_out(vty, "%-12s  %-12s  %-13s  %-4s  %-4s  %-9s  %-23s  %-23s%s",
+       vty_out(vty, "%-12s  %-12s  %-13s  %-8s  %-4s  %-9s  %-23s  %-23s%s",
                asp->cfg.name,
                as_list_for_asp(asp, as_buf, sizeof(as_buf)),
                asp->fi ? osmo_fsm_inst_state_name(asp->fi) : "uninitialized",
@@ -1232,8 +1231,8 @@
                }
        }

-       vty_out(vty, "ASP Name      AS Name       State          Type  Role  
SCTP Role  Local Addresses          Remote Addresses%s", VTY_NEWLINE);
-       vty_out(vty, "------------  ------------  -------------  ----  ----  
---------  -----------------------  -----------------------%s", VTY_NEWLINE);
+       vty_out(vty, "ASP Name      AS Name       State          Type      Role 
 SCTP Role  Local Addresses          Remote Addresses%s", VTY_NEWLINE);
+       vty_out(vty, "------------  ------------  -------------  --------  ---- 
 ---------  -----------------------  -----------------------%s", VTY_NEWLINE);

        if (asp) {
                show_one_asp(vty, asp);
@@ -1992,7 +1991,7 @@
        SHOW_STR CS7_STR INST_STR INST_STR "Application Server (AS)\n"
        "Display all active ASs\n"
        "Display all ASs (default)\n"
-       "Display all m3ua ASs\n"
+       "Display all M3UA (SCTP and TCP) ASs\n"
        "Display all SUA ASs\n")
 {
        struct osmo_ss7_instance *inst;
@@ -2011,8 +2010,11 @@
        vty_out(vty, "------------ ------------ ---------- ------------- ---- 
------------- --- ----- ----- -------%s", VTY_NEWLINE);

        llist_for_each_entry(as, &inst->as_list, list) {
-               if (filter && !strcmp(filter, "m3ua") && as->cfg.proto != 
OSMO_SS7_ASP_PROT_M3UA_SCTP)
-                       continue;
+               if (filter && !strcmp(filter, "m3ua")) {
+                       if (as->cfg.proto != OSMO_SS7_ASP_PROT_M3UA_SCTP &&
+                           as->cfg.proto != OSMO_SS7_ASP_PROT_M3UA_TCP)
+                               continue;
+               }
                if (filter && !strcmp(filter, "sua") && as->cfg.proto != 
OSMO_SS7_ASP_PROT_SUA)
                        continue;
                if (filter && !strcmp(filter, "active") && 
!osmo_ss7_as_active(as))
diff --git a/src/osmo_ss7_xua_srv.c b/src/osmo_ss7_xua_srv.c
index 32266ff..365b955 100644
--- a/src/osmo_ss7_xua_srv.c
+++ b/src/osmo_ss7_xua_srv.c
@@ -71,14 +71,22 @@

        LOGP(DLSS7, LOGL_INFO, "%s: New %s connection accepted\n", sock_name, 
proto_name);

-       if (oxs->cfg.proto == OSMO_SS7_ASP_PROT_IPA) {
+       switch (oxs->cfg.proto) {
+       case OSMO_SS7_ASP_PROT_IPA:
                srv = osmo_stream_srv_create(oxs, link, fd,
                                             ss7_asp_ipa_srv_conn_cb,
                                             ss7_asp_xua_srv_conn_closed_cb, 
NULL);
-       } else {
+               break;
+       case OSMO_SS7_ASP_PROT_M3UA_TCP:
+               srv = osmo_stream_srv_create(oxs, link, fd,
+                                            ss7_asp_m3ua_tcp_srv_conn_cb,
+                                            ss7_asp_xua_srv_conn_closed_cb, 
NULL);
+               break;
+       default:
                srv = osmo_stream_srv_create(oxs, link, fd,
                                             ss7_asp_xua_srv_conn_cb,
                                             ss7_asp_xua_srv_conn_closed_cb, 
NULL);
+               break;
        }
        if (!srv) {
                LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server "
@@ -157,7 +165,7 @@
         * data */
        osmo_stream_srv_set_data(srv, asp);

-       if (oxs->cfg.proto != OSMO_SS7_ASP_PROT_IPA) {
+       if (ss7_asp_proto_to_ip_proto(asp->cfg.proto) == IPPROTO_SCTP) {
                rc = ss7_asp_apply_peer_primary_address(asp);
                rc = ss7_asp_apply_primary_address(asp);
        }
diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c
index 79b2857..ac9f63e 100644
--- a/src/sccp_scrc.c
+++ b/src/sccp_scrc.c
@@ -152,6 +152,7 @@
                case OSMO_SS7_ASP_PROT_SUA:
                        return sua_tx_xua_as(as, xua);
                case OSMO_SS7_ASP_PROT_M3UA_SCTP:
+               case OSMO_SS7_ASP_PROT_M3UA_TCP:
                case OSMO_SS7_ASP_PROT_IPA:
                        return sua2sccp_tx_m3ua(inst, xua);
                default:
diff --git a/src/ss7_internal.h b/src/ss7_internal.h
index fd01ca4..f6e73d6 100644
--- a/src/ss7_internal.h
+++ b/src/ss7_internal.h
@@ -25,6 +25,7 @@
 int ss7_asp_proto_to_ip_proto(enum osmo_ss7_asp_protocol proto);
 int ss7_asp_ipa_srv_conn_cb(struct osmo_stream_srv *conn);
 int ss7_asp_xua_srv_conn_cb(struct osmo_stream_srv *conn);
+int ss7_asp_m3ua_tcp_srv_conn_cb(struct osmo_stream_srv *conn);
 int ss7_asp_xua_srv_conn_closed_cb(struct osmo_stream_srv *srv);
 int ss7_asp_apply_peer_primary_address(const struct osmo_ss7_asp *asp);
 int ss7_asp_apply_primary_address(const struct osmo_ss7_asp *asp);
diff --git a/src/xua_rkm.c b/src/xua_rkm.c
index aba6187..bb8bc0f 100644
--- a/src/xua_rkm.c
+++ b/src/xua_rkm.c
@@ -237,6 +237,7 @@
        } else if (asp->inst->cfg.permit_dyn_rkm_alloc) {
                /* Create an AS for this routing key */
                snprintf(namebuf, sizeof(namebuf), "as-rkm-%u", rctx);
+               /* XXX: M3UA-over-SCTP or M3UA-over-TCP?  Can we use 
asp->cfg.proto maybe? */
                as = osmo_ss7_as_find_or_create(asp->inst, namebuf, 
OSMO_SS7_ASP_PROT_M3UA_SCTP);
                if (!as) {
                        LOGPASP(asp, DLSS7, LOGL_ERROR, "RKM: Cannot create AS 
%s\n", namebuf);
diff --git a/src/xua_snm.c b/src/xua_snm.c
index 63aaa80..9eee07d 100644
--- a/src/xua_snm.c
+++ b/src/xua_snm.c
@@ -90,6 +90,7 @@
 {
        switch (asp->cfg.proto) {
        case OSMO_SS7_ASP_PROT_M3UA_SCTP:
+       case OSMO_SS7_ASP_PROT_M3UA_TCP:
                m3ua_tx_snm_available(asp, rctx, num_rctx, aff_pc, num_aff_pc, 
info_str, available);
                break;
        case OSMO_SS7_ASP_PROT_SUA:
@@ -105,6 +106,7 @@
 {
        switch (asp->cfg.proto) {
        case OSMO_SS7_ASP_PROT_M3UA_SCTP:
+       case OSMO_SS7_ASP_PROT_M3UA_TCP:
                m3ua_tx_dupu(asp, rctx, num_rctx, dpc, user, cause, info_str);
                break;
        case OSMO_SS7_ASP_PROT_SUA:
@@ -122,6 +124,7 @@
 {
        switch (asp->cfg.proto) {
        case OSMO_SS7_ASP_PROT_M3UA_SCTP:
+       case OSMO_SS7_ASP_PROT_M3UA_TCP:
                m3ua_tx_snm_congestion(asp, rctx, num_rctx, aff_pc, num_aff_pc,
                                       concerned_dpc, cong_level, info_string);
                break;
@@ -436,6 +439,7 @@

        switch (asp->cfg.proto) {
        case OSMO_SS7_ASP_PROT_M3UA_SCTP:
+       case OSMO_SS7_ASP_PROT_M3UA_TCP:
                cause_user = xua_msg_get_u32(xua, M3UA_IEI_USER_CAUSE);
                break;
        case OSMO_SS7_ASP_PROT_SUA:
diff --git a/tests/vty/ss7_asp_test.vty b/tests/vty/ss7_asp_test.vty
index 914d8d4..36187b1 100644
--- a/tests/vty/ss7_asp_test.vty
+++ b/tests/vty/ss7_asp_test.vty
@@ -1,7 +1,7 @@
 ss7_asp_vty_test> list
 ... !show cs7
   show cs7 instance <0-15> users
-  show cs7 (sua|m3ua|ipa) [<0-65534>]
+  show cs7 (sua|m3ua|m3ua-tcp|ipa) [<0-65534>]
   show cs7 config
   show cs7 instance <0-15> asp
   show cs7 instance <0-15> asp name ASP_NAME
@@ -22,7 +22,7 @@
 ss7_asp_vty_test# list
 ... !show cs7
   show cs7 instance <0-15> users
-  show cs7 (sua|m3ua|ipa) [<0-65534>]
+  show cs7 (sua|m3ua|m3ua-tcp|ipa) [<0-65534>]
   show cs7 config
   show cs7 instance <0-15> asp
   show cs7 instance <0-15> asp name ASP_NAME
@@ -47,12 +47,13 @@
 ss7_asp_vty_test# show cs7 ?
   instance  An instance of the SS7 stack
   sua       SCCP User Adaptation
-  m3ua      MTP3 User Adaptation
+  m3ua      MTP3 User Adaptation (SCTP)
+  m3ua-tcp  MTP3 User Adaptation (TCP)
   ipa       IPA Multiplex (SCCP Lite)
   config    Currently running cs7 configuration

 ss7_asp_vty_test# show cs7 m3ua ?
-  [<0-65534>]  Port Number
+  [<0-65534>]  SCTP/TCP Port Number

 ss7_asp_vty_test# show cs7 instance ?
   <0-15>  An instance of the SS7 stack
@@ -69,7 +70,7 @@
 ss7_asp_vty_test# show cs7 instance 0 as ?
   active  Display all active ASs
   all     Display all ASs (default)
-  m3ua    Display all m3ua ASs
+  m3ua    Display all M3UA (SCTP and TCP) ASs
   sua     Display all SUA ASs

 ss7_asp_vty_test# show cs7 instance 0 sccp ?
@@ -94,9 +95,9 @@
   point-code format default
   point-code delimiter (default|dash)
   xua rkm routing-key-allocation (static-only|dynamic-permitted)
-  asp NAME <0-65535> <0-65535> (sua|m3ua|ipa)
+  asp NAME <0-65535> <0-65535> (sua|m3ua|m3ua-tcp|ipa)
   no asp NAME
-  as NAME (sua|m3ua|ipa)
+  as NAME (sua|m3ua|m3ua-tcp|ipa)
   no as NAME
   sccp-address NAME
   no sccp-address NAME
@@ -153,20 +154,22 @@
 ss7_asp_vty_test(config-cs7)# asp ?
   NAME  Name of ASP
 ss7_asp_vty_test(config-cs7)# asp foo ?
-  <0-65535>  Remote SCTP port number
+  <0-65535>  Remote SCTP/TCP port number
 ss7_asp_vty_test(config-cs7)# asp foo 0 ?
-  <0-65535>  Local SCTP port number
+  <0-65535>  Local SCTP/TCP port number
 ss7_asp_vty_test(config-cs7)# asp foo 0 0 ?
-  sua   SCCP User Adaptation
-  m3ua  MTP3 User Adaptation
-  ipa   IPA Multiplex (SCCP Lite)
+  sua       SCCP User Adaptation
+  m3ua      MTP3 User Adaptation (SCTP)
+  m3ua-tcp  MTP3 User Adaptation (TCP)
+  ipa       IPA Multiplex (SCCP Lite)

 ss7_asp_vty_test(config-cs7)# as ?
   NAME  Name of the Application Server
 ss7_asp_vty_test(config-cs7)# as foo ?
-  sua   SCCP User Adaptation
-  m3ua  MTP3 User Adaptation
-  ipa   IPA Multiplex (SCCP Lite)
+  sua       SCCP User Adaptation
+  m3ua      MTP3 User Adaptation (SCTP)
+  m3ua-tcp  MTP3 User Adaptation (TCP)
+  ipa       IPA Multiplex (SCCP Lite)

 ss7_asp_vty_test(config-cs7)# sccp-address ?
   NAME  Name of the SCCP Address
@@ -268,24 +271,24 @@
 ss7_asp_vty_test(config-cs7-asp)# remote-ip 127.0.0.200
 ss7_asp_vty_test(config-cs7-asp)# local-ip 127.0.0.100
 ss7_asp_vty_test(config-cs7-asp)# do show cs7 instance 0 asp
-ASP Name      AS Name       State          Type  Role  SCTP Role  Local 
Addresses          Remote Addresses
-------------  ------------  -------------  ----  ----  ---------  
-----------------------  -----------------------
-my-asp        ?             uninitialized  m3ua  sg    server     
127.0.0.100:54321        127.0.0.200:12345
+ASP Name      AS Name       State          Type      Role  SCTP Role  Local 
Addresses          Remote Addresses
+------------  ------------  -------------  --------  ----  ---------  
-----------------------  -----------------------
+my-asp        ?             uninitialized  m3ua      sg    server     
127.0.0.100:54321        127.0.0.200:12345
 ss7_asp_vty_test(config-cs7-asp)# remote-ip 127.0.0.201
 ss7_asp_vty_test(config-cs7-asp)# local-ip 127.0.0.101
 ss7_asp_vty_test(config-cs7-asp)# do show cs7 instance 0 asp
-ASP Name      AS Name       State          Type  Role  SCTP Role  Local 
Addresses          Remote Addresses
-------------  ------------  -------------  ----  ----  ---------  
-----------------------  -----------------------
-my-asp        ?             uninitialized  m3ua  sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201):12345
+ASP Name      AS Name       State          Type      Role  SCTP Role  Local 
Addresses          Remote Addresses
+------------  ------------  -------------  --------  ----  ---------  
-----------------------  -----------------------
+my-asp        ?             uninitialized  m3ua      sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201):12345
 ss7_asp_vty_test(config-cs7-asp)# ! Mark as primary:
 ss7_asp_vty_test(config-cs7-asp)# remote-ip 127.0.0.201 primary
 ss7_asp_vty_test(config-cs7-asp)# ! 'local-ip 127.0.0.101 primary' cannot be 
tested here since output may be different based on sysctl available
 ss7_asp_vty_test(config-cs7-asp)# local-ip 127.0.0.101
 ...
 ss7_asp_vty_test(config-cs7-asp)# do show cs7 instance 0 asp
-ASP Name      AS Name       State          Type  Role  SCTP Role  Local 
Addresses          Remote Addresses
-------------  ------------  -------------  ----  ----  ---------  
-----------------------  -----------------------
-my-asp        ?             uninitialized  m3ua  sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201*):12345
+ASP Name      AS Name       State          Type      Role  SCTP Role  Local 
Addresses          Remote Addresses
+------------  ------------  -------------  --------  ----  ---------  
-----------------------  -----------------------
+my-asp        ?             uninitialized  m3ua      sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201*):12345
 ss7_asp_vty_test(config-cs7-asp)# show running-config
 ...
   local-ip 127.0.0.100
@@ -298,9 +301,9 @@
 ss7_asp_vty_test(config-cs7-asp)# remote-ip 127.0.0.201
 ss7_asp_vty_test(config-cs7-asp)# local-ip 127.0.0.101
 ss7_asp_vty_test(config-cs7-asp)# do show cs7 instance 0 asp
-ASP Name      AS Name       State          Type  Role  SCTP Role  Local 
Addresses          Remote Addresses
-------------  ------------  -------------  ----  ----  ---------  
-----------------------  -----------------------
-my-asp        ?             uninitialized  m3ua  sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201):12345
+ASP Name      AS Name       State          Type      Role  SCTP Role  Local 
Addresses          Remote Addresses
+------------  ------------  -------------  --------  ----  ---------  
-----------------------  -----------------------
+my-asp        ?             uninitialized  m3ua      sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201):12345
 ss7_asp_vty_test(config-cs7-asp)# show running-config
 ...
   local-ip 127.0.0.100
@@ -369,23 +372,23 @@
 ss7_asp_vty_test(config-cs7-as)# routing-key 0 3.2.1

 ss7_asp_vty_test(config-cs7-as)# do show cs7 instance 0 asp
-ASP Name      AS Name       State          Type  Role  SCTP Role  Local 
Addresses          Remote Addresses
-------------  ------------  -------------  ----  ----  ---------  
-----------------------  -----------------------
-my-asp        my-ass        ASP_DOWN       m3ua  sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201):12345
+ASP Name      AS Name       State          Type      Role  SCTP Role  Local 
Addresses          Remote Addresses
+------------  ------------  -------------  --------  ----  ---------  
-----------------------  -----------------------
+my-asp        my-ass        ASP_DOWN       m3ua      sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201):12345

 ss7_asp_vty_test(config-cs7-as)# exit
 ss7_asp_vty_test(config-cs7)# do show cs7 instance 0 asp
-ASP Name      AS Name       State          Type  Role  SCTP Role  Local 
Addresses          Remote Addresses
-------------  ------------  -------------  ----  ----  ---------  
-----------------------  -----------------------
-my-asp        my-ass        ASP_DOWN       m3ua  sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201):12345
+ASP Name      AS Name       State          Type      Role  SCTP Role  Local 
Addresses          Remote Addresses
+------------  ------------  -------------  --------  ----  ---------  
-----------------------  -----------------------
+my-asp        my-ass        ASP_DOWN       m3ua      sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201):12345

 ss7_asp_vty_test(config-cs7)# exit


 ss7_asp_vty_test(config)# do show cs7 instance 0 asp
-ASP Name      AS Name       State          Type  Role  SCTP Role  Local 
Addresses          Remote Addresses
-------------  ------------  -------------  ----  ----  ---------  
-----------------------  -----------------------
-my-asp        my-ass        ASP_DOWN       m3ua  sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201):12345
+ASP Name      AS Name       State          Type      Role  SCTP Role  Local 
Addresses          Remote Addresses
+------------  ------------  -------------  --------  ----  ---------  
-----------------------  -----------------------
+my-asp        my-ass        ASP_DOWN       m3ua      sg    server     
(127.0.0.100|127.0.0.101):54321  (127.0.0.200|127.0.0.201):12345

 ss7_asp_vty_test(config)# do show cs7 instance 0 as all
                           Routing    Routing Key                          Cic  
 Cic   Traffic
@@ -428,8 +431,8 @@
 ss7_asp_vty_test(config-cs7)# no asp my-asp

 ss7_asp_vty_test(config-cs7)# do show cs7 instance 0 asp
-ASP Name      AS Name       State          Type  Role  SCTP Role  Local 
Addresses          Remote Addresses
-------------  ------------  -------------  ----  ----  ---------  
-----------------------  -----------------------
+ASP Name      AS Name       State          Type      Role  SCTP Role  Local 
Addresses          Remote Addresses
+------------  ------------  -------------  --------  ----  ---------  
-----------------------  -----------------------

 ss7_asp_vty_test(config-cs7)# do show cs7 instance 0 as all
                           Routing    Routing Key                          Cic  
 Cic   Traffic

--
To view, visit https://gerrit.osmocom.org/c/libosmo-sccp/+/35796?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmo-sccp
Gerrit-Branch: master
Gerrit-Change-Id: I8c76d271472befacbeb998a93bbdc9e8660d9b5d
Gerrit-Change-Number: 35796
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <[email protected]>
Gerrit-MessageType: newchange

Reply via email to