numeric_mode  = is_flag_set(NUMERIC_MODE); verbose_mode  = is_flag_set(VERBOSE_MODE);
numeric_mode      = is_flag_set(NUMERIC_MODE); verbose_mode      = is_flag_set(VERBOSE_MODE); very_verbose_mode = is_flag_set(VERY_VERBOSE_MODE);
int do_connect(const connection_attributes *attrs, int *rt_socktype){	const address *remote, *local;	int err, fd = -1;	struct addrinfo hints, *res = NULL, *ptr;	bool connect_attempted = FALSE;	bool numeric_mode      = FALSE;	bool verbose_mode      = FALSE;	char name_buf[AI_STR_SIZE];	/* make sure that attrs is a valid pointer */	assert(attrs != NULL);		/* setup the addresses of the two connection endpoints */	remote = ca_remote_address(attrs);	local  = ca_local_address(attrs);	/* make sure all the preconditions are respected */	assert(remote->address != NULL && strlen(remote->address) > 0);	assert(remote->service != NULL && strlen(remote->service) > 0);	assert(local->address == NULL  || strlen(local->address)  > 0);	assert(local->service == NULL  || strlen(local->service)  > 0);	/* setup flags */	numeric_mode  = is_flag_set(NUMERIC_MODE);	verbose_mode  = is_flag_set(VERBOSE_MODE);		/* setup hints structure to be passed to getaddrinfo */	memset(&hints, 0, sizeof(hints));	ca_to_addrinfo(&hints, attrs);#ifdef HAVE_GETADDRINFO_AI_ADDRCONFIG	hints.ai_flags |= AI_ADDRCONFIG;#endif		if (numeric_mode == TRUE)		hints.ai_flags |= AI_NUMERICHOST;	/* get the address of the remote end of the connection */	err = getaddrinfo(remote->address, remote->service, &hints, &res);	if (err != 0)		fatal(_("forward host lookup failed "		      "for remote endpoint %s: %s"),		      remote->address, gai_strerror(err));	/* check the results of getaddrinfo */	assert(res != NULL);	/* try connecting to any of the addresses returned by getaddrinfo */	for (ptr = res; ptr != NULL; ptr = ptr->ai_next) {		/* only accept results we can handle */		if (skip_address(ptr) == TRUE) continue;		/* we are going to try to connect to this address */		connect_attempted = TRUE;		/* create the socket */		fd = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);		if (fd < 0) {			/* ignore this address if it is not supported */			if (unsupported_sock_error(errno))				continue;			fatal(_("socket creation failed: %s"),			      strerror(errno));		}		#if defined(ENABLE_IPV6) && defined(IPV6_V6ONLY)		if (ptr->ai_family == PF_INET6) {			int on = 1;			/* in case of error, we will go on anyway... */			err = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,			                 &on, sizeof(on));			if (err < 0) 				warn(_("error with sockopt IPV6_V6ONLY"));		}#endif 		/* setup configurable socket options */		set_sockopts(attrs, fd, ptr);		/* setup buf if we're in verbose mode */		if (verbose_mode == TRUE) 			getnameinfo_ex(ptr->ai_addr, ptr->ai_addrlen, 			               name_buf, sizeof(name_buf),				       numeric_mode);							/* setup local source address and/or service */		if (local->address != NULL || local->service != NULL) {			struct addrinfo *src_res = NULL, *src_ptr;					/* setup hints structure to be passed to getaddrinfo */			memset(&hints, 0, sizeof(hints));			hints.ai_family   = ptr->ai_family;			hints.ai_flags    = AI_PASSIVE;			hints.ai_socktype = ptr->ai_socktype;			hints.ai_protocol = ptr->ai_protocol;				if (is_flag_set(NUMERIC_MODE) == TRUE) 				hints.ai_flags |= AI_NUMERICHOST;					/* get the local IP address of the connection */			err = getaddrinfo(local->address, local->service,			                  &hints, &src_res);			if (err != 0) {				if (verbose_mode == TRUE) {					warn(_("bind to source addr/port "					     "failed when connecting to "					     "%s: %s"), name_buf,					     gai_strerror(err));				}				close(fd);				fd = -1;				continue;			}			/* check the results of getaddrinfo */			assert(src_res != NULL);			/* try binding to any of the addresses */			for (src_ptr = src_res; src_ptr != NULL;			     src_ptr = src_ptr->ai_next)			{				err = bind(fd, src_ptr->ai_addr,					   src_ptr->ai_addrlen);				if (err == 0) break;			}						if (err != 0) {				/* make sure we have tried all addresses */				assert(src_ptr == NULL);								if (verbose_mode == TRUE) {					warn(_("bind to source addr/port "					     "failed when connecting to "					     "%s: %s"), name_buf,					     strerror(errno));				}				freeaddrinfo(src_res);				close(fd);				fd = -1;				continue;			}			freeaddrinfo(src_res);		}		/* attempt the connection */		err = connect_with_timeout(fd, ptr, ca_connect_timeout(attrs));				switch (err) {		case CONNECTION_SUCCESS: 			/* everything went ok */			break;		case CONNECTION_FAILED: 			/* connection failed */			if (verbose_mode == TRUE) 				warn(_("cannot connect to %s: %s"),				     name_buf, strerror(errno));			close(fd);			fd = -1;			continue;		case CONNECTION_TIMEOUT: 			/* connection failed */			if (verbose_mode == TRUE) 				warn(_("timeout while connecting to %s"),				     name_buf);			close(fd);			fd = -1;			continue;		default: 			assert(0&&"Invalid result from connect_with_timeout");		}		/* exit from the loop if we have a valid connection */		if (fd >= 0)			break;	}	/* either all possibilities were exahusted, or a connection was made */	assert(ptr == NULL || fd >= 0);		/* if the connection failed, output an error message */	if (ptr == NULL) {		/* if a connection was attempted, an error has been output */		if (connect_attempted == FALSE) {			fatal(_("forward lookup returned "			      "no usable socket types"));		} else {			fatal(_("unable to connect to address %s, service %s"), 			      remote->address, remote->service);		}	}	/* let the user know the connection has been established */	if (verbose_mode == TRUE)		warn(_("%s open"), name_buf);	/* return the socktype */	if (rt_socktype != NULL)		*rt_socktype = ptr->ai_socktype;	/* cleanup addrinfo structure */	freeaddrinfo(res);	return fd;}