Example #1
0
static void
connectHostNext(ConnectState *connectState) {
	Socket *sock;

	while (connectState->infoPtr != NULL) {
		sock = tryConnectHostNext(connectState);

		if (sock != Socket_noSocket) {
			// Connection succeeded or connection in progress
			connectState->nd =
					NetDescriptor_new(sock, (void *) connectState);
			if (connectState->nd == NULL) {
				ConnectError error;
				int savedErrno = errno;

				log_add(log_Error, "NetDescriptor_new() failed: %s.\n",
						strerror(errno));
				Socket_close(sock);
				freeaddrinfo(connectState->info);
				connectState->info = NULL;
				connectState->infoPtr = NULL;
				connectState->state = Connect_closed;
				error.state = Connect_connecting;
				error.err = savedErrno;
				doConnectErrorCallback(connectState, &error);
				return;
			}

			NetDescriptor_setWriteCallback(connectState->nd, connectCallback);
			setConnectTimeout(connectState);
			return;
		}

		connectState->infoPtr = connectState->infoPtr->ai_next;
	}

	// Connect failed to all addresses.

	if (connectState->flags.retryDelayMs == Connect_noRetry) {
		connectHostReportAllFailed(connectState);
		return;
	}

	setConnectRetryAlarm(connectState);
}
Example #2
0
static void
acceptSingleConnection(ListenState *listenState, NetDescriptor *nd) {
	Socket *sock;
	Socket *acceptResult;
	struct sockaddr_storage addr;
	socklen_t addrLen;
	NetDescriptor *newNd;

	sock = NetDescriptor_getSocket(nd);
	addrLen = sizeof (addr);
	acceptResult = Socket_accept(sock, (struct sockaddr *) &addr, &addrLen);
	if (acceptResult == Socket_noSocket) {
		switch (errno) {
			case EWOULDBLOCK:
			case ECONNABORTED:
				// Nothing serious. Keep listening.
				return;
			case EMFILE:
			case ENFILE:
			case ENOBUFS:
			case ENOMEM:
#ifdef ENOSR
			case ENOSR:
#endif
				// Serious problems, but future connections may still
				// be possible.
				log_add(log_Warning, "accept() reported '%s'",
						strerror(errno));
				return;
			default:
				// Should not happen.
				log_add(log_Fatal, "Internal error: accept() reported "
						"'%s'", strerror(errno));
				explode();
		}
	}

	(void) Socket_setReuseAddr(acceptResult);
			// Ignore errors; it's not a big deal.
	if (Socket_setNonBlocking(acceptResult) == -1) {
		int savedErrno = errno;
		log_add(log_Error, "Could not make socket non-blocking: %s.",
				strerror(errno));
		Socket_close(acceptResult);
		errno = savedErrno;
		return;
	}
	(void) Socket_setInlineOOB(acceptResult);
			// Ignore errors; it's not a big deal as the other
			// party is not not supposed to send any OOB data.
	(void) Socket_setKeepAlive(sock);
			// Ignore errors; it's not a big deal.

#ifdef DEBUG
	{
		char hostname[NI_MAXHOST];
		int gniRes;

		gniRes = getnameinfo((struct sockaddr *) &addr, addrLen,
				hostname, sizeof hostname, NULL, 0, 0);
		if (gniRes != 0) {
			log_add(log_Error, "Error while performing hostname "
					"lookup for incoming connection: %s",
					(gniRes == EAI_SYSTEM) ? strerror(errno) :
					gai_strerror(gniRes));
		} else {
			log_add(log_Debug, "Accepted incoming connection from '%s'.",
					hostname);
		}
	}
#endif
	
	newNd = NetDescriptor_new(acceptResult, NULL);
	if (newNd == NULL) {
		int savedErrno = errno;
		log_add(log_Error, "NetDescriptor_new() failed: %s.",
				strerror(errno));
		Socket_close(acceptResult);
		errno = savedErrno;
		return;
	}

	doListenConnectCallback(listenState, nd, newNd,
			(struct sockaddr *) &addr, addrLen);
	// NB: newNd is now handed over to the callback function, and should
	//     no longer be referenced from here.
}
Example #3
0
static NetDescriptor *
listenPortSingle(struct ListenState *listenState, struct addrinfo *info) {
	Socket *sock;
	int bindResult;
	int listenResult;
	NetDescriptor *nd;

	sock = Socket_openNative(info->ai_family, info->ai_socktype,
			info->ai_protocol);
	if (sock == Socket_noSocket) {
		int savedErrno = errno;
		log_add(log_Error, "socket() failed: %s.", strerror(errno));
		errno = savedErrno;
		return NULL;
	}

	(void) Socket_setReuseAddr(sock);
			// Ignore errors; it's not a big deal.
	if (Socket_setNonBlocking(sock) == -1) {
		int savedErrno = errno;
		// Error message is already printed.
		Socket_close(sock);
		errno = savedErrno;
		return NULL;
	}
	
	bindResult = Socket_bind(sock, info->ai_addr, info->ai_addrlen);
	if (bindResult == -1) {
		int savedErrno = errno;
		if (errno == EADDRINUSE) {
#ifdef DEBUG
			log_add(log_Warning, "bind() failed: %s.", strerror(errno));
#endif
		} else
			log_add(log_Error, "bind() failed: %s.", strerror(errno));
		Socket_close(sock);
		errno = savedErrno;
		return NULL;
	}

	listenResult = Socket_listen(sock, listenState->flags.backlog);
	if (listenResult == -1) {
		int savedErrno = errno;
		log_add(log_Error, "listen() failed: %s.", strerror(errno));
		Socket_close(sock);
		errno = savedErrno;
		return NULL;
	}

	nd = NetDescriptor_new(sock, (void *) listenState);
	if (nd == NULL) {
		int savedErrno = errno;
		log_add(log_Error, "NetDescriptor_new() failed: %s.",
				strerror(errno));
		Socket_close(sock);
		errno = savedErrno;
		return NULL;
	}
		
	NetDescriptor_setReadCallback(nd, acceptCallback);

	return nd;
}