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;
}
dl_list_add(&s->event_queue, &e->list);
"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 */
* 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.
*/
- if (dl_list_empty(&s->addr_list))
- return -1;
- if (s->current_event)
- return -1;
- if (dl_list_empty(&s->event_queue))
+ if (dl_list_empty(&s->addr_list) ||
+ s->current_event ||
+ dl_list_empty(&s->event_queue))
return -1;
s->current_event = e = event_dequeue(s);
* event_add - Add a new event to a queue
* @s: Subscription
* @data: Event data (is copied; caller retains ownership)
- * Returns: 0 on success, 1 on error
+ * @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;
if (len >= MAX_EVENTS_QUEUED) {
wpa_printf(MSG_DEBUG, "WPS UPnP: Too many events queued for "
"subscriber %p", s);
- return 1;
+ if (probereq)
+ return 1;
+
+ /* Drop oldest entry to allow EAP event to be stored. */
+ e = event_dequeue(s);
+ if (!e)
+ return 1;
+ event_delete(e);
+ }
+
+ 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;
+ return -1;
dl_list_init(&e->list);
e->s = s;
e->data = wpabuf_dup(data);
if (e->data == NULL) {
os_free(e);
- return 1;
+ return -1;
}
e->subscriber_sequence = s->next_subscriber_sequence++;
if (s->next_subscriber_sequence == 0)