Esempio n. 1
0
static void open_socket_out_connected(struct tevent_req *subreq)
{
	struct tevent_req *req =
		tevent_req_callback_data(subreq, struct tevent_req);
	struct open_socket_out_state *state =
		tevent_req_data(req, struct open_socket_out_state);
	int ret;
	int sys_errno;

	ret = async_connect_recv(subreq, &sys_errno);
	TALLOC_FREE(subreq);
	if (ret == 0) {
		tevent_req_done(req);
		return;
	}

	if (
#ifdef ETIMEDOUT
		(sys_errno == ETIMEDOUT) ||
#endif
		(sys_errno == EINPROGRESS) ||
		(sys_errno == EALREADY) ||
		(sys_errno == EAGAIN)) {

		/*
		 * retry
		 */

		if (state->wait_usec < 250000) {
			state->wait_usec *= 1.5;
		}

		subreq = async_connect_send(state, state->ev, state->fd,
					    (struct sockaddr *)&state->ss,
					    state->salen);
		if (tevent_req_nomem(subreq, req)) {
			return;
		}
		if (!tevent_req_set_endtime(
			    subreq, state->ev,
			    timeval_current_ofs_usec(state->wait_usec))) {
			tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
			return;
		}
		tevent_req_set_callback(subreq, open_socket_out_connected, req);
		return;
	}

#ifdef EISCONN
	if (sys_errno == EISCONN) {
		tevent_req_done(req);
		return;
	}
#endif

	/* real error */
	tevent_req_nterror(req, map_nt_error_from_unix(sys_errno));
}
Esempio n. 2
0
struct tevent_req *ctdb_conn_init_send(TALLOC_CTX *mem_ctx,
				       struct tevent_context *ev,
				       const char *sock)
{
	struct tevent_req *req, *subreq;
	struct ctdb_conn_init_state *state;

	req = tevent_req_create(mem_ctx, &state, struct ctdb_conn_init_state);
	if (req == NULL) {
		return NULL;
	}

	if (!lp_clustering()) {
		tevent_req_error(req, ENOSYS);
		return tevent_req_post(req, ev);
	}

	if (strlen(sock) >= sizeof(state->addr.sun_path)) {
		tevent_req_error(req, ENAMETOOLONG);
		return tevent_req_post(req, ev);
	}

	state->conn = talloc(state, struct ctdb_conn);
	if (tevent_req_nomem(state->conn, req)) {
		return tevent_req_post(req, ev);
	}

	state->conn->outqueue = tevent_queue_create(
		state->conn, "ctdb outqueue");
	if (tevent_req_nomem(state->conn->outqueue, req)) {
		return tevent_req_post(req, ev);
	}

	state->conn->fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (state->conn->fd == -1) {
		tevent_req_error(req, errno);
		return tevent_req_post(req, ev);
	}
	talloc_set_destructor(state->conn, ctdb_conn_destructor);

	state->addr.sun_family = AF_UNIX;
	strncpy(state->addr.sun_path, sock, sizeof(state->addr.sun_path));

	subreq = async_connect_send(state, ev, state->conn->fd,
				    (struct sockaddr *)&state->addr,
				    sizeof(state->addr), before_connect_cb,
				    after_connect_cb, NULL);
	if (tevent_req_nomem(subreq, req)) {
		return tevent_req_post(req, ev);
	}
	tevent_req_set_callback(subreq, ctdb_conn_init_done, req);
	return req;
}
Esempio n. 3
0
struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
					struct event_context *ev,
					const struct sockaddr_storage *pss,
					uint16_t port,
					int timeout)
{
	char addr[INET6_ADDRSTRLEN];
	struct tevent_req *result, *subreq;
	struct open_socket_out_state *state;
	NTSTATUS status;

	result = tevent_req_create(mem_ctx, &state,
				   struct open_socket_out_state);
	if (result == NULL) {
		return NULL;
	}
	state->ev = ev;
	state->ss = *pss;
	state->port = port;
	state->wait_usec = 10000;
	state->salen = -1;

	state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
	if (state->fd == -1) {
		status = map_nt_error_from_unix(errno);
		goto post_status;
	}
	talloc_set_destructor(state, open_socket_out_state_destructor);

	if (!tevent_req_set_endtime(
		    result, ev, timeval_current_ofs_msec(timeout))) {
		goto fail;
	}

#if defined(HAVE_IPV6)
	if (pss->ss_family == AF_INET6) {
		struct sockaddr_in6 *psa6;
		psa6 = (struct sockaddr_in6 *)&state->ss;
		psa6->sin6_port = htons(port);
		if (psa6->sin6_scope_id == 0
		    && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
			setup_linklocal_scope_id(
				(struct sockaddr *)&(state->ss));
		}
		state->salen = sizeof(struct sockaddr_in6);
	}
#endif
	if (pss->ss_family == AF_INET) {
		struct sockaddr_in *psa;
		psa = (struct sockaddr_in *)&state->ss;
		psa->sin_port = htons(port);
		state->salen = sizeof(struct sockaddr_in);
	}

	if (pss->ss_family == AF_UNIX) {
		state->salen = sizeof(struct sockaddr_un);
	}

	print_sockaddr(addr, sizeof(addr), &state->ss);
	DEBUG(3,("Connecting to %s at port %u\n", addr,	(unsigned int)port));

	subreq = async_connect_send(state, state->ev, state->fd,
				    (struct sockaddr *)&state->ss,
				    state->salen);
	if ((subreq == NULL)
	    || !tevent_req_set_endtime(
		    subreq, state->ev,
		    timeval_current_ofs(0, state->wait_usec))) {
		goto fail;
	}
	tevent_req_set_callback(subreq, open_socket_out_connected, result);
	return result;

 post_status:
	tevent_req_nterror(result, status);
	return tevent_req_post(result, ev);
 fail:
	TALLOC_FREE(result);
	return NULL;
}