WPS: Limit Probe Request event queuing if subscriber may have left

Instead of queuing all events for a subscriber, only queue more
important events if delivery of event notifications starts failing.
This allows more time for the subscriber to recover since the maximum
queue length if not reached because of Probe Request frames only.
This commit is contained in:
Jouni Malinen 2010-10-17 20:58:58 +03:00
parent d1e17fbc9c
commit 3904567d0b
3 changed files with 22 additions and 4 deletions

View file

@ -499,7 +499,8 @@ static void upnp_wps_device_send_event(struct upnp_wps_device_sm *sm)
dl_list_for_each_safe(s, tmp, &sm->subscriptions, struct subscription,
list) {
if (event_add(s, buf) == 1) {
if (event_add(s, buf, sm->wlanevent_type ==
UPNP_WPS_WLANEVENT_TYPE_PROBE) == 1) {
wpa_printf(MSG_INFO, "WPS UPnP: Dropping "
"subscriber %p due to event backlog", s);
dl_list_del(&s->list);
@ -650,7 +651,7 @@ static int subscription_first_event(struct subscription *s)
wpabuf_put_property(buf, "WLANEvent", wlan_event);
wpabuf_put_str(buf, tail);
ret = event_add(s, buf);
ret = event_add(s, buf, 0);
if (ret) {
wpabuf_free(buf);
return ret;
@ -798,6 +799,7 @@ int upnp_wps_device_send_wlan_event(struct upnp_wps_device_sm *sm,
os_free(sm->wlanevent);
sm->wlanevent = val;
sm->wlanevent_type = ev_type;
upnp_wps_device_send_event(sm);
ret = 0;

View file

@ -132,6 +132,7 @@ static void event_retry(struct wps_event_ *e, int do_next_address)
wpa_printf(MSG_DEBUG, "WPS UPnP: Giving up on sending event "
"for %s", e->addr->domain_and_port);
event_delete(e);
s->last_event_failed = 1;
if (!dl_list_empty(&s->event_queue))
event_send_all_later(s->sm);
return;
@ -222,6 +223,7 @@ static void event_http_cb(void *ctx, struct http_client *c,
"WPS UPnP: Got event %p reply OK from %s",
e, e->addr->domain_and_port);
e->addr->num_failures = 0;
s->last_event_failed = 0;
event_delete(e);
/* Schedule sending more if there is more to send */
@ -367,9 +369,10 @@ void event_send_stop_all(struct upnp_wps_device_sm *sm)
* event_add - Add a new event to a queue
* @s: Subscription
* @data: Event data (is copied; caller retains ownership)
* @probereq: Whether this is a Probe Request event
* Returns: 0 on success, -1 on error, 1 on max event queue limit reached
*/
int event_add(struct subscription *s, const struct wpabuf *data)
int event_add(struct subscription *s, const struct wpabuf *data, int probereq)
{
struct wps_event_ *e;
unsigned int len;
@ -381,6 +384,17 @@ int event_add(struct subscription *s, const struct wpabuf *data)
return 1;
}
if (s->last_event_failed && probereq && len > 0) {
/*
* Avoid queuing frames for subscribers that may have left
* without unsubscribing.
*/
wpa_printf(MSG_DEBUG, "WPS UPnP: Do not queue more Probe "
"Request frames for subscription %p since last "
"delivery failed", s);
return -1;
}
e = os_zalloc(sizeof(*e));
if (e == NULL)
return -1;

View file

@ -92,6 +92,7 @@ struct subscription {
struct dl_list event_queue; /* Queued event messages. */
struct wps_event_ *current_event; /* non-NULL if being sent (not in q)
*/
int last_event_failed; /* Whether delivery of last event failed */
/* Information from SetSelectedRegistrar action */
u8 selected_registrar;
@ -132,6 +133,7 @@ struct upnp_wps_device_sm {
*/
char *wlanevent; /* the last WLANEvent data */
enum upnp_wps_wlanevent_type wlanevent_type;
/* FIX: maintain separate structures for each UPnP peer */
struct upnp_wps_peer peer;
@ -168,7 +170,7 @@ int web_listener_start(struct upnp_wps_device_sm *sm);
void web_listener_stop(struct upnp_wps_device_sm *sm);
/* wps_upnp_event.c */
int event_add(struct subscription *s, const struct wpabuf *data);
int event_add(struct subscription *s, const struct wpabuf *data, int probereq);
void event_delete_all(struct subscription *s);
void event_send_all_later(struct upnp_wps_device_sm *sm);
void event_send_stop_all(struct upnp_wps_device_sm *sm);