summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2018-08-09 14:32:57 +0200
committerRuben Undheim <ruben.undheim@gmail.com>2018-08-09 14:32:57 +0200
commit34019def52323e5aec00c2d2aeed9b20d43b720d (patch)
treed63114b8c31ee3b828c56315390eeba17888639b
parent8e5f4267a07a2d69c1632eb9830e553fab5c6b79 (diff)
New upstream version 0.10.0
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac10
-rw-r--r--doc/Makefile.am3
-rw-r--r--doc/examples/Makefile.am4
-rw-r--r--examples/Makefile.am6
-rw-r--r--examples/m3ua_example.c122
-rw-r--r--examples/sccp_demo_user.c266
-rwxr-xr-xgit-version-gen4
-rw-r--r--include/osmocom/sigtran/osmo_ss7.h11
-rw-r--r--include/osmocom/sigtran/xua_msg.h2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/ipa.c12
-rw-r--r--src/m3ua.c1
-rw-r--r--src/osmo_ss7.c41
-rw-r--r--src/sccp2sua.c2
-rw-r--r--src/sccp_scrc.c7
-rw-r--r--src/sccp_user.c2
-rw-r--r--src/xua_default_lm_fsm.c1
-rw-r--r--src/xua_internal.h2
-rw-r--r--src/xua_msg.c8
-rw-r--r--src/xua_rkm.c1
-rw-r--r--tests/xua/xua_test.c20
23 files changed, 369 insertions, 162 deletions
diff --git a/.gitignore b/.gitignore
index e63e4ee..9423d67 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,7 +60,7 @@ tests/package.m4
tests/testsuite
tests/testsuite.log
-examples/m3ua_example
+examples/sccp_demo_user
stp/osmo-stp
diff --git a/Makefile.am b/Makefile.am
index 1ac8e11..3f4de13 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
-SUBDIRS = include src tests examples stp
+SUBDIRS = include src tests examples stp doc
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libosmo-sccp.pc libosmo-mtp.pc libosmo-sigtran.pc libosmo-xua.pc
diff --git a/configure.ac b/configure.ac
index d2d4d02..c0cc488 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,10 +29,10 @@ if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
fi
PKG_PROG_PKG_CONFIG([0.20])
-PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.11.0)
-PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.11.0)
-PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.11.0)
-PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.2.0)
+PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.12.0)
+PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.12.0)
+PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.12.0)
+PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.3.0)
old_LIBS=$LIBS
AC_SEARCH_LIBS([sctp_send], [sctp], [
@@ -120,5 +120,7 @@ AC_OUTPUT(
tests/ss7/Makefile
examples/Makefile
stp/Makefile
+ doc/Makefile
+ doc/examples/Makefile
Doxyfile
Makefile)
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..1d42b0a
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = \
+ examples \
+ $(NULL)
diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am
new file mode 100644
index 0000000..b1a7a0f
--- /dev/null
+++ b/doc/examples/Makefile.am
@@ -0,0 +1,4 @@
+examples_stpdir = $(docdir)/examples/osmo-stp
+examples_stp_DATA = osmo-stp.cfg
+
+EXTRA_DIST = $(examples_stp_DATA)
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 6418aca..1993a01 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -4,8 +4,8 @@ AM_LDFLAGS=$(COVERAGE_LDFLAGS)
noinst_HEADERS = internal.h
-noinst_PROGRAMS = m3ua_example
+noinst_PROGRAMS = sccp_demo_user
-m3ua_example_SOURCES = m3ua_example.c sccp_test_server.c sccp_test_vty.c
-m3ua_example_LDADD = $(top_builddir)/src/libosmo-sigtran.la \
+sccp_demo_user_SOURCES = sccp_demo_user.c sccp_test_server.c sccp_test_vty.c
+sccp_demo_user_LDADD = $(top_builddir)/src/libosmo-sigtran.la \
$(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS)
diff --git a/examples/m3ua_example.c b/examples/m3ua_example.c
deleted file mode 100644
index a9f455c..0000000
--- a/examples/m3ua_example.c
+++ /dev/null
@@ -1,122 +0,0 @@
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-
-#include <osmocom/core/select.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/core/application.h>
-#include <osmocom/core/fsm.h>
-#include <osmocom/vty/vty.h>
-#include <osmocom/vty/telnet_interface.h>
-
-#include <osmocom/sigtran/osmo_ss7.h>
-#include <osmocom/sigtran/sccp_sap.h>
-#include <osmocom/sigtran/sccp_helpers.h>
-#include <osmocom/sigtran/protocol/sua.h>
-#include <osmocom/sigtran/protocol/m3ua.h>
-
-#include "internal.h"
-
-static struct osmo_sccp_instance *g_sccp;
-
-static struct osmo_sccp_instance *sua_server_helper(void)
-{
- struct osmo_sccp_instance *sccp;
-
- sccp = osmo_sccp_simple_server(NULL, 1, OSMO_SS7_ASP_PROT_M3UA,
- -1, "127.0.0.2");
-
- osmo_sccp_simple_server_add_clnt(sccp, OSMO_SS7_ASP_PROT_M3UA,
- "23", 23, -1, 0, NULL);
-
- return sccp;
-}
-
-/***********************************************************************
- * Initialization
- ***********************************************************************/
-
-static void signal_handler(int signal)
-{
- fprintf(stdout, "signal %d received\n", signal);
-
- switch (signal) {
- case SIGUSR1:
- talloc_report_full(osmo_sccp_get_ss7(g_sccp), stderr);
- break;
- case SIGUSR2:
- talloc_report_full(NULL, stderr);
- break;
- }
-}
-
-static const struct log_info_cat log_info_cat[] = {
-};
-
-static const struct log_info log_info = {
- .cat = log_info_cat,
- .num_cat = ARRAY_SIZE(log_info_cat),
-};
-
-static void init_logging(void)
-{
- const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP };
- unsigned int i;
- void *tall_ctx = talloc_named_const(NULL, 1, "example");
- msgb_talloc_ctx_init(tall_ctx, 0);
- osmo_init_logging2(tall_ctx, &log_info);
-
- for (i = 0; i < ARRAY_SIZE(log_cats); i++)
- log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG);
-}
-
-static struct vty_app_info vty_info = {
- .name = "sccp-test",
- .version = 0,
-};
-
-int main(int argc, char **argv)
-{
- bool client;
- int rc;
-
- talloc_enable_leak_report_full();
-
- signal(SIGUSR1, &signal_handler);
- signal(SIGUSR2, &signal_handler);
-
- init_logging();
- osmo_ss7_init();
- osmo_fsm_log_addr(false);
- vty_init(&vty_info);
- osmo_ss7_vty_init_asp(NULL);
- osmo_sccp_vty_init();
-
- if (argc <= 1)
- client = true;
- else
- client = false;
-
- rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), 2324+client);
- if (rc < 0) {
- perror("Erro binding VTY port\n");
- exit(1);
- }
-
-
- if (client) {
- g_sccp = osmo_sccp_simple_client(NULL, "client", 23, OSMO_SS7_ASP_PROT_M3UA, 0, NULL, M3UA_PORT, "127.0.0.2");
- sccp_test_user_vty_install(g_sccp, OSMO_SCCP_SSN_BSSAP);
- } else {
- g_sccp = sua_server_helper();
- sccp_test_server_init(g_sccp);
- }
-
- while (1) {
- osmo_select_main(0);
- }
-}
diff --git a/examples/sccp_demo_user.c b/examples/sccp_demo_user.c
new file mode 100644
index 0000000..28dd166
--- /dev/null
+++ b/examples/sccp_demo_user.c
@@ -0,0 +1,266 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <ctype.h>
+
+#include <osmocom/core/select.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/application.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/telnet_interface.h>
+
+#include <osmocom/sigtran/osmo_ss7.h>
+#include <osmocom/sigtran/sccp_sap.h>
+#include <osmocom/sigtran/sccp_helpers.h>
+#include <osmocom/sigtran/protocol/sua.h>
+#include <osmocom/sigtran/protocol/m3ua.h>
+
+#include "internal.h"
+
+static struct osmo_sccp_instance *g_sccp;
+
+static struct osmo_sccp_instance *sua_server_helper(int local_port, const char *local_address, int local_pc,
+ int remote_port, const char *remote_address, int remote_pc)
+{
+ struct osmo_sccp_instance *sccp;
+
+ sccp = osmo_sccp_simple_server(NULL, local_pc, OSMO_SS7_ASP_PROT_M3UA, local_port, local_address);
+ if (sccp == NULL)
+ return NULL;
+
+ osmo_sccp_simple_server_add_clnt(sccp, OSMO_SS7_ASP_PROT_M3UA, "client", remote_pc, local_port,
+ remote_port, remote_address);
+
+ return sccp;
+}
+
+/***********************************************************************
+ * Initialization
+ ***********************************************************************/
+
+static void signal_handler(int signal)
+{
+ fprintf(stdout, "signal %d received\n", signal);
+
+ switch (signal) {
+ case SIGUSR1:
+ talloc_report_full(osmo_sccp_get_ss7(g_sccp), stderr);
+ break;
+ case SIGUSR2:
+ talloc_report_full(NULL, stderr);
+ break;
+ }
+}
+
+static const struct log_info_cat log_info_cat[] = {
+};
+
+static const struct log_info log_info = {
+ .cat = log_info_cat,
+ .num_cat = ARRAY_SIZE(log_info_cat),
+};
+
+static void init_logging(void)
+{
+ const int log_cats[] = { DLSS7, DLSUA, DLM3UA, DLSCCP, DLINP };
+ unsigned int i;
+ void *tall_ctx = talloc_named_const(NULL, 1, "example");
+ msgb_talloc_ctx_init(tall_ctx, 0);
+ osmo_init_logging2(tall_ctx, &log_info);
+
+ for (i = 0; i < ARRAY_SIZE(log_cats); i++)
+ log_set_category_filter(osmo_stderr_target, log_cats[i], 1, LOGL_DEBUG);
+}
+
+static struct vty_app_info vty_info = {
+ .name = "sccp-demo-user",
+ .version = 0,
+};
+
+#define DEFAULT_LOCAL_ADDRESS_SERVER "127.0.0.1"
+#define DEFAULT_LOCAL_ADDRESS_CLIENT "127.0.0.2"
+#define DEFAULT_REMOTE_ADDRESS_CLIENT DEFAULT_LOCAL_ADDRESS_SERVER
+#define DEFAULT_REMOTE_ADDRESS_SERVER DEFAULT_LOCAL_ADDRESS_CLIENT
+#define DEFAULT_LOCAL_PORT_SERVER M3UA_PORT
+#define DEFAULT_LOCAL_PORT_CLIENT M3UA_PORT
+#define DEFAULT_REMOTE_PORT_CLIENT DEFAULT_LOCAL_PORT_SERVER
+#define DEFAULT_REMOTE_PORT_SERVER DEFAULT_LOCAL_PORT_CLIENT
+#define DEFAULT_REMOTE_PORT_SERVER_STR DEFAULT_LOCAL_PORT_CLIENT_STR
+#define DEFAULT_PC_SERVER 1
+#define DEFAULT_PC_CLIENT 23
+
+static void usage(void) {
+ fprintf(stderr, "sccp_demo_user [-c] [-l LOCAL_ADDRESS[:LOCAL_PORT]]\n"
+ " [-r REMOTE_ADDRESS[:REMOTE_PORT]]\n"
+ " [-L LOCAL_POINT_CODE] [-R REMOTE_POINT_CODE]\n"
+ "Options:\n"
+ " -c: Run in client mode (default is server mode)\n"
+ " -l: local IP address and SCTP port (default is %s:%d in server mode,\n"
+ " %s:%d in client mode)\n"
+ " -r: remote IP address and SCTP port (default is %s:%d in server mode,\n"
+ " %s:%d in client mode)\n"
+ " -L: local point code (default is %d in server mode, %d in client mode)\n"
+ " -R: remote point code (default is %d in server mode, %d in client mode)\n",
+ DEFAULT_LOCAL_ADDRESS_SERVER, DEFAULT_LOCAL_PORT_SERVER,
+ DEFAULT_LOCAL_ADDRESS_CLIENT, DEFAULT_LOCAL_PORT_CLIENT,
+ DEFAULT_REMOTE_ADDRESS_SERVER, DEFAULT_REMOTE_PORT_SERVER,
+ DEFAULT_REMOTE_ADDRESS_CLIENT, DEFAULT_REMOTE_PORT_CLIENT,
+ DEFAULT_PC_SERVER, DEFAULT_PC_CLIENT,
+ DEFAULT_PC_CLIENT, DEFAULT_PC_SERVER);
+ exit(1);
+}
+
+static int is_decimal_string(const char *s)
+{
+ const char *p = s;
+
+ if (*p == '\0')
+ return 0;
+
+ while (*p) {
+ if (!isdigit(*p++))
+ return 0;
+ }
+ return 1;
+}
+
+static int parse_address_port(char **address, int *port, const char *arg)
+{
+ char *s, *colon;
+
+ s = strdup(arg);
+ OSMO_ASSERT(s);
+
+ colon = strrchr(s, ':');
+ if (colon) {
+ char *portstr = colon + 1;
+ *colon = '\0';
+ if (*portstr == '\0') {
+ fprintf(stderr, "missing port number after : in '%s'\n", arg);
+ free(s);
+ return 1;
+ }
+ if (!is_decimal_string(portstr)) {
+ fprintf(stderr, "invalid port number: '%s'\n", portstr);
+ free(s);
+ return 1;
+ }
+ *port = atoi(portstr);
+ }
+
+ *address = s;
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ bool client = false;
+ int rc, ch;
+ char *local_address = DEFAULT_LOCAL_ADDRESS_SERVER;
+ int local_port = DEFAULT_LOCAL_PORT_SERVER;
+ int local_pc = DEFAULT_PC_SERVER;
+ char *remote_address = DEFAULT_REMOTE_ADDRESS_SERVER;
+ int remote_port = DEFAULT_REMOTE_PORT_SERVER;
+ int remote_pc = DEFAULT_PC_CLIENT;
+ bool lflag = false, rflag = false, Lflag = false, Rflag = false;
+
+ while ((ch = getopt(argc, argv, "cl:r:L:R:")) != -1) {
+ switch (ch) {
+ case 'c':
+ client = true;
+
+ /* Set client-mode defaults unless already overridden during option parsing. */
+ if (!lflag) {
+ local_address = DEFAULT_LOCAL_ADDRESS_CLIENT;
+ local_port = DEFAULT_LOCAL_PORT_CLIENT;
+ }
+ if (!Lflag)
+ local_pc = DEFAULT_PC_CLIENT;
+ if (!rflag) {
+ remote_address = DEFAULT_REMOTE_ADDRESS_CLIENT;
+ remote_port = DEFAULT_REMOTE_PORT_CLIENT;
+ }
+ if (!Rflag)
+ remote_pc = DEFAULT_PC_SERVER;
+ break;
+ case 'l':
+ if (parse_address_port(&local_address, &local_port, optarg))
+ exit(1);
+ lflag = true;
+ break;
+ case 'r':
+ if (parse_address_port(&remote_address, &remote_port, optarg))
+ exit(1);
+ rflag = true;
+ break;
+ case 'L':
+ if (!is_decimal_string(optarg)) {
+ fprintf(stderr, "invalid decimal point code: '%s'\n", optarg);
+ exit(1);
+ }
+ local_pc = atoi(optarg);
+ Lflag = true;
+ break;
+ case 'R':
+ if (!is_decimal_string(optarg)) {
+ fprintf(stderr, "invalid decimal point code: '%s'\n", optarg);
+ exit(1);
+ }
+ remote_pc = atoi(optarg);
+ Rflag = true;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage();
+
+ talloc_enable_leak_report_full();
+
+ signal(SIGUSR1, &signal_handler);
+ signal(SIGUSR2, &signal_handler);
+
+ init_logging();
+ osmo_ss7_init();
+ osmo_fsm_log_addr(false);
+ vty_init(&vty_info);
+ osmo_ss7_vty_init_asp(NULL);
+ osmo_sccp_vty_init();
+
+ rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), 2324+client);
+ if (rc < 0) {
+ perror("Error binding VTY port");
+ exit(1);
+ }
+
+ if (client) {
+ g_sccp = osmo_sccp_simple_client(NULL, "client", local_pc, OSMO_SS7_ASP_PROT_M3UA,
+ local_port, local_address, remote_port, remote_address);
+ if (g_sccp == NULL) {
+ perror("Could not create SCCP client");
+ exit (1);
+ }
+ sccp_test_user_vty_install(g_sccp, OSMO_SCCP_SSN_BSSAP);
+ } else {
+ g_sccp = sua_server_helper(local_port, local_address, local_pc,
+ remote_port, remote_address, remote_pc);
+ if (g_sccp == NULL) {
+ perror("Could not create SCCP server");
+ exit(1);
+ }
+ sccp_test_server_init(g_sccp);
+ }
+
+ while (1) {
+ osmo_select_main(0);
+ }
+}
diff --git a/git-version-gen b/git-version-gen
index 8e59c5a..42cf3d2 100755
--- a/git-version-gen
+++ b/git-version-gen
@@ -92,8 +92,8 @@ fi
if test -n "$v"
then
: # use $v
-elif test -d ./.git \
- && v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
+elif
+ v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
|| git describe --abbrev=4 HEAD 2>/dev/null` \
&& case $v in
[0-9]*) ;;
diff --git a/include/osmocom/sigtran/osmo_ss7.h b/include/osmocom/sigtran/osmo_ss7.h
index fd3f103..a93c663 100644
--- a/include/osmocom/sigtran/osmo_ss7.h
+++ b/include/osmocom/sigtran/osmo_ss7.h
@@ -408,6 +408,17 @@ int osmo_ss7_asp_send(struct osmo_ss7_asp *asp, struct msgb *msg);
int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp);
int osmo_ss7_asp_use_default_lm(struct osmo_ss7_asp *asp, int log_level);
+/*! Weak function to handle payload for unknown/unsupported PPID or IPA StreamID.
+ * This function can be overridden by application code to implement whatever handling
+ * it wants for such additional payloads/streams.
+ * \param[in] asp Application Server Process through which data was received
+ * \param[in] ppid_sid SCTP PPID (in sigtran case) or IPA Stream ID
+ * \param[in] msg Message buffer containing received data. Continues to be owned by caller!
+ * \return 0 on success; negative on error */
+typedef int osmo_ss7_asp_rx_unknown_cb(struct osmo_ss7_asp *asp, int ppid_mux, struct msgb *msg);
+
+void osmo_ss7_register_rx_unknown_cb(osmo_ss7_asp_rx_unknown_cb *cb);
+
#define LOGPASP(asp, subsys, level, fmt, args ...) \
LOGP(subsys, level, "asp-%s: " fmt, (asp)->cfg.name, ## args)
diff --git a/include/osmocom/sigtran/xua_msg.h b/include/osmocom/sigtran/xua_msg.h
index 423adbc..e912e02 100644
--- a/include/osmocom/sigtran/xua_msg.h
+++ b/include/osmocom/sigtran/xua_msg.h
@@ -69,6 +69,8 @@ struct xua_msg_event_map {
extern const struct xua_dialect xua_dialect_sua;
extern const struct xua_dialect xua_dialect_m3ua;
+void osmo_xua_msg_tall_ctx_init(void *ctx);
+
struct xua_msg *xua_msg_alloc(void);
void xua_msg_free(struct xua_msg *msg);
diff --git a/src/Makefile.am b/src/Makefile.am
index 3af23d1..9cea642 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,7 +25,7 @@ lib_LTLIBRARIES = libosmo-sigtran.la
# This is _NOT_ the library release version, it's an API version.
# Please read Chapter 6 "Library interface versions" of the libtool
# documentation before making any modification
-LIBVERSION=1:0:1
+LIBVERSION=2:0:2
libosmo_sigtran_la_SOURCES = sccp_sap.c sua.c m3ua.c xua_msg.c sccp_helpers.c \
sccp2sua.c sccp_scrc.c sccp_sclc.c sccp_scoc.c \
diff --git a/src/ipa.c b/src/ipa.c
index 9f04746..f3a7a52 100644
--- a/src/ipa.c
+++ b/src/ipa.c
@@ -202,8 +202,9 @@ static struct msgb *patch_sccp_with_pc(struct osmo_ss7_asp *asp, struct msgb *sc
static int ipa_rx_msg_sccp(struct osmo_ss7_asp *asp, struct msgb *msg)
{
+ int rc;
struct m3ua_data_hdr data_hdr;
- struct xua_msg *xua = xua_msg_alloc();
+ struct xua_msg *xua;
struct osmo_ss7_as *as = find_as_for_asp(asp);
uint32_t opc, dpc;
@@ -258,11 +259,14 @@ static int ipa_rx_msg_sccp(struct osmo_ss7_asp *asp, struct msgb *msg)
data_hdr.dpc = osmo_htonl(dpc);
/* Create M3UA message in XUA structure */
xua = m3ua_xfer_from_data(&data_hdr, msgb_l2(msg), msgb_l2len(msg));
+ msgb_free(msg);
/* Update xua->mtp with values from data_hdr */
m3ua_dh_to_xfer_param(&xua->mtp, &data_hdr);
/* Pass on as if we had received it from an M3UA ASP */
- return m3ua_hmdc_rx_from_l2(asp->inst, xua);
+ rc = m3ua_hmdc_rx_from_l2(asp->inst, xua);
+ xua_msg_free(xua);
+ return rc;
}
/*! \brief process M3UA message received from socket
@@ -288,9 +292,7 @@ int ipa_rx_msg(struct osmo_ss7_asp *asp, struct msgb *msg)
rc = ipa_rx_msg_sccp(asp, msg);
break;
default:
- LOGPASP(asp, DLSS7, LOGL_DEBUG, "Unknown Stream ID 0x%02x: %s\n",
- hh->proto, msgb_hexdump(msg));
- rc = -1;
+ rc = ss7_asp_rx_unknown(asp, hh->proto, msg);
}
return rc;
diff --git a/src/m3ua.c b/src/m3ua.c
index f1fe3f1..d7ede40 100644
--- a/src/m3ua.c
+++ b/src/m3ua.c
@@ -584,6 +584,7 @@ static int m3ua_rx_xfer(struct osmo_ss7_asp *asp, struct xua_msg *xua)
xua_msg_free_tag(xua, M3UA_IEI_ROUTE_CTX);
return m3ua_hmdc_rx_from_l2(asp->inst, xua);
+ /* xua will be freed by caller m3ua_rx_msg() */
}
static int m3ua_rx_mgmt_err(struct osmo_ss7_asp *asp, struct xua_msg *xua)
diff --git a/src/osmo_ss7.c b/src/osmo_ss7.c
index 30677b9..025c21c 100644
--- a/src/osmo_ss7.c
+++ b/src/osmo_ss7.c
@@ -307,6 +307,7 @@ static const uint16_t prot2port[] = {
[OSMO_SS7_ASP_PROT_NONE] = 0,
[OSMO_SS7_ASP_PROT_SUA] = SUA_PORT,
[OSMO_SS7_ASP_PROT_M3UA] = M3UA_PORT,
+ [OSMO_SS7_ASP_PROT_IPA] = 5000,
};
int osmo_ss7_asp_protocol_port(enum osmo_ss7_asp_protocol prot)
@@ -1449,11 +1450,8 @@ static int xua_srv_conn_cb(struct osmo_stream_srv *conn)
rc = sua_rx_msg(asp, msg);
else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA)
rc = m3ua_rx_msg(asp, msg);
- else {
- LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u "
- "received\n", ppid);
- rc = 0;
- }
+ else
+ rc = ss7_asp_rx_unknown(asp, ppid, msg);
out:
msgb_free(msg);
@@ -1590,11 +1588,8 @@ static int xua_cli_read_cb(struct osmo_stream_cli *conn)
rc = sua_rx_msg(asp, msg);
else if (ppid == M3UA_PPID && asp->cfg.proto == OSMO_SS7_ASP_PROT_M3UA)
rc = m3ua_rx_msg(asp, msg);
- else {
- LOGPASP(asp, DLSS7, LOGL_NOTICE, "SCTP chunk for unknown PPID %u "
- "received\n", ppid);
- rc = 0;
- }
+ else
+ rc = ss7_asp_rx_unknown(asp, ppid, msg);
out:
msgb_free(msg);
@@ -1917,3 +1912,29 @@ enum osmo_ss7_as_traffic_mode osmo_ss7_tmode_from_xua(uint32_t in)
return OSMO_SS7_AS_TMOD_BCAST;
}
}
+
+static osmo_ss7_asp_rx_unknown_cb *g_osmo_ss7_asp_rx_unknown_cb;
+
+int ss7_asp_rx_unknown(struct osmo_ss7_asp *asp, int ppid_mux, struct msgb *msg)
+{
+ if (g_osmo_ss7_asp_rx_unknown_cb)
+ return (*g_osmo_ss7_asp_rx_unknown_cb)(asp, ppid_mux, msg);
+
+ switch(asp->cfg.proto) {
+ case OSMO_SS7_ASP_PROT_IPA:
+ LOGPASP(asp, DLSS7, LOGL_NOTICE, "Rx IPA for unknown Stream ID 0x%02x: %s\n",
+ ppid_mux, msgb_hexdump(msg));
+ break;
+ default:
+ LOGPASP(asp, DLSS7, LOGL_NOTICE, "Rx SCTP chunk for unknown PPID %u: %s\n",
+ ppid_mux, msgb_hexdump(msg));
+ break;
+ }
+ return 0;
+}
+
+/*! Register a call-back function for unknown SCTP PPID / IPA Stream ID */
+void osmo_ss7_register_rx_unknown_cb(osmo_ss7_asp_rx_unknown_cb *cb)
+{
+ g_osmo_ss7_asp_rx_unknown_cb = cb;
+}
diff --git a/src/sccp2sua.c b/src/sccp2sua.c
index afc38c7..2f5b687 100644
--- a/src/sccp2sua.c
+++ b/src/sccp2sua.c
@@ -330,7 +330,7 @@ static int sccp_addr_to_sua(struct xua_msg *xua, uint16_t iei, const uint8_t *ad
if (rc < 0)
return rc;
- LOGP(DLSUA, LOGL_DEBUG, "Parsed Addr: %s\n", osmo_sccp_addr_dump(&osa));
+ LOGP(DLSUA, LOGL_DEBUG, "IEI %u: Parsed Addr: %s\n", iei, osmo_sccp_addr_dump(&osa));
/* Then re-encode it as SUA address */
return xua_msg_add_sccp_addr(xua, iei, &osa);
diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c
index dca5645..cd01774 100644
--- a/src/sccp_scrc.c
+++ b/src/sccp_scrc.c
@@ -279,8 +279,15 @@ static int scrc_translate_node_9(struct osmo_sccp_instance *inst,
translated.ri != OSMO_SCCP_RI_SSN_IP) {
/* TODO: GT Routing */
LOGP(DLSCCP, LOGL_NOTICE, "GT Routing not implemented yet\n");
+#if 1
+ /* Prevent endless recursion, see OS#2666. */
+ sccp_sclc_rx_scrc_rout_fail(inst, xua,
+ SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE);
+ return 0;
+#else
/* Node 7 (Sheet 5) */
return scrc_node_7(inst, xua, called);
+#endif
}
/* Check DPC resultant from GT translation */
diff --git a/src/sccp_user.c b/src/sccp_user.c
index a6161c0..99ed96e 100644
--- a/src/sccp_user.c
+++ b/src/sccp_user.c
@@ -611,7 +611,6 @@ osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst,
as = osmo_ss7_as_find_or_create(ss7, as_name, prot);
if (!as)
goto out_strings;
- talloc_free(as_name);
/* route only selected PC to the client */
rt = osmo_ss7_route_create(ss7->rtable_system, pc, 0xffff, as_name);
@@ -624,6 +623,7 @@ osmo_sccp_simple_server_add_clnt(struct osmo_sccp_instance *inst,
asp->cfg.is_server = true;
osmo_ss7_as_add_asp(as, asp_name);
talloc_free(asp_name);
+ talloc_free(as_name);
osmo_ss7_asp_restart(asp);
return ss7->sccp;
diff --git a/src/xua_default_lm_fsm.c b/src/xua_default_lm_fsm.c
index eba89c2..11a97a2 100644
--- a/src/xua_default_lm_fsm.c
+++ b/src/xua_default_lm_fsm.c
@@ -175,6 +175,7 @@ static int lm_timer_cb(struct osmo_fsm_inst *fi)
* let's dynamically register */
osmo_fsm_inst_state_chg(fi, S_RKM_REG, 10, T_WAIT_RK_REG_RESP);
prim = xua_xlm_prim_alloc(OSMO_XLM_PRIM_M_RK_REG, PRIM_OP_REQUEST);
+ OSMO_ASSERT(prim);
as = find_first_as_in_asp(lmp->asp);
if (!as) {
LOGPFSML(fi, LOGL_ERROR, "Unable to find AS!\n");
diff --git a/src/xua_internal.h b/src/xua_internal.h
index 96bd153..d836fae 100644
--- a/src/xua_internal.h
+++ b/src/xua_internal.h
@@ -78,3 +78,5 @@ int osmo_isup_party_parse(char *out_digits, const uint8_t *in,
int osmo_sccp_addr_parse(struct osmo_sccp_addr *out,
const uint8_t *addr, unsigned int addrlen);
int osmo_sccp_addr_encode(struct msgb *msg, const struct osmo_sccp_addr *in);
+
+int ss7_asp_rx_unknown(struct osmo_ss7_asp *asp, int ppid_mux, struct msgb *msg);
diff --git a/src/xua_msg.c b/src/xua_msg.c
index d56009f..ed0cdc7 100644
--- a/src/xua_msg.c
+++ b/src/xua_msg.c
@@ -33,7 +33,13 @@
#include <string.h>
#include <errno.h>
-static void *tall_xua;
+static void *tall_xua = NULL;
+
+/* Allocate the root talloc context used for xua_msg_alloc(). */
+void osmo_xua_msg_tall_ctx_init(void *ctx)
+{
+ tall_xua = talloc_named_const(ctx, 0, "xua_msg");
+}
struct xua_msg *xua_msg_alloc(void)
{
diff --git a/src/xua_rkm.c b/src/xua_rkm.c
index b3c5be7..b79f7f3 100644
--- a/src/xua_rkm.c
+++ b/src/xua_rkm.c
@@ -545,6 +545,7 @@ int osmo_xlm_sap_down(struct osmo_ss7_asp *asp, struct osmo_prim_hdr *oph)
break;
}
+ msgb_free(prim->oph.msg);
return 0;
}
diff --git a/tests/xua/xua_test.c b/tests/xua/xua_test.c
index 3e370fe..37ba645 100644
--- a/tests/xua/xua_test.c
+++ b/tests/xua/xua_test.c
@@ -387,8 +387,8 @@ static const struct sccp2sua_testcase sccp2sua_testcases[] = {
.hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT),
.parts = {
PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0),
- PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap),
- PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap),
+ PARTARR(SUA_IEI_DEST_ADDR, sua_addr_ssn_bssmap),
+ PARTARR(SUA_IEI_SRC_ADDR, sua_addr_ssn_bssmap),
},
},
}, {
@@ -398,8 +398,8 @@ static const struct sccp2sua_testcase sccp2sua_testcases[] = {
.hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT),
.parts = {
PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0),
- PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap_pc1),
- PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap_pc92),
+ PARTARR(SUA_IEI_DEST_ADDR, sua_addr_ssn_bssmap_pc1),
+ PARTARR(SUA_IEI_SRC_ADDR, sua_addr_ssn_bssmap_pc92),
},
},
}, {
@@ -409,8 +409,8 @@ static const struct sccp2sua_testcase sccp2sua_testcases[] = {
.hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT),
.parts = {
PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0),
- PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap_pc1),
- PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap_pc92),
+ PARTARR(SUA_IEI_DEST_ADDR, sua_addr_ssn_bssmap_pc1),
+ PARTARR(SUA_IEI_SRC_ADDR, sua_addr_ssn_bssmap_pc92),
},
},
}, {
@@ -420,8 +420,8 @@ static const struct sccp2sua_testcase sccp2sua_testcases[] = {
.hdr = XUA_HDR(SUA_MSGC_CL, SUA_CL_CLDT),
.parts = {
PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class0),
- PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap),
- PARTARR(SUA_IEI_SRC_ADDR, &sua_addr_ssn_bssmap),
+ PARTARR(SUA_IEI_DEST_ADDR, sua_addr_ssn_bssmap),
+ PARTARR(SUA_IEI_SRC_ADDR, sua_addr_ssn_bssmap),
},
},
}, {
@@ -432,7 +432,7 @@ static const struct sccp2sua_testcase sccp2sua_testcases[] = {
.parts = {
PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class2),
PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_bsc),
- PARTARR(SUA_IEI_DEST_ADDR, &sua_addr_ssn_bssmap),
+ PARTARR(SUA_IEI_DEST_ADDR, sua_addr_ssn_bssmap),
},
},
}, {
@@ -443,7 +443,7 @@ static const struct sccp2sua_testcase sccp2sua_testcases[] = {
.parts = {
PARTU32(SUA_IEI_PROTO_CLASS, &sua_proto_class2),
PARTU32(SUA_IEI_SRC_REF, &sua_loc_ref_msc),
- PARTARR(SUA_IEI_DEST_ADDR, &sua_loc_ref_bsc),
+ PARTARR(SUA_IEI_DEST_ADDR, sua_addr_ssn_bssmap),
},
},
}, {