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 <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2013-12-16 21:08:28 +01:00 committed by Jouni Malinen
parent 46b8d4c004
commit acb69cec6f
11 changed files with 58 additions and 56 deletions

View file

@ -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;
};
/**

View file

@ -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,

View file

@ -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"

View file

@ -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);
/**

View file

@ -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,

View file

@ -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;

View file

@ -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);

View file

@ -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)

View file

@ -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, &params);
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);

View file

@ -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);

View file

@ -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 */