Bug #4319
closeddetermine auc_3g_ind from actual source_name of a request, not from the GSUP client conn
100%
Description
Each VLR requesting auth tuples should use a distinct IND bucket for 3G auth.
Currently we do that by assigning a different IND to each connected client.
Since MSC and SGSN for a given subscriber are two distinct GSUP peers, they will end up using distinct INDs.
However, in a distributed setup, a roaming subscriber has one direct GSUP peer proxying for both remote MSC and SGSN.
That means as soon as a subscriber roams to a different site, the site's MSC and SGSN compete for the same IND bucket and waste SQNs rapidly.
So instead of using the local client as IND, we need to keep a list of VLR names and assign a different IND to each.
Then we use the GSUP source_name as indicator, which reflects the actual remote VLR's name.
Hence MSC and SGSN will be distinct INDs also for remote sites.
This could be done in-mem like now, but would also be better to persist in the database.
In #4305, there is a discussion about IND collisions across remote sites.
The discussion goes about how often per day a subscriber is likely to pass between sites that have identical INDs set.
When thinking about MSC vs SGSN INDs, however, an IND collision would be far worse, because each and every CS and PS Complete-Layer-3 would waste SQNs and load osmo-hlr to generate auth all the time.
So it would make sense to have a built-in scheme that definitely and always avoids CS vs. PS IND collisions.
We could simply assign even-numbered INDs to CS and odd INDs to PS.
Related issues
Updated by neels over 4 years ago
- Assignee set to neels
- Priority changed from Normal to High
Updated by neels over 4 years ago
- Related to Feature #4318: osmo-msc should indicate CS-domain in GSUP SendAuthInfo-Request added
Updated by neels over 4 years ago
- Description updated (diff)
- Status changed from New to In Progress
Updated by neels over 4 years ago
neels wrote:
So it would make sense to have a built-in scheme that definitely and always avoids CS vs. PS IND collisions.
We could simply assign even-numbered INDs to CS and odd INDs to PS.
This part is not as trivial as I thought at first. It is of course easy to make sure that a CS IND is always even and a PS IND is always odd, but what also plays into this is that the source_name also differs for MSC vs. SGSN.
Example: site A has 'MSC-A' and 'SGSN-A'.
My first idea would be to keep one table of known source_name entities, and apply the CS/PS bit after that.
This plays out as:
idx | source_name | resulting IND |
1 | 'MSC-A' | (1 << 1) = 2 |
2 | 'SGSN-A' | (2 << 1) + 1 = 5 |
I get 2 and 5, where I would have liked to get 0 and 1.
It is not actually a problem that it starts with 2, so I am fine with geting 2 and 3.
But since SGSN-A has table index 2, I get 2 and 5.
Imagine every site always showing up with MSC and SGSN in sequence, then we would have
idx | source_name | resulting IND ((idx << 1) + ps ) % 32 |
1 | MSC-A | 2 |
2 | SGSN-A | 5 |
3 | MSC-B | 6 |
4 | SGSN-B | 9 |
5 | MSC-C | 10 |
6 | SGSN-C | 13 |
7 | MSC-D | 14 |
8 | SGSN-D | 17 |
9 | MSC-E | 18 |
10 | SGSN-E | 21 |
11 | MSC-F | 22 |
12 | SGSN-F | 25 |
13 | MSC-G | 26 |
14 | SGSN-G | 29 |
15 | MSC-H | 30 |
16 | SGSN-H | 1 |
17 | MSC-I | 2 |
18 | SGSN-I | 5 |
i.e. the cumulative effect of SGSN getting only every other table index + the separation makes us use only half the IND space by skipping every other IND, and actually upon IND number space wrapping, makes us wrap exactly back to the already used IND instead of those in-between: we use 2 and 6 for MSC, but never 0 or 4.
I would still like to separate CS and PS INDs for certain, though, yet not rely on the MSCs and SGSNs to always turn up nicely in sequence.
So I need separate tables for CS and PS.
1 | MSC-A | 2 |
2 | MSC-B | 4 |
3 | MSC-C | 6 |
4 | MSC-D | 8 |
5 | MSC-E | 10 |
6 | MSC-F | 12 |
7 | MSC-G | 14 |
8 | MSC-H | 16 |
9 | MSC-I | 18 |
10 | MSC-J | 20 |
11 | MSC-K | 22 |
12 | MSC-L | 24 |
13 | MSC-M | 26 |
14 | MSC-N | 28 |
15 | MSC-O | 30 |
16 | MSC-P | 0 |
1 | SGSN-A | 3 |
2 | SGSN-B | 5 |
3 | SGSN-C | 7 |
4 | SGSN-D | 9 |
5 | SGSN-E | 11 |
6 | SGSN-F | 13 |
7 | SGSN-G | 15 |
8 | SGSN-H | 17 |
9 | SGSN-I | 19 |
10 | SGSN-J | 21 |
11 | SGSN-K | 23 |
12 | SGSN-L | 25 |
13 | SGSN-M | 27 |
14 | SGSN-N | 29 |
15 | SGSN-O | 31 |
16 | SGSN-P | 1 |
17 | SGSN-Q | 3 |
(Separate tables allow using SQLite PRIMARY KEY autoincrement independently.)
Updated by neels over 4 years ago
found a way to have both in one table with disctinct indexes for each cn_domain,
with the benefit that the cn_domain is just a number, and arbitrary other cn_domains could be invented without needing to change the db scheme.
((We could use a separate cn_domain (OSMO_GSUP_CN_DOMAIN_NONE == 0) for those SendAuthInfo requests that failed to send a CN domain at all.
The benefit would be nil though -- I'm not going to <<1 another bit to assign actually half of all IND space for omitted CN domain indicators. Ok, nice feat but not useful unless we actually have more valid CN domains.))
CREATE TABLE ind ( cn_domain INTEGER NOT NULL, -- 3G auth IND bucket to be used for this VLR, where IND = (idx << 1) + is_ps ind INTEGER NOT NULL, -- VLR identification, usually the GSUP source_name vlr TEXT NOT NULL, PRIMARY KEY(ind), UNIQUE (cn_domain, vlr) ); insert into ind (cn_domain, ind, vlr) select $cn_domain, count(ind)*2+$cn_domain-1, $vlr from ind where cn_domain = $cn_domain;
Updated by neels over 4 years ago
meh, that looks nice because it directly shows the actually used IND, but leads to problems adding new entries as soon as one of them is removed from the middle. Separate tables may be necessary after all, unless I find something nifty to also cover that.
Another aspect is that we might like an IND to become re-used if it was deleted, instead of first wrapping around the entire number space.
So unless some SQL magic shows up that converges in finite time, we'll actually need to read all IND entries into RAM and handle all those constraints in C instead.
Updated by neels over 4 years ago
- % Done changed from 50 to 80
This does exactly what we want:
CREATE TABLE ind ( cn_domain INTEGER NOT NULL, -- 3G auth IND bucket to be used for this VLR, where IND = (idx << 1) + cn_domain -1 ind INTEGER PRIMARY KEY, -- VLR identification, usually the GSUP source_name vlr TEXT NOT NULL, UNIQUE (cn_domain, vlr) ); insert into ind (cn_domain, ind, vlr) SELECT $cn_domain, CASE WHEN EXISTS(SELECT NULL from ind where cn_domain = $cn_domain LIMIT 1) THEN ( SELECT ((ind + 2) - ((ind + 2)%2) + ($cn_domain-1)) FROM ind as mo WHERE NOT EXISTS (SELECT NULL FROM ind as mi WHERE cn_domain = $cn_domain and mi.ind = ((mo.ind + 2) - ((mo.ind + 2)%2) + $cn_domain-1)) ORDER BY ind LIMIT 1 ) ELSE ($cn_domain-1) END ind , $vlr;
Updated by neels over 4 years ago
Patch is implemented and passes C tests. Next up is test in a live environment and verify that ttcn3 suite still passes.
Updated by neels over 4 years ago
Turns out that bit-shifting separation isn't such a great idea after all.
See https://osmocom.org/issues/4318#note-7
We do need some way or other of getting adjacent sites into distinct IND pools,
all of:
- CS and PS of the same site
- 4G and 23G of the same site
- physically adjacent separate sites.
By now I think my bit shifting idea is not a good one at all, because it
addresses only one of the above points. We need a solution for all of them.
Instead, I will roll back that complexity and use a simple incrementing IND across all VLR names.
Updated by neels over 4 years ago
- % Done changed from 80 to 90
https://gerrit.osmocom.org/c/osmo-hlr/+/16764
waiting for merge
Updated by neels over 4 years ago
- Status changed from In Progress to Resolved
- % Done changed from 90 to 100
merged
Updated by neels over 4 years ago
- Status changed from Resolved to In Progress
- % Done changed from 100 to 90
whoops sorry, this one is still waiting on gerrit
Updated by fixeria over 2 years ago
- Status changed from In Progress to Resolved
- % Done changed from 90 to 100
19.07.2021 "Change has been successfully rebased and submitted as 3f9d1977df0df33f69f0b23cd10a26afd551111d by laforge"