diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2017-03-15 00:07:43 +0100 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2017-03-16 05:51:11 +0100 |
commit | cab2fcd5b5a7276fc9a89e449e9d3ede11790711 (patch) | |
tree | 3ac8a5510a7db3bfcc13501ac2ad9d44b467fd1f /src/gsup_server.c | |
parent | ee392bb3b1fdfd45e8b4401622e0ee6cc66f9695 (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.c | 45 |
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); |