SCCP: implement variable limit on Optional Data (CR,CC,CREF,RLSD)
When the Optional Data surpasses 130 bytes, it is not sent as part of SCCP CR, CC, CREF or RLSD messages, but gets sent separately in a Data Form 1. Make this 130 user configurable. This is specified to be 130 bytes exactly, but to interop with non-conforming peers, make this limit adjustable per cs7 instance, via osmo_sccp_vty_init(). Add and test new VTY config: cs7 instance N sccp max-optional-data (<0-999999>|standard) Related: ITU-T Q.713 4.2 to 4.5 Related: Ia68dad973ef18513b52f5accb5264c557c7295ea osmo-ttcn3-hacks Related: SYS#6423 Change-Id: If35697234796af8943691b2de62218e7dc93a08c
This commit is contained in:
parent
460ba631b5
commit
a0fbeeb4d2
|
@ -58,6 +58,8 @@ struct osmo_sccp_instance {
|
|||
struct osmo_ss7_user ss7_user;
|
||||
|
||||
struct osmo_sccp_timer_val timers[OSMO_SCCP_TIMERS_COUNT];
|
||||
|
||||
uint32_t max_optional_data;
|
||||
};
|
||||
|
||||
struct osmo_sccp_user {
|
||||
|
|
|
@ -676,11 +676,12 @@ static bool xua_drop_data_check_drop(const struct osmo_scu_prim *prim, unsigned
|
|||
static bool xua_opt_data_cache_keep(struct sccp_connection *conn, const struct osmo_scu_prim *prim, int msg_type)
|
||||
{
|
||||
uint8_t *buf;
|
||||
uint32_t max_optional_data = conn->inst->max_optional_data;
|
||||
|
||||
if (xua_drop_data_check_drop(prim, SCCP_MAX_DATA, "cache overrun"))
|
||||
return false;
|
||||
|
||||
if (msgb_l2len(prim->oph.msg) > SCCP_MAX_OPTIONAL_DATA) {
|
||||
if (msgb_l2len(prim->oph.msg) > max_optional_data) {
|
||||
if (conn->opt_data_cache) {
|
||||
/* Caching optional data, but there already is optional data occupying the cache: */
|
||||
LOGP(DLSCCP, LOGL_ERROR, "replacing unsent %u bytes of optional data cache with %s optional data\n",
|
||||
|
@ -703,6 +704,8 @@ static bool xua_opt_data_cache_keep(struct sccp_connection *conn, const struct o
|
|||
/* Check optional Data size limit, cache if necessary, return indication whether original opt data should be sent */
|
||||
static bool xua_opt_data_length_lim(struct sccp_connection *conn, const struct osmo_scu_prim *prim, int msg_type)
|
||||
{
|
||||
uint32_t max_optional_data = conn->inst->max_optional_data;
|
||||
|
||||
if (!(prim && msgb_l2(prim->oph.msg) && msgb_l2len(prim->oph.msg)))
|
||||
return false;
|
||||
|
||||
|
@ -711,7 +714,7 @@ static bool xua_opt_data_length_lim(struct sccp_connection *conn, const struct o
|
|||
case SUA_CO_COAK: /* §4.3 Connection confirm (CC) */
|
||||
return xua_opt_data_cache_keep(conn, prim, msg_type);
|
||||
case SUA_CO_COREF: /* §4.4 Connection refused (CREF) */
|
||||
if (xua_drop_data_check_drop(prim, SCCP_MAX_OPTIONAL_DATA, "over ITU-T Rec. Q.713 §4.4 limit")) {
|
||||
if (xua_drop_data_check_drop(prim, max_optional_data, "over ITU-T Rec. Q.713 §4.4 limit")) {
|
||||
/* From the state diagrams in ITU-T Rec Q.714, there's no way to send DT1 neither before nor after CREF
|
||||
* at this point, so the only option we have is to drop optional data:
|
||||
* see Figure C.3 / Q.714 (sheet 2 of 6) */
|
||||
|
@ -719,7 +722,7 @@ static bool xua_opt_data_length_lim(struct sccp_connection *conn, const struct o
|
|||
}
|
||||
break;
|
||||
case SUA_CO_RELRE: /* §4.5 Released (RLSD) */
|
||||
if (msgb_l2len(prim->oph.msg) > SCCP_MAX_OPTIONAL_DATA) {
|
||||
if (msgb_l2len(prim->oph.msg) > max_optional_data) {
|
||||
if (xua_drop_data_check_drop(prim, SCCP_MAX_DATA, "protocol error"))
|
||||
return false;
|
||||
/* There's no need to cache the optional data since the connection is still active at this point:
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <osmocom/sigtran/mtp_sap.h>
|
||||
#include <osmocom/sigtran/protocol/mtp.h>
|
||||
#include <osmocom/sigtran/sccp_helpers.h>
|
||||
#include <osmocom/sccp/sccp_types.h>
|
||||
|
||||
#include "sccp_internal.h"
|
||||
#include "xua_internal.h"
|
||||
|
@ -235,6 +236,7 @@ osmo_sccp_instance_create(struct osmo_ss7_instance *ss7, void *priv)
|
|||
inst->ss7_user.name = "SCCP";
|
||||
inst->ss7_user.prim_cb = mtp_user_prim_cb;
|
||||
inst->ss7_user.priv = inst;
|
||||
inst->max_optional_data = SCCP_MAX_OPTIONAL_DATA;
|
||||
|
||||
rc = sccp_scmg_init(inst);
|
||||
if (rc < 0) {
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include <osmocom/sigtran/osmo_ss7.h>
|
||||
#include <osmocom/sigtran/protocol/mtp.h>
|
||||
|
||||
#include <osmocom/sccp/sccp_types.h>
|
||||
|
||||
#include "xua_internal.h"
|
||||
#include "sccp_internal.h"
|
||||
|
||||
|
@ -165,6 +167,36 @@ DEFUN_ATTR(sccp_timer, sccp_timer_cmd,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(sccp_max_optional_data, sccp_max_optional_data_cmd,
|
||||
"sccp max-optional-data (<0-999999>|standard)",
|
||||
"Configure SCCP behavior\n"
|
||||
"Adjust the upper bound for the optional data length (the payload) for CR, CC, CREF and RLSD messages."
|
||||
" For any Optional Data part larger than this value in octets, send CR, CC, CREF and RLSD"
|
||||
" messages without any payload, and send the data payload in a separate Data Form 1 message."
|
||||
" ITU-T Q.713 sections 4.2 thru 4.5 define a limit of 130 bytes for the 'Data' parameter. This limit can be"
|
||||
" adjusted here. May be useful for interop with nonstandard SCCP peers.\n"
|
||||
"Set a non-standard maximum allowed number of bytes\n"
|
||||
"Use the ITU-T Q.713 4.2 to 4.5 standard value of 130\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
{
|
||||
struct osmo_ss7_instance *ss7 = vty->index;
|
||||
int val;
|
||||
|
||||
if (!strcmp(argv[0], "standard"))
|
||||
val = SCCP_MAX_OPTIONAL_DATA;
|
||||
else
|
||||
val = atoi(argv[0]);
|
||||
|
||||
osmo_ss7_ensure_sccp(ss7);
|
||||
if (!ss7->sccp) {
|
||||
vty_out(vty, "%% Error: cannot instantiate SCCP instance%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
ss7->sccp->max_optional_data = val;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static const char *osmo_sccp_timer_val_name(const struct osmo_sccp_timer_val *val)
|
||||
{
|
||||
static char buf[16];
|
||||
|
@ -227,6 +259,8 @@ static void write_sccp_timers(struct vty *vty, const char *indent,
|
|||
void osmo_sccp_vty_write_cs7_node(struct vty *vty, const char *indent, struct osmo_sccp_instance *inst)
|
||||
{
|
||||
write_sccp_timers(vty, indent, inst, false);
|
||||
if (inst->max_optional_data != SCCP_MAX_OPTIONAL_DATA)
|
||||
vty_out(vty, "%ssccp max-optional-data %u%s", indent, inst->max_optional_data, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
DEFUN(show_sccp_timers, show_sccp_timers_cmd,
|
||||
|
@ -262,4 +296,5 @@ void osmo_sccp_vty_init(void)
|
|||
install_lib_element_ve(&show_sccp_timers_cmd);
|
||||
gen_sccp_timer_cmd_strs(&sccp_timer_cmd);
|
||||
install_lib_element(L_CS7_NODE, &sccp_timer_cmd);
|
||||
install_lib_element(L_CS7_NODE, &sccp_max_optional_data_cmd);
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@ ss7_asp_vty_test(config-cs7)# list
|
|||
sccp-address NAME
|
||||
no sccp-address NAME
|
||||
sccp-timer (conn_est|ias|iar|rel|repeat_rel|int|guard|reset|reassembly) <1-999999>
|
||||
sccp max-optional-data (<0-999999>|standard)
|
||||
|
||||
ss7_asp_vty_test(config-cs7)# ?
|
||||
...
|
||||
|
@ -101,6 +102,7 @@ ss7_asp_vty_test(config-cs7)# ?
|
|||
as Configure an Application Server
|
||||
sccp-address Create/Modify an SCCP addressbook entry
|
||||
sccp-timer Configure SCCP timer values, see ITU-T Q.714
|
||||
sccp Configure SCCP behavior
|
||||
|
||||
ss7_asp_vty_test(config-cs7)# description ?
|
||||
TEXT Text until the end of the line
|
||||
|
@ -427,3 +429,43 @@ ss7_asp_vty_test(config-cs7)# sccp-timer ?
|
|||
|
||||
ss7_asp_vty_test(config-cs7)# sccp-timer conn_est ?
|
||||
<1-999999> Timer value, in seconds
|
||||
|
||||
ss7_asp_vty_test(config-cs7)# sccp ?
|
||||
max-optional-data Adjust the upper bound for the optional data length (the payload) for CR, CC, CREF and RLSD messages. For any Optional Data part larger than this value in octets, send CR, CC, CREF and RLSD messages without any payload, and send the data payload in a separate Data Form 1 message. ITU-T Q.713 sections 4.2 thru 4.5 define a limit of 130 bytes for the 'Data' parameter. This limit can be adjusted here. May be useful for interop with nonstandard SCCP peers.
|
||||
|
||||
ss7_asp_vty_test(config-cs7)# sccp max-optional-data ?
|
||||
<0-999999> Set a non-standard maximum allowed number of bytes
|
||||
standard Use the ITU-T Q.713 4.2 to 4.5 standard value of 130
|
||||
|
||||
ss7_asp_vty_test(config-cs7)# show running-config
|
||||
... !sccp max-optional-data
|
||||
|
||||
ss7_asp_vty_test(config-cs7)# sccp max-optional-data 0
|
||||
ss7_asp_vty_test(config-cs7)# show running-config
|
||||
...
|
||||
sccp max-optional-data 0
|
||||
...
|
||||
|
||||
ss7_asp_vty_test(config-cs7)# sccp max-optional-data 123
|
||||
ss7_asp_vty_test(config-cs7)# show running-config
|
||||
...
|
||||
sccp max-optional-data 123
|
||||
...
|
||||
|
||||
ss7_asp_vty_test(config-cs7)# sccp max-optional-data 999999
|
||||
ss7_asp_vty_test(config-cs7)# show running-config
|
||||
...
|
||||
cs7 instance 0
|
||||
...
|
||||
sccp max-optional-data 999999
|
||||
...
|
||||
cs7 instance 1
|
||||
... !sccp max-optional-data
|
||||
|
||||
ss7_asp_vty_test(config-cs7)# sccp max-optional-data standard
|
||||
ss7_asp_vty_test(config-cs7)# show running-config
|
||||
... !sccp max-optional-data
|
||||
|
||||
ss7_asp_vty_test(config-cs7)# sccp max-optional-data 130
|
||||
ss7_asp_vty_test(config-cs7)# show running-config
|
||||
... !sccp max-optional-data
|
||||
|
|
Loading…
Reference in New Issue