From 529b55c16b58845f227825731f963b387c648a88 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Wed, 9 May 2018 22:11:25 +0900 Subject: [PATCH 1/2] Introduce new configuration for SCTP streams (#54) SCTP initmsg - Number of output streams : configured(default:30) - Maximum input streams : 65535 - Maximum attempts : 4 - Maximum initial timeout : 8 seconds --- lib/core/include/core_network.h | 2 ++ lib/core/src/unix/sctp.c | 17 +++++++++-- src/app/context.c | 8 ++++++ src/app/context.h | 1 + src/mme/mme_init.c | 5 +++- src/mme/s1ap_path.h | 2 +- src/mme/s1ap_sctp.c | 3 +- src/mme/s1ap_usrsctp.c | 51 ++++++++++++++++++++++++++++++++- support/config/nextepc.conf.in | 3 ++ 9 files changed, 86 insertions(+), 6 deletions(-) diff --git a/lib/core/include/core_network.h b/lib/core/include/core_network.h index 6d9850922..c41198251 100644 --- a/lib/core/include/core_network.h +++ b/lib/core/include/core_network.h @@ -194,6 +194,8 @@ CORE_DECLARE(status_t) tcp_client(sock_id *new, c_sockaddr_t *sa_list); /* * SCTP Socket */ +CORE_DECLARE(void) sctp_set_num_ostreams(int sctp_streams); + CORE_DECLARE(status_t) sctp_socket(sock_id *new, int family, int type); CORE_DECLARE(status_t) sctp_server(sock_id *new, int type, c_sockaddr_t *sa_list); diff --git a/lib/core/src/unix/sctp.c b/lib/core/src/unix/sctp.c index 684e69f59..cc66212ff 100644 --- a/lib/core/src/unix/sctp.c +++ b/lib/core/src/unix/sctp.c @@ -12,8 +12,16 @@ static status_t set_paddrparams(sock_id id, c_uint32_t spp_hbinterval); static status_t set_rtoinfo(sock_id id, c_uint32_t srto_initial, c_uint32_t srto_min, c_uint32_t srto_max); static status_t set_initmsg(sock_id id, + c_uint32_t sinit_num_ostreams, c_uint32_t sinit_max_instreams, c_uint32_t sinit_max_attempts, c_uint32_t sinit_max_init_timeo); +static int sctp_num_ostreams = -1; + +void sctp_set_num_ostreams(int sctp_streams) +{ + sctp_num_ostreams = sctp_streams; +} + status_t sctp_socket(sock_id *new, int family, int type) { status_t rv; @@ -41,10 +49,11 @@ status_t sctp_socket(sock_id *new, int family, int type) /* * INITMSG * + * max number of input streams : 65535 * max attemtps : 4 * max initial timeout : 8 secs */ - rv = set_initmsg(*new, 4, 8000); + rv = set_initmsg(*new, sctp_num_ostreams, 65535, 4, 8000); d_assert(rv == CORE_OK, return CORE_ERROR,); return CORE_OK; @@ -394,6 +403,7 @@ static status_t set_rtoinfo(sock_id id, } static status_t set_initmsg(sock_id id, + c_uint32_t sinit_num_ostreams, c_uint32_t sinit_max_instreams, c_uint32_t sinit_max_attempts, c_uint32_t sinit_max_init_timeo) { sock_t *sock = (sock_t *)id; @@ -401,7 +411,8 @@ static status_t set_initmsg(sock_id id, socklen_t socklen; d_assert(id, return CORE_ERROR,); - + d_assert(sinit_num_ostreams > 1, return CORE_ERROR, + "Invalid SCTP number of output streams = %d\n", sctp_num_ostreams); memset(&initmsg, 0, sizeof(initmsg)); socklen = sizeof(initmsg); @@ -419,6 +430,8 @@ static status_t set_initmsg(sock_id id, initmsg.sinit_max_attempts, initmsg.sinit_max_init_timeo); + initmsg.sinit_num_ostreams = sinit_num_ostreams; + initmsg.sinit_max_instreams = sinit_max_instreams; initmsg.sinit_max_attempts = sinit_max_attempts; initmsg.sinit_max_init_timeo = sinit_max_init_timeo; diff --git a/src/app/context.c b/src/app/context.c index a976b2790..8b2cd3a29 100644 --- a/src/app/context.c +++ b/src/app/context.c @@ -11,6 +11,8 @@ #include "context.h" +#define DEFAULT_SCTP_STREAMS 30 + static context_t self; static int context_initialized = 0; @@ -103,6 +105,7 @@ status_t context_setup_trace_module() static status_t context_prepare() { self.logger.console = -1; + self.parameter.sctp_streams = DEFAULT_SCTP_STREAMS; return CORE_OK; } @@ -256,6 +259,11 @@ status_t context_parse_config() self.parameter.no_pcrf = yaml_iter_bool(¶meter_iter); } + else if (!strcmp(parameter_key, "sctp_streams")) + { + const char *v = yaml_iter_value(¶meter_iter); + if (v) self.parameter.sctp_streams = atoi(v); + } else if (!strcmp(parameter_key, "no_ipv4")) { self.parameter.no_ipv4 = diff --git a/src/app/context.h b/src/app/context.h index de95c1ac3..7be610663 100644 --- a/src/app/context.h +++ b/src/app/context.h @@ -54,6 +54,7 @@ typedef struct _context_t { int no_pcrf; /* Network */ + int sctp_streams; int no_ipv4; int no_ipv6; int prefer_ipv4; diff --git a/src/mme/mme_init.c b/src/mme/mme_init.c index 682944edc..e9e61489c 100644 --- a/src/mme/mme_init.c +++ b/src/mme/mme_init.c @@ -7,6 +7,7 @@ #include "gtp/gtp_xact.h" +#include "app/context.h" #include "mme_event.h" #include "mme_fd_path.h" @@ -42,7 +43,9 @@ status_t mme_initialize() if (rv != CORE_OK) return CORE_ERROR; #define USRSCTP_LOCAL_UDP_PORT 9899 - rv = s1ap_init(USRSCTP_LOCAL_UDP_PORT); + rv = s1ap_init( + context_self()->parameter.sctp_streams, + USRSCTP_LOCAL_UDP_PORT); if (rv != CORE_OK) return rv; rv = thread_create(&sm_thread, NULL, sm_main, NULL); diff --git a/src/mme/s1ap_path.h b/src/mme/s1ap_path.h index c3726753e..675569f68 100644 --- a/src/mme/s1ap_path.h +++ b/src/mme/s1ap_path.h @@ -10,7 +10,7 @@ extern "C" { #endif /* __cplusplus */ -CORE_DECLARE(status_t) s1ap_init(c_uint16_t port); +CORE_DECLARE(status_t) s1ap_init(int sctp_streams, c_uint16_t port); CORE_DECLARE(status_t) s1ap_final(); CORE_DECLARE(status_t) s1ap_open(); diff --git a/src/mme/s1ap_sctp.c b/src/mme/s1ap_sctp.c index 772d6026f..cf225d6b7 100644 --- a/src/mme/s1ap_sctp.c +++ b/src/mme/s1ap_sctp.c @@ -9,8 +9,9 @@ static int s1ap_accept_handler(sock_id sock, void *data); -status_t s1ap_init(c_uint16_t port) +status_t s1ap_init(int sctp_streams, c_uint16_t port) { + sctp_set_num_ostreams(sctp_streams); return CORE_OK; } diff --git a/src/mme/s1ap_usrsctp.c b/src/mme/s1ap_usrsctp.c index 9036cbb75..65ccafe86 100644 --- a/src/mme/s1ap_usrsctp.c +++ b/src/mme/s1ap_usrsctp.c @@ -37,7 +37,9 @@ static int s1ap_usrsctp_recv_handler(struct socket *sock, static c_sockaddr_t *usrsctp_remote_addr(union sctp_sockstore *store); static void debug_printf(const char *format, ...); -status_t s1ap_init(c_uint16_t port) +static int sctp_num_ostreams = -1; + +status_t s1ap_init(int sctp_streams, c_uint16_t port) { usrsctp_init(port, NULL, debug_printf); #ifdef SCTP_DEBUG @@ -45,6 +47,7 @@ status_t s1ap_init(c_uint16_t port) #endif usrsctp_sysctl_set_sctp_blackhole(2); usrsctp_sysctl_set_sctp_enable_sack_immediately(1); + sctp_num_ostreams = sctp_streams; return CORE_OK; } @@ -238,6 +241,8 @@ static status_t s1ap_usrsctp_socket(sock_id *new, SCTP_ADAPTATION_INDICATION, SCTP_PARTIAL_DELIVERY_EVENT }; + struct sctp_initmsg initmsg; + socklen_t socklen; int i; if (!(sock = usrsctp_socket(family, type, IPPROTO_SCTP, @@ -268,6 +273,50 @@ static status_t s1ap_usrsctp_socket(sock_id *new, } } + memset(&initmsg, 0, sizeof(struct sctp_initmsg)); + socklen = sizeof(struct sctp_initmsg); + if (usrsctp_getsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, &socklen) != 0) + { + d_error("getsockopt for SCTP_INITMSG failed(%d:%s)", + errno, strerror( errno )); + return CORE_ERROR; + } + + d_trace(3, "Old INITMSG (numout:%d maxin:%d maxattempt:%d maxinit_to:%d)\n", + initmsg.sinit_num_ostreams, + initmsg.sinit_max_instreams, + initmsg.sinit_max_attempts, + initmsg.sinit_max_init_timeo); + + /* + * INITMSG + * + * max number of input streams : 65535 + * max attemtps : 4 + * max initial timeout : 8 secs + */ + d_assert(sctp_num_ostreams > 1, return CORE_ERROR, + "Invalid SCTP number of output streams = %d\n", sctp_num_ostreams); + + initmsg.sinit_num_ostreams = sctp_num_ostreams; + initmsg.sinit_max_instreams = 65535; + initmsg.sinit_max_attempts = 4; + initmsg.sinit_max_init_timeo = 8000; + + if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, + &initmsg, sizeof(initmsg)) != 0) + { + d_error("setsockopt for SCTP_INITMSG failed(%d:%s)", + errno, strerror( errno )); + return CORE_ERROR; + } + + d_trace(3,"New INITMSG (numout:%d maxin:%d maxattempt:%d maxinit_to:%d)\n", + initmsg.sinit_num_ostreams, + initmsg.sinit_max_instreams, + initmsg.sinit_max_attempts, + initmsg.sinit_max_init_timeo); + *new = (sock_id)sock; return CORE_OK; diff --git a/support/config/nextepc.conf.in b/support/config/nextepc.conf.in index e755f6bb8..1b579aab0 100644 --- a/support/config/nextepc.conf.in +++ b/support/config/nextepc.conf.in @@ -13,6 +13,9 @@ logger: # # parameter: # +# o Number of output streams per SCTP associations. +# sctp_streams: 30 +# # o Disable use of IPv4 addresses (only IPv6) # no_ipv4: true # From 280aaf9fe1c68d66886a24e6ba7fba531876da83 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Thu, 10 May 2018 11:18:43 +0900 Subject: [PATCH 2/2] Add SCTP output stream generator (#54) --- src/mme/mme_context.c | 9 +++++++++ src/mme/mme_context.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/mme/mme_context.c b/src/mme/mme_context.c index ad32a2ccd..bf0ae7ac4 100644 --- a/src/mme/mme_context.c +++ b/src/mme/mme_context.c @@ -1938,6 +1938,15 @@ mme_ue_t* mme_ue_add(enb_ue_t *enb_ue) mme_ue->mme_s11_teid = mme_ue->index; + /* + * SCTP output stream identification + * Default context_self()->parameter.sctp_streams : 30 + * 0 : Non UE signalling + * 1-29 : UE specific association + */ + mme_ue->ostream_id = NEXT_ID(self.ostream_id, + 1, context_self()->parameter.sctp_streams-1); + /* Create New GUTI */ mme_ue_new_guti(mme_ue); diff --git a/src/mme/mme_context.h b/src/mme/mme_context.h index 86c183d54..bd124a9ed 100644 --- a/src/mme/mme_context.h +++ b/src/mme/mme_context.h @@ -113,6 +113,7 @@ typedef struct _mme_context_t { /* Generator for unique identification */ c_uint32_t mme_ue_s1ap_id; /* mme_ue_s1ap_id generator */ + c_uint16_t ostream_id; /* ostream_id generator */ /* M-TMSI Pool */ struct { @@ -244,6 +245,8 @@ struct _mme_ue_t { c_uint32_t mme_s11_teid; /* MME-S11-TEID is derived from INDEX */ c_uint32_t sgw_s11_teid; /* SGW-S11-TEID is received from SGW */ + c_uint16_t ostream_id; /* SCTP output stream identification */ + /* UE Info */ tai_t tai; e_cgi_t e_cgi;