diff options
Diffstat (limited to 'src/gsup_server.c')
-rw-r--r-- | src/gsup_server.c | 84 |
1 files changed, 22 insertions, 62 deletions
diff --git a/src/gsup_server.c b/src/gsup_server.c index 756473a..20ea162 100644 --- a/src/gsup_server.c +++ b/src/gsup_server.c @@ -32,6 +32,7 @@ #include <osmocom/hlr/gsup_server.h> #include <osmocom/hlr/gsup_router.h> +#include <osmocom/hlr/hlr.h> #define LOG_GSUP_CONN(conn, level, fmt, args...) \ LOGP(DLGSUP, level, "GSUP peer %s: " fmt, \ @@ -179,11 +180,9 @@ static int osmo_gsup_server_read_cb(struct ipa_server_conn *conn, if (hh->proto == IPAC_PROTO_IPACCESS) { rc = ipa_server_conn_ccm(conn, msg); - if (rc < 0) { - /* conn is already invalid here! */ - return -1; - } msgb_free(msg); + if (rc < 0) /* conn is already invalid here! */ + return -1; return 0; } @@ -317,43 +316,6 @@ 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); -} - static void update_fd_settings(int fd) { int ret; @@ -386,10 +348,9 @@ static int osmo_gsup_server_accept_cb(struct ipa_server_link *link, int fd) /* link data structure with server structure */ conn->server = gsups; - osmo_gsup_server_add_conn(&gsups->clients, conn); + llist_add_tail(&conn->list, &gsups->clients); - LOGP(DLGSUP, LOGL_INFO, "New GSUP client %s:%d (IND=%u)\n", - conn->conn->addr, conn->conn->port, conn->auc_3g_ind); + LOGP(DLGSUP, LOGL_INFO, "New GSUP client %s:%d\n", conn->conn->addr, conn->conn->port); update_fd_settings(fd); @@ -484,19 +445,16 @@ int osmo_gsup_configure_wildcard_apn(struct osmo_gsup_message *gsup, * \param[out] gsup The gsup message to populate. * \param[in] imsi The subscriber's IMSI. * \param[in] msisdn The subscriber's MSISDN. - * \param[out] msisdn_enc A buffer large enough to store the MSISDN in encoded form. - * \param[in] msisdn_enc_size Size of the buffer (must be >= OSMO_GSUP_MAX_CALLED_PARTY_BCD_LEN). - * \param[out] apn_buf A buffer large enough to store an APN (required if cn_domain is OSMO_GSUP_CN_DOMAIN_PS). - * \param[in] apn_buf_size Size of APN buffer (must be >= APN_MAXLEN). * \param[in] cn_domain The CN Domain of the subscriber connection. + * \param[in] talloc_ctx To allocation memory for dynamic fields (msisdn, apn) in the gsup field * \returns 0 on success, and negative on error. */ int osmo_gsup_create_insert_subscriber_data_msg(struct osmo_gsup_message *gsup, const char *imsi, const char *msisdn, - uint8_t *msisdn_enc, size_t msisdn_enc_size, - uint8_t *apn_buf, size_t apn_buf_size, - enum osmo_gsup_cn_domain cn_domain) + enum osmo_gsup_cn_domain cn_domain, + void *talloc_ctx) { int len; + uint8_t *msisdn_buf = talloc_size(talloc_ctx, OSMO_GSUP_MAX_CALLED_PARTY_BCD_LEN); OSMO_ASSERT(gsup); *gsup = (struct osmo_gsup_message){ @@ -505,27 +463,29 @@ int osmo_gsup_create_insert_subscriber_data_msg(struct osmo_gsup_message *gsup, osmo_strlcpy(gsup->imsi, imsi, sizeof(gsup->imsi)); - if (msisdn_enc_size < OSMO_GSUP_MAX_CALLED_PARTY_BCD_LEN) - return -ENOSPC; - - OSMO_ASSERT(msisdn_enc); - len = gsm48_encode_bcd_number(msisdn_enc, msisdn_enc_size, 0, msisdn); + len = gsm48_encode_bcd_number(msisdn_buf, OSMO_GSUP_MAX_CALLED_PARTY_BCD_LEN, 0, msisdn); if (len < 1) { LOGP(DLGSUP, LOGL_ERROR, "%s: Error: cannot encode MSISDN '%s'\n", imsi, msisdn); return -ENOSPC; } - gsup->msisdn_enc = msisdn_enc; + gsup->msisdn_enc = msisdn_buf; gsup->msisdn_enc_len = len; #pragma message "FIXME: deal with encoding the following data: gsup.hlr_enc" gsup->cn_domain = cn_domain; if (gsup->cn_domain == OSMO_GSUP_CN_DOMAIN_PS) { - OSMO_ASSERT(apn_buf_size >= APN_MAXLEN); - OSMO_ASSERT(apn_buf); - /* FIXME: PDP infos - use more fine-grained access control - instead of wildcard APN */ - osmo_gsup_configure_wildcard_apn(gsup, apn_buf, apn_buf_size); + if (g_hlr->ps.pdp_profile.enabled) { + OSMO_ASSERT(g_hlr->ps.pdp_profile.num_pdp_infos <= ARRAY_SIZE(g_hlr->ps.pdp_profile.pdp_infos)); + OSMO_ASSERT(g_hlr->ps.pdp_profile.num_pdp_infos <= ARRAY_SIZE(gsup->pdp_infos)); + memcpy(gsup->pdp_infos, + g_hlr->ps.pdp_profile.pdp_infos, + sizeof(struct osmo_gsup_pdp_info) * g_hlr->ps.pdp_profile.num_pdp_infos); + gsup->num_pdp_infos = g_hlr->ps.pdp_profile.num_pdp_infos; + } else { + uint8_t *apn_buf = talloc_size(talloc_ctx, APN_MAXLEN); + osmo_gsup_configure_wildcard_apn(gsup, apn_buf, APN_MAXLEN); + } } return 0; |