예제 #1
0
static void
connectHostResolveCallback(ResolveState *resolveState,
		struct addrinfo *info) {
	ConnectState *connectState =
			(ConnectState *) ResolveState_getExtra(resolveState);

	connectState->state = Connect_connecting;

	Resolve_close(resolveState);
	connectState->resolveState = NULL;

	if (connectState->flags.familyPrefer != PF_UNSPEC) {
		// Reorganise the 'info' list to put the structures of the
		// prefered family in front.
		struct addrinfo *preferred;
		struct addrinfo **preferredEnd;
		struct addrinfo *rest;
		struct addrinfo **restEnd;
		splitAddrInfoOnFamily(info, connectState->flags.familyPrefer,
				&preferred, &preferredEnd, &rest, &restEnd);
		info = preferred;
		*preferredEnd = rest;
	}

	connectState->info = info;
	connectState->infoPtr = info;

	connectHostNext(connectState);
}
예제 #2
0
static void
connectRetryCallback(ConnectState *connectState) {
	connectState->alarm = NULL;

	connectState->infoPtr = connectState->info;
	connectHostNext(connectState);
}
예제 #3
0
static void
connectCallback(NetDescriptor *nd) {
	// Called by the NetManager when a connection has been established.
	ConnectState *connectState =
			(ConnectState *) NetDescriptor_getExtra(nd);
	int err;

	if (connectState->alarm != NULL) {
		Alarm_remove(connectState->alarm);
		connectState->alarm = NULL;
	}

	if (connectState->state == Connect_closed) {
		// The connection attempt has been aborted.
#ifdef DEBUG
		log_add(log_Debug, "Connection attempt was aborted.");
#endif
		ConnectState_decRef(connectState);
		return;
	}

	if (Socket_getError(NetDescriptor_getSocket(nd), &err) == -1) {
		log_add(log_Fatal, "Socket_getError() failed: %s.",
				strerror(errno));
		explode();
	}
	if (err != 0) {
#ifdef DEBUG
		log_add(log_Debug, "connect() failed: %s.", strerror(err));
#endif
		NetDescriptor_close(nd);
		connectState->nd = NULL;
		connectState->infoPtr = connectState->infoPtr->ai_next;
		connectHostNext(connectState);
		return;
	}

#ifdef DEBUG
	log_add(log_Debug, "Connection established.");
#endif

	// Notify the higher layer.
	connectState->nd = NULL;
			// The callback function takes over ownership of the
			// NetDescriptor.
	NetDescriptor_setWriteCallback(nd, NULL);
	// Note that connectState->info and connectState->infoPtr are cleaned up
	// when ConnectState_close() is called by the callback function.
	
	ConnectState_incRef(connectState);
	doConnectCallback(connectState, nd, connectState->infoPtr->ai_addr,
			connectState->infoPtr->ai_addrlen);
	{
		// The callback called should release the last reference to
		// the connectState, by calling ConnectState_close().
		bool released = ConnectState_decRef(connectState);
		assert(released);
		(void) released;  // In case assert() evaluates to nothing.
	}
}
예제 #4
0
static void
connectTimeoutCallback(ConnectState *connectState) {
	connectState->alarm = NULL;

	NetDescriptor_close(connectState->nd);
	connectState->nd = NULL;

	connectState->infoPtr = connectState->infoPtr->ai_next;
	connectHostNext(connectState);
}