WPS: Merge event_send_start() error paths
[mech_eap.git] / src / wps / wps_upnp_event.c
index 9deca52..94aae75 100644 (file)
@@ -132,6 +132,9 @@ 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;
        }
        dl_list_add(&s->event_queue, &e->list);
@@ -220,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 */
@@ -272,11 +276,9 @@ static int event_send_start(struct subscription *s)
         * 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);
@@ -365,9 +367,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)
- * 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;
@@ -376,18 +379,36 @@ int event_add(struct subscription *s, const struct wpabuf *data)
        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)