diff --git a/include/client.h b/include/client.h index 943098e..b8ab1c1 100644 --- a/include/client.h +++ b/include/client.h @@ -233,7 +233,7 @@ struct LocalUser conf_item_t *att_conf; /* attached conf */ struct server_conf *att_sconf; - struct irc_sockaddr_storage ip; + struct rb_sockaddr_storage ip; time_t last_nick_change; int number_of_nick_changes; diff --git a/include/hostmask.h b/include/hostmask.h index 191cce5..1f92b8c 100644 --- a/include/hostmask.h +++ b/include/hostmask.h @@ -85,7 +85,7 @@ struct AddressRec struct { /* Pointer into ConfItem... -A1kmm */ - struct irc_sockaddr_storage addr; + struct rb_sockaddr_storage addr; int bits; } ipa; diff --git a/include/ircd_defs.h b/include/ircd_defs.h index 7105a99..bb49fa0 100644 --- a/include/ircd_defs.h +++ b/include/ircd_defs.h @@ -154,9 +154,9 @@ #ifdef IPV6 -#define irc_sockaddr_storage sockaddr_storage +#define rb_sockaddr_storage sockaddr_storage #else -#define irc_sockaddr_storage sockaddr +#define rb_sockaddr_storage sockaddr #define ss_family sa_family #ifdef SOCKADDR_IN_HAS_LEN #define ss_len sa_len diff --git a/include/listener.h b/include/listener.h index 9bab533..bc03d08 100644 --- a/include/listener.h +++ b/include/listener.h @@ -27,28 +27,25 @@ #ifndef INCLUDED_listener_h #define INCLUDED_listener_h -#include "ircd_defs.h" - -struct Client; - -struct Listener -{ - struct Listener *next; /* list node pointer */ - const char *name; /* listener name */ - int fd; /* file descriptor */ - int ref_count; /* number of connection references */ - int active; /* current state of listener */ - int index; /* index into poll array */ - struct irc_sockaddr_storage addr; - struct DNSQuery *dns_query; - char vhost[HOSTLEN + 1]; /* virtual name of listener */ -}; - -extern void add_listener(int port, const char *vaddr_ip, int family); -extern void close_listener(struct Listener *listener); -extern void close_listeners(void); -extern const char *get_listener_name(const struct Listener *listener); -extern void show_ports(struct Client *client); -extern void free_listener(struct Listener *); +struct Client; + +struct Listener +{ + rb_dlink_node node; + const char *name; /* listener name */ + rb_fde_t *F; /* file descriptor */ + int ref_count; /* number of connection references */ + int active; /* current state of listener */ + int ssl; /* ssl listener */ + struct rb_sockaddr_storage addr; + char vhost[HOSTLEN + 1]; /* virtual name of listener */ +}; + +void add_listener(int port, const char *vaddr_ip, int family, int ssl); +void close_listener(struct Listener *listener); +void close_listeners(void); +const char *get_listener_name(struct Listener *listener); +void show_ports(struct Client *client); +void free_listener(struct Listener *); #endif /* INCLUDED_listener_h */ diff --git a/include/res.h b/include/res.h index 7633897..2e7f662 100644 --- a/include/res.h +++ b/include/res.h @@ -23,7 +23,7 @@ struct DNSReply { char *h_name; - struct irc_sockaddr_storage addr; + struct rb_sockaddr_storage addr; }; struct DNSQuery @@ -32,14 +32,14 @@ struct DNSQuery void (*callback)(void* vptr, struct DNSReply *reply); /* callback to call */ }; -extern struct irc_sockaddr_storage irc_nsaddr_list[]; +extern struct rb_sockaddr_storage irc_nsaddr_list[]; extern int irc_nscount; extern void init_resolver(void); extern void restart_resolver(void); extern void delete_resolver_queries(const struct DNSQuery *); extern void gethost_byname_type(const char *, struct DNSQuery *, int); -extern void gethost_byaddr(const struct irc_sockaddr_storage *, struct DNSQuery *); +extern void gethost_byaddr(const struct rb_sockaddr_storage *, struct DNSQuery *); extern void add_local_domain(char *, size_t); extern void report_dns_servers(struct Client *); diff --git a/include/s_conf.h b/include/s_conf.h index 584fab5..c44d1ff 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -46,7 +46,7 @@ struct hostent; struct ip_value { - struct irc_sockaddr_storage ip; + struct rb_sockaddr_storage ip; int ip_mask; int type; }; diff --git a/include/s_newconf.h b/include/s_newconf.h index bd3282c..3567098 100644 --- a/include/s_newconf.h +++ b/include/s_newconf.h @@ -203,7 +203,7 @@ struct server_conf time_t hold; int aftype; - struct irc_sockaddr_storage my_ipnum; + struct rb_sockaddr_storage my_ipnum; char *class_name; struct Class *class; diff --git a/modules/m_dline.c b/modules/m_dline.c index 1cf22a0..32cc408 100644 --- a/modules/m_dline.c +++ b/modules/m_dline.c @@ -76,7 +76,7 @@ mo_dline(struct Client *client_p, struct Client *source_p, const char *dlhost; char *oper_reason; char *reason = def; - struct irc_sockaddr_storage daddr; + struct rb_sockaddr_storage daddr; char cidr_form_host[HOSTLEN + 1]; struct ConfItem *aconf; int bits; diff --git a/modules/m_gline.c b/modules/m_gline.c index 5e8db9d..8301c87 100644 --- a/modules/m_gline.c +++ b/modules/m_gline.c @@ -695,7 +695,7 @@ remove_temp_gline(const char *user, const char *host) { struct ConfItem *aconf; rb_dlink_node *ptr; - struct irc_sockaddr_storage addr, caddr; + struct rb_sockaddr_storage addr, caddr; int bits, cbits; int mtype, gtype; diff --git a/modules/m_kline.c b/modules/m_kline.c index faa6ad7..29fba0d 100644 --- a/modules/m_kline.c +++ b/modules/m_kline.c @@ -691,7 +691,7 @@ static int already_placed_kline(struct Client *source_p, const char *luser, const char *lhost, int tkline) { const char *reason, *p; - struct irc_sockaddr_storage iphost, *piphost; + struct rb_sockaddr_storage iphost, *piphost; struct ConfItem *aconf; int t, bits; diff --git a/modules/m_testline.c b/modules/m_testline.c index 53e698b..a261d41 100644 --- a/modules/m_testline.c +++ b/modules/m_testline.c @@ -61,7 +61,7 @@ mo_testline(struct Client *client_p, struct Client *source_p, int parc, const ch { struct ConfItem *aconf; struct ConfItem *resv_p; - struct irc_sockaddr_storage ip; + struct rb_sockaddr_storage ip; char user_trunc[USERLEN + 1], notildeuser_trunc[USERLEN + 1]; const char *name = NULL; const char *username = NULL; diff --git a/src/hostmask.c b/src/hostmask.c index d00aeb7..273f116 100644 --- a/src/hostmask.c +++ b/src/hostmask.c @@ -39,7 +39,7 @@ static unsigned long hash_ipv6(struct sockaddr *, int); static unsigned long hash_ipv4(struct sockaddr *, int); -/* int parse_netmask(const char *, struct irc_sockaddr_storage *, int *); +/* int parse_netmask(const char *, struct rb_sockaddr_storage *, int *); * Input: A hostmask, or an IPV4/6 address. * Output: An integer describing whether it is an IPV4, IPV6 address or a * hostmask, an address(if it is an IP mask), @@ -51,7 +51,7 @@ parse_netmask(const char *text, struct sockaddr *naddr, int *nb) { char *ip = LOCAL_COPY(text); char *ptr; - struct irc_sockaddr_storage *addr, xaddr; + struct rb_sockaddr_storage *addr, xaddr; int *b, xb; if(nb == NULL) b = &xb; @@ -59,9 +59,9 @@ parse_netmask(const char *text, struct sockaddr *naddr, int *nb) b = nb; if(naddr == NULL) - addr = (struct irc_sockaddr_storage *)&xaddr; + addr = (struct rb_sockaddr_storage *)&xaddr; else - addr = (struct irc_sockaddr_storage *)naddr; + addr = (struct rb_sockaddr_storage *)naddr; #ifdef IPV6 if(strchr(ip, ':')) @@ -109,7 +109,7 @@ init_host_hash(void) memset(&atable, 0, sizeof(atable)); } -/* unsigned long hash_ipv4(struct irc_sockaddr_storage*) +/* unsigned long hash_ipv4(struct rb_sockaddr_storage*) * Input: An IP address. * Output: A hash value of the IP address. * Side effects: None @@ -128,7 +128,7 @@ hash_ipv4(struct sockaddr *saddr, int bits) return 0; } -/* unsigned long hash_ipv6(struct irc_sockaddr_storage*) +/* unsigned long hash_ipv6(struct rb_sockaddr_storage*) * Input: An IP address. * Output: A hash value of the IP address. * Side effects: None @@ -196,7 +196,7 @@ get_mask_hash(const char *text) return hash_text(text); } -/* struct ConfItem* find_conf_by_address(const char*, struct irc_sockaddr_storage*, +/* struct ConfItem* find_conf_by_address(const char*, struct rb_sockaddr_storage*, * int type, int fam, const char *username) * Input: The hostname, the address, the type of mask to find, the address * family, the username. @@ -343,7 +343,7 @@ find_conf_by_address(const char *name, const char *sockhost, } /* struct ConfItem* find_address_conf(const char*, const char*, - * struct irc_sockaddr_storage*, int); + * struct rb_sockaddr_storage*, int); * Input: The hostname, username, address, address family. * Output: The applicable ConfItem. * Side-effects: None @@ -416,7 +416,7 @@ find_address_conf(const char *host, const char *sockhost, const char *user, return iconf; } -/* struct ConfItem* find_dline(struct irc_sockaddr_storage*, int) +/* struct ConfItem* find_dline(struct rb_sockaddr_storage*, int) * Input: An address, an address family. * Output: The best matching D-line or exempt line. * Side effects: None. @@ -442,7 +442,7 @@ find_exact_conf_by_address(const char *address, int type, const char *username) int masktype, bits; unsigned long hv; struct AddressRec *arec; - struct irc_sockaddr_storage addr; + struct rb_sockaddr_storage addr; if(address == NULL) address = "/NOMATCH!/"; @@ -548,7 +548,7 @@ delete_one_address_conf(const char *address, struct ConfItem *aconf) int masktype, bits; unsigned long hv; struct AddressRec *arec, *arecl = NULL; - struct irc_sockaddr_storage addr; + struct rb_sockaddr_storage addr; masktype = parse_netmask(address, (struct sockaddr *)&addr, &bits); #ifdef IPV6 if(masktype == HM_IPV6) diff --git a/src/irc_string.c b/src/irc_string.c index a32c1cc..f5f1187 100644 --- a/src/irc_string.c +++ b/src/irc_string.c @@ -539,7 +539,7 @@ inetpton_sock(const char *src, struct sockaddr *dst) { ((struct sockaddr_in *) dst)->sin_port = 0; ((struct sockaddr_in *) dst)->sin_family = AF_INET; - SET_SS_LEN((struct irc_sockaddr_storage *) dst, sizeof(struct sockaddr_in)); + SET_SS_LEN((struct rb_sockaddr_storage *) dst, sizeof(struct sockaddr_in)); return 1; } #ifdef IPV6 @@ -547,7 +547,7 @@ inetpton_sock(const char *src, struct sockaddr *dst) { ((struct sockaddr_in6 *) dst)->sin6_port = 0; ((struct sockaddr_in6 *) dst)->sin6_family = AF_INET6; - SET_SS_LEN((struct irc_sockaddr_storage *) dst, sizeof(struct sockaddr_in6)); + SET_SS_LEN((struct rb_sockaddr_storage *) dst, sizeof(struct sockaddr_in6)); return 1; } #endif diff --git a/src/listener.c b/src/listener.c index e8647cf..9b7d939 100644 --- a/src/listener.c +++ b/src/listener.c @@ -1,582 +1,557 @@ -/* - * ircd-ratbox: A slightly useful ircd. - * listener.c: Listens on a port. - * - * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center - * Copyright (C) 1996-2002 Hybrid Development Team - * Copyright (C) 2002-2005 ircd-ratbox development team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - * - * $Id: listener.c 3460 2007-05-18 20:31:33Z jilles $ - */ - -#include "stdinc.h" -#include "setup.h" -#include "listener.h" -#include "client.h" -#include "irc_string.h" -#include "sprintf_irc.h" -#include "ircd.h" -#include "ircd_defs.h" -#include "numeric.h" -#include "s_conf.h" -#include "s_newconf.h" -#include "s_stats.h" -#include "send.h" -#include "s_auth.h" -#include "reject.h" -#include "s_conf.h" -#include "hostmask.h" - -#ifndef INADDR_NONE -#define INADDR_NONE ((unsigned int) 0xffffffff) -#endif - -#if defined(NO_IN6ADDR_ANY) && defined(IPV6) -static const struct in6_addr in6addr_any = -{ { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }; -#endif - -static PF accept_connection; - -static listener_t *ListenerPollList = NULL; - -static listener_t * -make_listener(struct irc_sockaddr_storage *addr) -{ - listener_t *listener = (listener_t *) rb_malloc(sizeof(listener_t)); - s_assert(0 != listener); - - listener->name = me.name; - listener->fd = -1; - memcpy(&listener->addr, addr, sizeof(struct irc_sockaddr_storage)); - listener->next = NULL; - return listener; -} - -void -free_listener(listener_t *listener) -{ - s_assert(NULL != listener); - if(listener == NULL) - return; - /* - * remove from listener list - */ - if(listener == ListenerPollList) - ListenerPollList = listener->next; - else - { - listener_t *prev = ListenerPollList; - for (; prev; prev = prev->next) - { - if(listener == prev->next) - { - prev->next = listener->next; - break; - } - } - } - - /* free */ - rb_free(listener); -} - -#define PORTNAMELEN 6 /* ":31337" */ - -/* - * get_listener_name - return displayable listener name and port - * returns "host.foo.org:6667" for a given listener - */ -const char * -get_listener_name(const listener_t *listener) -{ - static char buf[HOSTLEN + HOSTLEN + PORTNAMELEN + 4]; - int port = 0; - - s_assert(NULL != listener); - if(listener == NULL) - return NULL; - -#ifdef IPV6 - if(listener->addr.ss_family == AF_INET6) - port = ntohs(((const struct sockaddr_in6 *)&listener->addr)->sin6_port); - else -#endif - port = ntohs(((const struct sockaddr_in *)&listener->addr)->sin_port); - - rb_snprintf(buf, sizeof(buf), "%s[%s/%u]", me.name, listener->name, port); - return buf; -} - -/* - * show_ports - send port listing to a client - * inputs - pointer to client to show ports to - * output - none - * side effects - show ports - */ -void -show_ports(struct Client *source_p) -{ - listener_t *listener = 0; - - for (listener = ListenerPollList; listener; listener = listener->next) - { - sendto_one_numeric(source_p, RPL_STATSPLINE, - form_str(RPL_STATSPLINE), 'P', -#ifdef IPV6 - ntohs(listener->addr.ss_family == AF_INET ? ((struct sockaddr_in *)&listener->addr)->sin_port : - ((struct sockaddr_in6 *)&listener->addr)->sin6_port), -#else - ntohs(((struct sockaddr_in *)&listener->addr)->sin_port), -#endif - IsOperAdmin(source_p) ? listener->name : me.name, - listener->ref_count, (listener->active) ? "active" : "disabled"); - } -} - -/* - * inetport - create a listener socket in the AF_INET or AF_INET6 domain, - * bind it to the port given in 'port' and listen to it - * returns true (1) if successful false (0) on error. - * - * If the operating system has a define for SOMAXCONN, use it, otherwise - * use RATBOX_SOMAXCONN - */ -#ifdef SOMAXCONN -#undef RATBOX_SOMAXCONN -#define RATBOX_SOMAXCONN SOMAXCONN -#endif - -static int -inetport(listener_t *listener) -{ - int fd; - int opt = 1; - - /* - * At first, open a new socket - */ - - fd = rb_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; - } - } - - /* - * At one point, we enforced a strange arbitrary limit here. - * We no longer do this, and just check if the fd is valid or not. - * -nenolod - */ - if(fd == -1) - { - report_error("opening listener socket %s:%s", - get_listener_name(listener), - get_listener_name(listener), errno); - 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); - rb_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); - rb_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); - rb_close(fd); - return 0; - } - - listener->fd = fd; - - /* Listen completion events are READ events .. */ - - accept_connection(fd, listener); - return 1; -} - -static listener_t * -find_listener(struct irc_sockaddr_storage *addr) -{ - listener_t *listener = NULL; - listener_t *last_closed = NULL; - - for (listener = ListenerPollList; listener; listener = listener->next) - { - if(addr->ss_family != listener->addr.ss_family) - continue; - - switch(addr->ss_family) - { - case AF_INET: - { - struct sockaddr_in *in4 = (struct sockaddr_in *)addr; - struct sockaddr_in *lin4 = (struct sockaddr_in *)&listener->addr; - if(in4->sin_addr.s_addr == lin4->sin_addr.s_addr && - in4->sin_port == lin4->sin_port ) - { - if(listener->fd == -1) - last_closed = listener; - else - return(listener); - } - break; - } -#ifdef IPV6 - case AF_INET6: - { - struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr; - struct sockaddr_in6 *lin6 =(struct sockaddr_in6 *)&listener->addr; - if(IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &lin6->sin6_addr) && - in6->sin6_port == lin6->sin6_port) - { - if(listener->fd == -1) - last_closed = listener; - else - return(listener); - } - break; - - } -#endif - - default: - break; - } - } - return last_closed; -} - - -/* - * 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) -{ - listener_t *listener; - struct irc_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(inetpton(family, vhost_ip, &((struct sockaddr_in *)&vaddr)->sin_addr) <= 0) - return; - } -#ifdef IPV6 - else - { - if(inetpton(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 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 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->fd > -1) - return; - } - else - { - listener = make_listener(&vaddr); - listener->next = ListenerPollList; - ListenerPollList = listener; - } - - listener->fd = -1; - - if(inetport(listener)) - listener->active = 1; - else - close_listener(listener); -} - -/* - * close_listener - close a single listener - */ -void -close_listener(listener_t *listener) -{ - s_assert(listener != NULL); - if(listener == NULL) - return; - if(listener->fd >= 0) - { - rb_close(listener->fd); - listener->fd = -1; - } - - listener->active = 0; - - if(listener->ref_count) - return; - - free_listener(listener); -} - -/* - * close_listeners - close and free all listeners that are not being used - */ -void -close_listeners() -{ - listener_t *listener; - listener_t *listener_next = 0; - /* - * close all 'extra' listening ports we have - */ - for (listener = ListenerPollList; listener; listener = listener_next) - { - listener_next = listener->next; - close_listener(listener); - } -} - -#define DLINE_WARNING "ERROR :You have been D-lined.\r\n" - -/* - * add_connection - creates a client which has just connected to us on - * the given fd. The sockhost field is initialized with the ip# of the host. - * The client is sent to the auth module for verification, and not put in - * any client list yet. - */ -static void -add_connection(listener_t *listener, int fd, struct sockaddr *sai, int exempt) -{ - struct Client *new_client; - s_assert(NULL != listener); - - /* - * get the client socket name from the socket - * the client has already been checked out in accept_connection - */ - new_client = make_client(NULL); - - memcpy(&new_client->localClient->ip, sai, sizeof(struct irc_sockaddr_storage)); - - /* - * copy address to 'sockhost' as a string, copy it to host too - * so we have something valid to put into error messages... - */ - inetntop_sock((struct sockaddr *)&new_client->localClient->ip, new_client->sockhost, - sizeof(new_client->sockhost)); - - - strlcpy(new_client->host, new_client->sockhost, sizeof(new_client->host)); - - new_client->localClient->F = rb_add_fd(fd); - - new_client->localClient->listener = listener; - ++listener->ref_count; - - if(!exempt) - { - if(check_reject(new_client)) - return; - if(add_unknown_ip(new_client)) - return; - } - - start_auth(new_client); -} - - -static void -accept_connection(int pfd, void *data) -{ - static time_t last_oper_notice = 0; - struct irc_sockaddr_storage sai; - socklen_t addrlen = sizeof(sai); - int fd; - listener_t *listener = data; - struct ConfItem *aconf; - char buf[BUFSIZE]; - - s_assert(listener != NULL); - if(listener == NULL) - return; - /* - * There may be many reasons for error return, but - * in otherwise correctly working environment the - * probable cause is running out of file descriptors - * (EMFILE, ENFILE or others?). The man pages for - * accept don't seem to list these as possible, - * although it's obvious that it may happen here. - * Thus no specific errors are tested at this - * point, just assume that connections cannot - * be accepted until some old is closed first. - */ - - fd = rb_accept(listener->fd, (struct sockaddr *)&sai, &addrlen); - if(fd < 0) - { - /* Re-register a new IO request for the next accept .. */ - rb_setselect(listener->fd, FDLIST_SERVICE, - COMM_SELECT_READ, accept_connection, listener, 0); - return; - } - - /* This needs to be done here, otherwise we break dlines */ - mangle_mapped_sockaddr((struct sockaddr *)&sai); - - /* - * check for connection limit - * TBD: this is stupid... either we have a socket or we don't. -nenolod - */ - if((rb_get_maxconnections() - 10) < fd) - { - ++ServerStats->is_ref; - /* - * slow down the whining to opers bit - */ - if((last_oper_notice + 20) <= rb_current_time()) - { - sendto_realops_snomask(SNO_GENERAL, L_ALL, - "All connections in use. (%s)", - get_listener_name(listener)); - last_oper_notice = rb_current_time(); - } - - write(fd, "ERROR :All connections in use\r\n", 32); - rb_close(fd); - /* Re-register a new IO request for the next accept .. */ - rb_setselect(listener->fd, FDLIST_SERVICE, - COMM_SELECT_READ, accept_connection, listener, 0); - return; - } - - /* Do an initial check we aren't connecting too fast or with too many - * from this IP... */ - aconf = find_dline((struct sockaddr *) &sai, sai.ss_family); - /* check it wasn't an exempt */ - if (aconf != NULL && (aconf->status & CONF_EXEMPTDLINE) == 0) - { - ServerStats->is_ref++; - - if(ConfigFileEntry.dline_with_reason) - { - if (rb_snprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", aconf->passwd) >= (sizeof(buf)-1)) - { - buf[sizeof(buf) - 3] = '\r'; - buf[sizeof(buf) - 2] = '\n'; - buf[sizeof(buf) - 1] = '\0'; - } - } - else - rb_sprintf(buf, "ERROR :You have been D-lined.\r\n"); - - write(fd, buf, strlen(buf)); - rb_close(fd); - - /* Re-register a new IO request for the next accept .. */ - rb_setselect(listener->fd, FDLIST_SERVICE, - COMM_SELECT_READ, accept_connection, listener, 0); - return; - } - - ServerStats->is_ac++; - add_connection(listener, fd, (struct sockaddr *)&sai, aconf ? 1 : 0); - - /* Re-register a new IO request for the next accept .. */ - rb_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ, - accept_connection, listener, 0); -} +/* + * ircd-ratbox: A slightly useful ircd. + * listener.c: Listens on a port. + * + * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center + * Copyright (C) 1996-2002 Hybrid Development Team + * Copyright (C) 2002-2005 ircd-ratbox development team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * $Id: listener.c 25169 2008-03-29 21:41:31Z jilles $ + */ + +#include "stdinc.h" +#include "struct.h" +#include "ratbox_lib.h" +#include "listener.h" +#include "client.h" +#include "match.h" +#include "ircd.h" +#include "numeric.h" +#include "s_conf.h" +#include "s_newconf.h" +#include "s_stats.h" +#include "send.h" +#include "s_auth.h" +#include "reject.h" +#include "s_log.h" +#include "sslproc.h" +#include "hash.h" + +static rb_dlink_list listener_list; +static int accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, void *data); +static void accept_callback(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t addrlen, void *data); + + + +static struct Listener * +make_listener(struct rb_sockaddr_storage *addr) +{ + struct Listener *listener = rb_malloc(sizeof(struct Listener)); + s_assert(0 != listener); + listener->name = ServerInfo.name; /* me.name may not be valid yet -- jilles */ + listener->F = NULL; + memcpy(&listener->addr, addr, sizeof(struct rb_sockaddr_storage)); + return listener; +} + +void +free_listener(struct Listener *listener) +{ + s_assert(NULL != listener); + if(listener == NULL) + return; + + rb_dlinkDelete(&listener->node, &listener_list); + rb_free(listener); +} + +#define PORTNAMELEN 6 /* ":31337" */ + +/* + * get_listener_name - return displayable listener name and port + * returns "host.foo.org:6667" for a given listener + */ +const char * +get_listener_name(struct Listener *listener) +{ + static char buf[HOSTLEN + HOSTLEN + PORTNAMELEN + 4]; + int port = 0; + + s_assert(NULL != listener); + if(listener == NULL) + return NULL; + +#ifdef IPV6 + if(GET_SS_FAMILY(&listener->addr) == AF_INET6) + port = ntohs(((const struct sockaddr_in6 *)&listener->addr)->sin6_port); + else +#endif + port = ntohs(((const struct sockaddr_in *)&listener->addr)->sin_port); + + rb_snprintf(buf, sizeof(buf), "%s[%s/%u]", me.name, listener->name, port); + return buf; +} + +/* + * show_ports - send port listing to a client + * inputs - pointer to client to show ports to + * output - none + * side effects - show ports + */ +void +show_ports(struct Client *source_p) +{ + struct Listener *listener; + rb_dlink_node *ptr; + + RB_DLINK_FOREACH(ptr, listener_list.head) + { + listener = ptr->data; + sendto_one_numeric(source_p, RPL_STATSPLINE, + form_str(RPL_STATSPLINE), 'P', +#ifdef IPV6 + ntohs(GET_SS_FAMILY(&listener->addr) == AF_INET ? ((struct sockaddr_in *)&listener->addr)->sin_port : + ((struct sockaddr_in6 *)&listener->addr)->sin6_port), +#else + ntohs(((struct sockaddr_in *)&listener->addr)->sin_port), +#endif + IsOperAdmin(source_p) ? listener->name : me.name, + listener->ref_count, (listener->active) ? "active" : "disabled", + listener->ssl ? " ssl" : ""); + } +} + +/* + * inetport - create a listener socket in the AF_INET or AF_INET6 domain, + * bind it to the port given in 'port' and listen to it + * returns true (1) if successful false (0) on error. + * + * If the operating system has a define for SOMAXCONN, use it, otherwise + * use RATBOX_SOMAXCONN + */ +#ifdef SOMAXCONN +#undef RATBOX_SOMAXCONN +#define RATBOX_SOMAXCONN SOMAXCONN +#endif + +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 IPV6 + if(GET_SS_FAMILY(&listener->addr) == 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) + { + report_error("opening listener socket %s:%s", + get_listener_name(listener), + get_listener_name(listener), errno); + return 0; + } + else if((maxconnections - 10) < rb_get_fd(F)) /* XXX this is kinda bogus*/ + { + report_error("no more connections left for listener %s:%s", + get_listener_name(listener), + get_listener_name(listener), errno); + 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))) + { + report_error("setting SO_REUSEADDR for listener %s:%s", + get_listener_name(listener), + get_listener_name(listener), errno); + 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))) + { + report_error("binding listener socket %s:%s", + get_listener_name(listener), + get_listener_name(listener), errno); + rb_close(F); + return 0; + } + + if((ret = rb_listen(F, RATBOX_SOMAXCONN))) + { + report_error("listen failed for %s:%s", + get_listener_name(listener), + get_listener_name(listener), errno); + rb_close(F); + return 0; + } + + listener->F = F; + + rb_accept_tcp(listener->F, accept_precallback, accept_callback, listener); + return 1; +} + +static struct Listener * +find_listener(struct rb_sockaddr_storage *addr) +{ + struct Listener *listener = NULL; + struct Listener *last_closed = NULL; + rb_dlink_node *ptr; + + RB_DLINK_FOREACH(ptr, listener_list.head) + { + listener = ptr->data; + if(GET_SS_FAMILY(addr) != GET_SS_FAMILY(&listener->addr)) + continue; + + switch(GET_SS_FAMILY(addr)) + { + case AF_INET: + { + struct sockaddr_in *in4 = (struct sockaddr_in *)addr; + struct sockaddr_in *lin4 = (struct sockaddr_in *)&listener->addr; + if(in4->sin_addr.s_addr == lin4->sin_addr.s_addr && + in4->sin_port == lin4->sin_port ) + { + if(listener->F == NULL) + last_closed = listener; + else + return(listener); + } + break; + } +#ifdef IPV6 + case AF_INET6: + { + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr; + struct sockaddr_in6 *lin6 =(struct sockaddr_in6 *)&listener->addr; + if(IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &lin6->sin6_addr) && + in6->sin6_port == lin6->sin6_port) + { + if(listener->F == NULL) + last_closed = listener; + else + return(listener); + } + break; + + } +#endif + + default: + break; + } + } + return last_closed; +} + +/* + * 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)); + GET_SS_FAMILY(&vaddr) = family; + + if(vhost_ip != NULL) + { + if(rb_inet_pton_sock(vhost_ip, (struct sockaddr *)&vaddr) <= 0) + return; + } else + { + switch(family) + { + case AF_INET: + ((struct sockaddr_in *)&vaddr)->sin_addr.s_addr = INADDR_ANY; + break; +#ifdef IPV6 + case AF_INET6: + memcpy(&((struct sockaddr_in6 *)&vaddr)->sin6_addr, &in6addr_any, sizeof(struct in6_addr)); + break; +#endif + default: + return; + } + } + switch(family) + { + case AF_INET: + SET_SS_LEN(&vaddr, sizeof(struct sockaddr_in)); + ((struct sockaddr_in *)&vaddr)->sin_port = htons(port); + break; +#ifdef 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); + rb_dlinkAdd(listener, &listener->node, &listener_list); + } + + listener->F = NULL; + listener->ssl = ssl; + if(inetport(listener)) + listener->active = 1; + else + close_listener(listener); +} + +/* + * close_listener - close a single listener + */ +void +close_listener(struct Listener *listener) +{ + s_assert(listener != NULL); + if(listener == NULL) + return; + if(listener->F != NULL) + { + rb_close(listener->F); + listener->F = NULL; + } + + listener->active = 0; + + if(listener->ref_count) + return; + + free_listener(listener); +} + +/* + * close_listeners - close and free all listeners that are not being used + */ +void +close_listeners() +{ + struct Listener *listener; + rb_dlink_node *ptr, *next; + + RB_DLINK_FOREACH_SAFE(ptr, next, listener_list.head) + { + listener = ptr->data; + close_listener(listener); + } +} + +/* + * add_connection - creates a client which has just connected to us on + * the given fd. The sockhost field is initialized with the ip# of the host. + * The client is sent to the auth module for verification, and not put in + * any client list yet. + */ +static void +add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, struct sockaddr *lai, void *ssl_ctl) +{ + struct Client *new_client; + s_assert(NULL != listener); + /* + * get the client socket name from the socket + * the client has already been checked out in accept_connection + */ + new_client = make_client(NULL); + + memcpy(&new_client->localClient->ip, sai, sizeof(struct rb_sockaddr_storage)); + new_client->localClient->lip = rb_malloc(sizeof(struct rb_sockaddr_storage)); + memcpy(new_client->localClient->lip, lai, sizeof(struct rb_sockaddr_storage)); + + /* + * copy address to 'sockhost' as a string, copy it to host too + * so we have something valid to put into error messages... + */ + rb_inet_ntop_sock((struct sockaddr *)&new_client->localClient->ip, new_client->sockhost, + sizeof(new_client->sockhost)); + + + rb_strlcpy(new_client->host, new_client->sockhost, sizeof(new_client->host)); + +#ifdef IPV6 + if(GET_SS_FAMILY(&new_client->localClient->ip) == AF_INET6 && ConfigFileEntry.dot_in_ip6_addr == 1) + { + rb_strlcat(new_client->host, ".", sizeof(new_client->host)); + } +#endif + + new_client->localClient->F = F; + add_to_cli_fd_hash(new_client); + new_client->localClient->listener = listener; + new_client->localClient->ssl_ctl = ssl_ctl; + if(ssl_ctl != NULL || rb_fd_ssl(F)) + SetSSL(new_client); + + ++listener->ref_count; + + start_auth(new_client); +} + +static time_t last_oper_notice = 0; + +static const char *toofast = "ERROR :Reconnecting too fast, throttled.\r\n"; + +static int +accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, void *data) +{ + struct Listener *listener = (struct Listener *)data; + char buf[BUFSIZE]; + struct ConfItem *aconf; + + if(listener->ssl && (!ssl_ok || !get_ssld_count())) + { + fprintf(stderr, "closed socket\n"); + rb_close(F); + return 0; + } + + if((maxconnections - 10) < rb_get_fd(F)) /* XXX this is kinda bogus */ + { + ++ServerStats.is_ref; + /* + * slow down the whining to opers bit + */ + if((last_oper_notice + 20) <= rb_current_time()) + { + sendto_realops_flags(UMODE_ALL, L_ALL, + "All connections in use. (%s)", + get_listener_name(listener)); + last_oper_notice = rb_current_time(); + } + + rb_write(F, "ERROR :All connections in use\r\n", 32); + rb_close(F); + /* Re-register a new IO request for the next accept .. */ + return 0; + } + + aconf = find_dline(addr); + if(aconf != NULL && (aconf->status & CONF_EXEMPTDLINE)) + return 1; + + /* Do an initial check we aren't connecting too fast or with too many + * from this IP... */ + if(aconf != NULL) + { + ServerStats.is_ref++; + + if(ConfigFileEntry.dline_with_reason) + { + if (rb_snprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", aconf->passwd) >= (int)(sizeof(buf)-1)) + { + buf[sizeof(buf) - 3] = '\r'; + buf[sizeof(buf) - 2] = '\n'; + buf[sizeof(buf) - 1] = '\0'; + } + } + else + strcpy(buf, "ERROR :You have been D-lined.\r\n"); + + rb_write(F, buf, strlen(buf)); + rb_close(F); + return 0; + } + + if(check_reject(F, addr)) + return 0; + + if(throttle_add(addr)) + { + rb_write(F, toofast, strlen(toofast)); + rb_close(F); + return 0; + } + + return 1; +} + +static void +accept_ssld(rb_fde_t *F, struct sockaddr *addr, struct sockaddr *laddr, struct Listener *listener) +{ + ssl_ctl_t *ctl; + rb_fde_t *xF[2]; + rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Incoming ssld Connection"); + ctl = start_ssld_accept(F, xF[1], rb_get_fd(xF[0])); /* this will close F for us */ + add_connection(listener, xF[0], addr, laddr, ctl); +} + +static void +accept_callback(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t addrlen, void *data) +{ + struct Listener *listener = data; + struct rb_sockaddr_storage lip; + unsigned int locallen = sizeof(struct rb_sockaddr_storage); + + ServerStats.is_ac++; + if(getsockname(rb_get_fd(F), (struct sockaddr *) &lip, &locallen) < 0) + { + /* this shouldn't fail so... */ + /* XXX add logging of this */ + rb_close(F); + } + if(listener->ssl) + accept_ssld(F, addr, (struct sockaddr *)&lip, listener); + else + add_connection(listener, F, addr, (struct sockaddr *)&lip, NULL); +} diff --git a/src/match.c b/src/match.c index 7a9ad94..12e4c01 100644 --- a/src/match.c +++ b/src/match.c @@ -326,7 +326,7 @@ int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, u_int mask */ int match_ips(const char *s1, const char *s2) { - struct irc_sockaddr_storage ipaddr, maskaddr; + struct rb_sockaddr_storage ipaddr, maskaddr; char mask[BUFSIZE]; char address[HOSTLEN + 1]; char *len; @@ -380,7 +380,7 @@ int match_ips(const char *s1, const char *s2) int match_cidr(const char *s1, const char *s2) { - struct irc_sockaddr_storage ipaddr, maskaddr; + struct rb_sockaddr_storage ipaddr, maskaddr; char mask[BUFSIZE]; char address[NICKLEN + USERLEN + HOSTLEN + 6]; char *ipmask; diff --git a/src/res.c b/src/res.c index f61485e..e84e7a5 100644 --- a/src/res.c +++ b/src/res.c @@ -79,7 +79,7 @@ struct reslist char resend; /* send flag. 0 == dont resend */ time_t sentat; time_t timeout; - struct irc_sockaddr_storage addr; + struct rb_sockaddr_storage addr; char *name; struct DNSQuery *query; /* query callback for this request */ }; @@ -90,7 +90,7 @@ static rb_dlink_list request_list = { NULL, NULL, 0 }; static void rem_request(struct reslist *request); static struct reslist *make_request(struct DNSQuery *query); static void do_query_name(struct DNSQuery *query, const char *name, struct reslist *request, int); -static void do_query_number(struct DNSQuery *query, const struct irc_sockaddr_storage *, +static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_storage *, struct reslist *request); static void query_name(struct reslist *request); static int send_res_msg(const char *buf, int len, int count); @@ -100,7 +100,7 @@ static int proc_answer(struct reslist *request, HEADER * header, char *, char *) static struct reslist *find_id(int id); static struct DNSReply *make_dnsreply(struct reslist *request); -extern struct irc_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS]; +extern struct rb_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS]; extern int irc_nscount; extern char irc_domain[HOSTLEN + 1]; @@ -116,7 +116,7 @@ extern char irc_domain[HOSTLEN + 1]; * paul vixie, 29may94 * revised for ircd, cryogen(stu) may03 */ -static int res_ourserver(const struct irc_sockaddr_storage *inp) +static int res_ourserver(const struct rb_sockaddr_storage *inp) { #ifdef IPV6 struct sockaddr_in6 *v6; @@ -128,7 +128,7 @@ static int res_ourserver(const struct irc_sockaddr_storage *inp) for (ns = 0; ns < irc_nscount; ns++) { - const struct irc_sockaddr_storage *srv = &irc_nsaddr_list[ns]; + const struct rb_sockaddr_storage *srv = &irc_nsaddr_list[ns]; #ifdef IPV6 v6 = (struct sockaddr_in6 *)srv; #endif @@ -392,7 +392,7 @@ void gethost_byname_type(const char *name, struct DNSQuery *query, int type) /* * gethost_byaddr - get host name from address */ -void gethost_byaddr(const struct irc_sockaddr_storage *addr, struct DNSQuery *query) +void gethost_byaddr(const struct rb_sockaddr_storage *addr, struct DNSQuery *query) { do_query_number(query, addr, NULL); } @@ -424,7 +424,7 @@ static void do_query_name(struct DNSQuery *query, const char *name, struct resli /* * do_query_number - Use this to do reverse IP# lookups. */ -static void do_query_number(struct DNSQuery *query, const struct irc_sockaddr_storage *addr, +static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_storage *addr, struct reslist *request) { const unsigned char *cp; @@ -432,7 +432,7 @@ static void do_query_number(struct DNSQuery *query, const struct irc_sockaddr_st if (request == NULL) { request = make_request(query); - memcpy(&request->addr, addr, sizeof(struct irc_sockaddr_storage)); + memcpy(&request->addr, addr, sizeof(struct rb_sockaddr_storage)); request->name = (char *)rb_malloc(HOSTLEN + 1); } @@ -734,8 +734,8 @@ static void res_readreply(int fd, void *data) struct DNSReply *reply = NULL; int rc; int answer_count; - socklen_t len = sizeof(struct irc_sockaddr_storage); - struct irc_sockaddr_storage lsin; + socklen_t len = sizeof(struct rb_sockaddr_storage); + struct rb_sockaddr_storage lsin; rc = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&lsin, &len); diff --git a/src/reslib.c b/src/reslib.c index d2b029c..4f2c570 100644 --- a/src/reslib.c +++ b/src/reslib.c @@ -96,7 +96,7 @@ /* $Id: reslib.c 1695 2006-06-27 15:11:23Z jilles $ */ /* from Hybrid Id: reslib.c 177 2005-10-22 09:05:05Z michael $ */ -struct irc_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS]; +struct rb_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS]; int irc_nscount = 0; char irc_domain[HOSTLEN + 1]; diff --git a/src/s_auth.c b/src/s_auth.c index d245470..53df4e6 100644 --- a/src/s_auth.c +++ b/src/s_auth.c @@ -265,8 +265,8 @@ auth_error(struct AuthRequest *auth) static int start_auth_query(struct AuthRequest *auth) { - struct irc_sockaddr_storage localaddr; - socklen_t locallen = sizeof(struct irc_sockaddr_storage); + struct rb_sockaddr_storage localaddr; + socklen_t locallen = sizeof(struct rb_sockaddr_storage); int fd; int family; diff --git a/src/s_newconf.c b/src/s_newconf.c index 222a32e..c73db3d 100644 --- a/src/s_newconf.c +++ b/src/s_newconf.c @@ -284,7 +284,7 @@ struct oper_conf * find_oper_conf(const char *username, const char *host, const char *locip, const char *name) { struct oper_conf *oper_p; - struct irc_sockaddr_storage ip, cip; + struct rb_sockaddr_storage ip, cip; char addr[HOSTLEN+1]; int bits, cbits; rb_dlink_node *ptr; diff --git a/src/s_serv.c b/src/s_serv.c index cd3a90f..5905d08 100644 --- a/src/s_serv.c +++ b/src/s_serv.c @@ -1469,7 +1469,7 @@ int serv_connect(struct server_conf *server_p, struct Client *by) { struct Client *client_p; - struct irc_sockaddr_storage myipnum; + struct rb_sockaddr_storage myipnum; int fd; char vhoststr[HOSTIPLEN];