diff options
author | Ruben Undheim <ruben.undheim@gmail.com> | 2018-08-09 14:32:57 +0200 |
---|---|---|
committer | Ruben Undheim <ruben.undheim@gmail.com> | 2018-08-09 14:32:57 +0200 |
commit | 34019def52323e5aec00c2d2aeed9b20d43b720d (patch) | |
tree | d63114b8c31ee3b828c56315390eeba17888639b | |
parent | 8e5f4267a07a2d69c1632eb9830e553fab5c6b79 (diff) |
New upstream version 0.10.0
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | doc/Makefile.am | 3 | ||||
-rw-r--r-- | doc/examples/Makefile.am | 4 | ||||
-rw-r--r-- | examples/Makefile.am | 6 | ||||
-rw-r--r-- | examples/m3ua_example.c | 122 | ||||
-rw-r--r-- | examples/sccp_demo_user.c | 266 | ||||
-rwxr-xr-x | git-version-gen | 4 | ||||
-rw-r--r-- | include/osmocom/sigtran/osmo_ss7.h | 11 | ||||
-rw-r--r-- | include/osmocom/sigtran/xua_msg.h | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/ipa.c | 12 | ||||
-rw-r--r-- | src/m3ua.c | 1 | ||||
-rw-r--r-- | src/osmo_ss7.c | 41 | ||||
-rw-r--r-- | src/sccp2sua.c | 2 | ||||
-rw-r--r-- | src/sccp_scrc.c | 7 | ||||
-rw-r--r-- | src/sccp_user.c | 2 | ||||
-rw-r--r-- | src/xua_default_lm_fsm.c | 1 | ||||
-rw-r--r-- | src/xua_internal.h | 2 | ||||
-rw-r--r-- | src/xua_msg.c | 8 | ||||
-rw-r--r-- | src/xua_rkm.c | 1 | ||||
-rw-r--r-- | tests/xua/xua_test.c | 20 |
23 files changed, 369 insertions, 162 deletions
@@ -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 \ @@ -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; @@ -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), }, }, }, { |