WPS: Convert struct subscr_addr to use dl_list

This commit is contained in:
Jouni Malinen 2009-12-19 13:47:00 +02:00
parent dacf478352
commit f98b440c47
5 changed files with 35 additions and 69 deletions

View file

@ -2764,10 +2764,13 @@ static void wps_registrar_sel_reg_union(struct wps_registrar *reg)
s = reg->wps->wps_upnp->subscriptions; s = reg->wps->wps_upnp->subscriptions;
while (s) { while (s) {
if (s->addr_list) struct subscr_addr *sa;
sa = dl_list_first(&s->addr_list, struct subscr_addr, list);
if (sa) {
wpa_printf(MSG_DEBUG, "WPS: External Registrar %s:%d", wpa_printf(MSG_DEBUG, "WPS: External Registrar %s:%d",
inet_ntoa(s->addr_list->saddr.sin_addr), inet_ntoa(sa->saddr.sin_addr),
ntohs(s->addr_list->saddr.sin_port)); ntohs(sa->saddr.sin_port));
}
if (s->selected_registrar) if (s->selected_registrar)
wps_registrar_sel_reg_add(reg, s); wps_registrar_sel_reg_add(reg, s);
else else

View file

@ -280,53 +280,18 @@ static void subscr_addr_delete(struct subscr_addr *a)
} }
/* subscr_addr_unlink -- unlink subscriber address from linked list */
static void subscr_addr_unlink(struct subscription *s, struct subscr_addr *a)
{
struct subscr_addr **listp = &s->addr_list;
s->n_addr--;
a->next->prev = a->prev;
a->prev->next = a->next;
if (*listp == a) {
if (a == a->next) {
/* last in queue */
*listp = NULL;
assert(s->n_addr == 0);
} else {
*listp = a->next;
}
}
}
/* subscr_addr_free_all -- unlink and delete list of subscriber addresses. */ /* subscr_addr_free_all -- unlink and delete list of subscriber addresses. */
static void subscr_addr_free_all(struct subscription *s) static void subscr_addr_free_all(struct subscription *s)
{ {
struct subscr_addr **listp = &s->addr_list; struct subscr_addr *a, *tmp;
struct subscr_addr *a; dl_list_for_each_safe(a, tmp, &s->addr_list, struct subscr_addr, list)
while ((a = *listp) != NULL) { {
subscr_addr_unlink(s, a); dl_list_del(&a->list);
subscr_addr_delete(a); subscr_addr_delete(a);
} }
} }
/* subscr_addr_link -- add subscriber address to list of addresses */
static void subscr_addr_link(struct subscription *s, struct subscr_addr *a)
{
struct subscr_addr **listp = &s->addr_list;
s->n_addr++;
if (*listp == NULL) {
*listp = a->next = a->prev = a;
} else {
a->next = *listp;
a->prev = (*listp)->prev;
a->prev->next = a;
a->next->prev = a;
}
}
/* subscr_addr_add_url -- add address(es) for one url to subscription */ /* subscr_addr_add_url -- add address(es) for one url to subscription */
static void subscr_addr_add_url(struct subscription *s, const char *url) static void subscr_addr_add_url(struct subscription *s, const char *url)
{ {
@ -403,7 +368,7 @@ static void subscr_addr_add_url(struct subscription *s, const char *url)
} }
for (rp = result; rp; rp = rp->ai_next) { for (rp = result; rp; rp = rp->ai_next) {
/* Limit no. of address to avoid denial of service attack */ /* Limit no. of address to avoid denial of service attack */
if (s->n_addr >= MAX_ADDR_PER_SUBSCRIPTION) { if (dl_list_len(&s->addr_list) >= MAX_ADDR_PER_SUBSCRIPTION) {
wpa_printf(MSG_INFO, "WPS UPnP: subscr_addr_add_url: " wpa_printf(MSG_INFO, "WPS UPnP: subscr_addr_add_url: "
"Ignoring excessive addresses"); "Ignoring excessive addresses");
break; break;
@ -425,7 +390,7 @@ static void subscr_addr_add_url(struct subscription *s, const char *url)
os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr)); os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr));
a->saddr.sin_port = htons(port); a->saddr.sin_port = htons(port);
subscr_addr_link(s, a); dl_list_add(&s->addr_list, &a->list);
a = NULL; /* don't free it below */ a = NULL; /* don't free it below */
} }
@ -598,8 +563,7 @@ static void subscription_link_to_end(struct subscription *s)
void subscription_destroy(struct subscription *s) void subscription_destroy(struct subscription *s)
{ {
wpa_printf(MSG_DEBUG, "WPS UPnP: Destroy subscription %p", s); wpa_printf(MSG_DEBUG, "WPS UPnP: Destroy subscription %p", s);
if (s->addr_list) subscr_addr_free_all(s);
subscr_addr_free_all(s);
event_delete_all(s); event_delete_all(s);
upnp_er_remove_notification(s); upnp_er_remove_notification(s);
os_free(s); os_free(s);
@ -762,6 +726,7 @@ struct subscription * subscription_start(struct upnp_wps_device_sm *sm,
s = os_zalloc(sizeof(*s)); s = os_zalloc(sizeof(*s));
if (s == NULL) if (s == NULL)
return NULL; return NULL;
dl_list_init(&s->addr_list);
s->sm = sm; s->sm = sm;
s->timeout_time = expire; s->timeout_time = expire;

View file

@ -50,7 +50,7 @@ struct wps_event_ {
struct wps_event_ *prev; /* double linked list */ struct wps_event_ *prev; /* double linked list */
struct subscription *s; /* parent */ struct subscription *s; /* parent */
unsigned subscriber_sequence; /* which event for this subscription*/ unsigned subscriber_sequence; /* which event for this subscription*/
int retry; /* which retry */ unsigned int retry; /* which retry */
struct subscr_addr *addr; /* address to connect to */ struct subscr_addr *addr; /* address to connect to */
struct wpabuf *data; /* event data to send */ struct wpabuf *data; /* event data to send */
struct http_client *http_event; struct http_client *http_event;
@ -170,7 +170,7 @@ static void event_retry(struct wps_event_ *e, int do_next_address)
if (do_next_address) if (do_next_address)
e->retry++; e->retry++;
if (e->retry >= s->n_addr) { if (e->retry >= dl_list_len(&s->addr_list)) {
wpa_printf(MSG_DEBUG, "WPS UPnP: Giving up on sending event " wpa_printf(MSG_DEBUG, "WPS UPnP: Giving up on sending event "
"for %s", e->addr->domain_and_port); "for %s", e->addr->domain_and_port);
return; return;
@ -271,23 +271,26 @@ static void event_http_cb(void *ctx, struct http_client *c,
static int event_send_start(struct subscription *s) static int event_send_start(struct subscription *s)
{ {
struct wps_event_ *e; struct wps_event_ *e;
int itry; unsigned int itry;
struct wpabuf *buf; struct wpabuf *buf;
/* /*
* Assume we are called ONLY with no current event and ONLY with * Assume we are called ONLY with no current event and ONLY with
* nonempty event queue and ONLY with at least one address to send to. * nonempty event queue and ONLY with at least one address to send to.
*/ */
assert(s->addr_list != NULL); assert(!dl_list_empty(&s->addr_list));
assert(s->current_event == NULL); assert(s->current_event == NULL);
assert(s->event_queue != NULL); assert(s->event_queue != NULL);
s->current_event = e = event_dequeue(s); s->current_event = e = event_dequeue(s);
/* Use address acc. to no. of retries */ /* Use address according to number of retries */
e->addr = s->addr_list; itry = 0;
for (itry = 0; itry < e->retry; itry++) dl_list_for_each(e->addr, &s->addr_list, struct subscr_addr, list)
e->addr = e->addr->next; if (itry++ == e->retry)
break;
if (itry < e->retry)
return -1;
buf = event_build_message(e); buf = event_build_message(e);
if (buf == NULL) { if (buf == NULL) {
@ -320,7 +323,7 @@ static void event_send_all_later_handler(void *eloop_data, void *user_ctx)
if (s == NULL) if (s == NULL)
return; return;
do { do {
if (s->addr_list == NULL) { if (dl_list_empty(&s->addr_list)) {
/* if we've given up on all addresses */ /* if we've given up on all addresses */
wpa_printf(MSG_DEBUG, "WPS UPnP: Removing " wpa_printf(MSG_DEBUG, "WPS UPnP: Removing "
"subscription with no addresses"); "subscription with no addresses");

View file

@ -11,6 +11,7 @@
#ifndef WPS_UPNP_I_H #ifndef WPS_UPNP_I_H
#define WPS_UPNP_I_H #define WPS_UPNP_I_H
#include "utils/list.h"
#include "http.h" #include "http.h"
#define UPNP_MULTICAST_ADDRESS "239.255.255.250" /* for UPnP multicasting */ #define UPNP_MULTICAST_ADDRESS "239.255.255.250" /* for UPnP multicasting */
@ -66,9 +67,7 @@ struct advertisement_state_machine {
* for a subscriber until we find one that seems to work. * for a subscriber until we find one that seems to work.
*/ */
struct subscr_addr { struct subscr_addr {
/* double linked list */ struct dl_list list;
struct subscr_addr *next;
struct subscr_addr *prev;
struct subscription *s; /* parent */ struct subscription *s; /* parent */
char *domain_and_port; /* domain and port part of url */ char *domain_and_port; /* domain and port part of url */
char *path; /* "filepath" part of url (from "mem") */ char *path; /* "filepath" part of url (from "mem") */
@ -95,8 +94,7 @@ struct subscription {
*/ */
u8 uuid[UUID_LEN]; u8 uuid[UUID_LEN];
/* Linked list of address alternatives (rotate through on failure) */ /* Linked list of address alternatives (rotate through on failure) */
struct subscr_addr *addr_list; struct dl_list addr_list;
int n_addr; /* Number of addresses in list */
struct wps_event_ *event_queue; /* Queued event messages. */ struct wps_event_ *event_queue; /* Queued event messages. */
int n_queue; /* How many events are queued */ int n_queue; /* How many events are queued */
struct wps_event_ *current_event; /* non-NULL if being sent (not in q) struct wps_event_ *current_event; /* non-NULL if being sent (not in q)

View file

@ -541,13 +541,9 @@ static int find_er_addr(struct subscription *s, struct sockaddr_in *cli)
{ {
struct subscr_addr *a; struct subscr_addr *a;
a = s->addr_list; dl_list_for_each(a, &s->addr_list, struct subscr_addr, list) {
while (a) {
if (cli->sin_addr.s_addr == a->saddr.sin_addr.s_addr) if (cli->sin_addr.s_addr == a->saddr.sin_addr.s_addr)
return 1; return 1;
a = a->next;
if (a == s->addr_list)
break;
} }
return 0; return 0;
} }
@ -1134,11 +1130,12 @@ static void web_connection_parse_unsubscribe(struct upnp_wps_device_sm *sm,
if (got_uuid) { if (got_uuid) {
s = subscription_find(sm, uuid); s = subscription_find(sm, uuid);
if (s) { if (s) {
struct subscr_addr *sa;
sa = dl_list_first(&s->addr_list, struct subscr_addr,
list);
wpa_printf(MSG_DEBUG, "WPS UPnP: Unsubscribing %p %s", wpa_printf(MSG_DEBUG, "WPS UPnP: Unsubscribing %p %s",
s, s, (sa && sa->domain_and_port) ?
(s && s->addr_list && sa->domain_and_port : "-null-");
s->addr_list->domain_and_port) ?
s->addr_list->domain_and_port : "-null-");
subscription_unlink(s); subscription_unlink(s);
subscription_destroy(s); subscription_destroy(s);
} }