aboutsummaryrefslogtreecommitdiffstats
path: root/src/gsup_server.c
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-03-15 00:07:43 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-03-16 05:51:11 +0100
commitcab2fcd5b5a7276fc9a89e449e9d3ede11790711 (patch)
tree3ac8a5510a7db3bfcc13501ac2ad9d44b467fd1f /src/gsup_server.c
parentee392bb3b1fdfd45e8b4401622e0ee6cc66f9695 (diff)
UMTS AKA: implement SQN increment according to SEQ and IND
Add ind_bitlen column to auc_3g to record each USIM's IND size according to 3GPP TS 33.102 -- default is 5 bits, as suggested by the spec. Introduce auc_3g_ind to each connecting GSUP client to use as IND index for generating auth tuples sent to this client. With osmo_gsup_server_add_conn(), implement a scheme where clients receive fixed auc_3g_ind indexes based on the order in which they connect; each new connection takes the lowest unused auc_3g_ind, so in case one of the clients restarts, it will most likely receive the same auc_3g_ind, and if one client disconnects, no other clients' auc_3g_ind are affected. Add gsup_server_test.c to test the auc_3g_ind index distribution scheme. Depends: libosmocore I4eac5be0c0b2cede04464c4c3a0873102d952453 for llist_first Related: OS#1969 Change-Id: If4501ed4ff8e923fa6fe8b80c44c5ad647a8ed60
Diffstat (limited to 'src/gsup_server.c')
-rw-r--r--src/gsup_server.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/src/gsup_server.c b/src/gsup_server.c
index b0e1858..b382c86 100644
--- a/src/gsup_server.c
+++ b/src/gsup_server.c
@@ -211,6 +211,43 @@ static int osmo_gsup_server_closed_cb(struct ipa_server_conn *conn)
return 0;
}
+/* Add conn to the clients list in a way that conn->auc_3g_ind takes the lowest
+ * unused integer and the list of clients remains sorted by auc_3g_ind.
+ * Keep this function non-static to allow linking in a unit test. */
+void osmo_gsup_server_add_conn(struct llist_head *clients,
+ struct osmo_gsup_conn *conn)
+{
+ struct osmo_gsup_conn *c;
+ struct osmo_gsup_conn *prev_conn;
+
+ c = llist_first_entry_or_null(clients, struct osmo_gsup_conn, list);
+
+ /* Is the first index, 0, unused? */
+ if (!c || c->auc_3g_ind > 0) {
+ conn->auc_3g_ind = 0;
+ llist_add(&conn->list, clients);
+ return;
+ }
+
+ /* Look for a gap later on */
+ prev_conn = NULL;
+ llist_for_each_entry(c, clients, list) {
+ /* skip first item, we know it has auc_3g_ind == 0. */
+ if (!prev_conn) {
+ prev_conn = c;
+ continue;
+ }
+ if (c->auc_3g_ind > prev_conn->auc_3g_ind + 1)
+ break;
+ prev_conn = c;
+ }
+
+ OSMO_ASSERT(prev_conn);
+
+ conn->auc_3g_ind = prev_conn->auc_3g_ind + 1;
+ llist_add(&conn->list, &prev_conn->list);
+}
+
/* a client has connected to the server socket and we have accept()ed it */
static int osmo_gsup_server_accept_cb(struct ipa_server_link *link, int fd)
{
@@ -225,15 +262,15 @@ static int osmo_gsup_server_accept_cb(struct ipa_server_link *link, int fd)
conn->conn = ipa_server_conn_create(gsups, link, fd,
osmo_gsup_server_read_cb,
osmo_gsup_server_closed_cb, conn);
- conn->conn->ccm_cb = osmo_gsup_server_ccm_cb;
OSMO_ASSERT(conn->conn);
+ conn->conn->ccm_cb = osmo_gsup_server_ccm_cb;
/* link data structure with server structure */
conn->server = gsups;
- llist_add_tail(&conn->list, &gsups->clients);
+ osmo_gsup_server_add_conn(&gsups->clients, conn);
- LOGP(DLGSUP, LOGL_INFO, "New GSUP client %s:%d\n",
- conn->conn->addr, conn->conn->port);
+ LOGP(DLGSUP, LOGL_INFO, "New GSUP client %s:%d (IND=%u)\n",
+ conn->conn->addr, conn->conn->port, conn->auc_3g_ind);
/* request the identity of the client */
rc = ipa_ccm_send_id_req(fd);