WPS: Convert struct subscription to use struct dl_list
This commit is contained in:
parent
f98b440c47
commit
ec32c29471
5 changed files with 50 additions and 107 deletions
|
@ -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, ®->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 */
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue