From 0a58f658fe814a5f8d328c8b40fb24f0300a6878 Mon Sep 17 00:00:00 2001 From: sam Date: Fri, 2 Apr 2004 23:35:24 +0000 Subject: Change handling of probe response frames. Previously we always dropped the refcnt on the node but left it in the node table. This allows the node table to hold the results of scanned ap's but for ibss scans left nodes w/o any driver-private state setup and/or a bad refcnt (when the nodes were timed out they were prematurely discarded). Now we treat nodes identified for ap scanning as before but force nodes discovered when scanning for ibss neighbors to have complete/proper state and hold the refcnt on the node. Any other nodes created because of these frames are discarded directly (need to optimize this case to eliminate various work that's immediately discarded). --- sys/net80211/ieee80211_input.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index b638c0e..153a650 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -714,6 +714,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, ni->ni_esslen = ssid[1]; memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); memcpy(ni->ni_essid, ssid + 2, ssid[1]); + allocbs = 1; } else if (ssid[1] != 0 && isprobe) { /* * Update ESSID at probe response to adopt hidden AP by @@ -722,7 +723,9 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, ni->ni_esslen = ssid[1]; memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); memcpy(ni->ni_essid, ssid + 2, ssid[1]); - } + allocbs = 0; + } else + allocbs = 0; IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); ni->ni_rssi = rssi; ni->ni_rstamp = rstamp; @@ -736,7 +739,29 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, ni->ni_erp = erp; /* NB: must be after ni_chan is setup */ ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT); - ieee80211_unref_node(&ni); + /* + * When scanning we record results (nodes) with a zero + * refcnt. Otherwise we want to hold the reference for + * ibss neighbors so the nodes don't get released prematurely. + * Anything else can be discarded (XXX and should be handled + * above so we don't do so much work). + */ + if (ic->ic_state == IEEE80211_S_SCAN) + ieee80211_unref_node(&ni); /* NB: do not free */ + else if (ic->ic_opmode == IEEE80211_M_IBSS && + allocbs && isprobe) { + /* + * Fake an association so the driver can setup it's + * private state. The rate set has been setup above; + * there is no handshake as in ap/station operation. + */ + if (ic->ic_newassoc) + (*ic->ic_newassoc)(ic, ni, 1); + /* NB: hold reference */ + } else { + /* XXX optimize to avoid work done above */ + ieee80211_free_node(ic, ni); + } break; } -- cgit v1.1