laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/38959?usp=email )
Change subject: contrib/suci-keytool.py: Convenience tool for SUCI key generation
......................................................................
contrib/suci-keytool.py: Convenience tool for SUCI key generation
This adds a small utility program that can be used for generating
keys used for SUCI in 5G SA networks, as well as for dumping them
in a format that's compatible with what is needed on the USIM.
Change-Id: I9e92bbba7f700e160ea9c58da5f23fa4c31d40c6
---
A contrib/suci-keytool.py
M docs/index.rst
A docs/suci-keytool.rst
3 files changed, 111 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/59/38959/1
diff --git a/contrib/suci-keytool.py b/contrib/suci-keytool.py
new file mode 100755
index 0000000..6abd489
--- /dev/null
+++ b/contrib/suci-keytool.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+
+# small utility program to deal with 5G SUCI key material, at least for the ECIES Protection Scheme
+# Profile A (curve25519) and B (secp256r1)
+
+# (C) 2024 by Harald Welte <laforge(a)osmocom.org>
+# SPDX-License-Identifier: GPL-2.0+
+
+import argparse
+
+from osmocom.utils import b2h
+from Cryptodome.PublicKey import ECC
+# if used with pycryptodome < v3.21.0 you will get the following error when using curve25519:
+# "Cryptodome.PublicKey.ECC.UnsupportedEccFeature: Unsupported ECC purpose (OID: 1.3.101.110)"
+
+def gen_key(opts):
+ # FIXME: avoid overwriting key files
+ mykey = ECC.generate(curve=opts.curve)
+ data = mykey.export_key(format='PEM')
+ with open(opts.key_file, "wt") as f:
+ f.write(data)
+
+def dump_pkey(opts):
+
+ #with open("curve25519-1.key", "r") as f:
+
+ with open(opts.key_file, "r") as f:
+ data = f.read()
+ mykey = ECC.import_key(data)
+
+ der = mykey.public_key().export_key(format='raw', compress=opts.compressed)
+ print(b2h(der))
+
+arg_parser = argparse.ArgumentParser(description="""Generate or export SUCI keys for 5G SA networks""")
+arg_parser.add_argument('--key-file', help='The key file to use', required=True)
+
+subparsers = arg_parser.add_subparsers(dest='command', help="The command to perform", required=True)
+
+parser_genkey = subparsers.add_parser('generate-key', help='Generate a new key pair')
+parser_genkey.add_argument('--curve', help='The ECC curve to use', choices=['secp256r1','curve25519'], required=True)
+
+parser_dump_pkey = subparsers.add_parser('dump-pub-key', help='Dump the public key')
+parser_dump_pkey.add_argument('--compressed', help='Use point compression', action='store_true')
+
+if __name__ == '__main__':
+
+ opts = arg_parser.parse_args()
+
+ if opts.command == 'generate-key':
+ gen_key(opts)
+ elif opts.command == 'dump-pub-key':
+ dump_pkey(opts)
diff --git a/docs/index.rst b/docs/index.rst
index 228fb79..1dfa624 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -44,6 +44,7 @@
library
osmo-smdpp
sim-rest
+ suci-keytool
Indices and tables
diff --git a/docs/suci-keytool.rst b/docs/suci-keytool.rst
new file mode 100644
index 0000000..88e3a24
--- /dev/null
+++ b/docs/suci-keytool.rst
@@ -0,0 +1,58 @@
+suci-keytool
+============
+
+Subscriber concealment is an important feature of the 5G SA architecture: It avoids the many privacy
+issues associated with having a permanent identifier (SUPI, traditionally the IMSI) transmitted in plain text
+over the air interface. Using SUCI solves this issue not just for the air interface; it even ensures the SUPI/IMSI
+is not known to the visited network (VPLMN) at all.
+
+In principle, the SUCI mechanism works by encrypting the SUPI by asymmetric (public key) cryptography:
+Only the HPLMN is in possession of the private key and hence can decrypt the SUCI to the SUPI, while
+each subscriber has the public key in order to encrypt their SUPI into the SUCI. In reality, the
+details are more complex, as there are ephemeral keys and cryptographic MAC involved.
+
+In any case, in order to operate a SUCI-enabled 5G SA network, you will have to
+
+#. generate a ECC key pair of public + private key
+#. deploy the public key on your USIMs
+#. deploy the private key on your 5GC, specifically the UDM function
+
+pysim contains (int its `contrib` directory) a small utility program that can make it easy to generate
+such keys: `suci-keytool.py`
+
+Generating keys
+~~~~~~~~~~~~~~~
+
+Example: Generating a *secp256r1* ECC public key pair and storing it to `/tmp/suci.key`:
+::
+
+ $ ./contrib/suci-keytool.py --key-file /tmp/suci.key generate-key --curve secp256r1
+
+Dumping public keys
+~~~~~~~~~~~~~~~~~~~
+
+In order to store the key to SIM cards as part of `ADF.USIM/DF.5GS/EF.SUCI_Calc_Info`, you will need
+a hexadecimal representation of the public key. You can achieve that using the `dump-pub-key` operation
+of suci-keytool:
+
+Example: Dumping the public key part from a previously generated key file:
+::
+
+ $ ./contrib/suci-keytool.py --key-file /tmp/suci.key dump-pub-key
+ 0473152f32523725f5175d255da2bd909de97b1d06449a9277bc629fe42112f8643e6b69aa6dce6c86714ccbe6f2e0f4f4898d102e2b3f0c18ce26626f052539bb
+
+If you want the point-compressed representation, you can use the `--compressed` option:
+::
+
+ $ ./contrib/suci-keytool.py --key-file /tmp/suci.key dump-pub-key --compressed
+ 0373152f32523725f5175d255da2bd909de97b1d06449a9277bc629fe42112f864
+
+
+
+suci-keytool syntax
+~~~~~~~~~~~~~~~~~~~
+
+.. argparse::
+ :module: contrib.suci-keytool
+ :func: arg_parser
+ :prog: contrib/suci-keytool.py
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/38959?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I9e92bbba7f700e160ea9c58da5f23fa4c31d40c6
Gerrit-Change-Number: 38959
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Attention is currently required from: dexter.
Hello Jenkins Builder,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-bsc/+/38957?usp=email
to look at the new patch set (#3).
The following approvals got outdated and were removed:
Verified-1 by Jenkins Builder
Change subject: pcu_sock: do not receive a TXT ind. with PCU_VERSION for a specific BTS
......................................................................
pcu_sock: do not receive a TXT ind. with PCU_VERSION for a specific BTS
We receive a TXT indication that contains the PCU_VERSION from the PCU when the
connection to the PCU is established. This message contains a BTS number, which
is always 0. This is a hard coded value that does not refer to a specific BTS
object. Also it is not logical to inform a specific BTS object about the PCU
version. This information should be directed to the connecting process as a
whole. However, we use this TXT indication to trigger certain initialization
processes on the BTS object we manage inside the BSC process. Unfortunately the
BSC is currently using the BTS Number in the TXT indication to resolve the BTS
object. This is not correct, instead the BSC should iterate of over all BTS
objects and trigger the initializations for each BTS object that has a BSC
co-located PCU.
This change does not have any dependencies, it just corrects the behavior of
the BSC on initialization.
Related: OS#6507
Change-Id: I3fbf5430db8b8ea29efb147bd162706990453fc5
---
M src/osmo-bsc/pcu_sock.c
1 file changed, 33 insertions(+), 10 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/57/38957/3
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/38957?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newpatchset
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I3fbf5430db8b8ea29efb147bd162706990453fc5
Gerrit-Change-Number: 38957
Gerrit-PatchSet: 3
Gerrit-Owner: dexter <pmaier(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Attention: dexter <pmaier(a)sysmocom.de>
dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/38958?usp=email )
Change subject: pcu_sock: do not receive a TXT ind. with PCU_VERSION for a specific BTS
......................................................................
pcu_sock: do not receive a TXT ind. with PCU_VERSION for a specific BTS
We receive a TXT indication that contains the PCU_VERSION from the PCU when the
connection to the PCU is established. This message contains a BTS number, which
is always 0. This is a hard coded value that does not refer to a specific BTS
object. Also it is not logical to inform a specific BTS object about the PCU
version. This information should be directed to the connecting process as a
whole. However, we use this TXT indication to trigger certain initialization
processes on the BTS object we manage inside the BTS process (currently this
is only 1 bts, but this may change in the future). So instead of using the
BTS in the TXT indication, we should iterate of over all BTS objects and
trigger the initializations for each of the BTS objects.
This change does not have any dependencies, nor does it change the current
behavior of osmo-bts. It just cleans up the logic, so that it works by
intension and not just by chance.
Related: OS#6507
Change-Id: I1bb8d0ec5e8d4b9f822f94249a75d8dc477144a3
---
M src/common/pcu_sock.c
1 file changed, 37 insertions(+), 15 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/58/38958/1
diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c
index 048e766..d35f3f4 100644
--- a/src/common/pcu_sock.c
+++ b/src/common/pcu_sock.c
@@ -858,25 +858,31 @@
static int pcu_rx_txt_ind(struct gsm_bts *bts,
struct gsm_pcu_if_txt_ind *txt)
{
- int rc;
+ int rc = 0;
switch (txt->type) {
case PCU_VERSION:
LOGP(DPCU, LOGL_INFO, "OsmoPCU version %s connected\n",
txt->text);
- oml_tx_failure_event_rep(&bts->gprs.cell.mo, NM_SEVER_CEASED, OSMO_EVT_PCU_VERS, txt->text);
- osmo_strlcpy(bts->pcu_version, txt->text, MAX_VERSION_LENGTH);
- /* patch SI to advertise GPRS, *if* the SI sent by BSC said so */
- regenerate_si3_restoctets(bts);
- regenerate_si4_restoctets(bts);
+ /* we use the reception of the PCU_VERSION as a trigger to make the PCU available for
+ * all BTSs handled by this process (currently this is exactly one BTS, see FIXME notes) */
+ llist_for_each_entry(bts, &g_bts_sm->bts_list, list) {
+ oml_tx_failure_event_rep(&bts->gprs.cell.mo, NM_SEVER_CEASED, OSMO_EVT_PCU_VERS, txt->text);
+ osmo_strlcpy(bts->pcu_version, txt->text, MAX_VERSION_LENGTH);
- rc = pcu_tx_si_all(bts);
+ /* patch SI to advertise GPRS, *if* the SI sent by BSC said so */
+ regenerate_si3_restoctets(bts);
+ regenerate_si4_restoctets(bts);
+
+ if (pcu_tx_si_all(bts) < 0)
+ rc = -EINVAL;
+ }
if (rc < 0)
- return -EINVAL;
-
+ return rc;
break;
case PCU_OML_ALERT:
+ OSMO_ASSERT(bts);
oml_tx_failure_event_rep(&bts->gprs.cell.mo, NM_SEVER_INDETERMINATE, OSMO_EVT_EXT_ALARM,
txt->text);
break;
@@ -937,35 +943,51 @@
return -EINVAL; \
} \
} while (0)
+
+#define ENSURE_BTS_OBJECT() \
+ do { \
+ if ((bts = gsm_bts_num(g_bts_sm, pcu_prim->bts_nr)) == NULL) { \
+ LOGP(DPCU, LOGL_ERROR, "Received PCU Prim for non-existent BTS %u\n", pcu_prim->bts_nr); \
+ return -EINVAL; \
+ } \
+ } while (0)
+
static int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim, size_t prim_len)
{
int rc = 0;
struct gsm_bts *bts;
size_t exp_len;
- if ((bts = gsm_bts_num(g_bts_sm, pcu_prim->bts_nr)) == NULL) {
- LOGP(DPCU, LOGL_ERROR, "Received PCU Prim for non-existent BTS %u\n", pcu_prim->bts_nr);
- return -EINVAL;
- }
-
switch (msg_type) {
case PCU_IF_MSG_DATA_REQ:
+ ENSURE_BTS_OBJECT();
CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.data_req);
rc = pcu_rx_data_req(bts, msg_type, &pcu_prim->u.data_req);
break;
case PCU_IF_MSG_PAG_REQ:
+ ENSURE_BTS_OBJECT();
CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.pag_req);
rc = pcu_rx_pag_req(bts, msg_type, &pcu_prim->u.pag_req);
break;
case PCU_IF_MSG_ACT_REQ:
+ ENSURE_BTS_OBJECT();
CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.act_req);
rc = pcu_rx_act_req(bts, &pcu_prim->u.act_req);
break;
case PCU_IF_MSG_TXT_IND:
CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.txt_ind);
- rc = pcu_rx_txt_ind(bts, &pcu_prim->u.txt_ind);
+ if (pcu_prim->u.txt_ind.type == PCU_VERSION) {
+ /* A TXT indication that carries the PCU_VERSION is always addressed to the
+ * receiving process as a whole, which means we will not resolve a specific
+ * BTS object in this case. */
+ rc = pcu_rx_txt_ind(NULL, &pcu_prim->u.txt_ind);
+ } else {
+ ENSURE_BTS_OBJECT();
+ rc = pcu_rx_txt_ind(bts, &pcu_prim->u.txt_ind);
+ }
break;
case PCU_IF_MSG_CONTAINER:
+ ENSURE_BTS_OBJECT();
CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.container);
/* ^ check if we can access container fields, v check with container data length */
exp_len = PCUIF_HDR_SIZE + sizeof(pcu_prim->u.container) + osmo_load16be(&pcu_prim->u.container.length);
--
To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/38958?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: I1bb8d0ec5e8d4b9f822f94249a75d8dc477144a3
Gerrit-Change-Number: 38958
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier(a)sysmocom.de>
Attention is currently required from: dexter.
Hello Jenkins Builder,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/osmo-bsc/+/38957?usp=email
to look at the new patch set (#2).
The following approvals got outdated and were removed:
Verified-1 by Jenkins Builder
Change subject: pcu_sock: do not receive a TXT ind. with PCU_VERSION for a specific BTS
......................................................................
pcu_sock: do not receive a TXT ind. with PCU_VERSION for a specific BTS
We receive a TXT indication that contains the PCU_VERSION from the PCU when the
connection to the PCU is established. This message contains a BTS number, which
is always 0. This is a hard coded value that does not refer to a specific BTS
object. Also it is not logical to inform a specific BTS object about the PCU
version. This information should be directed to the connecting process as a
whole. However, we use this TXT indication to trigger certain initialization
processes on the BTS object we manage inside the BSC process. Unfortunately the
BSC is currently using the BTS Number in the TXT indication to resolve the BTS
object. This is not correct, instead the BSC should iterate of over all BTS
objects and trigger the initializations for each BTS object that has a BSC
co-located PCU.
This change does not have any dependencies, it just corrects the behavior of
the BSC on initialization.
Related: OS#6507
Change-Id: I3fbf5430db8b8ea29efb147bd162706990453fc5
---
M src/osmo-bsc/pcu_sock.c
1 file changed, 32 insertions(+), 10 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/57/38957/2
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/38957?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newpatchset
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I3fbf5430db8b8ea29efb147bd162706990453fc5
Gerrit-Change-Number: 38957
Gerrit-PatchSet: 2
Gerrit-Owner: dexter <pmaier(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Attention: dexter <pmaier(a)sysmocom.de>
Jenkins Builder has posted comments on this change by dexter. ( https://gerrit.osmocom.org/c/osmo-bsc/+/38957?usp=email )
Change subject: pcu_sock: do not receive a TXT ind. with PCU_VERSION for a specific BTS
......................................................................
Patch Set 1:
(2 comments)
File src/osmo-bsc/pcu_sock.c:
Robot Comment from checkpatch (run ID jenkins-gerrit-lint-20251):
https://gerrit.osmocom.org/c/osmo-bsc/+/38957/comment/dc65aebc_1b4e6d5a?usp… :
PS1, Line 694: LOGP(DPCU, LOGL_ERROR, "Unknown TXT_IND type %u received\n",
code indent should use tabs where possible
Robot Comment from checkpatch (run ID jenkins-gerrit-lint-20251):
https://gerrit.osmocom.org/c/osmo-bsc/+/38957/comment/d18662e6_831fc8e1?usp… :
PS1, Line 712: #define ENSURE_BTS_OBJECT() \
Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/38957?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I3fbf5430db8b8ea29efb147bd162706990453fc5
Gerrit-Change-Number: 38957
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier(a)sysmocom.de>
Gerrit-CC: Jenkins Builder
Gerrit-Comment-Date: Tue, 26 Nov 2024 16:45:46 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/38957?usp=email )
Change subject: pcu_sock: do not receive a TXT ind. with PCU_VERSION for a specific BTS
......................................................................
pcu_sock: do not receive a TXT ind. with PCU_VERSION for a specific BTS
We receive a TXT indication that contains the PCU_VERSION from the PCU when the
connection to the PCU is established. This message contains a BTS number, which
is always 0. This is a hard coded value that does not refer to a specific BTS
object. Also it is not logical to inform a specific BTS object about the PCU
version. This information should be directed to the connecting process as a
whole. However, we use this TXT indication to trigger certain initialization
processes on the BTS object we manage inside the BSC process. Unfortunately the
BSC is currently using the BTS Number in the TXT indication to resolve the BTS
object. This is not correct, instead the BSC should iterate of over all BTS
objects and trigger the initializations for each BTS object that has a BSC
co-located PCU.
This change does not have any dependencies, it just corrects the behavior of
the BSC on initialization.
Related: OS#6507
Change-Id: I3fbf5430db8b8ea29efb147bd162706990453fc5
---
M src/osmo-bsc/pcu_sock.c
1 file changed, 31 insertions(+), 10 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/57/38957/1
diff --git a/src/osmo-bsc/pcu_sock.c b/src/osmo-bsc/pcu_sock.c
index 02a3d84..23e4479 100644
--- a/src/osmo-bsc/pcu_sock.c
+++ b/src/osmo-bsc/pcu_sock.c
@@ -665,24 +665,33 @@
return 0;
}
-static int pcu_rx_txt_ind(struct gsm_bts *bts,
+static int pcu_rx_txt_ind(struct gsm_network *net, struct gsm_bts *bts,
const struct gsm_pcu_if_txt_ind *txt)
{
- int rc;
+ int rc = 0;
switch (txt->type) {
case PCU_VERSION:
- LOG_BTS(bts, DPCU, LOGL_INFO, "OsmoPCU version %s connected\n",
+ LOGP(DPCU, LOGL_INFO, "OsmoPCU version %s connected\n",
txt->text);
- rc = pcu_tx_si_all(bts);
+
+ /* we use the reception of the PCU_VERSION as a trigger to make the PCU available for
+ * all BTSs handled by this process (currently this is exactly one BTS, see FIXME notes) */
+ llist_for_each_entry(bts, &net->bts_list, list) {
+ if (bsc_co_located_pcu(bts)) {
+ if (pcu_tx_si_all(bts) < 0)
+ rc = -EINVAL;
+ }
+ }
if (rc < 0)
return -EINVAL;
break;
case PCU_OML_ALERT:
+ OSMO_ASSERT(bts);
LOG_BTS(bts, DPCU, LOGL_ERROR, "PCU external alarm: %s\n", txt->text);
break;
default:
- LOG_BTS(bts, DPCU, LOGL_ERROR, "Unknown TXT_IND type %u received\n",
+ LOGP(DPCU, LOGL_ERROR, "Unknown TXT_IND type %u received\n",
txt->type);
return -EINVAL;
}
@@ -699,25 +708,37 @@
return -EINVAL; \
} \
} while (0)
+
+#define ENSURE_BTS_OBJECT() \
+ if ((bts = gsm_bts_num(net, pcu_prim->bts_nr)) == NULL) { \
+ LOGP(DPCU, LOGL_ERROR, "Received PCU Prim for non-existent BTS %u\n", pcu_prim->bts_nr); \
+ return -EINVAL; \
+ }
+
static int pcu_rx(struct gsm_network *net, uint8_t msg_type,
struct gsm_pcu_if *pcu_prim, size_t prim_len)
{
int rc = 0;
struct gsm_bts *bts;
- bts = gsm_bts_num(net, pcu_prim->bts_nr);
- if (!bts)
- return -EINVAL;
-
switch (msg_type) {
case PCU_IF_MSG_DATA_REQ:
case PCU_IF_MSG_PAG_REQ:
+ ENSURE_BTS_OBJECT();
CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.data_req);
rc = pcu_rx_data_req(bts, msg_type, &pcu_prim->u.data_req);
break;
case PCU_IF_MSG_TXT_IND:
CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.txt_ind);
- rc = pcu_rx_txt_ind(bts, &pcu_prim->u.txt_ind);
+ if (pcu_prim->u.txt_ind.type == PCU_VERSION) {
+ /* A TXT indication that carries the PCU_VERSION is always addressed to the
+ * receiving process as a whole, which means we will not resolve a specific
+ * BTS object in this case. */
+ rc = pcu_rx_txt_ind(net, NULL, &pcu_prim->u.txt_ind);
+ } else {
+ ENSURE_BTS_OBJECT();
+ rc = pcu_rx_txt_ind(NULL, bts, &pcu_prim->u.txt_ind);
+ }
break;
default:
LOGP(DPCU, LOGL_ERROR, "Received unknown PCU msg type %d\n",
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/38957?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I3fbf5430db8b8ea29efb147bd162706990453fc5
Gerrit-Change-Number: 38957
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier(a)sysmocom.de>
pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-netif/+/38955?usp=email )
Change subject: stream_cli: Add API osmo_stream_cli_set_tx_queue_max_length()
......................................................................
stream_cli: Add API osmo_stream_cli_set_tx_queue_max_length()
Change-Id: I3935fb933fe6136d68a9403eebbaf2616c2e5578
---
M TODO-RELEASE
M include/osmocom/netif/stream.h
M src/stream_cli.c
3 files changed, 37 insertions(+), 6 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/55/38955/1
diff --git a/TODO-RELEASE b/TODO-RELEASE
index 4f59788..74a0abb 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -8,3 +8,4 @@
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
libosmo-netif add API osmo_stream_cli_set_{ip_dscp,priority}(), osmo_stream_srv_link_set_{ip_dscp,priority}()
+libosmo-netif add API osmo-stream_cli_set_tx_queue_max_length()
diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h
index 6edf915..3b3e04e 100644
--- a/include/osmocom/netif/stream.h
+++ b/include/osmocom/netif/stream.h
@@ -208,6 +208,7 @@
void osmo_stream_cli_set_data(struct osmo_stream_cli *cli, void *data);
void osmo_stream_cli_set_reconnect_timeout(struct osmo_stream_cli *cli, int timeout);
void *osmo_stream_cli_get_data(struct osmo_stream_cli *cli);
+int osmo_stream_cli_set_tx_queue_max_length(struct osmo_stream_cli *cli, unsigned int size);
char *osmo_stream_cli_get_sockname(const struct osmo_stream_cli *cli);
struct osmo_fd *osmo_stream_cli_get_ofd(struct osmo_stream_cli *cli);
int osmo_stream_cli_get_fd(const struct osmo_stream_cli *cli);
diff --git a/src/stream_cli.c b/src/stream_cli.c
index 88d5f9e..a00f32a 100644
--- a/src/stream_cli.c
+++ b/src/stream_cli.c
@@ -96,7 +96,9 @@
struct osmo_fd ofd;
struct osmo_io_fd *iofd;
};
- struct llist_head tx_queue;
+ struct llist_head tx_queue; /* osmo_ofd mode (only): Queue of msgbs */
+ unsigned int tx_queue_count; /* osmo_ofd mode (only): Current amount of msgbs queued */
+ unsigned int tx_queue_max_length; /* Max amount of msgbs which can be enqueued */
struct osmo_timer_list timer;
enum osmo_stream_cli_state state;
char *addr[OSMO_STREAM_MAX_ADDRS];
@@ -321,12 +323,11 @@
struct msgb *msg;
int ret;
- if (llist_empty(&cli->tx_queue)) {
+ msg = msgb_dequeue_count(&cli->tx_queue, &cli->tx_queue_count);
+ if (!msg) { /* done, tx_queue empty */
osmo_fd_write_disable(&cli->ofd);
return 0;
}
- msg = llist_first_entry(&cli->tx_queue, struct msgb, list);
- llist_del(&msg->list);
if (!osmo_stream_cli_is_connected(cli)) {
LOGSCLI(cli, LOGL_ERROR, "send: not connected, dropping data!\n");
@@ -367,6 +368,7 @@
/* Update msgb and re-add it at the start of the queue: */
msgb_pull(msg, ret);
llist_add(&msg->list, &cli->tx_queue);
+ cli->tx_queue_count++;
return 0;
}
@@ -376,6 +378,7 @@
if (err == EAGAIN) {
/* Re-add at the start of the queue to re-attempt: */
llist_add(&msg->list, &cli->tx_queue);
+ cli->tx_queue_count++;
return 0;
}
msgb_free(msg);
@@ -510,6 +513,7 @@
cli->reconnect_timeout = 5; /* default is 5 seconds. */
cli->segmentation_cb = NULL;
INIT_LLIST_HEAD(&cli->tx_queue);
+ cli->tx_queue_max_length = 1024; /* Default tx queue size, msgbs. */
cli->ma_pars.sctp.version = 0;
@@ -863,6 +867,24 @@
return cli->data;
}
+/*! Set the maximum length queue of the stream client.
+ * \param[in] cli Stream Client to modify
+ * \param[in] size maximum amount of msgbs which can be queued in the internal tx queue.
+ * \returns 0 on success, negative on error.
+ *
+ * The maximum length queue default value is 1024 msgbs. */
+int osmo_stream_cli_set_tx_queue_max_length(struct osmo_stream_cli *cli, unsigned int size)
+{
+ cli->tx_queue_max_length = size;
+
+ if (cli->iofd) /* Otherwise, this will be done in osmo_stream_cli_open() */
+ osmo_iofd_set_txqueue_max_length(cli->iofd, cli->tx_queue_max_length);
+
+ /* XXX: Here, in OSMO_STREAM_MODE_OSMO_FD mode we could check current
+ * size of cli->tx_queue and shrink it from the front or back... */
+ return 0;
+}
+
/*! Retrieve the stream client socket description.
* Calling this function will build a string that describes the socket in terms of its local/remote
* address/port. The returned name is stored in a static buffer; it is hence not re-entrant or thread-safe.
@@ -944,6 +966,7 @@
OSMO_ASSERT(!stream_cli_close(cli));
osmo_timer_del(&cli->timer);
msgb_queue_free(&cli->tx_queue);
+ cli->tx_queue_count = 0;
/* if we are in a user callback, delay freeing. */
if (cli->in_cb_mask != 0) {
LOGSCLI(cli, LOGL_DEBUG, "delay free() in_cb_mask=0x%02x\n", cli->in_cb_mask);
@@ -1204,8 +1227,8 @@
if (!cli->iofd)
goto error_close_socket;
+ osmo_iofd_set_txqueue_max_length(cli->iofd, cli->tx_queue_max_length);
osmo_iofd_notify_connected(cli->iofd);
-
configure_cli_segmentation_cb(cli, cli->segmentation_cb);
if (osmo_iofd_register(cli->iofd, fd) < 0)
@@ -1253,7 +1276,12 @@
switch (cli->mode) {
case OSMO_STREAM_MODE_OSMO_FD:
- msgb_enqueue(&cli->tx_queue, msg);
+ if (cli->tx_queue_count >= cli->tx_queue_max_length) {
+ LOGSCLI(cli, LOGL_ERROR, "send: tx queue full, dropping msg!\n");
+ msgb_free(msg);
+ return;
+ }
+ msgb_enqueue_count(&cli->tx_queue, msg, &cli->tx_queue_count);
osmo_fd_write_enable(&cli->ofd);
break;
case OSMO_STREAM_MODE_OSMO_IO:
@@ -1350,6 +1378,7 @@
switch (cli->mode) {
case OSMO_STREAM_MODE_OSMO_FD:
msgb_queue_free(&cli->tx_queue);
+ cli->tx_queue_count = 0;
/* If in state 'connecting', keep WRITE flag up to receive
* socket connection signal and then transition to STATE_CONNECTED: */
if (cli->state == STREAM_CLI_STATE_CONNECTED)
--
To view, visit https://gerrit.osmocom.org/c/libosmo-netif/+/38955?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-Change-Id: I3935fb933fe6136d68a9403eebbaf2616c2e5578
Gerrit-Change-Number: 38955
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>