aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2012-02-13 21:02:57 (GMT)
committerJouni Malinen <j@w1.fi>2012-02-13 21:02:57 (GMT)
commitff22d1e10e9d0ae870e4bb9986f863c17d2990cc (patch)
treeb2ed8fb48b65c63963803c55cc71403b5324f5cc
parent2624ed43117302cd97778f2f7e4c9fc8e7adf2e2 (diff)
downloadhostap-ff22d1e10e9d0ae870e4bb9986f863c17d2990cc.zip
hostap-ff22d1e10e9d0ae870e4bb9986f863c17d2990cc.tar.gz
hostap-ff22d1e10e9d0ae870e4bb9986f863c17d2990cc.tar.bz2
WPS: Fix clearing of SetSelectedRegistrar with multiple interfaces
The SetSelectedRegistrar timeout was registered for each registrar instance, but the only context pointer (struct subscription *) was shared with each registrar which resulted in the timeout getting cancelled for some of the registrar instances before the selected registrar (ER) information was cleared. In addition, when an ER unsubscribed from receiving events, the selected registrar information got cleared only from a single registrar. Fix these issues by registering a pointer to the registrar instance in the timeout and by iterating over all UPnP interfaces when removing a subscription. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
-rw-r--r--src/wps/wps_upnp.c5
-rw-r--r--src/wps/wps_upnp_ap.c16
-rw-r--r--src/wps/wps_upnp_i.h3
3 files changed, 15 insertions, 9 deletions
diff --git a/src/wps/wps_upnp.c b/src/wps/wps_upnp.c
index 06dcd20..766cac4 100644
--- a/src/wps/wps_upnp.c
+++ b/src/wps/wps_upnp.c
@@ -550,10 +550,13 @@ static void upnp_wps_device_send_event(struct upnp_wps_device_sm *sm)
*/
void subscription_destroy(struct subscription *s)
{
+ struct upnp_wps_device_interface *iface;
wpa_printf(MSG_DEBUG, "WPS UPnP: Destroy subscription %p", s);
subscr_addr_free_all(s);
event_delete_all(s);
- upnp_er_remove_notification(s);
+ dl_list_for_each(iface, &s->sm->interfaces,
+ struct upnp_wps_device_interface, list)
+ upnp_er_remove_notification(iface->wps->registrar, s);
os_free(s);
}
diff --git a/src/wps/wps_upnp_ap.c b/src/wps/wps_upnp_ap.c
index 2251f76..54ed98f 100644
--- a/src/wps/wps_upnp_ap.c
+++ b/src/wps/wps_upnp_ap.c
@@ -19,9 +19,10 @@
static void upnp_er_set_selected_timeout(void *eloop_ctx, void *timeout_ctx)
{
struct subscription *s = eloop_ctx;
+ struct wps_registrar *reg = timeout_ctx;
wpa_printf(MSG_DEBUG, "WPS: SetSelectedRegistrar from ER timed out");
s->selected_registrar = 0;
- wps_registrar_selected_registrar_changed(s->reg);
+ wps_registrar_selected_registrar_changed(reg);
}
@@ -40,7 +41,7 @@ int upnp_er_set_selected_registrar(struct wps_registrar *reg,
return -1;
s->reg = reg;
- eloop_cancel_timeout(upnp_er_set_selected_timeout, s, NULL);
+ eloop_cancel_timeout(upnp_er_set_selected_timeout, s, reg);
os_memset(s->authorized_macs, 0, sizeof(s->authorized_macs));
if (attr.selected_registrar == NULL || *attr.selected_registrar == 0) {
@@ -67,7 +68,7 @@ int upnp_er_set_selected_registrar(struct wps_registrar *reg,
#endif /* CONFIG_WPS2 */
}
eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
- upnp_er_set_selected_timeout, s, NULL);
+ upnp_er_set_selected_timeout, s, reg);
}
wps_registrar_selected_registrar_changed(reg);
@@ -76,10 +77,11 @@ int upnp_er_set_selected_registrar(struct wps_registrar *reg,
}
-void upnp_er_remove_notification(struct subscription *s)
+void upnp_er_remove_notification(struct wps_registrar *reg,
+ struct subscription *s)
{
s->selected_registrar = 0;
- eloop_cancel_timeout(upnp_er_set_selected_timeout, s, NULL);
- if (s->reg)
- wps_registrar_selected_registrar_changed(s->reg);
+ eloop_cancel_timeout(upnp_er_set_selected_timeout, s, reg);
+ if (reg)
+ wps_registrar_selected_registrar_changed(reg);
}
diff --git a/src/wps/wps_upnp_i.h b/src/wps/wps_upnp_i.h
index 3ecf05d..7f3c561 100644
--- a/src/wps/wps_upnp_i.h
+++ b/src/wps/wps_upnp_i.h
@@ -188,6 +188,7 @@ void event_send_stop_all(struct upnp_wps_device_sm *sm);
int upnp_er_set_selected_registrar(struct wps_registrar *reg,
struct subscription *s,
const struct wpabuf *msg);
-void upnp_er_remove_notification(struct subscription *s);
+void upnp_er_remove_notification(struct wps_registrar *reg,
+ struct subscription *s);
#endif /* WPS_UPNP_I_H */