Exemplo n.º 1
0
/**
 * We get called here from directly following a call to connect(2).
 * In order to determine if we've errored out or succeeded must call
 * getsockopt.
 */
static void uv__tcp_connect(uv_handle_t* handle) {
    int error;
    socklen_t errorsize = sizeof(int);

    assert(handle->fd >= 0);

    uv_req_t* req = handle->connect_req;
    assert(req);

    if (handle->delayed_error) {
        /* To smooth over the differences between unixes errors that
         * were reported synchronously on the first connect can be delayed
         * until the next tick--which is now.
         */
        error = handle->delayed_error;
        handle->delayed_error = 0;
    } else {
        /* Normal situation: we need to get the socket error from the kernel. */
        getsockopt(handle->fd, SOL_SOCKET, SO_ERROR, &error, &errorsize);
    }

    if (!error) {
        ev_io_start(EV_DEFAULT_ &handle->read_watcher);

        /* Successful connection */
        handle->connect_req = NULL;
        uv_connect_cb connect_cb = req->cb;
        if (connect_cb) {
            connect_cb(req, 0);
        }

    } else if (error == EINPROGRESS) {
        /* Still connecting. */
        return;
    } else {
        /* Error */
        uv_err_t err = uv_err_new(handle, error);

        handle->connect_req = NULL;

        uv_connect_cb connect_cb = req->cb;
        if (connect_cb) {
            connect_cb(req, -1);
        }

        uv_close(handle);
    }
}
Exemplo n.º 2
0
static int run_test(int inprocess) {
  uv_process_t process;
  uv_thread_t tid;
  int r;

  if (inprocess) {
    r = uv_thread_create(&tid, ipc_send_recv_helper_threadproc, (void *) 42);
    ASSERT(r == 0);

    uv_sleep(1000);

    r = uv_pipe_init(uv_default_loop(), &ctx.channel, 1);
    ASSERT(r == 0);

    uv_pipe_connect(&ctx.connect_req, &ctx.channel, TEST_PIPENAME_3, connect_cb);
  } else {
    spawn_helper(&ctx.channel, &process, "ipc_send_recv_helper");

    connect_cb(&ctx.connect_req, 0);
  }

  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
  ASSERT(r == 0);

  ASSERT(recv_cb_count == 2);

  if (inprocess) {
    r = uv_thread_join(&tid);
    ASSERT(r == 0);
  }

  return 0;
}
Exemplo n.º 3
0
static void udp_can_write(gpointer data, gint source, PurpleInputCondition cond)
{
	PurpleConnection *gc;
	qq_data *qd;
	socklen_t len;
	int error=0, ret;

	gc = (PurpleConnection *) data;
	g_return_if_fail(gc != NULL && gc->proto_data != NULL);

	qd = (qq_data *) gc->proto_data;


	purple_debug_info("proxy", "Connected.\n");

	/*
	 * getsockopt after a non-blocking connect returns -1 if something is
	 * really messed up (bad descriptor, usually). Otherwise, it returns 0 and
	 * error holds what connect would have returned if it blocked until now.
	 * Thus, error == 0 is success, error == EINPROGRESS means "try again",
	 * and anything else is a real error.
	 *
	 * (error == EINPROGRESS can happen after a select because the kernel can
	 * be overly optimistic sometimes. select is just a hint that you might be
	 * able to do something.)
	 */
	len = sizeof(error);
	ret = getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len);
	if (ret == 0 && error == EINPROGRESS)
		return; /* we'll be called again later */

	purple_input_remove(qd->udp_can_write_handler);
	qd->udp_can_write_handler = 0;
	if (ret < 0 || error != 0) {
		if(ret != 0)
			error = errno;

		close(source);

		purple_debug_error("proxy", "getsockopt SO_ERROR check: %s\n", g_strerror(error));

		connect_cb(gc, -1, _("Unable to connect"));
		return;
	}

	connect_cb(gc, source, NULL);
}
Exemplo n.º 4
0
int DeviceProxy_Callback::connect(int timeout) {
	int rv = 0;
	if(connect_cb)
		rv = connect_cb(timeout);
	if(rv == 0)
		p_is_connected = true;
	// No connect method - assume always connected
	return rv;
}
Exemplo n.º 5
0
static void udp_host_resolved(GSList *hosts, gpointer data, const char *error_message) {
	PurpleConnection *gc;
	qq_data *qd;
	struct sockaddr server_addr;
	int addr_size;
	gint fd = -1;
	int flags;

	gc = (PurpleConnection *) data;
	g_return_if_fail(gc != NULL && gc->proto_data != NULL);

	qd = (qq_data *) gc->proto_data;

	/* udp_query_data must be set as NULL.
	 * Otherwise purple_dnsquery_destroy in qq_disconnect cause glib double free error */
	qd->udp_query_data = NULL;

	if (!hosts || !hosts->data) {
		purple_connection_error_reason(gc,
				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
				_("Unable to resolve hostname"));
		return;
	}

	addr_size = GPOINTER_TO_INT(hosts->data);
	hosts = g_slist_remove(hosts, hosts->data);
	memcpy(&server_addr, hosts->data, addr_size);
	g_free(hosts->data);

	hosts = g_slist_remove(hosts, hosts->data);
	while(hosts) {
		hosts = g_slist_remove(hosts, hosts->data);
		g_free(hosts->data);
		hosts = g_slist_remove(hosts, hosts->data);
	}

	fd = socket(PF_INET, SOCK_DGRAM, 0);
	if (fd < 0) {
		purple_debug_error("QQ",
				"Unable to create socket: %s\n", g_strerror(errno));
		return;
	}

	/* we use non-blocking mode to speed up connection */
	flags = fcntl(fd, F_GETFL);
	fcntl(fd, F_SETFL, flags | O_NONBLOCK);
#ifndef _WIN32
	fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif

	/* From Unix-socket-FAQ: http://www.faqs.org/faqs/unix-faq/socket/
	 *
	 * If a UDP socket is unconnected, which is the normal state after a
	 * bind() call, then send() or write() are not allowed, since no
	 * destination is available; only sendto() can be used to send data.
	 *
	 * Calling connect() on the socket simply records the specified address
	 * and port number as being the desired communications partner. That
	 * means that send() or write() are now allowed; they use the destination
	 * address and port given on the connect call as the destination of packets.
	 */
	if (connect(fd, &server_addr, addr_size) >= 0) {
		purple_debug_info("QQ", "Connected.\n");
		flags = fcntl(fd, F_GETFL);
		fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
		connect_cb(gc, fd, NULL);
		return;
	}

	/* [EINPROGRESS]
	 *    The socket is marked as non-blocking and the connection cannot be
	 *    completed immediately. It is possible to select for completion by
	 *    selecting the socket for writing.
	 * [EINTR]
	 *    A signal interrupted the call.
	 *    The connection is established asynchronously.
	 */
	if ((errno == EINPROGRESS) || (errno == EINTR)) {
			purple_debug_warning( "QQ", "Connect in asynchronous mode.\n");
			qd->udp_can_write_handler = purple_input_add(fd, PURPLE_INPUT_WRITE, udp_can_write, gc);
			return;
		}

	purple_debug_error("QQ", "Connection failed: %s\n", g_strerror(errno));
	close(fd);
}