Bug #3871

Updated by neels 3 months ago

In summary:
* 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


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:

| ---N_CONNECT--> | ---osmo_scu_prim.connect.conn_id--> | BSSAP implementation stores new conn_id.
| | |
| <--N_DATA-----> | <> |

But in case of an inter-BSC HO, the MSC initiates a connection to the BSC instead:

| <--N_CONNECT--- | <--osmo_scu_prim.connect.conn_id--- | BSSAP implementation *invents* new conn_id.
| | |
| <--N_DATA-----> | <> |

(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 established 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.


Add picture from clipboard (Maximum size: 48.8 MB)