/* subscription_list_age -- remove expired subscriptions */ static void subscription_list_age(struct upnp_wps_device_sm *sm, time_t now) { struct subscription *s, *tmp; dl_list_for_each_safe(s, tmp, &sm->subscriptions, struct subscription, list) { if (s->timeout_time > now) break; wpa_printf(MSG_DEBUG, "WPS UPnP: Removing aged subscription"); dl_list_del(&s->list); subscription_destroy(s); } }
/** * upnp_wps_device_send_event - Queue event messages for subscribers * @sm: WPS UPnP state machine from upnp_wps_device_init() * * This function queues the last WLANEvent to be sent for all currently * subscribed UPnP control points. sm->wlanevent must have been set with the * encoded data before calling this function. */ static void upnp_wps_device_send_event(struct upnp_wps_device_sm *sm) { /* Enqueue event message for all subscribers */ struct wpabuf *buf; /* holds event message */ int buf_size = 0; struct subscription *s, *tmp; /* Actually, utf-8 is the default, but it doesn't hurt to specify it */ const char *format_head = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" "<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">\n"; const char *format_tail = "</e:propertyset>\n"; if (dl_list_empty(&sm->subscriptions)) { /* optimize */ return; } /* Determine buffer size needed first */ buf_size += os_strlen(format_head); buf_size += 50 + 2 * os_strlen("WLANEvent"); if (sm->wlanevent) buf_size += os_strlen(sm->wlanevent); buf_size += os_strlen(format_tail); buf = wpabuf_alloc(buf_size); if (buf == NULL) return; wpabuf_put_str(buf, format_head); wpabuf_put_property(buf, "WLANEvent", sm->wlanevent); wpabuf_put_str(buf, format_tail); wpa_printf(MSG_MSGDUMP, "WPS UPnP: WLANEvent message:\n%s", (char *) wpabuf_head(buf)); dl_list_for_each_safe(s, tmp, &sm->subscriptions, struct subscription, list) { if (event_add(s, buf)) { wpa_printf(MSG_INFO, "WPS UPnP: Dropping " "subscriber due to event backlog"); dl_list_del(&s->list); subscription_destroy(s); } } wpabuf_free(buf); }
/** * subscription_start - Remember a UPnP control point to send events to. * @sm: WPS UPnP state machine from upnp_wps_device_init() * @callback_urls: Callback URLs * Returns: %NULL on error, or pointer to new subscription structure. */ struct subscription * subscription_start(struct upnp_wps_device_sm *sm, const char *callback_urls) { struct subscription *s; time_t now = time(NULL); time_t expire = now + UPNP_SUBSCRIBE_SEC; /* Get rid of expired subscriptions so we have room */ subscription_list_age(sm, now); /* If too many subscriptions, remove oldest */ if (dl_list_len(&sm->subscriptions) >= MAX_SUBSCRIPTIONS) { s = dl_list_first(&sm->subscriptions, struct subscription, list); wpa_printf(MSG_INFO, "WPS UPnP: Too many subscriptions, " "trashing oldest"); dl_list_del(&s->list); subscription_destroy(s); }
static void client_destroy (client_t *c) { subscription_t *sub; ctx_t *ctx = c->ctx; if (c->disconnect_notify) { struct disconnect_notify *d; d = zhash_first (c->disconnect_notify); while (d) { disconnect_destroy (c, d); d = zhash_next (c->disconnect_notify); } zhash_destroy (&c->disconnect_notify); } if (c->subscriptions) { while ((sub = zlist_pop (c->subscriptions))) subscription_destroy (ctx->h, sub); zlist_destroy (&c->subscriptions); } if (c->uuid) zuuid_destroy (&c->uuid); if (c->outqueue) { flux_msg_t *msg; while ((msg = zlist_pop (c->outqueue))) flux_msg_destroy (msg); zlist_destroy (&c->outqueue); } flux_fd_watcher_stop (ctx->h, c->outw); flux_fd_watcher_destroy (c->outw); flux_msg_iobuf_clean (&c->outbuf); flux_fd_watcher_stop (ctx->h, c->inw); flux_fd_watcher_destroy (c->inw); flux_msg_iobuf_clean (&c->inbuf); if (c->fd != -1) close (c->fd); free (c); }
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); }