assert(attrs != NULL);
void do_listen(connection_attributes *attrs){	address *remote, *local;	int nfd, i, fd, err, ns = -1, socktype = -1, maxfd = -1;	struct addrinfo hints, *res = NULL, *ptr;	char hbuf_num[NI_MAXHOST + 1];	char sbuf_num[NI_MAXSERV + 1];	char c_hbuf_rev[NI_MAXHOST + 1];	char c_hbuf_num[NI_MAXHOST + 1];	char c_sbuf_num[NI_MAXSERV + 1];	bool numeric_mode      = FALSE;	bool verbose_mode      = FALSE;	bool dont_reuse_addr   = FALSE;	struct bound_socket_t* bound_sockets = NULL;	fd_set accept_fdset;	/* make sure all the preconditions are respected */	assert(attrs != NULL);	assert(local->address == NULL || strlen(local->address) > 0);	assert(local->service != NULL && strlen(local->service) > 0);	assert(remote->address == NULL || strlen(remote->address) > 0);	assert(remote->service == NULL || strlen(remote->service) > 0);	/* setup flags */	numeric_mode    = is_flag_set(NUMERIC_MODE);	verbose_mode    = is_flag_set(VERBOSE_MODE);	dont_reuse_addr = is_flag_set(DONT_REUSE_ADDR);		/* setup the addresses of the two connection endpoints */	remote = &(attrs->remote_address);	local  = &(attrs->local_address);	/* initialize accept_fdset */	FD_ZERO(&accept_fdset);		/* setup hints structure to be passed to getaddrinfo */	memset(&hints, 0, sizeof(hints));	connection_attributes_to_addrinfo(&hints, attrs);	hints.ai_flags = AI_PASSIVE;	if (numeric_mode == TRUE)		hints.ai_flags |= AI_NUMERICHOST;	/* get the IP address of the local end of the connection */	err = getaddrinfo(local->address, local->service, &hints, &res);	if (err != 0) 		fatal("forward host lookup failed for local endpoint %s (%s): %s",		      local->address? local->address : "[unspecified]",		      local->service, gai_strerror(err));			/* check the results of getaddrinfo */	assert(res != NULL);#ifdef ENABLE_IPV6	/* Some systems (eg. linux) will bind to both ipv6 AND ipv4 when	 * listening.  Connections will still be accepted from either ipv6 or	 * ipv4 clients (ipv4 will be mapped into ipv6).  However, this means	 * that we MUST bind the ipv6 address ONLY for these hosts.	 *	 * TODO: until we add a configure check to determine if the current	 * host does this double binding, we will just ensure that ipv6	 * sockets are bound first and then attempt to bind the ipv4 ones.  On	 * systems that double bind ipv6/ipv4 the ipv4 bind will simply fail.	 */	if (is_ipv6_enabled() == TRUE && is_double_binding_sane() == FALSE)		res = order_ipv6_first(res);#endif	/* try binding to all of the addresses returned by getaddrinfo */	nfd = 0;	for (ptr = res; ptr != NULL; ptr = ptr->ai_next) {		/* only use socktypes we can handle */		if (ptr->ai_socktype != SOCK_STREAM &&		    ptr->ai_socktype != SOCK_DGRAM) 			continue;#if defined(PF_INET6) && !defined(ENABLE_IPV6)		/* skip IPv6 if disabled */		if (ptr->ai_family == PF_INET6)			continue;#endif		/* get the numeric name for this source as a string */		err = getnameinfo(ptr->ai_addr, ptr->ai_addrlen,		                  hbuf_num, sizeof(hbuf_num),				  sbuf_num, sizeof(sbuf_num),				  NI_NUMERICHOST | NI_NUMERICSERV);		/* this should never happen */		if (err != 0)			fatal("getnameinfo failed: %s", gai_strerror(err));		/* 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("cannot create the socket: %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) perror("error with sockopt IPV6_V6ONLY");		}#endif 			/* set the reuse address socket option */		if (dont_reuse_addr == FALSE) {			int on = 1;			/* in case of error, we will go on anyway... */			err = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,			                 &on, sizeof(on));			if (err < 0) perror("error with sockopt SO_REUSEADDR");		}		/* bind to the local address */		err = bind(fd, ptr->ai_addr, ptr->ai_addrlen);		if (err != 0) {			warn("bind to source %s (%s) failed: %s",			     hbuf_num, sbuf_num, strerror(errno));			close(fd);			continue;		}		/* for stream based sockets, we need to listen for incoming		 * connections. the backlog parameter is set to 5 for backward		 * compatibility (it seems that at least some BSD-derived		 * system limit the backlog parameter to this value). */		if (ptr->ai_socktype == SOCK_STREAM) {			err = listen(fd, 5);			if (err != 0)				fatal("cannot listen on %s (%s): %s",				      hbuf_num, sbuf_num, strerror(errno));		}		if (verbose_mode == TRUE)			warn("listening on %s (%s) ...",			     hbuf_num, sbuf_num, strerror(errno));		/* add fd to bound_sockets (just add to the head of the list) */		bound_sockets =	add_bound_socket(bound_sockets, fd, 				                 ptr->ai_socktype);		/* add fd to accept_fdset */		FD_SET(fd, &accept_fdset);		maxfd = MAX(maxfd, fd);		nfd++;	}	freeaddrinfo(res);		if (nfd == 0)		fatal("failed to bind to any local addr/port");	/* enter into the accept loop */ 	for (;;) {		fd_set tmp_ap_fdset;		struct timeval tv, *tvp = NULL;		struct sockaddr_storage dest;		socklen_t destlen;		/* make a copy of accept_fdset before passing to select */		memcpy(&tmp_ap_fdset, &accept_fdset, sizeof(fd_set));		/* setup timeout */		if (attrs->connect_timeout > 0) {			tv.tv_sec = attrs->connect_timeout;			tv.tv_usec = 0;			tvp = &tv;		}		/* wait for an incoming connection */		err = select(maxfd + 1, &tmp_ap_fdset, NULL, NULL, tvp);		if (err == 0)			fatal("connection timed out");				if (err < 0) {			if (errno == EINTR) continue;			fatal("select error: %s", strerror(errno));		}		/* find the ready filedescriptor */		for (fd = 0; fd <= maxfd && !FD_ISSET(fd, &tmp_ap_fdset); ++fd)			;		/* if none were ready, loop to select again */		if (fd > maxfd)			continue;		/* find socket type in bound_sockets */		socktype = find_bound_socket(bound_sockets, fd);		destlen = sizeof(dest);			/* for stream sockets we accept a new connection, whereas for		 * dgram sockets we use MSG_PEEK to determine the sender */		if (socktype == SOCK_STREAM) {			ns = accept(fd, (struct sockaddr *)&dest, &destlen);			if (ns < 0)				fatal("cannot accept connection: %s",				      strerror(errno));		} else {			/* this is checked when binding listen sockets */			assert(socktype == SOCK_DGRAM);			err = recvfrom(fd, NULL, 0, MSG_PEEK,			               (struct sockaddr*)&dest, &destlen);			if (err < 0)				fatal("cannot recv from socket: %s",				      strerror(errno));			ns = dup(fd);			if (ns < 0)				fatal("cannot duplicate file descriptor %d: %s",				      fd, strerror(errno));		}		/* get names for each end of the connection */		if (verbose_mode == TRUE) {			struct sockaddr_storage src;			socklen_t srclen = sizeof(src);			/* find out what address the connection was to */			err = getsockname(ns, (struct sockaddr *)&src, &srclen);			if (err < 0)				fatal("getsockname failed: %s",				      strerror(errno));			/* get the numeric name for this source as a string */			err = getnameinfo((struct sockaddr *)&src, srclen,			                  hbuf_num, sizeof(hbuf_num), NULL, 0,			                  NI_NUMERICHOST | NI_NUMERICSERV);			/* this should never happen */			if (err != 0)				fatal("getnameinfo failed: %s",				      gai_strerror(err));			/* get the numeric name for this client as a string */			err = getnameinfo((struct sockaddr *)&dest, destlen,			                  c_hbuf_num, sizeof(c_hbuf_num),					  c_sbuf_num, sizeof(c_sbuf_num),					  NI_NUMERICHOST | NI_NUMERICSERV);			if (err != 0)				fatal("getnameinfo failed: %s",				      gai_strerror(err));			/* get the real name for this client as a string */			if (numeric_mode == FALSE) {				err = getnameinfo((struct sockaddr *)&dest,				                  destlen, c_hbuf_rev, 						  sizeof(c_hbuf_rev), 						  NULL, 0, 0);				if (err != 0) {					warn("inverse lookup failed for %s: %s",				             c_hbuf_num, gai_strerror(err));					strcpy(c_hbuf_rev, c_hbuf_num);				}			} else {				strcpy(c_hbuf_rev, c_hbuf_num);			}		}		/* check if connections from this client are allowed */		if ((remote == NULL) ||		    (remote->address == NULL && remote->service == NULL) ||		    (is_allowed((struct sockaddr*)&dest,remote,attrs) == TRUE)) {			if (socktype == SOCK_DGRAM) {				/* connect the socket to ensure we only talk				 * with this client */				err = connect(ns, (struct sockaddr*)&dest, 				              destlen);				if (err != 0)					fatal("cannot connect datagram socket: %s",					      strerror(errno));			}			if (verbose_mode == TRUE) {				warn("connect to %s (%s) from %s [%s] %s",				     hbuf_num, sbuf_num,				     c_hbuf_rev, c_hbuf_num, c_sbuf_num);			}			break;		} else {			if (socktype == SOCK_DGRAM) {				/* the connection wasn't accepted - 				 * remove the queued packet */				recvfrom(ns, NULL, 0, 0, NULL, 0);			}			close(ns);			ns = -1;			if (verbose_mode == TRUE) {				warn("refused connect to %s (%s) from %s [%s] %s",				     hbuf_num, sbuf_num,				     c_hbuf_rev, c_hbuf_num, c_sbuf_num);			}		}	}	/* close the listening sockets */	for (i = 0; i <= maxfd; ++i) {		if (FD_ISSET(i, &accept_fdset) != 0) close(i);	}	/* the ns and socktype should be set */	assert(ns >= 0);	assert(socktype != -1);	/* free the bound_socket list */	destroy_bound_sockets(bound_sockets);	/* fill out the remote io_stream */	ios_assign_socket(&(attrs->remote_stream), ns, socktype);}