]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FST: Make FST peer connection check more permissive in hostapd
authorAnton Nayshtut <qca_antonn@qca.qualcomm.com>
Tue, 10 Nov 2015 13:51:07 +0000 (15:51 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 25 Nov 2015 15:30:59 +0000 (17:30 +0200)
Modify the FST peer connection check so it won't skip peers without MB
IEs making it more permissive for peers that didn't provide MB IEs
during association request. This can be helpful, e.g., in cases where a
STA's interface connected before it was added to the FST group. This
allows the AP to receive FST Action frames and initiate session with a
STA via STA's interface that doesn't expose MB IEs.

The adjusted FST protocol is still safe, as it protects itself in many
other ways (checking band info and it's accordance to the interfaces,
Setup IDs, connection states of the interfaces involved, etc.)
effectively avoiding all types of invalid situations.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/fst/fst.c
src/fst/fst_ctrl_iface.c
src/fst/fst_group.c
src/fst/fst_iface.c
src/fst/fst_iface.h
src/fst/fst_session.c

index 2880870213e61c7368dd440274ed35f07128f58a..40430e29045f4fd575a17f4746e848f2fb0018ea 100644 (file)
@@ -160,7 +160,7 @@ void fst_global_del_ctrl(struct fst_ctrl_handle *h)
 void fst_rx_action(struct fst_iface *iface, const struct ieee80211_mgmt *mgmt,
                   size_t len)
 {
-       if (fst_iface_is_connected(iface, mgmt->sa))
+       if (fst_iface_is_connected(iface, mgmt->sa, FALSE))
                fst_session_on_action_rx(iface, mgmt, len);
        else
                wpa_printf(MSG_DEBUG,
index d0907188a389e175248be1ac44139f451d08d863..98ece9fbf4eec2eeb86bd5a0252367e0f0e437b1 100644 (file)
@@ -749,7 +749,7 @@ int fst_ctrl_iface_mb_info(const u8 *addr, char *buf, size_t buflen)
 
        foreach_fst_group(g) {
                foreach_fst_group_iface(g, f) {
-                       if (fst_iface_is_connected(f, addr)) {
+                       if (fst_iface_is_connected(f, addr, TRUE)) {
                                ret += print_band(num++, f, addr,
                                                  buf + ret, buflen - ret);
                        }
index f2cd3296fe1d7536a1b353056d7aaee66408de90..e0c055f0c56da69ae86579c886388fa345f00f78 100644 (file)
@@ -219,7 +219,8 @@ fst_group_get_new_iface_by_mbie_and_band_id(struct fst_group *g,
                                        fst_mbie_get_peer_addr(mbie);
 
                                if (peer_addr &&
-                                   fst_iface_is_connected(iface, peer_addr) &&
+                                   fst_iface_is_connected(iface, peer_addr,
+                                                          TRUE) &&
                                    band_id == fst_iface_get_band_id(iface)) {
                                        os_memcpy(iface_peer_addr, peer_addr,
                                                  ETH_ALEN);
index 5a92d2c33e420f41e562e33a8741995cb10f01c6..35e83cb7b4710ed5d266d7dd47dda26204b93617 100644 (file)
@@ -49,12 +49,13 @@ void fst_iface_delete(struct fst_iface *i)
 }
 
 
-Boolean fst_iface_is_connected(struct fst_iface *iface, const u8 *addr)
+Boolean fst_iface_is_connected(struct fst_iface *iface, const u8 *addr,
+                              Boolean mb_only)
 {
        struct fst_get_peer_ctx *ctx;
-       const u8 *a = fst_iface_get_peer_first(iface, &ctx, TRUE);
+       const u8 *a = fst_iface_get_peer_first(iface, &ctx, mb_only);
 
-       for (; a != NULL; a = fst_iface_get_peer_next(iface, &ctx, TRUE))
+       for (; a != NULL; a = fst_iface_get_peer_next(iface, &ctx, mb_only))
                if (os_memcmp(addr, a, ETH_ALEN) == 0)
                        return TRUE;
 
index 4670d894f7cbd3efb61a2a9a5a5e40ae7ef8dddb..0eb27325a2b882ab1043fa9a99bd973bbd9a6979 100644 (file)
@@ -123,7 +123,8 @@ static inline const u8 * fst_iface_get_peer_next(struct fst_iface *i,
        return i->iface_obj.get_peer_next(i->iface_obj.ctx, ctx, mb_only);
 }
 
-Boolean fst_iface_is_connected(struct fst_iface *iface, const u8 *addr);
+Boolean fst_iface_is_connected(struct fst_iface *iface, const u8 *addr,
+                              Boolean mb_only);
 void fst_iface_attach_mbie(struct fst_iface *i, struct wpabuf *mbie);
 enum mb_band_id fst_iface_get_band_id(struct fst_iface *i);
 
index 55fa69495e99ad4e07644661d81adfcdcde29f18..f804b122fc463cf4e6932abc1daa1bdf2c5414d8 100644 (file)
@@ -863,13 +863,15 @@ int fst_session_initiate_setup(struct fst_session *s)
                return -EINVAL;
        }
 
-       if (!fst_iface_is_connected(s->data.old_iface, s->data.old_peer_addr)) {
+       if (!fst_iface_is_connected(s->data.old_iface, s->data.old_peer_addr,
+                                   FALSE)) {
                fst_printf_session(s, MSG_ERROR,
                                   "The preset old peer address is not connected");
                return -EINVAL;
        }
 
-       if (!fst_iface_is_connected(s->data.new_iface, s->data.new_peer_addr)) {
+       if (!fst_iface_is_connected(s->data.new_iface, s->data.new_peer_addr,
+                                   FALSE)) {
                fst_printf_session(s, MSG_ERROR,
                                   "The preset new peer address is not connected");
                return -EINVAL;
@@ -966,7 +968,8 @@ int fst_session_respond(struct fst_session *s, u8 status_code)
                return -EINVAL;
        }
 
-       if (!fst_iface_is_connected(s->data.old_iface, s->data.old_peer_addr)) {
+       if (!fst_iface_is_connected(s->data.old_iface,
+                                   s->data.old_peer_addr, FALSE)) {
                fst_printf_session(s, MSG_ERROR,
                                   "The preset peer address is not in the peer list");
                return -EINVAL;