]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Fix clearing of SetSelectedRegistrar with multiple interfaces
authorJouni Malinen <jouni@qca.qualcomm.com>
Mon, 13 Feb 2012 21:02:57 +0000 (23:02 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 13 Feb 2012 21:02:57 +0000 (23:02 +0200)
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>

src/wps/wps_upnp.c
src/wps/wps_upnp_ap.c
src/wps/wps_upnp_i.h

index 06dcd201b472ecaea819db3b165dc382297c68b8..766cac49bd0f4bb3d9dc45aecb6f5a4c76dd161c 100644 (file)
@@ -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);
 }
 
index 2251f76bc5563dc23d165bf2cad6db8390757194..54ed98f0833f9db582166eb25a5e99fc0b68767d 100644 (file)
 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);
 }
index 3ecf05d54684714bdf2426e8b8223b5d7a6f3eab..7f3c56109e199c690cee3516d27fc239e4812baf 100644 (file)
@@ -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 */