The libdbd-sqlite3 provides SQLite3 driver for libdbi. We use it
by default for the built-in SMS Centre. Since [1], we have unit
test coverage for the db_sms_* API, thus we need libdbd-sqlite3
to be installed at build-time.
[1] Id94ad35b6f78f839137db2e17010fbf9b40111a3
Change-Id: Ice9fb11f5b8a39abecee426d2fadcf62b7ee47c4
man memcp doesn't define exact values for returned integer, it only
specifices a meaning for the sign of it.
So it happens that different versions/implementations actually return
different values when this test is run, making it fail.
Let's simply drop that info from logs since anyways it's not useful.
Change-Id: I771fb8f4fc56f337b16561d005ff1803a386d1c6
Catched by ASan on db_sms_test unit test:
DDB NOTICE test_db_sms_get('Empty TP-UD'): osmo-msc/src/libmsc/db.c:796:2: runtime error: null pointer passed as argument 2, which is declared to never be null
That happens on empty PDU because dbi_result_get_binary returns NULL,
and sms->user_data_len is 0, so it's harmless but we can avoid calling
mempcy and make ASan happy.
Change-Id: I545967464c406348b8505d1729213cfb4afcd3e2
Thanks to db_sms_test, it was discovered that storing an SMS with
empty TP-User-Data (TP-UDL=1) causes buffer overruns in libdbi
and it's SQLite3 driver (libdbdsqlite3):
DDB NOTICE test_db_sms_store('Empty TP-UD'): ==7791== Invalid write of size 2
==7791== at 0x857DC60: dbd_quote_binary (in /usr/lib/x86_64-linux-gnu/dbd/libdbdsqlite3.so)
==7791== by 0x5B2B321: dbi_conn_quote_binary_copy (in /usr/lib/x86_64-linux-gnu/libdbi.so.1.1.0)
==7791== by 0x4073B1: db_sms_store (db.c:701)
==7791== by 0x405BB5: test_db_sms_store (db_sms_test.c:310)
==7791== by 0x405BB5: main (db_sms_test.c:546)
==7791== Address 0x7ed1cf0 is 0 bytes after a block of size 0 alloc'd
==7791== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7791== by 0x857DC4B: dbd_quote_binary (in /usr/lib/x86_64-linux-gnu/dbd/libdbdsqlite3.so)
==7791== by 0x5B2B321: dbi_conn_quote_binary_copy (in /usr/lib/x86_64-linux-gnu/libdbi.so.1.1.0)
==7791== by 0x4073B1: db_sms_store (db.c:701)
==7791== by 0x405BB5: test_db_sms_store (db_sms_test.c:310)
==7791== by 0x405BB5: main (db_sms_test.c:546)
...
DDB NOTICE test_db_sms_get('Empty TP-UD'): ==8051== Invalid read of size 1
==8051== at 0x5B30510: _dbd_decode_binary (in /usr/lib/x86_64-linux-gnu/libdbi.so.1.1.0)
==8051== by 0x857D957: dbd_fetch_row (in /usr/lib/x86_64-linux-gnu/dbd/libdbdsqlite3.so)
==8051== by 0x5B2C86E: dbi_result_seek_row (in /usr/lib/x86_64-linux-gnu/libdbi.so.1.1.0)
==8051== by 0x40828F: next_row (db.c:188)
==8051== by 0x40828F: db_sms_get (db.c:805)
==8051== by 0x406C29: test_db_sms_get (db_sms_test.c:390)
==8051== by 0x405C14: main (db_sms_test.c:547)
==8051== Address 0x8f74641 is 0 bytes after a block of size 1 alloc'd
==8051== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8051== by 0x5DBEB49: strdup (strdup.c:42)
==8051== by 0x857D93C: dbd_fetch_row (in /usr/lib/x86_64-linux-gnu/dbd/libdbdsqlite3.so)
==8051== by 0x5B2C86E: dbi_result_seek_row (in /usr/lib/x86_64-linux-gnu/libdbi.so.1.1.0)
==8051== by 0x40828F: next_row (db.c:188)
==8051== by 0x40828F: db_sms_get (db.c:805)
==8051== by 0x406C29: test_db_sms_get (db_sms_test.c:390)
==8051== by 0x405C14: main (db_sms_test.c:547)
==8051==
success, as expected
DDB NOTICE verify_sms('Empty TP-UD'): user_data_len mismatch: E0 vs A3
Apparently, dbi_conn_quote_binary_copy() doesn't properly handle
zero-length input. Let's guard against this.
Observed with:
- libdbi-dev 0.9.0-1
- libdbd-sqlite3:amd64 0.9.0-2ubuntu2
Change-Id: If0b2bb557118c5f0e520a2e6c2816336f6028661
Since OsmoMSC has built-in SMSC, it needs to store the messages
somewhere. Currently we use libdbi and SQLite3 back-end for that.
For a long time, the db_sms_* API remained uncovered by unit tests.
This change aims to fix that, and does cover the following calls:
- db_sms_store(),
- db_sms_get(),
- db_sms_get_next_unsent(),
- db_sms_mark_delivered(),
- db_sms_delete_sent_message_by_id(),
- db_sms_delete_by_msisdn(),
- db_sms_delete_oldest_expired_message().
Due to performance reasons, the test database is initialized in
RAM using the magic filename ':memory:'. This is a feature of
SQLite3 (and not libdbi), see:
https://www.sqlite.org/inmemorydb.html
Of course, this unit test helped to discover some problems:
1) Storing an SMS with empty TP-User-Data (TP-UDL=0) causes
buffer overruns in both db_sms_store() and db_sms_get().
2) TP-User-Data-Length is always being interpreted in octets,
regardless of DCS (Data Coding Scheme). This results in
storing garbage in the database if the default 7-bit
encoding is used. Fortunately, the 'user_data' buffer
in structure 'gsm_sms' is large emough, so we don't
experience buffer overruns.
3) db_sms_delete_oldest_expired_message() doesn't work
as expected. Instead of removing the *oldest* expired
message, it tries to remove the *newest* one.
The current test expectations do reflect these problems.
All of them will be fixed in the follow-up patches.
Change-Id: Id94ad35b6f78f839137db2e17010fbf9b40111a3
We also need stubs for the upcoming db_sms tests.
Due to a known bug of automake [1], we cannot use 'subdir-objects',
so as a side effect this change introduces some autoreconf warnings.
[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=752993
Change-Id: I8846c940f2695fd33e1007fecac83e73f508bb34
In the most cases we need to check whether particular char buffer
is empty or not. Using strlen() for that involves more CPU power,
so let's just check the first character against '\0'.
Change-Id: I8728876b80c870e82247e6e56f719e10ed322a95
The current way of printing subscriber, connection, and transaction
info is ugly (sorry) and has several problems:
- the terminal width should be large enough to fit quite long lines,
otherwise the output is unreadable and looks misaligned;
- some fields (such as subscriber name) can be larger than it's
expected, so either they're getting truncated, or again, the
output is misaligned and unreadable;
- adding new info fields would require one to think about the
alignment and would make the output even more cumbersome.
Here is an example output of 'show connection' command:
_Subscriber_______________________________________ _LAC_ _RAN___________________ _MSC-A_state_________ _MSC-A_use_
IMSI-123456789012345:MSISDN-12345:TMSI-0x12345678 1 GERAN-A-4294967295:A5-3 WAIT_CLASSMARK_UPDATE 2=cm_service,trans_cc
IMSI-123456789012356:MSISDN-234567:TMSI-0x123ABC78 65535 UTRAN-Iu-4294967295 COMMUNICATING 2=cm_service,trans_sms
IMSI-262073993158656:MSISDN-123456:TMSI-0x493026BA 1 GERAN-A-1 MSC_A_ST_COMMUNICATING 1=1 (silent_call)
Another 'show subscriber' command mixes the information about
subscriber, its connections and transactions without any alignment,
what also decreases the readability.
This change introduces a hierarchical approach, based on the old
'field per line' formatting. First of all, the VTY commands were
extended with optional flags:
show connection [trans]
show subscriber cache [(conn|trans|conn+trans)]
show subscriber TYPE ID [(conn|trans|conn+trans)]
so it can be decided, whether to print child connections and/or
transaction, or not. For example:
show connection trans
would print all connections and their child transactions with
hierarchical alignment:
Connection #00:
Subscriber: IMSI-262073993158656:MSISDN-123456:TMSI-0x76760B75
RAN connection: GERAN-A-1
RAN connection state: MSC_A_ST_COMMUNICATING
LAC / cell ID: 1 / 0
Use count total: 1
Use count: 1 (silent_call)
Transaction #00:
Unique (global) identifier: 0x00000000
GSM 04.07 identifier (MT): 0
Type: silent-call
another example is:
show subscriber cache conn+trans
which would print all known subscribers,
their active connections and transactions:
Subscriber #00:
MSISDN: 123456
LAC / cell ID: 1 / 0
RAN type: GERAN-A
IMSI: 262073993158656
TMSI: 76760B75
...
Connection:
RAN connection: GERAN-A-1
RAN connection state: MSC_A_ST_COMMUNICATING
...
Transaction #00:
Unique (global) identifier: 0x00000000
GSM 04.07 identifier (MT): 0
Type: silent-call
Transaction #01:
Unique (global) identifier: 0x00000001
GSM 04.07 identifier (MO): 0
Type: SMS
Transaction #02:
Unique (global) identifier: 0x00000002
GSM 04.07 identifier (MT): 0
Type: SMS
Please note that we don't print redundant info in child nodes
(i.e. connection and transaction info), such as subscriber name
in connection info, nor connection name in transaction info - it
is clear from the hierarchical formatting.
Change-Id: I5e58b56204c3f3d019e8d4c3c96cefdbb4af4d47
The HLR (which is connected via the GSUP interface) may fail and
disconnect. On the next location update the VLR will try to talk to the
HLR and fail. This failure event is not communicated towards the SGs
related code and the SGs-association will remain in the LA-PRESENT state
forever. Lets add code to report the problem to the SGs code and trigger
a RESET an the SGs interface.
- Add a flag to report an HLR problem back to the SGs code
- Fix the FSM that controls the reset
- Make sure the all SGs associations are reset when the failure occurs.
Change-Id: Icc7df92879728bc98c85fc1d5d8b4c6246501b12
Related: OS#3859
According to 3GPP TS 29.002, section 7.6.8.7, MMS (More Messages to Send)
is an optional IE of MT-ForwardSM-Req message which is used by SMSC to
indicate that there are more (multi-part) MT SMS messages to be sent.
The MSC needs to use this indication in order to decide whether to
keep the RAN connection with a given subscriber open.
Related Change-Id: (TTCN) I6308586a70c4fb3254c519330a61a9667372149f
Change-Id: Ic46b04913b2e8cc5d11a39426dcc1bfe11f1d31e
Related: OS#3587
in osmo-msc/Makefile.am, osmo-msc was actually missing the LIBASN1C_LIBS even
though it included LIBASN1C_CFLAGS. Probably libasn1c is implicitly linked from
libranap.so, but doesn't hurt to name it.
When building without Iu support, the LIBOSMORANAP* and LIBASN1C* vars are
empty, so no need to explicitly switch on BUILD_IU, just name them.
Change-Id: I39ae5e3f0f7661ca9ee5c17a500be28c461d7ec7
DB counters has been used to save osmo_counters & osmo_rate_ctr to a local
sqlite databases every 60 seconds.
This is quite slow e.g. 1000 subscriber might slow the msc down.
Change-Id: Id64f1839a55b5326f74ec04b7a5dbed9d269b89c
Later on we want to do extra steps upon receiving a Rx Reset Ack
(checking for Osmux support from peer). Let's move handling of this
message into its own function to have handling implementation in one
place.
Change-Id: I516c4baf6071d26f6c530726d93677bed968efd1
When 'check-imei-rqd 1 early' is set in the config, send the IMEI to
the HLR before doing the location update with the HLR.
The OsmoHLR documentation referenced in the code will be added in
osmo-hlr.git's Change-Id I2dd4a56f7b8be8b5d0e6fc32e04459e5e278d0a9.
Related: OS#2542
Change-Id: I88283cad23793b475445d814ff49db534cb41244
Copy IMEISV to IMEI when IMEISV changes. The additional SV digits will
get cut off then. This is needed for the subscriber on demand use case,
since we can get the IMEISV early (see [1]), but need to send the IMEI
to the Check IMEI procedure.
While adjusting the tests, I have noticed that there are code paths
where we ask the MS for the IMEISV first, and later ask the MS for the
IMEI, although we already have the IMEISV. This could be improved in a
future patch.
[1] Change-Id I256224194c3b8caf2b58a88d11dccd32c569201f
Related: OS#2542
Change-Id: I02e7b66848bf7dddb31b105e2ae981432817ae1e
Set the length of vlr_subscr->imei to
GSM23003_IMEI_NUM_DIGITS_NO_CHK (14)
instead of
GSM23003_IMEISV_NUM_DIGITS (16).
Note that there is also GSM23003_IMEI_NUM_DIGITS (15), which includes
an additional checksum digit. This digit is not intended for digital
transmission, so we don't need to store it. Also by not storing it, we
can simply copy the IMEI-part from the IMEISV to the IMEI without
worrying about the checksum (will be done in a follow up patch).
A good overview of the IMEI/IMEISV structure is here:
https://en.wikipedia.org/wiki/International_Mobile_Equipment_Identity#Structure_of_the_IMEI_and_IMEISV_(IMEI_software_version)
Related: OS#2542
Change-Id: Iaf2569c099874b55acbd748b776394726cc5ce54
Prepare for Rhizomatica's subscriber on demand use case, in which the
network access is disabled by default for new subscribers, but the IMEI
is required in the HLR to find out which user has which IMSI. Due to the
network access being disabled, the location update request towards the
HLR fails and the MS gets rejected, so we need to get the IMEI early.
Related: OS#2542, OS#3755
Change-Id: I256224194c3b8caf2b58a88d11dccd32c569201f
Previous patch [1] removed NULL-safety from LOG_TRANS(). Fix that.
In case a trans is NULL, it is fine to log in the DMSC category, since the
context should still be general (erratic message or other initial problems).
[1] 7f85acea9b / I6dfe5b98fb9e884c2dde61d603832dafceb12123
"LOG_TRANS: store subsys in trans, unify USSD logging back to DMM"
Change-Id: I6e36c47bf828dd073b36c6301bbeabcc28e101e6
In state machine callback functions, instead of logging an error when
an invalid event arrives, do OSMO_ASSERT(0).
Change-Id: If5363ae37b414a0ac195e5f89664c75cbad0bb21
In ran_a_make_handover_request() we do prevent destination buffer
(r.encryption_information.key) overflow, but not source buffer
(n->geran.chosen_encryption->key) overrun if an incorrect key
length is received. Let's fix this.
Change-Id: I278bb72660634c2d535e1bd3d7fce5696da23575
Fixes: CID#198450 Out-of-bounds access
We basically need to make sure that one of two possible IEs
is not NULL, while another is NULL (eXclusive OR). This can
be done using at least two conditional branches.
Change-Id: Ie0f9b5c1bbbfb744e0615da07d76037d91b0abc8
Fixes: CID#198444 Logically dead code
For some reason, having ternary operator there makes Coverity think
that 'n->geran.chosen_encryption' is dereferenced before checking
against NULL. Let's make it happy, and move the assignment.
Change-Id: I95051d0f02e2fdd3ec8da3a506109e7b23e99b4b
Fixes: CID#198454 Dereference before null check
The librt is required for old glibc < 2.17 to get clock_gettime().
Since we do check the availability of this function libosmocore
and conditionally link it against librt, there is no need to do
such unconditional and redundant linkage here.
Change-Id: If587d16d2db677b97e3a0641027eb735af9c9c30
In gsm48_rx_mm_serv_req() we need to make sure that a given message
buffer is large enough to contain both 'gsm48_hdr' and
'gsm48_service_request' structures.
Comparing msg->data_len with size of pointer if wrong because:
- we actually need to compare with size of struct(s),
- we need msgb_l3len(), not length of the whole buffer.
Moreover, since we have to use the pointer arithmetics in order
to keep backwards compatibility with Phase1 phones, we also
need to check the length of both Classmark2 and MI IEs.
Change-Id: I6e7454d7a6f63fd5a0e12fb90d8c58688da0951e
Since in parse_umts_auth_resp() we are checking the length of
GSM48_IE_AUTH_RES_EXT TLV, we need to print its length, but
not the length of the whole L3.
Change-Id: I2bfebce6d017be834bfe7628ffa2b341eb82c11c
The MSC_A_EV_HANDOVER_END exists as parent term event for the msc_ho_fsm, but
it is not actually required as functional event, since all cleanup is handled
in msc_ho_fsm_cleanup().
That's why I never bothered to add the event to msc_a_fsm, but of course that
means we get an error message after each (successful and unsuccessful)
handover, that the MSC_A_EV_HANDOVER_END is not permitted.
Allow the event and ignore it to silence the error message.
Explain in a comment.
Change-Id: Ie8dc0c0a631b7da43111f329562007766a21b134