Signed-off-by: Richard Frankel <rofrankel@xxxxxxxxxx> Signed-off-by: Richard Frankel <richard@xxxxxxxxxx> On Wed, Aug 10, 2016 at 6:52 PM, Denton Gentry <dgentry@xxxxxxxxxx> wrote: > taxonomy: store probes in hostapd_sta_info. > > A weakness in the initial client taxonomy mechanism is > from storing both the Probe and Associate in the sta_info_t. > The sta_info_t is created after a client associates, which > means that any Probes sent prior to association are not > retained. The Associate Request has to be seen, and then > another Probe request after association, before we have > a signature for the client. > > Most clients send lots of Probes (lots and lots and lots > of Probes, actually), but a few do not. ChromeOS is notably > sparing in sending Probes, it can take a long time before > a signature for a ChromeOS device is available. > > Store the most recent Probe Request in the hostapd_sta_info > tracking list. When a sta_info_t is created, move the probe > from the hostapd_sta_info to the sta_info_t. > > Signed-off-by: dgentry@xxxxxxxxxx (Denton Gentry) > Signed-off-by: denny@xxxxxxxxxxxx (Denton Gentry) > --- > src/ap/beacon.c | 40 ++++++++++++++++++++++++++++++++++++---- > src/ap/beacon.h | 3 +++ > src/ap/hostapd.c | 2 +- > src/ap/hostapd.h | 2 ++ > src/ap/ieee802_11.c | 2 +- > src/ap/sta_info.c | 3 +++ > src/ap/taxonomy.c | 19 +++++++++++++++++-- > src/ap/taxonomy.h | 6 ++++-- > 8 files changed, 67 insertions(+), 10 deletions(-) > > diff --git a/src/ap/beacon.c b/src/ap/beacon.c > index 7cfc7f2..6eaa71e 100644 > --- a/src/ap/beacon.c > +++ b/src/ap/beacon.c > @@ -578,6 +578,17 @@ static enum ssid_match_result ssid_match(struct hostapd_data *hapd, > } > > > +void sta_track_del(struct hostapd_sta_info *info) > +{ > + if (info->probe_ie_taxonomy) { > + os_free((void *)info->probe_ie_taxonomy); > + info->probe_ie_taxonomy = NULL; > + } > + > + os_free(info); > +} > + > + > void sta_track_expire(struct hostapd_iface *iface, int force) > { > struct os_reltime now; > @@ -600,7 +611,7 @@ void sta_track_expire(struct hostapd_iface *iface, int force) > MAC2STR(info->addr)); > dl_list_del(&info->list); > iface->num_sta_seen--; > - os_free(info); > + sta_track_del(info); > } > } > > @@ -673,6 +684,21 @@ sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr, > return NULL; > } > > +void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr, > + const u8 **probe_ie_taxonomy, size_t *probe_ie_taxonomy_len) > +{ > + struct hostapd_sta_info *info = sta_track_get(iface, addr); > + if (!info) { > + *probe_ie_taxonomy = NULL; > + *probe_ie_taxonomy_len = 0; > + return; > + } > + > + *probe_ie_taxonomy = info->probe_ie_taxonomy; > + info->probe_ie_taxonomy = NULL; > + *probe_ie_taxonomy_len = info->probe_ie_taxonomy_len; > + info->probe_ie_taxonomy_len = 0; > +} > > void handle_probe_req(struct hostapd_data *hapd, > const struct ieee80211_mgmt *mgmt, size_t len, > @@ -784,9 +810,15 @@ void handle_probe_req(struct hostapd_data *hapd, > #endif /* CONFIG_P2P */ > > { > - struct sta_info *sta = ap_get_sta(hapd, mgmt->sa); > - if (sta) { > - hostapd_taxonomy_probe_req(hapd, sta, ie, ie_len); > + struct sta_info *sta; > + struct hostapd_sta_info *info; > + > + if ((sta = ap_get_sta(hapd, mgmt->sa)) != NULL) { > + taxonomy_sta_info_probe_req(hapd, sta, ie, ie_len); > + } else if ((info = sta_track_get(hapd->iface, > + mgmt->sa)) != NULL) { > + taxonomy_hostapd_sta_info_probe_req(hapd, info, > + ie, ie_len); > } > } > > diff --git a/src/ap/beacon.h b/src/ap/beacon.h > index d98f42e..266da39 100644 > --- a/src/ap/beacon.h > +++ b/src/ap/beacon.h > @@ -22,9 +22,12 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, > struct wpa_driver_ap_params *params); > void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params); > void sta_track_add(struct hostapd_iface *iface, const u8 *addr); > +void sta_track_del(struct hostapd_sta_info *info); > void sta_track_expire(struct hostapd_iface *iface, int force); > struct hostapd_data * > sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr, > const char *ifname); > +void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr, > + const u8 **probe_ie_taxonomy, size_t *probe_ie_taxonomy_len); > > #endif /* BEACON_H */ > diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c > index 65f513d..e5ed0b1 100644 > --- a/src/ap/hostapd.c > +++ b/src/ap/hostapd.c > @@ -374,7 +374,7 @@ static void sta_track_deinit(struct hostapd_iface *iface) > list))) { > dl_list_del(&info->list); > iface->num_sta_seen--; > - os_free(info); > + sta_track_del(info); > } > } > > diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h > index 195679e..963d9cb 100644 > --- a/src/ap/hostapd.h > +++ b/src/ap/hostapd.h > @@ -311,6 +311,8 @@ struct hostapd_sta_info { > struct dl_list list; > u8 addr[ETH_ALEN]; > struct os_reltime last_seen; > + const u8 *probe_ie_taxonomy; > + size_t probe_ie_taxonomy_len; > }; > > /** > diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c > index 52413cc..7d4f314 100644 > --- a/src/ap/ieee802_11.c > +++ b/src/ap/ieee802_11.c > @@ -2251,7 +2251,7 @@ static void handle_assoc(struct hostapd_data *hapd, > * remove the STA immediately. */ > sta->timeout_next = STA_NULLFUNC; > > - hostapd_taxonomy_assoc_req(hapd, sta, pos, left); > + taxonomy_sta_info_assoc_req(hapd, sta, pos, left); > > fail: > /* > diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c > index ed321f7..899cafd 100644 > --- a/src/ap/sta_info.c > +++ b/src/ap/sta_info.c > @@ -671,6 +671,9 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr) > sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ; > dl_list_init(&sta->ip6addr); > > + sta_track_claim_taxonomy_info(hapd->iface, addr, > + &sta->probe_ie_taxonomy, &sta->probe_ie_taxonomy_len); > + > return sta; > } > > diff --git a/src/ap/taxonomy.c b/src/ap/taxonomy.c > index 71f1645..3915b51 100644 > --- a/src/ap/taxonomy.c > +++ b/src/ap/taxonomy.c > @@ -271,7 +271,7 @@ int retrieve_sta_taxonomy(const struct hostapd_data *hapd, > return 0; > } > > -void hostapd_taxonomy_probe_req(const struct hostapd_data *hapd, > +void taxonomy_sta_info_probe_req(const struct hostapd_data *hapd, > struct sta_info *sta, const u8 *ie, size_t ie_len) > { > if (sta->probe_ie_taxonomy) { > @@ -286,7 +286,22 @@ void hostapd_taxonomy_probe_req(const struct hostapd_data *hapd, > } > } > > -void hostapd_taxonomy_assoc_req(const struct hostapd_data *hapd, > +void taxonomy_hostapd_sta_info_probe_req(const struct hostapd_data *hapd, > + struct hostapd_sta_info *info, const u8 *ie, size_t ie_len) > +{ > + if (info->probe_ie_taxonomy) { > + os_free(info->probe_ie_taxonomy); > + info->probe_ie_taxonomy = NULL; > + info->probe_ie_taxonomy_len = 0; > + } > + if (hapd->iconf->client_taxonomy) { > + info->probe_ie_taxonomy = os_malloc(ie_len); > + os_memcpy(info->probe_ie_taxonomy, ie, ie_len); > + info->probe_ie_taxonomy_len = ie_len; > + } > +} > + > +void taxonomy_sta_info_assoc_req(const struct hostapd_data *hapd, > struct sta_info *sta, const u8 *ie, size_t ie_len) > { > if (sta->assoc_ie_taxonomy) { > diff --git a/src/ap/taxonomy.h b/src/ap/taxonomy.h > index 6d2ec39..3b88a4d 100644 > --- a/src/ap/taxonomy.h > +++ b/src/ap/taxonomy.h > @@ -9,9 +9,11 @@ > #ifndef TAXONOMY_H > #define TAXONOMY_H > > -void hostapd_taxonomy_probe_req(const struct hostapd_data *hapd, > +void taxonomy_sta_info_probe_req(const struct hostapd_data *hapd, > struct sta_info *sta, const u8 *ie, size_t ie_len); > -void hostapd_taxonomy_assoc_req(const struct hostapd_data *hapd, > +void taxonomy_hostapd_sta_info_probe_req(const struct hostapd_data *hapd, > + struct hostapd_sta_info *sta, const u8 *ie, size_t ie_len); > +void taxonomy_sta_info_assoc_req(const struct hostapd_data *hapd, > struct sta_info *sta, const u8 *ie, size_t ie_len); > int retrieve_sta_taxonomy(const struct hostapd_data *hapd, > struct sta_info *sta, char *buf, size_t buflen); > -- > 2.8.0.rc3.226.g39d4020 > _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap