示例#1
0
/* static void comm_connect_tryconnect(int fd, void *notused)
 * Input: The fd, the handler data(unused).
 * Output: None.
 * Side-effects: Try and connect with pending connect data for the FD. If
 *               we succeed or get a fatal error, call the callback.
 *               Otherwise, it is still blocking or something, so register
 *               to select for a write event on this FD.
 */
static void
comm_connect_tryconnect(int fd, void *notused)
{
	int retval;
	fde_t *F = &fd_table[fd];

	if(F->connect.callback == NULL)
		return;
	/* Try the connect() */
	retval = connect(fd,
			 (struct sockaddr *) &fd_table[fd].connect.hostaddr, 
						       GET_SS_LEN(fd_table[fd].connect.hostaddr));
	/* Error? */
	if(retval < 0)
	{
		/*
		 * If we get EISCONN, then we've already connect()ed the socket,
		 * which is a good thing.
		 *   -- adrian
		 */
		if(errno == EISCONN)
			comm_connect_callback(F->fd, COMM_OK);
		else if(ignoreErrno(errno))
			/* Ignore error? Reschedule */
			comm_setselect(F->fd, FDLIST_SERVER, COMM_SELECT_WRITE|COMM_SELECT_RETRY,
				       comm_connect_tryconnect, NULL, 0);
		else
			/* Error? Fail with COMM_ERR_CONNECT */
			comm_connect_callback(F->fd, COMM_ERR_CONNECT);
		return;
	}
	/* If we get here, we've suceeded, so call with COMM_OK */
	comm_connect_callback(F->fd, COMM_OK);
}
示例#2
0
文件: listener.c 项目: Macs/NeoIRCd
static int
inetport(struct Listener *listener)
{
	rb_fde_t *F;
	int ret;
	int opt = 1;

	/*
	 * At first, open a new socket
	 */
	
	F = rb_socket(GET_SS_FAMILY(&listener->addr), SOCK_STREAM, 0, "Listener socket");

#ifdef RB_IPV6
	if(listener->addr.ss_family == AF_INET6)
	{
		struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&listener->addr;
		if(!IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &in6addr_any))
		{
			rb_inet_ntop(AF_INET6, &in6->sin6_addr, listener->vhost, sizeof(listener->vhost));
			listener->name = listener->vhost;
		}
	} else
#endif
	{
		struct sockaddr_in *in = (struct sockaddr_in *)&listener->addr;
		if(in->sin_addr.s_addr != INADDR_ANY)
		{
			rb_inet_ntop(AF_INET, &in->sin_addr, listener->vhost, sizeof(listener->vhost));
			listener->name = listener->vhost;
		}	
	}

	if(F == NULL)
	{
		ilog_error("opening listener socket");
		return 0;
	}
	else if((maxconnections - 10) < rb_get_fd(F)) /* XXX this is kinda bogus*/
	{
		ilog_error("no more connections left for listener");
		rb_close(F);
		return 0;
	}

	/*
	 * XXX - we don't want to do all this crap for a listener
	 * set_sock_opts(listener);
	 */
	if(setsockopt(rb_get_fd(F), SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)))
	{
		ilog_error("setting SO_REUSEADDR for listener");
		rb_close(F);
		return 0;
	}

	/*
	 * Bind a port to listen for new connections if port is non-null,
	 * else assume it is already open and try get something from it.
	 */

	if(bind(rb_get_fd(F), (struct sockaddr *) &listener->addr, GET_SS_LEN(&listener->addr)))
	{
		ilog_error("binding listener socket");
		rb_close(F);
		return 0;
	}

	if((ret = rb_listen(F, RATBOX_SOMAXCONN)))
	{
		ilog_error("listen()");
		rb_close(F);
		return 0;
	}

	listener->F = F;

	rb_accept_tcp(listener->F, accept_precallback, accept_callback, listener);
	return 1;
}
示例#3
0
static int
inetport(struct Listener *listener)
{
	rb_fde_t *F;
	int opt = 1;
	const char *errstr;

	/*
	 * At first, open a new socket
	 */

	F = rb_socket(GET_SS_FAMILY(&listener->addr), SOCK_STREAM, 0, "Listener socket");

#ifdef RB_IPV6
	if(listener->addr.ss_family == AF_INET6)
	{
		struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&listener->addr;
		if(!IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &in6addr_any))
		{
			rb_inet_ntop(AF_INET6, &in6->sin6_addr, listener->vhost, sizeof(listener->vhost));
			listener->name = listener->vhost;
		}
	} else
#endif
	{
		struct sockaddr_in *in = (struct sockaddr_in *)&listener->addr;
		if(in->sin_addr.s_addr != INADDR_ANY)
		{
			rb_inet_ntop(AF_INET, &in->sin_addr, listener->vhost, sizeof(listener->vhost));
			listener->name = listener->vhost;
		}
	}

	if(F == NULL)
	{
		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				"Cannot open socket for listener on port %d",
				get_listener_port(listener));
		ilog(L_MAIN, "Cannot open socket for listener %s",
				get_listener_name(listener));
		return 0;
	}
	else if((maxconnections - 10) < rb_get_fd(F)) /* XXX this is kinda bogus*/
	{
		ilog_error("no more connections left for listener");
		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				"No more connections left for listener on port %d",
				get_listener_port(listener));
		ilog(L_MAIN, "No more connections left for listener %s",
				get_listener_name(listener));
		rb_close(F);
		return 0;
	}

	/*
	 * XXX - we don't want to do all this crap for a listener
	 * set_sock_opts(listener);
	 */
	if(setsockopt(rb_get_fd(F), SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)))
	{
		errstr = strerror(rb_get_sockerr(F));
		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				"Cannot set SO_REUSEADDR for listener on port %d: %s",
				get_listener_port(listener), errstr);
		ilog(L_MAIN, "Cannot set SO_REUSEADDR for listener %s: %s",
				get_listener_name(listener), errstr);
		rb_close(F);
		return 0;
	}

	/*
	 * Bind a port to listen for new connections if port is non-null,
	 * else assume it is already open and try get something from it.
	 */

	if(bind(rb_get_fd(F), (struct sockaddr *) &listener->addr, GET_SS_LEN(&listener->addr)))
	{
		errstr = strerror(rb_get_sockerr(F));
		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				"Cannot bind for listener on port %d: %s",
				get_listener_port(listener), errstr);
		ilog(L_MAIN, "Cannot bind for listener %s: %s",
				get_listener_name(listener), errstr);
		rb_close(F);
		return 0;
	}

	if(rb_listen(F, CHARYBDIS_SOMAXCONN, listener->defer_accept))
	{
		errstr = strerror(rb_get_sockerr(F));
		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				"Cannot listen() for listener on port %d: %s",
				get_listener_port(listener), errstr);
		ilog(L_MAIN, "Cannot listen() for listener %s: %s",
				get_listener_name(listener), errstr);
		rb_close(F);
		return 0;
	}

	listener->F = F;

	rb_accept_tcp(listener->F, accept_precallback, accept_callback, listener);
	return 1;
}
示例#4
0
static int
inetport(struct Listener *listener)
{
	int fd;
	int opt = 1;

	/*
	 * At first, open a new socket
	 */

	fd = comm_socket(listener->addr.ss_family, SOCK_STREAM, 0, "Listener socket");

#ifdef IPV6
	if(listener->addr.ss_family == AF_INET6)
	{
		struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &listener->addr;
		if(!IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &in6addr_any))
		{
			inetntop(AF_INET6, &in6->sin6_addr, listener->vhost,
				 sizeof(listener->vhost));
			listener->name = listener->vhost;
		}
	}
	else
#endif
	{
		struct sockaddr_in *in = (struct sockaddr_in *) &listener->addr;
		if(in->sin_addr.s_addr != INADDR_ANY)
		{
			inetntop(AF_INET, &in->sin_addr, listener->vhost, sizeof(listener->vhost));
			listener->name = listener->vhost;
		}
	}


	if(fd == -1)
	{
		report_error("opening listener socket %s:%s",
			     get_listener_name(listener), get_listener_name(listener), errno);
		return 0;
	}
	else if((maxconnections - 10) < fd)
	{
		report_error("no more connections left for listener %s:%s",
			     get_listener_name(listener), get_listener_name(listener), errno);
		comm_close(fd);
		return 0;
	}
	/*
	 * XXX - we don't want to do all this crap for a listener
	 * set_sock_opts(listener);
	 */
	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)))
	{
		report_error("setting SO_REUSEADDR for listener %s:%s",
			     get_listener_name(listener), get_listener_name(listener), errno);
		comm_close(fd);
		return 0;
	}

	/*
	 * Bind a port to listen for new connections if port is non-null,
	 * else assume it is already open and try get something from it.
	 */

	if(bind(fd, (struct sockaddr *) &listener->addr, GET_SS_LEN(listener->addr)))
	{
		report_error("binding listener socket %s:%s",
			     get_listener_name(listener), get_listener_name(listener), errno);
		comm_close(fd);
		return 0;
	}

	if(listen(fd, RATBOX_SOMAXCONN))
	{
		report_error("listen failed for %s:%s",
			     get_listener_name(listener), get_listener_name(listener), errno);
		comm_close(fd);
		return 0;
	}

	listener->fd = fd;

	/* Listen completion events are READ events .. */

	accept_connection(fd, listener);
	return 1;
}