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); }
static void connectRetryCallback(ConnectState *connectState) { connectState->alarm = NULL; connectState->infoPtr = connectState->info; connectHostNext(connectState); }
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. } }
static void connectTimeoutCallback(ConnectState *connectState) { connectState->alarm = NULL; NetDescriptor_close(connectState->nd); connectState->nd = NULL; connectState->infoPtr = connectState->infoPtr->ai_next; connectHostNext(connectState); }