2017-04-03 17:46:20 +00:00
|
|
|
#pragma once
|
|
|
|
|
2017-04-03 18:39:26 +00:00
|
|
|
#include <osmocom/core/fsm.h>
|
|
|
|
#include <osmocom/core/prim.h>
|
2023-03-10 16:33:54 +00:00
|
|
|
#include <osmocom/core/linuxlist.h>
|
|
|
|
#include <osmocom/core/linuxrbtree.h>
|
2023-07-07 15:14:16 +00:00
|
|
|
#include <osmocom/core/tdef.h>
|
2017-04-03 18:39:26 +00:00
|
|
|
#include <osmocom/sigtran/sccp_sap.h>
|
|
|
|
#include <osmocom/sigtran/osmo_ss7.h>
|
2021-02-08 16:46:08 +00:00
|
|
|
#include <osmocom/sigtran/protocol/mtp.h>
|
2017-04-03 18:39:26 +00:00
|
|
|
|
2018-09-26 21:30:44 +00:00
|
|
|
#define SCCP_STR "Signalling Connection Control Part\n"
|
|
|
|
|
make SCCP timers configurable
The previous hardcoded SCCP timers may cause SCCP connection releases, if the
peer is configured with far lower timers than libosmo-sccp. Testing with a
specific SCCPlite MSC, I experienced an iar of just over three minutes, meaning
that calls would be cut off by the MSC, since the osmo-bsc failed to send an
Inactivity Timer message until seven minutes have passed.
With this patch, SCCP timers are configurable by the user.
Define constant global default timers, and variable user-configurable timers
with each osmo_sccp_instance.
Add VTY UI to configure the timers. Users must call osmo_sccp_vty_init() to get
the sccp-timer config nodes under the 'cs7' node. Show the new UI in
ss7_asp_test.vty.
Note that even though this function is not new at all, until recently, all of
our SCCP users (osmo-bsc, osmo-msc, osmo-sgsn, osmo-hnbgw) failed to call
osmo_sccp_vty_init(), and thus also missed out on the various 'show' commands
defined in sccp_vty.c. In other words, to benefit from the timer
configurability, the patches to call osmo_sccp_vty_init() must first be merged
to the corresponding master branches.
If a 'sccp-timer' config command occurs, the cs7 instance must allocate an SCCP
instance in order to store the timer config. Do that by calling the recently
added osmo_ss7_ensure_sccp() function.
Hence remove the limitation that the SCCP instance must not be populated from
the "simple" setup function. If we want to configure SCCP timers beforehand,
there must be an SCCP instance for that, and there is no hard reason to require
a NULL SCCP instance, besides the desire to prevent this function from being
invoked twice.
Change-Id: I28a7362aa838e648ecc9b26ee53dbcade81a9d65
2018-09-26 15:12:23 +00:00
|
|
|
/* Appendix C.4 of Q.714 */
|
|
|
|
enum osmo_sccp_timer {
|
2023-07-07 15:14:16 +00:00
|
|
|
/* 0 kept unused on purpose since it's handled specially by osmo_fsm */
|
|
|
|
OSMO_SCCP_TIMER_CONN_EST = 1,
|
make SCCP timers configurable
The previous hardcoded SCCP timers may cause SCCP connection releases, if the
peer is configured with far lower timers than libosmo-sccp. Testing with a
specific SCCPlite MSC, I experienced an iar of just over three minutes, meaning
that calls would be cut off by the MSC, since the osmo-bsc failed to send an
Inactivity Timer message until seven minutes have passed.
With this patch, SCCP timers are configurable by the user.
Define constant global default timers, and variable user-configurable timers
with each osmo_sccp_instance.
Add VTY UI to configure the timers. Users must call osmo_sccp_vty_init() to get
the sccp-timer config nodes under the 'cs7' node. Show the new UI in
ss7_asp_test.vty.
Note that even though this function is not new at all, until recently, all of
our SCCP users (osmo-bsc, osmo-msc, osmo-sgsn, osmo-hnbgw) failed to call
osmo_sccp_vty_init(), and thus also missed out on the various 'show' commands
defined in sccp_vty.c. In other words, to benefit from the timer
configurability, the patches to call osmo_sccp_vty_init() must first be merged
to the corresponding master branches.
If a 'sccp-timer' config command occurs, the cs7 instance must allocate an SCCP
instance in order to store the timer config. Do that by calling the recently
added osmo_ss7_ensure_sccp() function.
Hence remove the limitation that the SCCP instance must not be populated from
the "simple" setup function. If we want to configure SCCP timers beforehand,
there must be an SCCP instance for that, and there is no hard reason to require
a NULL SCCP instance, besides the desire to prevent this function from being
invoked twice.
Change-Id: I28a7362aa838e648ecc9b26ee53dbcade81a9d65
2018-09-26 15:12:23 +00:00
|
|
|
OSMO_SCCP_TIMER_IAS,
|
|
|
|
OSMO_SCCP_TIMER_IAR,
|
|
|
|
OSMO_SCCP_TIMER_REL,
|
|
|
|
OSMO_SCCP_TIMER_REPEAT_REL,
|
|
|
|
OSMO_SCCP_TIMER_INT,
|
|
|
|
OSMO_SCCP_TIMER_GUARD,
|
|
|
|
OSMO_SCCP_TIMER_RESET,
|
|
|
|
OSMO_SCCP_TIMER_REASSEMBLY,
|
|
|
|
/* This must remain the last item: */
|
2023-07-07 15:14:16 +00:00
|
|
|
OSMO_SCCP_TIMERS_LEN
|
make SCCP timers configurable
The previous hardcoded SCCP timers may cause SCCP connection releases, if the
peer is configured with far lower timers than libosmo-sccp. Testing with a
specific SCCPlite MSC, I experienced an iar of just over three minutes, meaning
that calls would be cut off by the MSC, since the osmo-bsc failed to send an
Inactivity Timer message until seven minutes have passed.
With this patch, SCCP timers are configurable by the user.
Define constant global default timers, and variable user-configurable timers
with each osmo_sccp_instance.
Add VTY UI to configure the timers. Users must call osmo_sccp_vty_init() to get
the sccp-timer config nodes under the 'cs7' node. Show the new UI in
ss7_asp_test.vty.
Note that even though this function is not new at all, until recently, all of
our SCCP users (osmo-bsc, osmo-msc, osmo-sgsn, osmo-hnbgw) failed to call
osmo_sccp_vty_init(), and thus also missed out on the various 'show' commands
defined in sccp_vty.c. In other words, to benefit from the timer
configurability, the patches to call osmo_sccp_vty_init() must first be merged
to the corresponding master branches.
If a 'sccp-timer' config command occurs, the cs7 instance must allocate an SCCP
instance in order to store the timer config. Do that by calling the recently
added osmo_ss7_ensure_sccp() function.
Hence remove the limitation that the SCCP instance must not be populated from
the "simple" setup function. If we want to configure SCCP timers beforehand,
there must be an SCCP instance for that, and there is no hard reason to require
a NULL SCCP instance, besides the desire to prevent this function from being
invoked twice.
Change-Id: I28a7362aa838e648ecc9b26ee53dbcade81a9d65
2018-09-26 15:12:23 +00:00
|
|
|
};
|
|
|
|
|
2023-07-07 15:14:16 +00:00
|
|
|
extern const struct osmo_tdef osmo_sccp_timer_defaults[OSMO_SCCP_TIMERS_LEN];
|
make SCCP timers configurable
The previous hardcoded SCCP timers may cause SCCP connection releases, if the
peer is configured with far lower timers than libosmo-sccp. Testing with a
specific SCCPlite MSC, I experienced an iar of just over three minutes, meaning
that calls would be cut off by the MSC, since the osmo-bsc failed to send an
Inactivity Timer message until seven minutes have passed.
With this patch, SCCP timers are configurable by the user.
Define constant global default timers, and variable user-configurable timers
with each osmo_sccp_instance.
Add VTY UI to configure the timers. Users must call osmo_sccp_vty_init() to get
the sccp-timer config nodes under the 'cs7' node. Show the new UI in
ss7_asp_test.vty.
Note that even though this function is not new at all, until recently, all of
our SCCP users (osmo-bsc, osmo-msc, osmo-sgsn, osmo-hnbgw) failed to call
osmo_sccp_vty_init(), and thus also missed out on the various 'show' commands
defined in sccp_vty.c. In other words, to benefit from the timer
configurability, the patches to call osmo_sccp_vty_init() must first be merged
to the corresponding master branches.
If a 'sccp-timer' config command occurs, the cs7 instance must allocate an SCCP
instance in order to store the timer config. Do that by calling the recently
added osmo_ss7_ensure_sccp() function.
Hence remove the limitation that the SCCP instance must not be populated from
the "simple" setup function. If we want to configure SCCP timers beforehand,
there must be an SCCP instance for that, and there is no hard reason to require
a NULL SCCP instance, besides the desire to prevent this function from being
invoked twice.
Change-Id: I28a7362aa838e648ecc9b26ee53dbcade81a9d65
2018-09-26 15:12:23 +00:00
|
|
|
|
|
|
|
extern const struct value_string osmo_sccp_timer_names[];
|
|
|
|
static inline const char *osmo_sccp_timer_name(enum osmo_sccp_timer val)
|
|
|
|
{ return get_value_string(osmo_sccp_timer_names, val); }
|
|
|
|
|
2017-04-03 18:39:26 +00:00
|
|
|
/* an instance of the SCCP stack */
|
|
|
|
struct osmo_sccp_instance {
|
|
|
|
/* entry in global list of ss7 instances */
|
|
|
|
struct llist_head list;
|
2023-03-10 16:33:54 +00:00
|
|
|
/* rbtree root of 'struct sccp_connection' in this instance */
|
|
|
|
struct rb_root connections;
|
2017-04-03 18:39:26 +00:00
|
|
|
/* list of SCCP users in this instance */
|
|
|
|
struct llist_head users;
|
|
|
|
/* routing context to be used in all outbound messages */
|
|
|
|
uint32_t route_ctx;
|
2019-04-03 12:04:22 +00:00
|
|
|
/* next connection ID to allocate */
|
2017-04-03 18:39:26 +00:00
|
|
|
uint32_t next_id;
|
|
|
|
struct osmo_ss7_instance *ss7;
|
|
|
|
void *priv;
|
|
|
|
|
|
|
|
struct osmo_ss7_user ss7_user;
|
make SCCP timers configurable
The previous hardcoded SCCP timers may cause SCCP connection releases, if the
peer is configured with far lower timers than libosmo-sccp. Testing with a
specific SCCPlite MSC, I experienced an iar of just over three minutes, meaning
that calls would be cut off by the MSC, since the osmo-bsc failed to send an
Inactivity Timer message until seven minutes have passed.
With this patch, SCCP timers are configurable by the user.
Define constant global default timers, and variable user-configurable timers
with each osmo_sccp_instance.
Add VTY UI to configure the timers. Users must call osmo_sccp_vty_init() to get
the sccp-timer config nodes under the 'cs7' node. Show the new UI in
ss7_asp_test.vty.
Note that even though this function is not new at all, until recently, all of
our SCCP users (osmo-bsc, osmo-msc, osmo-sgsn, osmo-hnbgw) failed to call
osmo_sccp_vty_init(), and thus also missed out on the various 'show' commands
defined in sccp_vty.c. In other words, to benefit from the timer
configurability, the patches to call osmo_sccp_vty_init() must first be merged
to the corresponding master branches.
If a 'sccp-timer' config command occurs, the cs7 instance must allocate an SCCP
instance in order to store the timer config. Do that by calling the recently
added osmo_ss7_ensure_sccp() function.
Hence remove the limitation that the SCCP instance must not be populated from
the "simple" setup function. If we want to configure SCCP timers beforehand,
there must be an SCCP instance for that, and there is no hard reason to require
a NULL SCCP instance, besides the desire to prevent this function from being
invoked twice.
Change-Id: I28a7362aa838e648ecc9b26ee53dbcade81a9d65
2018-09-26 15:12:23 +00:00
|
|
|
|
2023-07-07 15:14:16 +00:00
|
|
|
struct osmo_tdef *tdefs;
|
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
2023-04-18 19:59:41 +00:00
|
|
|
|
|
|
|
uint32_t max_optional_data;
|
2017-04-03 18:39:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct osmo_sccp_user {
|
|
|
|
/*! \brief entry in list of sccp users of \ref osmo_sccp_instance */
|
|
|
|
struct llist_head list;
|
|
|
|
/*! \brief pointer back to SCCP instance */
|
|
|
|
struct osmo_sccp_instance *inst;
|
|
|
|
/*! \brief human-readable name of this user */
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
/*! \brief SSN and/or point code to which we are bound */
|
|
|
|
uint16_t ssn;
|
|
|
|
uint32_t pc;
|
|
|
|
|
|
|
|
/* set if we are a server */
|
|
|
|
struct llist_head links;
|
|
|
|
|
|
|
|
/* user call-back function in case of incoming primitives */
|
|
|
|
osmo_prim_cb prim_cb;
|
|
|
|
void *priv;
|
|
|
|
|
|
|
|
/* Application Server FSM Instance */
|
|
|
|
struct osmo_fsm_inst *as_fi;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern int DSCCP;
|
|
|
|
|
|
|
|
struct xua_msg;
|
|
|
|
|
|
|
|
struct osmo_sccp_user *
|
|
|
|
sccp_user_find(struct osmo_sccp_instance *inst, uint16_t ssn, uint32_t pc);
|
|
|
|
|
|
|
|
/* Message from SCOC -> SCRC */
|
|
|
|
int sccp_scrc_rx_scoc_conn_msg(struct osmo_sccp_instance *inst,
|
|
|
|
struct xua_msg *xua);
|
|
|
|
|
|
|
|
/* Message from SCLC -> SCRC */
|
|
|
|
int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, struct xua_msg *xua);
|
|
|
|
|
|
|
|
/* Message from MTP (SUA) -> SCRC */
|
|
|
|
int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst,
|
|
|
|
struct xua_msg *xua);
|
|
|
|
|
|
|
|
/* Message from SCRC -> SCOC */
|
|
|
|
void sccp_scoc_rx_from_scrc(struct osmo_sccp_instance *inst,
|
|
|
|
struct xua_msg *xua);
|
|
|
|
void sccp_scoc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst,
|
|
|
|
struct xua_msg *xua, uint32_t cause);
|
|
|
|
|
|
|
|
void sccp_scoc_flush_connections(struct osmo_sccp_instance *inst);
|
|
|
|
|
|
|
|
/* Message from SCRC -> SCLC */
|
|
|
|
int sccp_sclc_rx_from_scrc(struct osmo_sccp_instance *inst,
|
|
|
|
struct xua_msg *xua);
|
|
|
|
void sccp_sclc_rx_scrc_rout_fail(struct osmo_sccp_instance *inst,
|
|
|
|
struct xua_msg *xua, uint32_t cause);
|
|
|
|
|
|
|
|
int sccp_user_prim_up(struct osmo_sccp_user *scut, struct osmo_scu_prim *prim);
|
|
|
|
|
|
|
|
/* SCU -> SCLC */
|
|
|
|
int sccp_sclc_user_sap_down(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph);
|
add caller-owns-msgb variant osmo_sccp_user_sap_down_nofree()
Add osmo_sccp_user_sap_down_nofree(), which is identical to
osmo_sccp_user_sap_down(), but doesn't imply a msgb_free().
To implement that, sccp_sclc_user_sap_down_nofree() with the same msgb
semantics is required.
Rationale:
Avoiding msgb leaks is easiest if the caller retains ownership of the msgb.
Take this hypothetical chain where leaks are obviously avoided:
void send()
{
msg = msgb_alloc();
dispatch(msg);
msgb_free(msg);
}
void dispatch(msg)
{
osmo_fsm_inst_dispatch(fi, msg);
}
void fi_on_event(fi, data)
{
if (socket_is_ok)
socket_write((struct msgb*)data);
}
void socket_write(msgb)
{
if (!ok1)
return;
if (ok2) {
if (!ok3)
return;
write(sock, msg->data);
}
}
However, if the caller passes ownership down to the msgb consumer, things
become nightmarishly complex:
void send()
{
msg = msgb_alloc();
rc = dispatch(msg);
/* dispatching event failed? */
if (rc)
msgb_free(msg);
}
int dispatch(msg)
{
if (osmo_fsm_inst_dispatch(fi, msg))
return -1;
if (something_else())
return -1; // <-- double free!
}
void fi_on_event(fi, data)
{
if (socket_is_ok) {
socket_write((struct msgb*)data);
else
/* socket didn't consume? */
msgb_free(data);
}
int socket_write(msgb)
{
if (!ok1)
return -1; // <-- leak!
if (ok2) {
if (!ok3)
goto out;
write(sock, msg->data);
}
out:
msgb_free(msg);
return -2;
}
If any link in this call chain fails to be aware of the importance to return a
failed RC or to free a msgb if the chain is broken, or to not return a failed
RC if the msgb is consumed, we have a hidden msgb leak or double free.
This is the case with osmo_sccp_user_sap_down(). In new osmo-msc, passing data
through various FSM instances, there is high potential for leak/double-free
bugs. A very large brain is required to track down every msgb path.
osmo_sccp_user_sap_down_nofree() makes this problem trivial to solve even for
humans.
Change-Id: Ic818efa78b90f727e1a94c18b60d9a306644f340
2019-03-10 03:41:27 +00:00
|
|
|
int sccp_sclc_user_sap_down_nofree(struct osmo_sccp_user *scu, struct osmo_prim_hdr *oph);
|
2017-04-03 17:46:20 +00:00
|
|
|
|
|
|
|
struct msgb *sccp_msgb_alloc(const char *name);
|
2017-04-03 18:39:26 +00:00
|
|
|
|
2020-04-20 17:35:09 +00:00
|
|
|
extern struct osmo_fsm sccp_scoc_fsm;
|
2017-04-14 18:16:10 +00:00
|
|
|
|
|
|
|
void sccp_scoc_show_connections(struct vty *vty, struct osmo_sccp_instance *inst);
|
make SCCP timers configurable
The previous hardcoded SCCP timers may cause SCCP connection releases, if the
peer is configured with far lower timers than libosmo-sccp. Testing with a
specific SCCPlite MSC, I experienced an iar of just over three minutes, meaning
that calls would be cut off by the MSC, since the osmo-bsc failed to send an
Inactivity Timer message until seven minutes have passed.
With this patch, SCCP timers are configurable by the user.
Define constant global default timers, and variable user-configurable timers
with each osmo_sccp_instance.
Add VTY UI to configure the timers. Users must call osmo_sccp_vty_init() to get
the sccp-timer config nodes under the 'cs7' node. Show the new UI in
ss7_asp_test.vty.
Note that even though this function is not new at all, until recently, all of
our SCCP users (osmo-bsc, osmo-msc, osmo-sgsn, osmo-hnbgw) failed to call
osmo_sccp_vty_init(), and thus also missed out on the various 'show' commands
defined in sccp_vty.c. In other words, to benefit from the timer
configurability, the patches to call osmo_sccp_vty_init() must first be merged
to the corresponding master branches.
If a 'sccp-timer' config command occurs, the cs7 instance must allocate an SCCP
instance in order to store the timer config. Do that by calling the recently
added osmo_ss7_ensure_sccp() function.
Hence remove the limitation that the SCCP instance must not be populated from
the "simple" setup function. If we want to configure SCCP timers beforehand,
there must be an SCCP instance for that, and there is no hard reason to require
a NULL SCCP instance, besides the desire to prevent this function from being
invoked twice.
Change-Id: I28a7362aa838e648ecc9b26ee53dbcade81a9d65
2018-09-26 15:12:23 +00:00
|
|
|
|
|
|
|
void osmo_sccp_vty_write_cs7_node(struct vty *vty, const char *indent, struct osmo_sccp_instance *inst);
|
2021-02-06 22:21:55 +00:00
|
|
|
|
|
|
|
/* Local Broadcast (LBCS) */
|
|
|
|
void sccp_lbcs_local_bcast_pcstate(struct osmo_sccp_instance *inst,
|
|
|
|
const struct osmo_scu_pcstate_param *pcstate);
|
|
|
|
void sccp_lbcs_local_bcast_state(struct osmo_sccp_instance *inst,
|
|
|
|
const struct osmo_scu_state_param *state);
|
|
|
|
|
|
|
|
/* SCCP Management (SCMG) */
|
2021-02-08 12:10:17 +00:00
|
|
|
void sccp_scmg_rx_ssn_allowed(struct osmo_sccp_instance *inst, uint32_t dpc, uint32_t ssn, uint32_t smi);
|
|
|
|
void sccp_scmg_rx_ssn_prohibited(struct osmo_sccp_instance *inst, uint32_t dpc, uint32_t ssn, uint32_t smi);
|
2021-02-06 22:21:55 +00:00
|
|
|
void sccp_scmg_rx_mtp_pause(struct osmo_sccp_instance *inst, uint32_t dpc);
|
|
|
|
void sccp_scmg_rx_mtp_resume(struct osmo_sccp_instance *inst, uint32_t dpc);
|
2021-02-08 16:46:08 +00:00
|
|
|
void sccp_scmg_rx_mtp_status(struct osmo_sccp_instance *inst, uint32_t dpc, enum mtp_unavail_cause cause);
|
2021-02-07 16:30:26 +00:00
|
|
|
int sccp_scmg_init(struct osmo_sccp_instance *inst);
|