Beispiel #1
0
int wps_er_ssdp_init(struct wps_er *er)
{
	if (add_ssdp_network(er->ifname)) {
		wpa_printf(MSG_INFO, "WPS ER: Failed to add routing entry for "
			   "SSDP");
		return -1;
	}

	er->multicast_sd = ssdp_open_multicast_sock(er->ip_addr);
	if (er->multicast_sd < 0) {
		wpa_printf(MSG_INFO, "WPS ER: Failed to open multicast socket "
			   "for SSDP");
		return -1;
	}

	er->ssdp_sd = ssdp_listener_open();
	if (er->ssdp_sd < 0) {
		wpa_printf(MSG_INFO, "WPS ER: Failed to open SSDP listener "
			   "socket");
		return -1;
	}

	if (eloop_register_sock(er->multicast_sd, EVENT_TYPE_READ,
				wps_er_ssdp_rx, er, NULL) ||
	    eloop_register_sock(er->ssdp_sd, EVENT_TYPE_READ,
				wps_er_ssdp_rx, er, NULL))
		return -1;

	wps_er_send_ssdp_msearch(er);

	return 0;
}
Beispiel #2
0
static void connection_setup_add_watch(struct ctrl_iface_dbus_priv *iface,
				       DBusWatch *watch)
{
	unsigned int flags;
	int fd;

	if (!dbus_watch_get_enabled(watch))
		return;

	flags = dbus_watch_get_flags(watch);
	fd = dbus_watch_get_unix_fd(watch);

	eloop_register_sock(fd, EVENT_TYPE_EXCEPTION, process_watch_exception,
			    iface, watch);

	if (flags & DBUS_WATCH_READABLE) {
		eloop_register_sock(fd, EVENT_TYPE_READ, process_watch_read,
				    iface, watch);
	}
	if (flags & DBUS_WATCH_WRITABLE) {
		eloop_register_sock(fd, EVENT_TYPE_WRITE, process_watch_write,
				    iface, watch);
	}

	dbus_watch_set_data(watch, iface, NULL);
}
Beispiel #3
0
static dbus_bool_t add_watch(DBusWatch *watch, void *data)
{
	struct wpas_dbus_priv *priv = data;
	unsigned int flags;
	int fd;

	if (!dbus_watch_get_enabled(watch))
		return TRUE;

	flags = dbus_watch_get_flags(watch);
	fd = dbus_watch_get_unix_fd(watch);

	eloop_register_sock(fd, EVENT_TYPE_EXCEPTION, process_watch_exception,
			    priv, watch);

	if (flags & DBUS_WATCH_READABLE) {
		eloop_register_sock(fd, EVENT_TYPE_READ, process_watch_read,
				    priv, watch);
	}
	if (flags & DBUS_WATCH_WRITABLE) {
		eloop_register_sock(fd, EVENT_TYPE_WRITE, process_watch_write,
				    priv, watch);
	}

	dbus_watch_set_data(watch, priv, NULL);

	return TRUE;
}
/* event_send_start -- prepare to send a event message to subscriber
 *
 * This gets complicated because:
 * -- The message is sent via TCP and we have to keep the stream open
 *      for 30 seconds to get a response... then close it.
 * -- But we might have other event happen in the meantime...
 *      we have to queue them, if we lose them then the subscriber will
 *      be forced to unsubscribe and subscribe again.
 * -- If multiple URLs are provided then we are supposed to try successive
 *      ones after 30 second timeout.
 * -- The URLs might use domain names instead of dotted decimal addresses,
 *      and resolution of those may cause unwanted sleeping.
 * -- Doing the initial TCP connect can take a while, so we have to come
 *      back after connection and then send the data.
 *
 * Returns nonzero on error;
 *
 * Prerequisite: No current event send (s->current_event == NULL)
 *      and non-empty queue.
 */
static int event_send_start(struct subscription *s)
{
	struct wps_event_ *e;
	int itry;

	/*
	 * 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.
	 */
	assert(s->addr_list != NULL);
	assert(s->current_event == NULL);
	assert(s->event_queue != NULL);

	s->current_event = e = event_dequeue(s);

	/* Use address acc. to no. of retries */
	e->addr = s->addr_list;
	for (itry = 0; itry < e->retry; itry++)
		e->addr = e->addr->next;

	e->sd = socket(AF_INET, SOCK_STREAM, 0);
	if (e->sd < 0) {
		event_retry(e, 0);
		return -1;
	}
	/* set non-blocking so we don't sleep waiting for connection */
	if (fcntl(e->sd, F_SETFL, O_NONBLOCK) != 0) {
		event_retry(e, 0);
		return -1;
	}
	/*
	 * Start the connect. It might succeed immediately but more likely will
	 * return errno EINPROGRESS.
	 */
	if (connect(e->sd, (struct sockaddr *) &e->addr->saddr,
		    sizeof(e->addr->saddr))) {
		if (errno != EINPROGRESS) {
			event_retry(e, 1);
			return -1;
		}
	}
	/* Call back when ready for writing (or on failure...). */
	if (eloop_register_sock(e->sd, EVENT_TYPE_WRITE, event_send_tx_ready,
				NULL, e)) {
		event_retry(e, 0);
		return -1;
	}
	e->sd_registered = 1;
	/* Don't wait forever! */
	if (eloop_register_timeout(EVENT_TIMEOUT_SEC, 0, event_timeout_handler,
				   NULL, e)) {
		event_retry(e, 0);
		return -1;
	}
	return 0;
}
Beispiel #5
0
struct http_client * http_client_addr(struct sockaddr_in *dst,
				      struct wpabuf *req, size_t max_response,
				      void (*cb)(void *ctx,
						 struct http_client *c,
						 enum http_client_event event),
				      void *cb_ctx)
{
	struct http_client *c;

	c = os_zalloc(sizeof(*c));
	if (c == NULL)
		return NULL;
	c->sd = -1;
	c->dst = *dst;
	c->max_response = max_response;
	c->cb = cb;
	c->cb_ctx = cb_ctx;

	c->sd = socket(AF_INET, SOCK_STREAM, 0);
	if (c->sd < 0)
		goto fail;

	if (fcntl(c->sd, F_SETFL, O_NONBLOCK) != 0) {
		wpa_printf(MSG_DEBUG, "HTTP: fnctl(O_NONBLOCK) failed: %s",
			   strerror(errno));
		goto fail;
	}

	if (connect(c->sd, (struct sockaddr *) dst, sizeof(*dst))) {
		if (errno != EINPROGRESS) {
			wpa_printf(MSG_DEBUG, "HTTP: Failed to connect: %s",
				   strerror(errno));
			goto fail;
		}

		/*
		 * Continue connecting in the background; eloop will call us
		 * once the connection is ready (or failed).
		 */
	}

	if (eloop_register_sock(c->sd, EVENT_TYPE_WRITE, http_client_tx_ready,
				c, NULL) ||
	    eloop_register_timeout(HTTP_CLIENT_TIMEOUT_SEC, 0,
				   http_client_timeout, c, NULL))
		goto fail;

	c->req = req;

	return c;

fail:
	http_client_free(c);
	return NULL;
}
Beispiel #6
0
int wps_er_ssdp_init(struct wps_er *er)
{
	if (add_ssdp_network(er->ifname))
		return -1;

	er->multicast_sd = ssdp_open_multicast_sock(er->ip_addr);
	if (er->multicast_sd < 0)
		return -1;

	er->ssdp_sd = ssdp_listener_open();
	if (er->ssdp_sd < 0)
		return -1;

	if (eloop_register_sock(er->multicast_sd, EVENT_TYPE_READ,
				wps_er_ssdp_rx, er, NULL) ||
	    eloop_register_sock(er->ssdp_sd, EVENT_TYPE_READ,
				wps_er_ssdp_rx, er, NULL))
		return -1;

	wps_er_send_ssdp_msearch(er);

	return 0;
}
Beispiel #7
0
/* httpread_create -- start a new reading session making use of eloop.
 * The new instance will use the socket descriptor for reading (until
 * it gets a file and not after) but will not close the socket, even
 * when the instance is destroyed (the application must do that).
 * Return NULL on error.
 *
 * Provided that httpread_create successfully returns a handle,
 * the callback fnc is called to handle httpread_event events.
 * The caller should do destroy on any errors or unknown events.
 *
 * Pass max_bytes == 0 to not read body at all (required for e.g.
 * reply to HEAD request).
 */
struct httpread *httpread_create(
        int sd,         /* descriptor of TCP socket to read from */
        void (*cb)(struct httpread *handle, void *cookie, 
                    enum httpread_event e),  /* call on event */
        void *cookie,    /* pass to callback */
        int max_bytes,          /* maximum body size else abort it */
        int timeout_seconds     /* 0; or total duration timeout period */
        )
{
        struct httpread *h = NULL;

        do {
                h = os_zalloc(sizeof(*h));
                if (h == NULL) break;
                h->sd = sd;
                h->cb = cb;
                h->cookie = cookie;
                h->max_bytes = max_bytes;
                h->timeout_seconds = timeout_seconds;

                if (timeout_seconds > 0) {
                        if (eloop_register_timeout(
                                        timeout_seconds, 
                                        0,
                                        httpread_timeout_handler, 
                                        NULL, 
                                        h)) {
                                /* No way to recover (from malloc failure) */
                                break;
                        }
                        h->to_registered = 1;
                }
                if (eloop_register_sock(sd, EVENT_TYPE_READ,
                                httpread_read_handler, NULL, h)) {
                        /* No way to recover (from malloc failure) */
                        break;
                }
                h->sd_registered = 1;
                return h;
        } while (0);

        /* Error */
        httpread_destroy(h);
        return NULL;
}
int eloop_register_read_sock(int sock, eloop_sock_handler handler,
                 void *eloop_data, void *user_data)
{
    return eloop_register_sock(sock, EVENT_TYPE_READ, handler,
                   eloop_data, user_data);
}