Beispiel #1
0
/* 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);
	}
}
Beispiel #2
0
/**
 * 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);
	}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
}