]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Convert struct subscription to use struct dl_list
authorJouni Malinen <j@w1.fi>
Sat, 19 Dec 2009 12:15:43 +0000 (14:15 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 19 Dec 2009 12:15:43 +0000 (14:15 +0200)
src/wps/wps_registrar.c
src/wps/wps_upnp.c
src/wps/wps_upnp_event.c
src/wps/wps_upnp_i.h
src/wps/wps_upnp_web.c

index e17a8025b01b73860df5a6a97feddd336bf12800..fc97091691cff1c4adb19b22e55f71ab55741035 100644 (file)
@@ -2762,8 +2762,8 @@ static void wps_registrar_sel_reg_union(struct wps_registrar *reg)
        if (reg->wps->wps_upnp == NULL)
                return;
 
-       s = reg->wps->wps_upnp->subscriptions;
-       while (s) {
+       dl_list_for_each(s, &reg->wps->wps_upnp->subscriptions,
+                        struct subscription, list) {
                struct subscr_addr *sa;
                sa = dl_list_first(&s->addr_list, struct subscr_addr, list);
                if (sa) {
@@ -2776,10 +2776,6 @@ static void wps_registrar_sel_reg_union(struct wps_registrar *reg)
                else
                        wpa_printf(MSG_DEBUG, "WPS: External Registrar not "
                                   "selected");
-
-               s = s->next;
-               if (s == reg->wps->wps_upnp->subscriptions)
-                       break;
        }
 #endif /* CONFIG_WPS_UPNP */
 }
index 148317cc8af5209cbc53828e03f67836735a3ffc..a4125f8918507d1ef7796c8aae49b1416e704932 100644 (file)
@@ -467,14 +467,14 @@ static void upnp_wps_device_send_event(struct upnp_wps_device_sm *sm)
        /* Enqueue event message for all subscribers */
        struct wpabuf *buf; /* holds event message */
        int buf_size = 0;
-       struct subscription *s;
+       struct subscription *s, *tmp;
        /* Actually, utf-8 is the default, but it doesn't hurt to specify it */
        const char *format_head =
                "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
                "<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">\n";
        const char *format_tail = "</e:propertyset>\n";
 
-       if (sm->subscriptions == NULL) {
+       if (dl_list_empty(&sm->subscriptions)) {
                /* optimize */
                return;
        }
@@ -496,19 +496,15 @@ static void upnp_wps_device_send_event(struct upnp_wps_device_sm *sm)
        wpa_printf(MSG_MSGDUMP, "WPS UPnP: WLANEvent message:\n%s",
                   (char *) wpabuf_head(buf));
 
-       s = sm->subscriptions;
-       do {
+       dl_list_for_each_safe(s, tmp, &sm->subscriptions, struct subscription,
+                             list) {
                if (event_add(s, buf)) {
-                       struct subscription *s_old = s;
                        wpa_printf(MSG_INFO, "WPS UPnP: Dropping "
                                   "subscriber due to event backlog");
-                       s = s_old->next;
-                       subscription_unlink(s_old);
-                       subscription_destroy(s_old);
-               } else {
-                       s = s->next;
+                       dl_list_del(&s->list);
+                       subscription_destroy(s);
                }
-       } while (s != sm->subscriptions);
+       }
 
        wpabuf_free(buf);
 }
@@ -520,43 +516,6 @@ static void upnp_wps_device_send_event(struct upnp_wps_device_sm *sm)
  * This is the result of an incoming HTTP over TCP SUBSCRIBE request.
  */
 
-/* subscription_unlink -- remove from the active list */
-void subscription_unlink(struct subscription *s)
-{
-       struct upnp_wps_device_sm *sm = s->sm;
-
-       if (s->next == s) {
-               /* only one? */
-               sm->subscriptions = NULL;
-       } else  {
-               if (sm->subscriptions == s)
-                       sm->subscriptions = s->next;
-               s->next->prev = s->prev;
-               s->prev->next = s->next;
-       }
-       sm->n_subscriptions--;
-}
-
-
-/* subscription_link_to_end -- link to end of active list
- * (should have high expiry time!)
- */
-static void subscription_link_to_end(struct subscription *s)
-{
-       struct upnp_wps_device_sm *sm = s->sm;
-
-       if (sm->subscriptions) {
-               s->next = sm->subscriptions;
-               s->prev = s->next->prev;
-               s->prev->next = s;
-               s->next->prev = s;
-       } else {
-               sm->subscriptions = s->next = s->prev = s;
-       }
-       sm->n_subscriptions++;
-}
-
-
 /* subscription_destroy -- destroy an unlinked subscription
  * Be sure to unlink first if necessary.
  */
@@ -573,10 +532,13 @@ void subscription_destroy(struct subscription *s)
 /* subscription_list_age -- remove expired subscriptions */
 static void subscription_list_age(struct upnp_wps_device_sm *sm, time_t now)
 {
-       struct subscription *s;
-       while ((s = sm->subscriptions) != NULL && s->timeout_time < now) {
+       struct subscription *s, *tmp;
+       dl_list_for_each_safe(s, tmp, &sm->subscriptions,
+                             struct subscription, list) {
+               if (s->timeout_time > now)
+                       break;
                wpa_printf(MSG_DEBUG, "WPS UPnP: Removing aged subscription");
-               subscription_unlink(s);
+               dl_list_del(&s->list);
                subscription_destroy(s);
        }
 }
@@ -588,17 +550,11 @@ static void subscription_list_age(struct upnp_wps_device_sm *sm, time_t now)
 struct subscription * subscription_find(struct upnp_wps_device_sm *sm,
                                        const u8 uuid[UUID_LEN])
 {
-       struct subscription *s0 = sm->subscriptions;
-       struct subscription *s = s0;
-
-       if (s0 == NULL)
-               return NULL;
-       do {
+       struct subscription *s;
+       dl_list_for_each(s, &sm->subscriptions, struct subscription, list) {
                if (os_memcmp(s->uuid, uuid, UUID_LEN) == 0)
                        return s; /* Found match */
-               s = s->next;
-       } while (s != s0);
-
+       }
        return NULL;
 }
 
@@ -715,11 +671,12 @@ struct subscription * subscription_start(struct upnp_wps_device_sm *sm,
        subscription_list_age(sm, now);
 
        /* If too many subscriptions, remove oldest */
-       if (sm->n_subscriptions >= MAX_SUBSCRIPTIONS) {
-               s = sm->subscriptions;
+       if (dl_list_len(&sm->subscriptions) >= MAX_SUBSCRIPTIONS) {
+               s = dl_list_first(&sm->subscriptions, struct subscription,
+                                 list);
                wpa_printf(MSG_INFO, "WPS UPnP: Too many subscriptions, "
                           "trashing oldest");
-               subscription_unlink(s);
+               dl_list_del(&s->list);
                subscription_destroy(s);
        }
 
@@ -733,14 +690,14 @@ struct subscription * subscription_start(struct upnp_wps_device_sm *sm,
        uuid_make(s->uuid);
        subscr_addr_list_create(s, callback_urls);
        /* Add to end of list, since it has the highest expiration time */
-       subscription_link_to_end(s);
+       dl_list_add_tail(&sm->subscriptions, &s->list);
        /* Queue up immediate event message (our last event)
         * as required by UPnP spec.
         */
        if (subscription_first_event(s)) {
                wpa_printf(MSG_INFO, "WPS UPnP: Dropping subscriber due to "
                           "event backlog");
-               subscription_unlink(s);
+               dl_list_del(&s->list);
                subscription_destroy(s);
                return NULL;
        }
@@ -762,10 +719,10 @@ struct subscription * subscription_renew(struct upnp_wps_device_sm *sm,
        if (s == NULL)
                return NULL;
        wpa_printf(MSG_DEBUG, "WPS UPnP: Subscription renewed");
-       subscription_unlink(s);
+       dl_list_del(&s->list);
        s->timeout_time = expire;
        /* add back to end of list, since it now has highest expiry */
-       subscription_link_to_end(s);
+       dl_list_add_tail(&sm->subscriptions, &s->list);
        return s;
 }
 
@@ -950,6 +907,16 @@ fail:
 }
 
 
+static void upnp_wps_free_subscriptions(struct dl_list *head)
+{
+       struct subscription *s, *tmp;
+       dl_list_for_each_safe(s, tmp, head, struct subscription, list) {
+               dl_list_del(&s->list);
+               subscription_destroy(s);
+       }
+}
+
+
 /**
  * upnp_wps_device_stop - Stop WPS UPnP operations on an interface
  * @sm: WPS UPnP state machine from upnp_wps_device_init()
@@ -963,11 +930,7 @@ void upnp_wps_device_stop(struct upnp_wps_device_sm *sm)
        web_listener_stop(sm);
        while (sm->msearch_replies)
                msearchreply_state_machine_stop(sm->msearch_replies);
-       while (sm->subscriptions)  {
-               struct subscription *s = sm->subscriptions;
-               subscription_unlink(s);
-               subscription_destroy(s);
-       }
+       upnp_wps_free_subscriptions(&sm->subscriptions);
 
        advertisement_state_machine_stop(sm, 1);
 
@@ -1095,6 +1058,7 @@ upnp_wps_device_init(struct upnp_wps_device_ctx *ctx, struct wps_context *wps,
        sm->ctx = ctx;
        sm->wps = wps;
        sm->priv = priv;
+       dl_list_init(&sm->subscriptions);
 
        return sm;
 }
@@ -1107,5 +1071,5 @@ upnp_wps_device_init(struct upnp_wps_device_ctx *ctx, struct wps_context *wps,
  */
 int upnp_wps_subscribers(struct upnp_wps_device_sm *sm)
 {
-       return sm->subscriptions != NULL;
+       return !dl_list_empty(&sm->subscriptions);
 }
index 300392726111c90899482df2a11032efceba1e07..4d9b46fd3f3246369f7eab692edb7ecaf30a6620 100644 (file)
@@ -238,7 +238,7 @@ static void event_http_cb(void *ctx, struct http_client *c,
                 */
                wpa_printf(MSG_DEBUG, "WPS UPnP: Deleting subscription due to "
                           "errors");
-               subscription_unlink(s);
+               dl_list_del(&s->list);
                subscription_destroy(s);
                break;
        case HTTP_CLIENT_TIMEOUT:
@@ -314,32 +314,26 @@ static int event_send_start(struct subscription *s)
 static void event_send_all_later_handler(void *eloop_data, void *user_ctx)
 {
        struct upnp_wps_device_sm *sm = user_ctx;
-       struct subscription *s;
-       struct subscription *s_old;
+       struct subscription *s, *tmp;
        int nerrors = 0;
 
        sm->event_send_all_queued = 0;
-       s = sm->subscriptions;
-       if (s == NULL)
-               return;
-       do {
+       dl_list_for_each_safe(s, tmp, &sm->subscriptions, struct subscription,
+                             list) {
                if (dl_list_empty(&s->addr_list)) {
                        /* if we've given up on all addresses */
                        wpa_printf(MSG_DEBUG, "WPS UPnP: Removing "
                                   "subscription with no addresses");
-                       s_old = s;
-                       s = s_old->next;
-                       subscription_unlink(s_old);
-                       subscription_destroy(s_old);
+                       dl_list_del(&s->list);
+                       subscription_destroy(s);
                } else {
                        if (s->current_event == NULL /* not busy */ &&
                            s->event_queue != NULL /* more to do */) {
                                if (event_send_start(s))
                                        nerrors++;
                        }
-                       s = s->next;
                }
-       } while (sm->subscriptions != NULL && s != sm->subscriptions);
+       }
 
        if (nerrors) {
                /* Try again later */
index 945059f9b47c0a2b7f49c2e33dc4ce8c1cf229ae..af9fccb3a233cc8d6f5dbdf9f19aa833afccb5f3 100644 (file)
@@ -81,9 +81,7 @@ struct subscr_addr {
  * also have to age out subscribers unless they renew.
  */
 struct subscription {
-       /* double linked list */
-       struct subscription *next;
-       struct subscription *prev;
+       struct dl_list list;
        struct upnp_wps_device_sm *sm; /* parent */
        time_t timeout_time; /* when to age out the subscription */
        unsigned next_subscriber_sequence; /* number our messages */
@@ -136,8 +134,7 @@ struct upnp_wps_device_sm {
        int web_port; /* our port that others get xml files from */
        struct http_server *web_srv;
        /* Note: subscriptions are kept in expiry order */
-       struct subscription *subscriptions; /* linked list */
-       int n_subscriptions; /* no of current subscriptions */
+       struct dl_list subscriptions;
        int event_send_all_queued; /* if we are scheduled to send events soon
                                    */
 
@@ -153,7 +150,6 @@ struct subscription * subscription_start(struct upnp_wps_device_sm *sm,
                                         const char *callback_urls);
 struct subscription * subscription_renew(struct upnp_wps_device_sm *sm,
                                         const u8 uuid[UUID_LEN]);
-void subscription_unlink(struct subscription *s);
 void subscription_destroy(struct subscription *s);
 struct subscription * subscription_find(struct upnp_wps_device_sm *sm,
                                        const u8 uuid[UUID_LEN]);
index 8813cda142703b330ce2ad80bcc02aa34be24ea0..a5f3201164d430b09a220ec281d97fe7d3e379d6 100644 (file)
@@ -553,16 +553,9 @@ static struct subscription * find_er(struct upnp_wps_device_sm *sm,
                                     struct sockaddr_in *cli)
 {
        struct subscription *s;
-
-       s = sm->subscriptions;
-       while (s) {
+       dl_list_for_each(s, &sm->subscriptions, struct subscription, list)
                if (find_er_addr(s, cli))
                        return s;
-               s = s->next;
-               if (s == sm->subscriptions)
-                       break;
-       }
-
        return NULL;
 }
 
@@ -1136,7 +1129,7 @@ static void web_connection_parse_unsubscribe(struct upnp_wps_device_sm *sm,
                        wpa_printf(MSG_DEBUG, "WPS UPnP: Unsubscribing %p %s",
                                   s, (sa && sa->domain_and_port) ?
                                   sa->domain_and_port : "-null-");
-                       subscription_unlink(s);
+                       dl_list_del(&s->list);
                        subscription_destroy(s);
                }
        } else {