struct eap_sim_pseudonym *pseudonyms;
struct eap_sim_reauth *reauths;
struct eap_sim_db_pending *pending;
+ unsigned int eap_sim_db_timeout;
#ifdef CONFIG_SQLITE
sqlite3 *sqlite_db;
char db_tmp_identity[100];
};
+static void eap_sim_db_del_timeout(void *eloop_ctx, void *user_ctx);
+static void eap_sim_db_query_timeout(void *eloop_ctx, void *user_ctx);
+
+
#ifdef CONFIG_SQLITE
static int db_table_exists(sqlite3 *db, const char *name)
}
+static void eap_sim_db_free_pending(struct eap_sim_db_data *data,
+ struct eap_sim_db_pending *entry)
+{
+ eloop_cancel_timeout(eap_sim_db_query_timeout, data, entry);
+ eloop_cancel_timeout(eap_sim_db_del_timeout, data, entry);
+ os_free(entry);
+}
+
+
+static void eap_sim_db_del_pending(struct eap_sim_db_data *data,
+ struct eap_sim_db_pending *entry)
+{
+ struct eap_sim_db_pending **pp = &data->pending;
+
+ while (*pp != NULL) {
+ if (*pp == entry) {
+ *pp = entry->next;
+ eap_sim_db_free_pending(data, entry);
+ return;
+ }
+ pp = &(*pp)->next;
+ }
+}
+
+
+static void eap_sim_db_del_timeout(void *eloop_ctx, void *user_ctx)
+{
+ struct eap_sim_db_data *data = eloop_ctx;
+ struct eap_sim_db_pending *entry = user_ctx;
+
+ wpa_printf(MSG_DEBUG, "EAP-SIM DB: Delete query timeout for %p", entry);
+ eap_sim_db_del_pending(data, entry);
+}
+
+
+static void eap_sim_db_query_timeout(void *eloop_ctx, void *user_ctx)
+{
+ struct eap_sim_db_data *data = eloop_ctx;
+ struct eap_sim_db_pending *entry = user_ctx;
+
+ /*
+ * Report failure and allow some time for EAP server to process it
+ * before deleting the query.
+ */
+ wpa_printf(MSG_DEBUG, "EAP-SIM DB: Query timeout for %p", entry);
+ entry->state = FAILURE;
+ data->get_complete_cb(data->ctx, entry->cb_session_ctx);
+ eloop_register_timeout(1, 0, eap_sim_db_del_timeout, data, entry);
+}
+
+
static void eap_sim_db_sim_resp_auth(struct eap_sim_db_data *data,
const char *imsi, char *buf)
{
parse_fail:
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
- os_free(entry);
+ eap_sim_db_free_pending(data, entry);
}
parse_fail:
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
- os_free(entry);
+ eap_sim_db_free_pending(data, entry);
}
/**
* eap_sim_db_init - Initialize EAP-SIM DB / authentication gateway interface
* @config: Configuration data (e.g., file name)
+ * @db_timeout: Database lookup timeout
* @get_complete_cb: Callback function for reporting availability of triplets
* @ctx: Context pointer for get_complete_cb
* Returns: Pointer to a private data structure or %NULL on failure
*/
struct eap_sim_db_data *
-eap_sim_db_init(const char *config,
+eap_sim_db_init(const char *config, unsigned int db_timeout,
void (*get_complete_cb)(void *ctx, void *session_ctx),
void *ctx)
{
data->sock = -1;
data->get_complete_cb = get_complete_cb;
data->ctx = ctx;
+ data->eap_sim_db_timeout = db_timeout;
data->fname = os_strdup(config);
if (data->fname == NULL)
goto fail;
while (pending) {
prev_pending = pending;
pending = pending->next;
- os_free(prev_pending);
+ eap_sim_db_free_pending(data, prev_pending);
}
os_free(data);
}
-static void eap_sim_db_expire_pending(struct eap_sim_db_data *data)
+static void eap_sim_db_expire_pending(struct eap_sim_db_data *data,
+ struct eap_sim_db_pending *entry)
{
- /* TODO: add limit for maximum length for pending list; remove latest
- * (i.e., last) entry from the list if the limit is reached; could also
- * use timeout to expire pending entries */
+ eloop_register_timeout(data->eap_sim_db_timeout, 0,
+ eap_sim_db_query_timeout, data, entry);
}
if (entry->state == FAILURE) {
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
"failure");
- os_free(entry);
+ eap_sim_db_free_pending(data, entry);
return EAP_SIM_DB_FAILURE;
}
os_memcpy(sres, entry->u.sim.sres,
num_chal * EAP_SIM_SRES_LEN);
os_memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN);
- os_free(entry);
+ eap_sim_db_free_pending(data, entry);
return num_chal;
}
entry->cb_session_ctx = cb_session_ctx;
entry->state = PENDING;
eap_sim_db_add_pending(data, entry);
- eap_sim_db_expire_pending(data);
+ eap_sim_db_expire_pending(data, entry);
+ wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added query %p", entry);
return EAP_SIM_DB_PENDING;
}
entry = eap_sim_db_get_pending(data, imsi, 1);
if (entry) {
if (entry->state == FAILURE) {
- os_free(entry);
+ eap_sim_db_free_pending(data, entry);
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failure");
return EAP_SIM_DB_FAILURE;
}
os_memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN);
os_memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN);
*res_len = entry->u.aka.res_len;
- os_free(entry);
+ eap_sim_db_free_pending(data, entry);
return 0;
}
entry->cb_session_ctx = cb_session_ctx;
entry->state = PENDING;
eap_sim_db_add_pending(data, entry);
- eap_sim_db_expire_pending(data);
+ eap_sim_db_expire_pending(data, entry);
+ wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added query %p", entry);
return EAP_SIM_DB_PENDING;
}