Beispiel #1
0
/* add_nameserver()
 *
 * input        - either an IPV4 address in dotted quad
 *                or an IPV6 address in : format
 * output       - NONE
 * side effects - entry in irc_nsaddr_list is filled in as needed
 */
static void
add_nameserver(const char *arg)
{
    struct addrinfo hints, *res;

    /* Done max number of nameservers? */
    if (irc_nscount >= IRCD_MAXNS) {
        ilog (L_MAIN, "Too many nameservers, ignoring %s", arg);
        return;
    }

    ilog (L_MAIN, "Using nameserver: %s", arg);

    memset(&hints, 0, sizeof(hints));
    hints.ai_family   = PF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;

    if (getaddrinfo(arg, "domain", &hints, &res))
        return;

    if (res == NULL)
        return;

    memcpy(&irc_nsaddr_list[irc_nscount], res->ai_addr, res->ai_addrlen);
    SET_SS_LEN(&irc_nsaddr_list[irc_nscount], res->ai_addrlen);
    irc_nscount++;
    freeaddrinfo(res);
}
Beispiel #2
0
/*
 * add_listener- create a new listener
 * port - the port number to listen on
 * vhost_ip - if non-null must contain a valid IP address string in
 * the format "255.255.255.255"
 */
void
add_listener(int port, const char *vhost_ip, int family, int ssl)
{
	struct Listener *listener;
	struct rb_sockaddr_storage vaddr;

	/*
	 * if no port in conf line, don't bother
	 */
	if(port == 0)
		return;
	memset(&vaddr, 0, sizeof(vaddr));
	vaddr.ss_family = family;

	if(vhost_ip != NULL)
	{
		if(family == AF_INET)
		{
			if(rb_inet_pton(family, vhost_ip, &((struct sockaddr_in *)&vaddr)->sin_addr) <= 0)
				return;
		} 
#ifdef RB_IPV6
		else
		{
			if(rb_inet_pton(family, vhost_ip, &((struct sockaddr_in6 *)&vaddr)->sin6_addr) <= 0)
				return;
		
		}
#endif
	} else
	{
		switch(family)
		{
			case AF_INET:
				((struct sockaddr_in *)&vaddr)->sin_addr.s_addr = INADDR_ANY;
				break;
#ifdef RB_IPV6
			case AF_INET6:
				memcpy(&((struct sockaddr_in6 *)&vaddr)->sin6_addr, &in6addr_any, sizeof(struct in6_addr));
				break;
			default:
				return;
#endif
		} 
	}
	switch(family)
	{
		case AF_INET:
			SET_SS_LEN(&vaddr, sizeof(struct sockaddr_in));
			((struct sockaddr_in *)&vaddr)->sin_port = htons(port);
			break;
#ifdef RB_IPV6
		case AF_INET6:
			SET_SS_LEN(&vaddr, sizeof(struct sockaddr_in6));
			((struct sockaddr_in6 *)&vaddr)->sin6_port = htons(port);
			break;
#endif
		default:
			break;
	}
	if((listener = find_listener(&vaddr)))
	{
		if(listener->F != NULL)
			return;
	}
	else
	{
		listener = make_listener(&vaddr);
		listener->next = ListenerPollList;
		ListenerPollList = listener;
	}

	listener->F = NULL;
	listener->ssl = ssl;

	if(inetport(listener))
		listener->active = 1;
	else
		close_listener(listener);
}
Beispiel #3
0
/*
 * void comm_connect_tcp(int fd, const char *host, u_short port,
 *                       struct sockaddr *clocal, int socklen,
 *                       CNCB *callback, void *data, int aftype, int timeout)
 * Input: An fd to connect with, a host and port to connect to,
 *        a local sockaddr to connect from + length(or NULL to use the
 *        default), a callback, the data to pass into the callback, the
 *        address family.
 * Output: None.
 * Side-effects: A non-blocking connection to the host is started, and
 *               if necessary, set up for selection. The callback given
 *               may be called now, or it may be called later.
 */
void
comm_connect_tcp(int fd, const char *host, u_short port,
		 struct sockaddr *clocal, int socklen, CNCB * callback,
		 void *data, int aftype, int timeout)
{
	void *ipptr = NULL;
	fde_t *F;
	s_assert(fd >= 0);
	F = &fd_table[fd];
	F->flags.called_connect = 1;
	s_assert(callback);
	F->connect.callback = callback;
	F->connect.data = data;

	memset(&F->connect.hostaddr, 0, sizeof(F->connect.hostaddr));
#ifdef IPV6
	if(aftype == AF_INET6)
	{
		struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&F->connect.hostaddr;
		SET_SS_LEN(F->connect.hostaddr, sizeof(struct sockaddr_in6));
		in6->sin6_port = htons(port);
		in6->sin6_family = AF_INET6;
		ipptr = &in6->sin6_addr;
	} else
#endif
	{
		struct sockaddr_in *in = (struct sockaddr_in *)&F->connect.hostaddr;
		SET_SS_LEN(F->connect.hostaddr, sizeof(struct sockaddr_in));
		in->sin_port = htons(port);
		in->sin_family = AF_INET;
		ipptr = &in->sin_addr;
	}

	/* Note that we're using a passed sockaddr here. This is because
	 * generally you'll be bind()ing to a sockaddr grabbed from
	 * getsockname(), so this makes things easier.
	 * XXX If NULL is passed as local, we should later on bind() to the
	 * virtual host IP, for completeness.
	 *   -- adrian
	 */
	if((clocal != NULL) && (bind(F->fd, clocal, socklen) < 0))
	{
		/* Failure, call the callback with COMM_ERR_BIND */
		comm_connect_callback(F->fd, COMM_ERR_BIND);
		/* ... and quit */
		return;
	}

	/* Next, if we have been given an IP, get the addr and skip the
	 * DNS check (and head direct to comm_connect_tryconnect().
	 */
	if(inetpton(aftype, host, ipptr) <= 0)
	{
		/* Send the DNS request, for the next level */
		F->dns_query = MyMalloc(sizeof(struct DNSQuery));
		F->dns_query->ptr = F;
		F->dns_query->callback = comm_connect_dns_callback;
		adns_gethost(host, aftype, F->dns_query);
	}
	else
	{
		/* We have a valid IP, so we just call tryconnect */
		/* Make sure we actually set the timeout here .. */
		comm_settimeout(F->fd, timeout * 1000, comm_connect_timeout, NULL);
		comm_connect_tryconnect(F->fd, NULL);
	}
}