Bug #3871
openosmo_scu_prim conn_id should be scoped per-user and direction, and should not correlate with the local-reference spoken on the SCCP wire
80%
Description
- separate osmo_scu_prim.*.conn_id from osmo_sccp_inst->next_id
- separate each osmo_sccp_user's conn_ids number spaces
- separate incoming from outgoing osmo_scu_prim.*.conn_id number spaces
Details:
The osmo_sccp_instance.next_id is responsible for local-reference IDs on the SCCP wire.
Currently, this same next_id number space is also used towards the SCU user, i.e. as osmo_scu_prim.*.conn_id.
Not only should this conn_id be scoped separately from the osmo_sccp_instance.next_id, but also be a distinct number space per SCU user.
struct sccp_connection in sccp_scoc.c is the place where an SCCP local-reference is correlated to an osmo_sccp_user.conn_id, it must store these IDs separately.
The number space for the osmo_scu_prim.*.conn_id should be guarded by some "next_id" counter in osmo_sccp_user.
Incoming and outgoing conn_ids must be made sure to not collide, best divide the number space in two for incoming and outgoing conn_ids.
For example, in osmo-msc, there may be two SCCP users connected to the same osmo_sccp_instance: one for OSMO_SCCP_SSN_BSSAP (= GERAN-A = 2G) and one for OSMO_SCCP_SSN_RANAP (= UTRAN-Iu = 3G).
Implementations using the SCU API might be completely separate, and it would be a "scoping violation" if these distinct users have to negotiate with each other about unused osmo_scu_prim conn_ids.
Another aspect is that there may be incoming SCCP connections and outgoing SCCP connections.
As an example:
From the perspective of osmo-msc, usually the BSC connects to the MSC:
BSC MSC AS SCCP-User | ---N_CONNECT--> | ---osmo_scu_prim.connect.conn_id--> | BSSAP implementation stores new conn_id. | | | | <--N_DATA-----> | <---osmo_scu_prim.data.conn_id----> |
But in case of an inter-BSC HO, the MSC initiates a connection to the BSC instead:
BSC MSC AS SCCP-User | <--N_CONNECT--- | <--osmo_scu_prim.connect.conn_id--- | BSSAP implementation *invents* new conn_id. | | | | <--N_DATA-----> | <---osmo_scu_prim.data.conn_id----> |
(Note, this is only relevant for Connection-Oriented Initial messages, i.e. Layer 3 Complete (incoming to MSC) and Handover Request (outgoing from MSC).
For example, Paging is done by a connection-less message that has no conn_id at all, after which the BSC establishes a connection when the MS has responded.)
To keep sane layer separation, it is important to maintain the osmo_scu_prim struct as the only communication interface between the SCCP-User and the SCCP instance.
Hence we cannot iterate all existing conn_ids and pick an unused one: an incoming SCCP connection might asynchronously pick the exact same conn_id.
In practice, this cannot happen right now, but the scoping should be such that it would be possible to place the SCCP User in a separate process.
So, a proposal is that for incoming connections, the libosmo-sccp creates new osmo_scu_prim.*.conn_id in the number space 0..0x7fffffff for incoming N-CONNECT,
while for outgoing N-CONNECT, the SCCP-User implementation creates new osmo_scu_prim.*.conn_id in the number space 0x80000000..0xffffffff. (Or rather, use the lowest bit to separate for shorter logging)
There should be osmo_sccp_user_* API to fetch an unused outgoing SCCP-User conn_id, so SCCP-Users don't need to implement their own.
Related issues