X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fwps%2Fwps_upnp_event.c;h=31ce82492af707cd3dbb65bb43c7c020fd9426a5;hb=8c3a2f11ab13c9629c05a396c1f888d6a8685bfb;hp=f3a2d4384bdef767ce9dbf9ee20705935abcab27;hpb=10fb1a984f253bf6ad39e7cbd53b56916a388116;p=libeap.git diff --git a/src/wps/wps_upnp_event.c b/src/wps/wps_upnp_event.c index f3a2d43..31ce824 100644 --- a/src/wps/wps_upnp_event.c +++ b/src/wps/wps_upnp_event.c @@ -31,6 +31,7 @@ */ #define MAX_EVENTS_QUEUED 20 /* How far behind queued events */ +#define MAX_FAILURES 10 /* Drop subscription after this many failures */ /* How long to wait before sending event */ #define EVENT_DELAY_SECONDS 0 @@ -166,6 +167,45 @@ static struct wpabuf * event_build_message(struct wps_event_ *e) } +static void event_addr_failure(struct wps_event_ *e) +{ + struct subscription *s = e->s; + + e->addr->num_failures++; + wpa_printf(MSG_DEBUG, "WPS UPnP: Failed to send event %p to %s " + "(num_failures=%u)", + e, e->addr->domain_and_port, e->addr->num_failures); + + if (e->addr->num_failures < MAX_FAILURES) { + /* Try other addresses, if available */ + event_retry(e, 1); + return; + } + + /* + * If other side doesn't like what we say, forget about them. + * (There is no way to tell other side that we are dropping them...). + */ + wpa_printf(MSG_DEBUG, "WPS UPnP: Deleting subscription %p " + "address %s due to errors", s, e->addr->domain_and_port); + dl_list_del(&e->addr->list); + subscr_addr_delete(e->addr); + e->addr = NULL; + + if (dl_list_empty(&s->addr_list)) { + /* if we've given up on all addresses */ + wpa_printf(MSG_DEBUG, "WPS UPnP: Removing subscription %p " + "with no addresses", s); + dl_list_del(&s->list); + subscription_destroy(s); + return; + } + + /* Try other addresses, if available */ + event_retry(e, 0); +} + + static void event_http_cb(void *ctx, struct http_client *c, enum http_client_event event) { @@ -179,6 +219,7 @@ static void event_http_cb(void *ctx, struct http_client *c, wpa_printf(MSG_DEBUG, "WPS UPnP: Got event %p reply OK from %s", e, e->addr->domain_and_port); + e->addr->num_failures = 0; event_delete(e); /* Schedule sending more if there is more to send */ @@ -186,24 +227,17 @@ static void event_http_cb(void *ctx, struct http_client *c, event_send_all_later(s->sm); break; case HTTP_CLIENT_FAILED: + wpa_printf(MSG_DEBUG, "WPS UPnP: Event send failure"); + event_addr_failure(e); + break; case HTTP_CLIENT_INVALID_REPLY: - wpa_printf(MSG_DEBUG, "WPS UPnP: Failed to send event to %s", - e->addr->domain_and_port); - - /* - * If other side doesn't like what we say, forget about them. - * (There is no way to tell other side that we are dropping - * them...). - * Alternately, we could just do event_delete(e) - */ - wpa_printf(MSG_DEBUG, "WPS UPnP: Deleting subscription due to " - "errors"); - dl_list_del(&s->list); - subscription_destroy(s); + wpa_printf(MSG_DEBUG, "WPS UPnP: Invalid reply"); + event_addr_failure(e); break; case HTTP_CLIENT_TIMEOUT: wpa_printf(MSG_DEBUG, "WPS UPnP: Event send timeout"); - event_retry(e, 1); + event_addr_failure(e); + break; } } @@ -283,18 +317,10 @@ static void event_send_all_later_handler(void *eloop_data, void *user_ctx) sm->event_send_all_queued = 0; 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"); - dl_list_del(&s->list); - subscription_destroy(s); - } else { - if (s->current_event == NULL /* not busy */ && - !dl_list_empty(&s->event_queue) /* more to do */) { - if (event_send_start(s)) - nerrors++; - } + if (s->current_event == NULL /* not busy */ && + !dl_list_empty(&s->event_queue) /* more to do */) { + if (event_send_start(s)) + nerrors++; } } @@ -339,7 +365,7 @@ 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 + * Returns: 0 on success, -1 on error, 1 on max event queue limit reached */ int event_add(struct subscription *s, const struct wpabuf *data) { @@ -355,13 +381,13 @@ int event_add(struct subscription *s, const struct wpabuf *data) 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)