From acb69cec6fc5fe1468169b92af22e7726704dc2c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 16 Dec 2013 21:08:28 +0100 Subject: [PATCH] wpa_supplicant: Use monotonic time for RX/BSS times The BSS table, scan timeout, and related functionality should use monotonic time since they care about relative values (age) only. Unfortunately, these are all connected, so the patch can't be split further. Another problem with this is that it changes the driver wrapper API. Though, it seems only the test driver is using this. Signed-hostap: Johannes Berg --- src/drivers/driver.h | 2 +- src/drivers/driver_test.c | 4 ++-- src/p2p/p2p.c | 40 +++++++++++++++---------------- src/p2p/p2p.h | 2 +- src/p2p/p2p_i.h | 6 ++--- wpa_supplicant/bss.c | 29 +++++++++++----------- wpa_supplicant/bss.h | 4 ++-- wpa_supplicant/ctrl_iface.c | 4 ++-- wpa_supplicant/p2p_supplicant.c | 15 ++++++------ wpa_supplicant/scan.c | 4 ++-- wpa_supplicant/wpa_supplicant_i.h | 4 ++-- 11 files changed, 58 insertions(+), 56 deletions(-) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 78dcc2503..8831051eb 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -233,7 +233,7 @@ struct wpa_scan_res { struct wpa_scan_results { struct wpa_scan_res **res; size_t num; - struct os_time fetch_time; + struct os_reltime fetch_time; }; /** diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c index 5742b988b..9c16ca9d7 100644 --- a/src/drivers/driver_test.c +++ b/src/drivers/driver_test.c @@ -1318,8 +1318,8 @@ static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx) if (drv->pending_p2p_scan && drv->p2p) { #ifdef CONFIG_P2P size_t i; - struct os_time now; - os_get_time(&now); + struct os_reltime now; + os_get_reltime(&now); for (i = 0; i < drv->num_scanres; i++) { struct wpa_scan_res *bss = drv->scanres[i]; if (p2p_scan_res_handler(drv->p2p, bss->bssid, diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index e52822de5..23b74c0eb 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -48,10 +48,10 @@ static void p2p_scan_timeout(void *eloop_ctx, void *timeout_ctx); static void p2p_expire_peers(struct p2p_data *p2p) { struct p2p_device *dev, *n; - struct os_time now; + struct os_reltime now; size_t i; - os_get_time(&now); + os_get_reltime(&now); dl_list_for_each_safe(dev, n, &p2p->devices, struct p2p_device, list) { if (dev->last_seen.sec + P2P_PEER_EXPIRATION_AGE >= now.sec) continue; @@ -63,7 +63,7 @@ static void p2p_expire_peers(struct p2p_data *p2p) * We are connected as a client to a group in which the * peer is the GO, so do not expire the peer entry. */ - os_get_time(&dev->last_seen); + os_get_reltime(&dev->last_seen); continue; } @@ -77,7 +77,7 @@ static void p2p_expire_peers(struct p2p_data *p2p) * The peer is connected as a client in a group where * we are the GO, so do not expire the peer entry. */ - os_get_time(&dev->last_seen); + os_get_reltime(&dev->last_seen); continue; } @@ -377,7 +377,7 @@ static struct p2p_device * p2p_create_device(struct p2p_data *p2p, dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { count++; if (oldest == NULL || - os_time_before(&dev->last_seen, &oldest->last_seen)) + os_reltime_before(&dev->last_seen, &oldest->last_seen)) oldest = dev; } if (count + 1 > p2p->cfg->max_peers && oldest) { @@ -480,7 +480,7 @@ static int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr, os_memcpy(dev->interface_addr, cli->p2p_interface_addr, ETH_ALEN); - os_get_time(&dev->last_seen); + os_get_reltime(&dev->last_seen); os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN); os_memcpy(dev->member_in_go_iface, go_interface_addr, ETH_ALEN); @@ -596,14 +596,14 @@ static void p2p_copy_wps_info(struct p2p_data *p2p, struct p2p_device *dev, * Info attributes. */ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, - struct os_time *rx_time, int level, const u8 *ies, + struct os_reltime *rx_time, int level, const u8 *ies, size_t ies_len, int scan_res) { struct p2p_device *dev; struct p2p_message msg; const u8 *p2p_dev_addr; int i; - struct os_time time_now; + struct os_reltime time_now; os_memset(&msg, 0, sizeof(msg)); if (p2p_parse_ies(ies, ies_len, &msg)) { @@ -637,7 +637,7 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, } if (rx_time == NULL) { - os_get_time(&time_now); + os_get_reltime(&time_now); rx_time = &time_now; } @@ -646,7 +646,7 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, * entry is newer than the one previously stored. */ if (dev->last_seen.sec > 0 && - os_time_before(rx_time, &dev->last_seen)) { + os_reltime_before(rx_time, &dev->last_seen)) { p2p_dbg(p2p, "Do not update peer entry based on old frame (rx_time=%u.%06u last_seen=%u.%06u)", (unsigned int) rx_time->sec, (unsigned int) rx_time->usec, @@ -656,7 +656,7 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, return -1; } - os_memcpy(&dev->last_seen, rx_time, sizeof(struct os_time)); + os_memcpy(&dev->last_seen, rx_time, sizeof(struct os_reltime)); dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY); @@ -982,7 +982,7 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout, int res; p2p_dbg(p2p, "Starting find (type=%d)", type); - os_get_time(&p2p->find_start); + os_get_reltime(&p2p->find_start); if (p2p->p2p_scan_running) { p2p_dbg(p2p, "p2p_scan is already running"); } @@ -1471,7 +1471,7 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, void p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, struct p2p_device *dev, struct p2p_message *msg) { - os_get_time(&dev->last_seen); + os_get_reltime(&dev->last_seen); p2p_copy_wps_info(p2p, dev, 0, msg); @@ -1810,7 +1810,7 @@ static void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr, if (dev) { if (dev->country[0] == 0 && msg.listen_channel) os_memcpy(dev->country, msg.listen_channel, 3); - os_get_time(&dev->last_seen); + os_get_reltime(&dev->last_seen); p2p_parse_free(&msg); return; /* already known */ } @@ -1821,7 +1821,7 @@ static void p2p_add_dev_from_probe_req(struct p2p_data *p2p, const u8 *addr, return; } - os_get_time(&dev->last_seen); + os_get_reltime(&dev->last_seen); dev->flags |= P2P_DEV_PROBE_REQ_ONLY; if (msg.listen_channel) { @@ -1855,7 +1855,7 @@ struct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, dev = p2p_get_device(p2p, addr); if (dev) { - os_get_time(&dev->last_seen); + os_get_reltime(&dev->last_seen); return dev; /* already known */ } @@ -2770,10 +2770,10 @@ static void p2p_prov_disc_cb(struct p2p_data *p2p, int success) int p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, - struct os_time *rx_time, int level, const u8 *ies, + struct os_reltime *rx_time, int level, const u8 *ies, size_t ies_len) { - if (os_time_before(rx_time, &p2p->find_start)) { + if (os_reltime_before(rx_time, &p2p->find_start)) { /* * The driver may have cached (e.g., in cfg80211 BSS table) the * scan results for relatively long time. To avoid reporting @@ -3455,7 +3455,7 @@ int p2p_get_peer_info_txt(const struct p2p_peer_info *info, struct p2p_device *dev; int res; char *pos, *end; - struct os_time now; + struct os_reltime now; if (info == NULL) return -1; @@ -3466,7 +3466,7 @@ int p2p_get_peer_info_txt(const struct p2p_peer_info *info, pos = buf; end = buf + buflen; - os_get_time(&now); + os_get_reltime(&now); res = os_snprintf(pos, end - pos, "age=%d\n" "listen_freq=%d\n" diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 22d0c5807..bff78ef99 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1245,7 +1245,7 @@ void p2p_rx_action(struct p2p_data *p2p, const u8 *da, const u8 *sa, * start of a pending operation, e.g., to start a pending GO negotiation. */ int p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, - struct os_time *rx_time, int level, const u8 *ies, + struct os_reltime *rx_time, int level, const u8 *ies, size_t ies_len); /** diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index efc163a08..4b328ca69 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -23,7 +23,7 @@ enum p2p_go_state { */ struct p2p_device { struct dl_list list; - struct os_time last_seen; + struct os_reltime last_seen; int listen_freq; enum p2p_wps_method wps_method; @@ -395,7 +395,7 @@ struct p2p_data { u8 *find_dev_id; u8 find_dev_id_buf[ETH_ALEN]; - struct os_time find_start; /* time of last p2p_find start */ + struct os_reltime find_start; /* time of last p2p_find start */ struct p2p_group **groups; size_t num_groups; @@ -718,7 +718,7 @@ struct p2p_device * p2p_add_dev_from_go_neg_req(struct p2p_data *p2p, void p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr, struct p2p_device *dev, struct p2p_message *msg); int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, - struct os_time *rx_time, int level, const u8 *ies, + struct os_reltime *rx_time, int level, const u8 *ies, size_t ies_len, int scan_res); struct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr); struct p2p_device * p2p_get_device_interface(struct p2p_data *p2p, diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index df1a0c886..e26cdc035 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -224,9 +224,9 @@ struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid, } -static void calculate_update_time(const struct os_time *fetch_time, +static void calculate_update_time(const struct os_reltime *fetch_time, unsigned int age_ms, - struct os_time *update_time) + struct os_reltime *update_time) { os_time_t usec; @@ -243,7 +243,7 @@ static void calculate_update_time(const struct os_time *fetch_time, static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src, - struct os_time *fetch_time) + struct os_reltime *fetch_time) { dst->flags = src->flags; os_memcpy(dst->bssid, src->bssid, ETH_ALEN); @@ -326,7 +326,7 @@ static int wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s) static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s, const u8 *ssid, size_t ssid_len, struct wpa_scan_res *res, - struct os_time *fetch_time) + struct os_reltime *fetch_time) { struct wpa_bss *bss; @@ -492,7 +492,7 @@ static void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes, static struct wpa_bss * wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, - struct wpa_scan_res *res, struct os_time *fetch_time) + struct wpa_scan_res *res, struct os_reltime *fetch_time) { u32 changes; @@ -587,17 +587,18 @@ void wpa_bss_update_start(struct wpa_supplicant *wpa_s) */ void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s, struct wpa_scan_res *res, - struct os_time *fetch_time) + struct os_reltime *fetch_time) { const u8 *ssid, *p2p; struct wpa_bss *bss; if (wpa_s->conf->ignore_old_scan_res) { - struct os_time update; + struct os_reltime update; calculate_update_time(fetch_time, res->age, &update); - if (os_time_before(&update, &wpa_s->scan_trigger_time)) { - struct os_time age; - os_time_sub(&wpa_s->scan_trigger_time, &update, &age); + if (os_reltime_before(&update, &wpa_s->scan_trigger_time)) { + struct os_reltime age; + os_reltime_sub(&wpa_s->scan_trigger_time, &update, + &age); wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Ignore driver BSS " "table entry that is %u.%06u seconds older " "than our scan trigger", @@ -781,19 +782,19 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info, void wpa_bss_flush_by_age(struct wpa_supplicant *wpa_s, int age) { struct wpa_bss *bss, *n; - struct os_time t; + struct os_reltime t; if (dl_list_empty(&wpa_s->bss)) return; - os_get_time(&t); + os_get_reltime(&t); t.sec -= age; dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) { if (wpa_bss_in_use(wpa_s, bss)) continue; - if (os_time_before(&bss->last_update, &t)) { + if (os_reltime_before(&bss->last_update, &t)) { wpa_bss_remove(wpa_s, bss, __func__); } else break; @@ -900,7 +901,7 @@ struct wpa_bss * wpa_bss_get_bssid_latest(struct wpa_supplicant *wpa_s, if (os_memcmp(bss->bssid, bssid, ETH_ALEN) != 0) continue; if (found == NULL || - os_time_before(&found->last_update, &bss->last_update)) + os_reltime_before(&found->last_update, &bss->last_update)) found = bss; } return found; diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h index 0d2693fde..4deeb5f56 100644 --- a/wpa_supplicant/bss.h +++ b/wpa_supplicant/bss.h @@ -84,7 +84,7 @@ struct wpa_bss { /** Timestamp of last Beacon/Probe Response frame */ u64 tsf; /** Time of the last update (i.e., Beacon or Probe Response RX) */ - struct os_time last_update; + struct os_reltime last_update; /** ANQP data */ struct wpa_bss_anqp *anqp; /** Length of the following IE field in octets (from Probe Response) */ @@ -98,7 +98,7 @@ struct wpa_bss { void wpa_bss_update_start(struct wpa_supplicant *wpa_s); void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s, struct wpa_scan_res *res, - struct os_time *fetch_time); + struct os_reltime *fetch_time); void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info, int new_scan); int wpa_bss_init(struct wpa_supplicant *wpa_s); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index a0604775a..b77a9447d 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -3248,9 +3248,9 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, } if (mask & WPA_BSS_MASK_AGE) { - struct os_time now; + struct os_reltime now; - os_get_time(&now); + os_get_reltime(&now); ret = os_snprintf(pos, end - pos, "age=%d\n", (int) (now.sec - bss->last_update.sec)); if (ret < 0 || ret >= end - pos) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index f02f05019..6e56f1b16 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -204,13 +204,13 @@ static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s, for (i = 0; i < scan_res->num; i++) { struct wpa_scan_res *bss = scan_res->res[i]; - struct os_time time_tmp_age, entry_ts; + struct os_reltime time_tmp_age, entry_ts; const u8 *ies; size_t ies_len; time_tmp_age.sec = bss->age / 1000; time_tmp_age.usec = (bss->age % 1000) * 1000; - os_time_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts); + os_reltime_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts); ies = (const u8 *) (bss + 1); ies_len = bss->ie_len; @@ -317,7 +317,7 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq, } } } else { - os_get_time(&wpa_s->scan_trigger_time); + os_get_reltime(&wpa_s->scan_trigger_time); wpa_s->scan_res_handler = wpas_p2p_scan_res_handler; } @@ -3783,7 +3783,8 @@ static int wpas_p2p_peer_go(struct wpa_supplicant *wpa_s, return 0; } - updated = os_time_before(&wpa_s->p2p_auto_started, &bss->last_update); + updated = os_reltime_before(&wpa_s->p2p_auto_started, + &bss->last_update); wpa_printf(MSG_DEBUG, "P2P: Current BSS entry for peer updated at " "%ld.%06ld (%supdated in last scan)", bss->last_update.sec, bss->last_update.usec, @@ -4028,7 +4029,7 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq) */ ret = wpa_drv_scan(wpa_s, ¶ms); if (!ret) { - os_get_time(&wpa_s->scan_trigger_time); + os_get_reltime(&wpa_s->scan_trigger_time); wpa_s->scan_res_handler = wpas_p2p_scan_res_join; } @@ -4315,7 +4316,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, dev_addr); } if (auto_join) { - os_get_time(&wpa_s->p2p_auto_started); + os_get_reltime(&wpa_s->p2p_auto_started); wpa_printf(MSG_DEBUG, "P2P: Auto join started at " "%ld.%06ld", wpa_s->p2p_auto_started.sec, @@ -5057,7 +5058,7 @@ int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr, wpa_s->auto_pd_scan_retry = 0; wpas_p2p_stop_find(wpa_s); wpa_s->p2p_join_scan_count = 0; - os_get_time(&wpa_s->p2p_auto_started); + os_get_reltime(&wpa_s->p2p_auto_started); wpa_printf(MSG_DEBUG, "P2P: Auto PD started at %ld.%06ld", wpa_s->p2p_auto_started.sec, wpa_s->p2p_auto_started.usec); diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index f38dfbb20..5b0c181bb 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -228,7 +228,7 @@ int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, wpa_supplicant_notify_scanning(wpa_s, 0); wpas_notify_scan_done(wpa_s, 0); } else { - os_get_time(&wpa_s->scan_trigger_time); + os_get_reltime(&wpa_s->scan_trigger_time); wpa_s->scan_runs++; wpa_s->normal_scans++; } @@ -1663,7 +1663,7 @@ wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, * Make sure we have a valid timestamp if the driver wrapper * does not set this. */ - os_get_time(&scan_res->fetch_time); + os_get_reltime(&scan_res->fetch_time); } filter_scan_res(wpa_s, scan_res); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index d96d5e4cc..3acb86519 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -479,7 +479,7 @@ struct wpa_supplicant { */ MANUAL_SCAN_REQ } scan_req, last_scan_req; - struct os_time scan_trigger_time; + struct os_reltime scan_trigger_time; int scan_runs; /* number of scan runs since WPS was started */ int *next_scan_freqs; int scan_interval; /* time in sec between scans to find suitable AP */ @@ -662,7 +662,7 @@ struct wpa_supplicant { int p2p_persistent_id; int p2p_go_intent; int p2p_connect_freq; - struct os_time p2p_auto_started; + struct os_reltime p2p_auto_started; struct wpa_ssid *p2p_last_4way_hs_fail; #endif /* CONFIG_P2P */