IPv6 support (hopefully with fewer future transition pains)
authorMichael Poole <mdpoole@troilus.org>
Thu, 19 Aug 2004 04:00:54 +0000 (04:00 +0000)
committerMichael Poole <mdpoole@troilus.org>
Thu, 19 Aug 2004 04:00:54 +0000 (04:00 +0000)
git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1094 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

58 files changed:
ChangeLog
config.h.in
configure
configure.in
include/IPcheck.h
include/client.h
include/gline.h
include/ircd_addrinfo.h [deleted file]
include/ircd_chattr.h
include/ircd_osdep.h
include/ircd_string.h
include/listener.h
include/match.h
include/numnicks.h
include/res.h
include/s_bsd.h
include/s_conf.h
include/s_debug.h
include/uping.h
ircd/IPcheck.c
ircd/Makefile.in
ircd/channel.c
ircd/gline.c
ircd/ircd.c
ircd/ircd_auth.c
ircd/ircd_getaddrinfo.c [deleted file]
ircd/ircd_getnameinfo.c [deleted file]
ircd/ircd_lexer.l
ircd/ircd_parser.y
ircd/ircd_res.c
ircd/ircd_reslib.c
ircd/ircd_string.c
ircd/listener.c
ircd/m_connect.c
ircd/m_nick.c
ircd/m_oper.c
ircd/m_userip.c
ircd/m_who.c
ircd/m_whois.c
ircd/match.c
ircd/numnicks.c
ircd/os_bsd.c [deleted file]
ircd/os_generic.c
ircd/os_linux.c [deleted file]
ircd/os_openbsd.c [deleted file]
ircd/os_solaris.c [deleted file]
ircd/res_adns.c [deleted file]
ircd/res_libresolv.c [deleted file]
ircd/s_auth.c
ircd/s_bsd.c
ircd/s_conf.c
ircd/s_misc.c
ircd/s_serv.c
ircd/s_stats.c
ircd/s_user.c
ircd/table_gen.c
ircd/uping.c
ircd/whocmds.c

index b9616279541f50174e4b080ce742275de956eb3e..39ffb29c6b84fb59c492bbe5a45921f1f11a1f5c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,76 @@
+2004-08-17  Michael Poole <mdpoole@troilus.org>
+
+       IPv6 support, with lots of code and design borrowed from a patch
+       by Alex Badea.
+
+       * config.h.in: Add place to #define IPV6 support.
+
+       * configure.in: Check for struct sockaddr_in6, and use that as
+       the default choice for IPv6 support.
+
+       * configure: Regenerate.
+
+       * include/IPcheck.h, include/client.h, include/gline.h,
+       include/ircd_string.h, include/listener.h, include/match.h,
+       include/res.h, include/s_bsd.h: Convert from struct in_addr (from
+       <netinet/in.h>) to struct irc_in_addr (from "res.h").
+
+       * include/ircd_osdep.h, include/s_conf.h, include/uping.h: Convert
+       from struct sockaddr_in (from <netinet/in.h>) to struct
+       irc_sockaddr (from "res.h").  Add new functions os_socket(),
+       os_accept(), os_sendto_nonb() to help abstract away actual
+       sockaddr types.
+
+       * include/ircd_chattr.h, ircd/table_gen.c: Define new bit to mark
+       characters valid in IPv6 addresses.
+
+       * include/numnicks.h, ircd/numnicks.c: New functions iptobase64()
+       and base64toip() to convert from base64 to struct irc_in_addr.
+
+       * ircd/IPcheck.c, ircd/channel.c, ircd/m_nick.c, ircd/m_oper.c,
+       ircd/m_userip.c, ircd/m_who.c, ircd/m_whois.c, ircd/s_misc.c,
+       ircd/s_serv.c, ircd/s_user.c, ircd/whocmds.c: Use struct
+       irc_in_addr instead of unsigned int or struct in_addr.
+
+       * ircd/gline.c: Use new more-generic ipmask functions.
+
+       * ircd/ircd.c: Use struct irc_sockaddr instead of separate port
+       fields.
+
+       * ircd/ircd_reslib.c: Use struct irc_sockaddr and ircd_aton()
+       instead of irc_ssaddr and irc_getaddrinfo().
+
+       * ircd/ircd_string.c: Implement new functions: IPv6-capable
+       ircd_ntoa_r(), ircd_aton_ip4(), ircd_aton().
+
+       * ircd/match.c: Delete IPv4-only matchcompIP().  Replace with
+       IPv6-capable ipmask_parse() and ipmask_check().
+
+       * ircd/numnicks.c: Implement new functions: iptobase64() and
+       base64toip().
+
+       * ircd/os_generic: Convert external parameters to be struct
+       irc_addrinfo.  When using IPv6 support, sockaddr_in6 is native.
+       Implement new functions os_sendto_nonb(), os_socket() and
+       os_accept().
+
+       * ircd/ircd_auth.c, ircd/ircd_parser.y, ircd/ircd_res.c,
+       ircd/listener.c, ircd/m_connect.c, ircd/s_auth.c, ircd/s_bsd.c,
+       ircd/s_conf.c, ircd/s_stats.c, ircd/uping.c: Use struct
+       irc_sockaddr instead of separate in_addr and port fields and new
+       OS support functions.
+
+       * include/ircd_addrinfo.h, ircd/ircd_getaddrinfo.c,
+       ircd/ircd_getnameinfo.c: Remove, since these functions are no
+       longer used.
+
+       * ircd/os_bsd.c, ircd/os_linux.c, ircd/os_openbsd.c,
+       ircd/os_solaris.c, ircd/res_adns.c, ircd/res_libresolv.c: Remove,
+       since these are unused and not compatible with IPv6 support.
+
+       * ircd/Makefile.in: Remove references to ircd_getXxxxinfo.c.
+       Regenerate dependencies.
+
 2004-08-17  Michael Poole <mdpoole@troilus.org>
 
        * ircd/ircd_lexer.l: Change tokenizer to reduce number of lexer
index 9d484726505952fec47b5b8bc34aa72b335eb59a..ab779ae5b7f9fe332df5efd8e69077b1f370b90d 100644 (file)
@@ -19,7 +19,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: config.h.in,v 1.6 2004-08-16 16:32:05 entrope Exp $
+ * $Id: config.h.in,v 1.7 2004-08-19 04:00:43 entrope Exp $
  */
 
 /* Define if you have the setrlimit function */
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef socklen_t
 
+/* Define if you want IPv6 support. */
+#undef IPV6
+
 #endif /* INCLUDED_config_h */
index 9b8428f01cf30f40e3991e5b768542c67ca71b81..ed7c59e1c7098bd7aeff1b7b677a2c779ec62e52 100755 (executable)
--- a/configure
+++ b/configure
@@ -862,6 +862,7 @@ Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
   --with-leak-detect          Turn on the leak detector(requires patched boehm)
+  --without-ipv6          disable IPv6 support (default is autodetect)
   --with-symlink=name     Name to give the symlink; if name is "no," no
                           symlink will be created.
   --with-mode=mode        Permissions (in octal) to give the binary
@@ -6713,6 +6714,69 @@ _ACEOF
 
 fi
 
+echo "$as_me:$LINENO: checking for struct sockaddr_in6" >&5
+echo $ECHO_N "checking for struct sockaddr_in6... $ECHO_C" >&6
+if test "${ac_cv_type_struct_sockaddr_in6+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <netinet/in.h>
+
+int
+main ()
+{
+if ((struct sockaddr_in6 *) 0)
+  return 0;
+if (sizeof (struct sockaddr_in6))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_struct_sockaddr_in6=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_struct_sockaddr_in6=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_in6" >&5
+echo "${ECHO_T}$ac_cv_type_struct_sockaddr_in6" >&6
+if test $ac_cv_type_struct_sockaddr_in6 = yes; then
+  unet_have_sockaddr_in6="yes"
+else
+  unet_have_sockaddr_in6="no"
+fi
+
 
 
 
@@ -8191,6 +8255,31 @@ if test x"$unet_cv_with_leak_detect" != xno; then
     fi
 fi
 
+
+# Check whether --with-ipv6 or --without-ipv6 was given.
+if test "${with_ipv6+set}" = set; then
+  withval="$with_ipv6"
+  ac_cv_use_ipv6=$withval
+else
+  ac_cv_use_ipv6=$unet_have_sockaddr_in6
+fi;
+echo "$as_me:$LINENO: checking whether to use IPv6" >&5
+echo $ECHO_N "checking whether to use IPv6... $ECHO_C" >&6
+if test "${ac_cv_use_ipv6+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_use_ipv6=no
+fi
+echo "$as_me:$LINENO: result: $ac_cv_use_ipv6" >&5
+echo "${ECHO_T}$ac_cv_use_ipv6" >&6
+if test x"$ac_cv_use_ipv6" != "xno" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define IPV6
+_ACEOF
+
+fi
+
 echo "$as_me:$LINENO: checking whether to enable asserts" >&5
 echo $ECHO_N "checking whether to enable asserts... $ECHO_C" >&6
 # Check whether --enable-asserts or --disable-asserts was given.
index 298eab7004af8671a5d212418ea997a61605f010..7c5e5b760578a4aa49b27b5d89c412a52ad05a80 100644 (file)
@@ -119,6 +119,8 @@ AC_STRUCT_TM
 AC_TYPE_UID_T
 unet_CHECK_TYPE_SIZES
 AC_CHECK_TYPE(socklen_t, unsigned int)
+AC_CHECK_TYPE(struct sockaddr_in6, [unet_have_sockaddr_in6="yes"], [unet_have_sockaddr_in6="no"], [#include <sys/types.h>
+#include <netinet/in.h>])
 
 dnl Checks for library functions.
 AC_CHECK_FUNCS([kqueue setrlimit getrusage times])
@@ -255,6 +257,15 @@ if test x"$unet_cv_with_leak_detect" != xno; then
     fi
 fi
 
+AC_ARG_WITH([ipv6],
+    AS_HELP_STRING([--without-ipv6], [disable IPv6 support (default is autodetect)]),
+    [ac_cv_use_ipv6=$withval],
+    [ac_cv_use_ipv6=$unet_have_sockaddr_in6])
+AC_CACHE_CHECK([whether to use IPv6], [ac_cv_use_ipv6], [ac_cv_use_ipv6=no])
+if test x"$ac_cv_use_ipv6" != "xno" ; then
+    AC_DEFINE([IPV6], , [Enable IPv6 support])
+fi
+
 dnl And now for --disable-asserts
 AC_MSG_CHECKING([whether to enable asserts])
 AC_ARG_ENABLE([asserts],
index 4062a90edd62ab2eed0c4e06e98b764765a08ff5..c5eb32dce32565b6a898ee0abeed45bfc8d4322e 100644 (file)
 #include <sys/types.h>          /* time_t, size_t */
 #define INCLUDED_sys_types_h
 #endif
-#ifndef INCLUDED_netinet_in_h
-#include <netinet/in.h>         /* in_addr */
-#define INCLUDED_netinet_in_h
-#endif
 
 struct Client;
+struct irc_in_addr;
 
 /*
  * Prototypes
  */
 extern void IPcheck_init(void);
-extern int IPcheck_local_connect(struct in_addr ip, time_t* next_target_out);
-extern void IPcheck_connect_fail(struct in_addr ip);
+extern int IPcheck_local_connect(const struct irc_in_addr *ip, time_t *next_target_out);
+extern void IPcheck_connect_fail(const struct irc_in_addr *ip);
 extern void IPcheck_connect_succeeded(struct Client *cptr);
 extern int IPcheck_remote_connect(struct Client *cptr, int is_burst);
 extern void IPcheck_disconnect(struct Client *cptr);
index e5aa4a25b36b730b57fb23fc67a6aa54b018907c..14967911b5fffda3b4a2628ee0b80c1020232b83 100644 (file)
 #ifndef INCLUDED_ircd_handler_h
 #include "ircd_handler.h"
 #endif
+#ifndef INCLUDED_res_h
+#include "res.h"
+#endif
 #ifndef INCLUDED_sys_types_h
 #include <sys/types.h>          /* time_t, size_t */
 #define INCLUDED_sys_types_h
 #endif
-#ifndef INCLUDED_netinet_in_h
-#include <netinet/in.h>         /* in_addr */
-#define INCLUDED_netinet_in_h
-#endif
 
 struct ConfItem;
 struct Listener;
@@ -234,13 +233,13 @@ struct Client {
    */
   time_t         cli_lasttime;  /* last time data read from socket */
   time_t         cli_since;     /* last time we parsed something, flood control */
-                               
+
   time_t         cli_firsttime; /* time client was created */
   time_t         cli_lastnick;  /* TimeStamp on nick */
   int            cli_marker;    /* /who processing marker */
   struct Flags   cli_flags;     /* client flags */
   unsigned int   cli_hopcount;  /* number of servers to this 0 = local */
-  struct in_addr cli_ip;        /* Real ip# NOT defined for remote servers! */
+  struct irc_in_addr cli_ip;    /* Real IP of client */
   short          cli_status;    /* Client type */
   unsigned char  cli_local;     /* local or remote client */
   struct Privs   cli_privs;     /* Oper privileges */
index a8e39132f355e16ba93235abb761a5093693d921..50ef60862c566ef2f55a94c79cb90d790096cb85 100644 (file)
@@ -27,7 +27,9 @@
 #define INCLUDED_sys_types_h
 #endif
 
-#include <netinet/in.h>
+#ifndef INCLUDED_res_h
+#include "res.h"
+#endif
 
 struct Client;
 struct StatDesc;
@@ -42,8 +44,8 @@ struct Gline {
   char        *gl_reason;
   time_t       gl_expire;
   time_t       gl_lastmod;
-  struct in_addr ipnum;  /* We store the IP in binary for ip glines */
-  char                 bits;
+  struct irc_in_addr gl_addr;  /* We store the IP in binary for ip glines */
+  unsigned char gl_bits;
   unsigned int gl_flags;
 };
 
diff --git a/include/ircd_addrinfo.h b/include/ircd_addrinfo.h
deleted file mode 100644 (file)
index d297dcb..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef INCLUDED_config_h
-#include "config.h"
-#endif
-
-#ifndef INCLUDED_sys_types_h
-#include <sys/types.h>
-#define INCLUDED_sys_types_h
-#endif
-
-#ifndef INCLUDED_sys_socket_h
-#include <sys/socket.h>
-#define INCLUDED_sys_socket_h
-#endif
-
-#include <netdb.h>
-
-#ifndef INCLUDED_netinet_in_h
-#include <netinet/in.h>
-#define INCLUDED_netinet_in_h
-#endif
-
-#ifdef HAVE_STDINT_H
-#ifndef INCLUDED_stdint_h
-#include <stdint.h>
-#define INCLUDED_stdint_h
-#endif
-#endif
-
-int irc_getaddrinfo(const char *hostname, const char *servname,
-                    const struct addrinfo *hints, struct addrinfo **res);
-int irc_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
-                    size_t hostlen, char *serv, size_t servlen, int flags);
-void irc_freeaddrinfo(struct addrinfo *ai);
index 3421fb6b4d12a91883db2b388f445e10846b52c6..31b8b98e2acbe872844399dd775a080146de77c8 100644 (file)
@@ -61,6 +61,7 @@
 #define NTL_EOL    0x10000  /* \r\n                                */
 #define NTL_KTIME  0x20000  /* Valid character for a k:line time   */
 #define NTL_CHPFX  0x40000  /* channel prefix char # & +           */
+#define NTL_IRCIP6 0x80000  /* Numeric IPv6 character (hex or colon) */
 
 /*
  * Tables used for translation and classification macros
@@ -98,6 +99,7 @@ extern const unsigned int  IRCD_CharAttrTab[];
 #define IsUserChar(c)      (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCUI)
 #define IsHostChar(c)      (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCHN)
 #define IsIPChar(c)        (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCIP)
+#define IsIP6Char(c)       (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCIP6)
 #define IsEol(c)           (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_EOL)
 #define IsKTimeChar(c)     (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_KTIME)
 
index 8639e721a5e328dac609895c1e665b9229b13f9b..87a443a87a64541974816ba6dd28d30ce000a9cc 100644 (file)
@@ -7,7 +7,7 @@
 #define INCLUDED_ircd_osdep_h
 
 struct Client;
-struct sockaddr_in;
+struct irc_sockaddr;
 struct MsgQ;
 
 typedef enum IOResult {
@@ -26,8 +26,13 @@ typedef void (*EnumFn)(struct Client*, const char* msg);
 extern int os_disable_options(int fd);
 extern int os_get_rusage(struct Client* cptr, int uptime, EnumFn enumerator);
 extern int os_get_sockerr(int fd);
-extern int os_get_sockname(int fd, struct sockaddr_in* sin_out);
-extern int os_get_peername(int fd, struct sockaddr_in* sin_out);
+extern int os_get_sockname(int fd, struct irc_sockaddr* sin_out);
+extern int os_get_peername(int fd, struct irc_sockaddr* sin_out);
+extern int os_socket(const struct irc_sockaddr* local, int type, const char* port_name);
+extern int os_accept(int fd, struct irc_sockaddr* peer);
+extern IOResult os_sendto_nonb(int fd, const char* buf, unsigned int length,
+                               unsigned int* length_out, unsigned int flags,
+                               const struct irc_sockaddr* peer);
 extern IOResult os_recv_nonb(int fd, char* buf, unsigned int length,
                         unsigned int* length_out);
 extern IOResult os_send_nonb(int fd, const char* buf, unsigned int length,
@@ -36,8 +41,8 @@ extern IOResult os_sendv_nonb(int fd, struct MsgQ* buf,
                              unsigned int* len_in, unsigned int* len_out);
 extern IOResult os_recvfrom_nonb(int fd, char* buf, unsigned int len,
                                  unsigned int* length_out,
-                                 struct sockaddr_in* from_out);
-extern IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin);
+                                 struct irc_sockaddr* from_out);
+extern IOResult os_connect_nonb(int fd, const struct irc_sockaddr* sin);
 extern int os_set_fdlimit(unsigned int max_descriptors);
 extern int os_set_listen(int fd, int backlog);
 extern int os_set_nonblocking(int fd);
index af2584ec029a0ad1aff09cc8b762759f1b93e351..b98c7e50473c38a009e762bf95eabab74c76c77e 100644 (file)
@@ -9,6 +9,8 @@
 #include "ircd_chattr.h"
 #endif
 
+struct irc_in_addr;
+
 /*
  * Macros
  */
@@ -32,8 +34,9 @@ extern int         unique_name_vector(char* names, char token,
                                       char** vector, int size);
 extern int         token_vector(char* names, char token,
                                 char** vector, int size);
-extern const char* ircd_ntoa(const char* addr);
-extern const char* ircd_ntoa_r(char* buf, const char* addr);
+extern const char* ircd_ntoa(const struct irc_in_addr* addr);
+extern const char* ircd_ntoa_r(char* buf, const struct irc_in_addr* addr);
+extern int         ircd_aton(struct irc_in_addr *addr, const char *str);
 extern char*       host_from_uh(char* buf, const char* userhost, size_t len);
 extern char*       ircd_strtok(char** save, char* str, char* fs);
 
index ec03e1699b16a4b900c3c0fe21bcad51710f8929..f33564e7ce5a411ee69397c88782ffad2f07f6a1 100644 (file)
 #ifndef INCLUDED_ircd_events_h
 #include "ircd_events.h"
 #endif
+#ifndef INCLUDED_res_h
+#include "res.h"
+#endif
 #ifndef INCLUDED_sys_types_h
 #include <sys/types.h>       /* size_t, broken BSD system headers */
 #define INCLUDED_sys_types_h
 #endif
-#ifndef INCLUDED_netinet_in_h
-#include <netinet/in.h>      /* in_addr */
-#define INCLUDED_netinet_in_h
-#endif
 
 struct Client;
 struct StatDesc;
@@ -41,15 +40,15 @@ struct StatDesc;
 struct Listener {
   struct Listener* next;               /* list node pointer */
   int              fd;                 /* file descriptor */
-  int              port;               /* listener IP port */
   int              ref_count;          /* number of connection references */
   unsigned char    active;             /* current state of listener */
   unsigned char    hidden;             /* hidden in stats output for clients */
   unsigned char    server;             /* 1 if port is a server listener */
+  unsigned char    mask_bits;          /* number of bits in mask address */
   int              index;              /* index into poll array */
   time_t           last_accept;        /* last time listener accepted */
-  struct in_addr   addr;               /* virtual address or INADDR_ANY */
-  struct in_addr   mask;               /* listener hostmask */
+  struct irc_sockaddr addr;            /* virtual address and port */
+  struct irc_in_addr mask;             /* listener hostmask */
   struct Socket    socket;             /* describe socket to event system */
 };
 
index 22a95b50b4269720d4f209d62ae324f4634c6bff..5cb7f3c7bb26726445a1e09f418d0d7fb045d057 100644 (file)
@@ -9,20 +9,10 @@
 #include <sys/types.h>         /* XXX - broken BSD system headers */
 #define INCLUDED_sys_types_h
 #endif
-#ifndef INCLUDED_netinet_in_h
-#include <netinet/in.h>        /* struct in_addr */
-#define INCLUDED_netinet_in_h
+#ifndef INCLUDED_res_h
+#include "res.h"
 #endif
 
-/*
- * Structures
- */
-struct in_mask {
-  struct in_addr bits;
-  struct in_addr mask;
-  int fall;
-};
-
 /*
  * Prototypes
  */
@@ -39,6 +29,8 @@ extern int matchcomp(char *cmask, int *minlen, int *charset, const char *mask);
 extern int matchexec(const char *string, const char *cmask, int minlen);
 extern int matchdecomp(char *mask, const char *cmask);
 extern int mmexec(const char *wcm, int wminlen, const char *rcm, int rminlen);
-extern int matchcompIP(struct in_mask *imask, const char *mask);
+
+extern int ipmask_parse(const char *in, struct irc_in_addr *mask, unsigned char *bits_ptr);
+extern int ipmask_check(const struct irc_in_addr *addr, const struct irc_in_addr *mask, unsigned char bits);
 
 #endif /* INCLUDED_match_h */
index cb812c399a86616006c5699e9b834e32616fbd86..78851ee80b6a48665b93c0c753740f9996cb0a5b 100644 (file)
@@ -81,6 +81,8 @@ extern struct Client* FindNServer(const char* numeric);
 
 extern unsigned int   base64toint(const char* str);
 extern const char*    inttobase64(char* buf, unsigned int v, unsigned int count);
+extern const char* iptobase64(char* buf, const struct irc_in_addr* addr, unsigned int count);
+extern void base64toip(const char* s, struct irc_in_addr* addr);
 
 #endif /* INCLUDED_numnicks_h */
 
index 6ca91ce48d204682b290cc6b3c75dc073803414a..7582f225b601744aca21d9f4a501c7d5bfcfc695 100644 (file)
@@ -7,13 +7,35 @@
 #ifndef INCLUDED_res_h
 #define INCLUDED_res_h
 
-#include "listener.h"
-#include "ircd_addrinfo.h"
+#ifndef INCLUDED_config_h
+#include "config.h"
+#endif
+
+#ifndef INCLUDED_sys_types_h
+#include <sys/types.h>
+#define INCLUDED_sys_types_h
+#endif
+
+#ifndef INCLUDED_sys_socket_h
+#include <sys/socket.h>
+#define INCLUDED_sys_socket_h
+#endif
+
+#include <netdb.h>
 
-#ifndef INADDR_NONE
-#define INADDR_NONE ((uint32_t)-1)
+#ifndef INCLUDED_netinet_in_h
+#include <netinet/in.h>
+#define INCLUDED_netinet_in_h
 #endif
 
+#ifdef HAVE_STDINT_H
+#ifndef INCLUDED_stdint_h
+#include <stdint.h>
+#define INCLUDED_stdint_h
+#endif
+#endif
+
+struct Client;
 struct StatDesc;
 
 /* Here we define some values lifted from nameser.h */
@@ -38,17 +60,22 @@ struct StatDesc;
 #define RRFIXEDSZ 10
 #define HFIXEDSZ 12
 
-struct irc_ssaddr
+struct irc_in_addr
+{
+  unsigned short in6_16[8];
+};
+
+struct irc_sockaddr
 {
-  struct sockaddr_storage ss;
-  size_t ss_len;
+  struct irc_in_addr addr;
+  unsigned short port;
 };
 
 struct DNSReply
 {
   char *h_name;
   int h_addrtype;
-  struct irc_ssaddr addr;
+  struct irc_in_addr addr;
 };
 
 struct DNSQuery
@@ -102,7 +129,10 @@ extern void delete_resolver_queries(const void *vptr);
 extern void report_dns_servers(struct Client *source_p, struct StatDesc *sd, int stat, char *param);
 extern void gethost_byname_type(const char *name, const struct DNSQuery *query, int type);
 extern void gethost_byname(const char *name, const struct DNSQuery *query);
-extern void gethost_byaddr(const struct irc_ssaddr *addr, const struct DNSQuery *query);
-extern void gethost_byinaddr(const struct in_addr *addr, const struct DNSQuery *query);
+extern void gethost_byaddr(const struct irc_in_addr *addr, const struct DNSQuery *query);
+extern int irc_in_addr_valid(const struct irc_in_addr *addr);
+extern int irc_in_addr_cmp(const struct irc_in_addr *a, const struct irc_in_addr *b);
+extern int irc_in_addr_is_ipv4(const struct irc_in_addr *addr);
+extern int irc_in_addr_is_loopback(const struct irc_in_addr *addr);
 
 #endif
index 289c5ecfb2946af59b3e5b0c55097cd613b50a08..69822bbd0892c40d9d1cec94eda337dde4c4a13b 100644 (file)
@@ -18,6 +18,7 @@ struct Client;
 struct ConfItem;
 struct Listener;
 struct MsgQ;
+struct irc_in_addr;
 
 /*
  * TCP window sizes
@@ -52,7 +53,7 @@ extern int            HighestFd;
 extern struct Client* LocalClientArray[MAXCONNECTIONS];
 extern int            OpenFileDescriptorCount;
 
-extern struct sockaddr_in VirtualHost;
+extern struct irc_sockaddr VirtualHost;
 
 enum PollType {
   PT_NONE,
@@ -73,7 +74,7 @@ struct Pollable {
   PollReadyFn      r_handler;
   PollReadyFn      w_handler;
 };
-  
+
 /*
  * Proto types
  */
@@ -87,7 +88,7 @@ extern int  read_message(time_t delay);
 extern void init_server_identity(void);
 extern void close_connections(int close_stderr);
 extern int  init_connection_limits(void);
-extern void set_virtual_host(struct in_addr addr);
+extern void set_virtual_host(const struct irc_in_addr *addr);
 extern void update_write(struct Client* cptr);
 
 #endif /* INCLUDED_s_bsd_h */
index 7e37d4cb06752773db8191ab9c035b04640a0f49..31a715740cb304294c3b4ed86047c2a9ed99bb81 100644 (file)
 #include <sys/types.h>
 #define INCLUDED_sys_types_h
 #endif
-#ifndef INCLUDED_netinet_in_h
-#include <netinet/in.h>        /* struct in_addr */
-#define INCLUDED_netinet_in_h
-#endif
 #include "client.h"
 
 struct Client;
@@ -56,13 +52,12 @@ struct ConfItem
   unsigned int status;      /* If CONF_ILLEGAL, delete when no clients */
   unsigned int clients;     /* Number of *LOCAL* clients using this */
   struct ConnectionClass *conn_class;  /* Class of connection */
-  struct in_addr ipnum;       /* ip number of host field */
+  struct irc_sockaddr address; /* ip and port */
   char *host;
   char *passwd;
   char *name;
   time_t hold; /* Hold until this time (calendar time) */
   int dns_pending; /* a dns request is pending */
-  unsigned short port;
   unsigned char bits; /* Number of bits for ipkills. */
   struct Privs privs; /* Priviledges for opers. */
   /* Used to detect if a privilege has been touched. */
@@ -74,8 +69,7 @@ struct ServerConf {
   char*              hostname;
   char*              passwd;
   char*              alias;
-  struct in_addr     address;
-  int                port;
+  struct irc_in_addr address;
   int                dns_pending;
   int                connected;
   time_t             hold;
@@ -94,9 +88,9 @@ struct DenyConf {
   char*               hostmask;
   char*               message;
   char*               usermask;
-  unsigned int        address;
+  struct irc_in_addr  address;
   unsigned int        flags;
-  char                bits;        /* Number of bits for ipkills */
+  unsigned char       bits;        /* Number of bits for ipkills */
 };
 
 #define DENY_FLAGS_FILE     0x0001 /* Comment is a filename */
@@ -109,7 +103,7 @@ struct DenyConf {
 struct LocalConf {
   char*          name;
   char*          description;
-  struct in_addr vhost_address;
+  struct irc_in_addr vhost_address;
   unsigned int   numeric;
   char*          location1;
   char*          location2;
index 30cf0152135c6297f7b6d113e9080cd8c293bd58..9b3f5e3c8a9440b9f5dbbc4effedab175b7769a4 100644 (file)
@@ -5,6 +5,9 @@
  */
 #ifndef INCLUDED_s_debug_h
 #define INCLUDED_s_debug_h
+#ifndef INCLUDED_config_h
+#include "config.h"          /* Needed for DEBUGMODE */
+#endif
 #ifndef INCLUDED_ircd_defs_h
 #include "ircd_defs.h"       /* Needed for HOSTLEN */
 #endif
index afdf2869e169d9b22d24b3e797145c659e1b71a2..3bb44b127df22146c4763d8afc9d46d3b871f0a9 100644 (file)
@@ -34,6 +34,9 @@
 #ifndef INCLUDED_ircd_events_h
 #include "ircd_events.h"
 #endif
+#ifndef INCLUDED_res_h
+#include "res.h"
+#endif
 
 struct Client;
 struct ConfItem;
@@ -42,7 +45,7 @@ struct UPing
 {
   struct UPing*      next;     /* next ping in list, usually null */
   int                fd;       /* socket file descriptor */
-  struct sockaddr_in sin;      /* socket name (ip addr, port, family ) */
+  struct irc_sockaddr addr;      /* socket name (ip addr, port, family ) */
   char               count;    /* number of pings requested */
   char               sent;     /* pings sent */
   char               received; /* pings received */
index b9e69e1d52fb1b9d6fb22ba14f4945141645f54f..56552b3e58d8d2e13edf006a4d4a7ebd8d2f81e8 100644 (file)
@@ -47,7 +47,7 @@ struct IPTargetEntry {
 struct IPRegistryEntry {
   struct IPRegistryEntry*  next;
   struct IPTargetEntry*    target;
-  unsigned int             addr;
+  struct irc_in_addr       addr;
   int                     last_connect;
   unsigned short           connected;
   unsigned char            attempts;
@@ -75,31 +75,40 @@ static struct IPRegistryEntry* freeList = 0;
 
 static struct Timer expireTimer;
 
-static unsigned int ip_registry_hash(unsigned int ip)
+static unsigned int ip_registry_hash(const struct irc_in_addr *ip)
 {
-  return ((ip >> 16) ^ ip) & (IP_REGISTRY_TABLE_SIZE - 1);
+  unsigned int res;
+
+  if (ip->in6_16[0] || ip->in6_16[1] || ip->in6_16[2] || ip->in6_16[3] || ip->in6_16[4]) {
+      /* Only use the first 64 bits of address, since the last 64 bits
+       * tend to be under user control. */
+      res = ip->in6_16[0] ^ ip->in6_16[1] ^ ip->in6_16[2] ^ ip->in6_16[3];
+  } else {
+      /* Looks like an IPv4 address. */
+      res = ip->in6_16[6] ^ ip->in6_16[7];
+  }
+  return res & (IP_REGISTRY_TABLE_SIZE - 1);
 }
 
-static struct IPRegistryEntry* ip_registry_find(unsigned int ip)
+static struct IPRegistryEntry* ip_registry_find(const struct irc_in_addr *ip)
 {
   struct IPRegistryEntry* entry = hashTable[ip_registry_hash(ip)];
-  for ( ; entry; entry = entry->next) {
-    if (entry->addr == ip)
+  for ( ; entry; entry = entry->next)
+    if (!irc_in_addr_cmp(ip, &entry->addr))
       break;
-  }
   return entry;
 }
 
 static void ip_registry_add(struct IPRegistryEntry* entry)
 {
-  unsigned int bucket = ip_registry_hash(entry->addr);
+  unsigned int bucket = ip_registry_hash(&entry->addr);
   entry->next = hashTable[bucket];
   hashTable[bucket] = entry;
 }
-  
+
 static void ip_registry_remove(struct IPRegistryEntry* entry)
 {
-  unsigned int bucket = ip_registry_hash(entry->addr);
+  unsigned int bucket = ip_registry_hash(&entry->addr);
   if (hashTable[bucket] == entry)
     hashTable[bucket] = entry->next;
   else {
@@ -112,7 +121,7 @@ static void ip_registry_remove(struct IPRegistryEntry* entry)
     }
   }
 }
+
 static struct IPRegistryEntry* ip_registry_new_entry()
 {
   struct IPRegistryEntry* entry = freeList;
@@ -227,14 +236,14 @@ void IPcheck_init(void)
  * cptr->nexttarget to be `now - (TARGET_DELAY * (FREE_TARGETS - 1))',
  * where FREE_TARGETS may range from 0 till STARTTARGETS.
  */
-int ip_registry_check_local(unsigned int addr, time_t* next_target_out)
+int ip_registry_check_local(const struct irc_in_addr *addr, time_t* next_target_out)
 {
   struct IPRegistryEntry* entry = ip_registry_find(addr);
   unsigned int free_targets = STARTTARGETS;
+
   if (0 == entry) {
     entry       = ip_registry_new_entry();
-    entry->addr = addr;    /* The IP number of registry entry */
+    memcpy(&entry->addr, addr, sizeof(entry->addr));
     ip_registry_add(entry);
     return 1;
   }
@@ -290,7 +299,7 @@ int ip_registry_check_local(unsigned int addr, time_t* next_target_out)
  */
 int ip_registry_check_remote(struct Client* cptr, int is_burst)
 {
-  struct IPRegistryEntry* entry = ip_registry_find((cli_ip(cptr)).s_addr);
+  struct IPRegistryEntry* entry = ip_registry_find(&cli_ip(cptr));
 
   /*
    * Mark that we did add/update an IPregistry entry
@@ -298,7 +307,7 @@ int ip_registry_check_remote(struct Client* cptr, int is_burst)
   SetIPChecked(cptr);
   if (0 == entry) {
     entry = ip_registry_new_entry();
-    entry->addr = (cli_ip(cptr)).s_addr;
+    memcpy(&entry->addr, &cli_ip(cptr), sizeof(entry->addr));
     if (is_burst)
       entry->attempts = 0;
     ip_registry_add(entry);
@@ -337,7 +346,7 @@ int ip_registry_check_remote(struct Client* cptr, int is_burst)
  *   a way that the client won't be penalized when trying to reconnect
  *   again.
  */
-void ip_registry_connect_fail(unsigned int addr)
+void ip_registry_connect_fail(const struct irc_in_addr *addr)
 {
   struct IPRegistryEntry* entry = ip_registry_find(addr);
   if (entry)
@@ -359,7 +368,7 @@ void ip_registry_connect_succeeded(struct Client *cptr)
 {
   const char*             tr    = "";
   unsigned int free_targets     = STARTTARGETS;
-  struct IPRegistryEntry* entry = ip_registry_find((cli_ip(cptr)).s_addr);
+  struct IPRegistryEntry* entry = ip_registry_find(&cli_ip(cptr));
 
   if (!entry) {
     Debug((DEBUG_ERROR, "Missing registry entry for: %s", cli_sock_ip(cptr)));
@@ -388,7 +397,7 @@ void ip_registry_connect_succeeded(struct Client *cptr)
  */
 void ip_registry_disconnect(struct Client *cptr)
 {
-  struct IPRegistryEntry* entry = ip_registry_find((cli_ip(cptr)).s_addr);
+  struct IPRegistryEntry* entry = ip_registry_find(&cli_ip(cptr));
   if (0 == entry) {
     /*
      * trying to find an entry for a server causes this to happen,
@@ -464,7 +473,7 @@ void ip_registry_disconnect(struct Client *cptr)
  *
  * Returns number of clients with the same IP number
  */
-int ip_registry_count(unsigned int addr)
+int ip_registry_count(const struct irc_in_addr *addr)
 {
   struct IPRegistryEntry* entry = ip_registry_find(addr);
   return (entry) ? entry->connected : 0;
@@ -496,10 +505,10 @@ int ip_registry_count(unsigned int addr)
  * cptr->nexttarget to be `now - (TARGET_DELAY * (FREE_TARGETS - 1))',
  * where FREE_TARGETS may range from 0 till STARTTARGETS.
  */
-int IPcheck_local_connect(struct in_addr a, time_t* next_target_out)
+int IPcheck_local_connect(const struct irc_in_addr *a, time_t* next_target_out)
 {
   assert(0 != next_target_out);
-  return ip_registry_check_local(a.s_addr, next_target_out);
+  return ip_registry_check_local(a, next_target_out);
 }
 
 /*
@@ -530,9 +539,9 @@ int IPcheck_remote_connect(struct Client *cptr, int is_burst)
  *   a way that the client won't be penalized when trying to reconnect
  *   again.
  */
-void IPcheck_connect_fail(struct in_addr a)
+void IPcheck_connect_fail(const struct irc_in_addr *a)
 {
-  ip_registry_connect_fail(a.s_addr);
+  ip_registry_connect_fail(a);
 }
 
 /*
@@ -574,5 +583,5 @@ void IPcheck_disconnect(struct Client *cptr)
 unsigned short IPcheck_nr(struct Client *cptr)
 {
   assert(0 != cptr);
-  return ip_registry_count(cli_ip(cptr).s_addr);
+  return ip_registry_count(&cli_ip(cptr));
 }
index cfe075df14e91314cf23a8df588446fc309a00e2..0fa39e26ffb42bc7ca2d3cc67da89b89145b2f5f 100644 (file)
@@ -98,8 +98,6 @@ IRCD_SRC = \
        ircd_crypt.c \
        ircd_events.c \
        ircd_features.c \
-       ircd_getaddrinfo.c \
-       ircd_getnameinfo.c \
        ircd_log.c \
        ircd_relay.c \
        ircd_reply.c \
@@ -361,46 +359,48 @@ depend: ${DEP_SRC} chattr.tab.c
 # ../config/config.h:
 #      @cd ../config; ${MAKE} config.h
 
-# DO NOT DELETE THIS LINE -- make depend depends on it.
+# DO NOT DELETE THIS LINE (or the blank line after it) -- make depend depends on them.
 
 IPcheck.o: IPcheck.c ../config.h ../include/IPcheck.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/msg.h ../include/numnicks.h \
-  ../include/ircd_alloc.h ../include/ircd_features.h ../include/s_debug.h \
-  ../include/s_user.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/msg.h \
+  ../include/numnicks.h ../include/ircd_alloc.h \
+  ../include/ircd_features.h ../include/s_debug.h ../include/s_user.h \
+  ../include/send.h
 channel.o: channel.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/destruct_event.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \
-  ../include/ircd_features.h ../include/ircd_log.h \
-  ../include/ircd_reply.h ../include/ircd_snprintf.h \
-  ../include/ircd_string.h ../include/list.h ../include/match.h \
-  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
-  ../include/querycmds.h ../include/s_bsd.h ../include/s_conf.h \
-  ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
-  ../include/send.h ../include/support.h ../include/sys.h \
-  ../include/whowas.h
+  ../include/res.h ../include/destruct_event.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+  ../include/ircd_chattr.h ../include/ircd_features.h \
+  ../include/ircd_log.h ../include/ircd_reply.h \
+  ../include/ircd_snprintf.h ../include/ircd_string.h ../include/list.h \
+  ../include/match.h ../include/msg.h ../include/numeric.h \
+  ../include/numnicks.h ../include/querycmds.h ../include/s_bsd.h \
+  ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
+  ../include/s_user.h ../include/send.h ../include/support.h \
+  ../include/sys.h ../include/whowas.h
 class.o: class.c ../config.h ../include/class.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_features.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/list.h ../include/numeric.h \
-  ../include/s_conf.h ../include/s_debug.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
+  ../include/numeric.h ../include/s_conf.h ../include/s_debug.h \
+  ../include/send.h
 client.o: client.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/class.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
-  ../include/list.h ../include/numeric.h ../include/s_conf.h \
-  ../include/s_debug.h ../include/send.h
+  ../include/ircd_handler.h ../include/res.h ../include/class.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+  ../include/ircd_reply.h ../include/list.h ../include/numeric.h \
+  ../include/s_conf.h ../include/s_debug.h ../include/send.h
 crule.o: crule.c ../config.h ../include/crule.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \
-  ../include/ircd_string.h ../include/match.h ../include/s_bsd.h \
-  ../include/s_debug.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+  ../include/ircd_chattr.h ../include/ircd_string.h ../include/match.h \
+  ../include/s_bsd.h ../include/s_debug.h
 dbuf.o: dbuf.c ../config.h ../include/dbuf.h ../include/ircd_alloc.h \
   ../include/ircd_chattr.h ../include/ircd_features.h ../include/send.h \
   ../include/sys.h
@@ -410,36 +410,35 @@ destruct_event.o: destruct_event.c ../config.h ../include/channel.h \
   ../include/send.h ../include/msg.h ../include/ircd_handler.h
 fileio.o: fileio.c ../config.h ../include/fileio.h \
   ../include/ircd_alloc.h
-gline.o: gline.c ../config.h ../include/gline.h ../include/client.h \
-  ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_features.h \
-  ../include/ircd_log.h ../include/ircd_reply.h \
-  ../include/ircd_snprintf.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/match.h ../include/numeric.h \
-  ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \
-  ../include/s_stats.h ../include/send.h ../include/support.h \
-  ../include/msg.h ../include/numnicks.h ../include/sys.h \
-  ../include/whocmds.h
+gline.o: gline.c ../config.h ../include/gline.h ../include/res.h \
+  ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
+  ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+  ../include/ircd_features.h ../include/ircd_log.h \
+  ../include/ircd_reply.h ../include/ircd_snprintf.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
+  ../include/numeric.h ../include/s_bsd.h ../include/s_debug.h \
+  ../include/s_misc.h ../include/s_stats.h ../include/send.h \
+  ../include/support.h ../include/msg.h ../include/numnicks.h \
+  ../include/sys.h ../include/whocmds.h
 hash.o: hash.c ../config.h ../include/hash.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/channel.h \
-  ../include/ircd_chattr.h ../include/ircd_string.h ../include/ircd.h \
-  ../include/struct.h ../include/msg.h ../include/send.h \
-  ../include/support.h ../include/sys.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/channel.h ../include/ircd_chattr.h ../include/ircd_string.h \
+  ../include/ircd.h ../include/struct.h ../include/msg.h \
+  ../include/send.h ../include/support.h ../include/sys.h
 ircd.o: ircd.c ../config.h ../include/ircd.h ../include/struct.h \
   ../include/ircd_defs.h ../include/IPcheck.h ../include/class.h \
   ../include/client.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/crule.h \
-  ../include/destruct_event.h ../include/channel.h ../include/hash.h \
-  ../include/ircd_alloc.h ../include/ircd_features.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/crule.h ../include/destruct_event.h ../include/channel.h \
+  ../include/hash.h ../include/ircd_alloc.h ../include/ircd_features.h \
   ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_signal.h \
   ../include/ircd_string.h ../include/ircd_chattr.h \
   ../include/ircd_crypt.h ../include/jupe.h ../include/list.h \
   ../include/match.h ../include/motd.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
-  ../include/parse.h ../include/res.h ../include/listener.h \
-  ../include/ircd_addrinfo.h ../include/s_auth.h ../include/s_bsd.h \
+  ../include/parse.h ../include/s_auth.h ../include/s_bsd.h \
   ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
   ../include/s_stats.h ../include/send.h ../include/sys.h \
   ../include/uping.h ../include/userload.h ../include/version.h \
@@ -449,13 +448,12 @@ ircd_alloc.o: ircd_alloc.c ../config.h ../include/ircd_alloc.h \
   ../include/ircd_defs.h
 ircd_auth.o: ircd_auth.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
   ../include/ircd_alloc.h ../include/ircd_auth.h \
   ../include/ircd_features.h ../include/ircd_log.h \
   ../include/ircd_osdep.h ../include/ircd_snprintf.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \
-  ../include/struct.h ../include/msg.h ../include/res.h \
-  ../include/listener.h ../include/ircd_addrinfo.h ../include/s_bsd.h \
+  ../include/struct.h ../include/msg.h ../include/s_bsd.h \
   ../include/s_misc.h ../include/s_user.h ../include/send.h
 ircd_crypt.o: ircd_crypt.c ../config.h ../include/ircd_crypt.h \
   ../include/ircd_alloc.h ../include/ircd_features.h \
@@ -469,128 +467,127 @@ ircd_events.o: ircd_events.c ../config.h ../include/ircd_events.h \
 ircd_features.o: ircd_features.c ../config.h ../include/ircd_features.h \
   ../include/channel.h ../include/ircd_defs.h ../include/class.h \
   ../include/client.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
-  ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/match.h ../include/motd.h \
-  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
-  ../include/random.h ../include/s_bsd.h ../include/s_debug.h \
-  ../include/s_misc.h ../include/send.h ../include/support.h \
-  ../include/sys.h ../include/whowas.h
-ircd_getaddrinfo.o: ircd_getaddrinfo.c ../include/ircd_addrinfo.h \
-  ../config.h
-ircd_getnameinfo.o: ircd_getnameinfo.c ../include/ircd_addrinfo.h \
-  ../config.h ../include/ircd_string.h ../include/ircd_chattr.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
+  ../include/motd.h ../include/msg.h ../include/numeric.h \
+  ../include/numnicks.h ../include/random.h ../include/s_bsd.h \
+  ../include/s_debug.h ../include/s_misc.h ../include/send.h \
+  ../include/support.h ../include/sys.h ../include/whowas.h
 ircd_log.o: ircd_log.c ../config.h ../include/ircd_log.h \
   ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/ircd_alloc.h ../include/ircd_reply.h \
+  ../include/res.h ../include/ircd_alloc.h ../include/ircd_reply.h \
   ../include/ircd_snprintf.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/ircd.h ../include/struct.h \
   ../include/numeric.h ../include/s_debug.h ../include/send.h
 ircd_relay.o: ircd_relay.c ../config.h ../include/ircd_relay.h \
   ../include/channel.h ../include/ircd_defs.h ../include/client.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_chattr.h ../include/ircd_features.h \
-  ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \
-  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
-  ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
-  ../include/send.h
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
+  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/match.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
+  ../include/s_misc.h ../include/s_user.h ../include/send.h
 ircd_reply.o: ircd_reply.c ../config.h ../include/ircd_reply.h \
   ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_snprintf.h \
-  ../include/msg.h ../include/numeric.h ../include/s_conf.h \
-  ../include/s_debug.h ../include/send.h
+  ../include/res.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_snprintf.h ../include/msg.h ../include/numeric.h \
+  ../include/s_conf.h ../include/s_debug.h ../include/send.h
 ircd_res.o: ircd_res.c ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../config.h ../include/ircd_handler.h ../include/ircd_alloc.h \
-  ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h \
-  ../include/ircd_snprintf.h ../include/ircd.h ../include/struct.h \
-  ../include/numeric.h ../include/fileio.h ../include/s_bsd.h \
-  ../include/s_stats.h ../include/ircd_features.h ../include/send.h \
-  ../include/sys.h ../include/res.h ../include/listener.h \
-  ../include/ircd_addrinfo.h ../include/ircd_reslib.h
+  ../config.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd_alloc.h ../include/ircd_log.h ../include/ircd_osdep.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/ircd_snprintf.h ../include/ircd.h \
+  ../include/struct.h ../include/numeric.h ../include/fileio.h \
+  ../include/s_bsd.h ../include/s_stats.h ../include/ircd_features.h \
+  ../include/send.h ../include/sys.h ../include/ircd_reslib.h
 ircd_reslib.o: ircd_reslib.c ../include/ircd.h ../include/struct.h \
-  ../include/ircd_defs.h ../include/res.h ../include/listener.h \
-  ../include/ircd_events.h ../config.h ../include/ircd_addrinfo.h \
+  ../include/ircd_defs.h ../include/res.h ../config.h \
   ../include/ircd_reslib.h ../include/fileio.h ../include/ircd_string.h \
   ../include/ircd_chattr.h
 ircd_signal.o: ircd_signal.c ../config.h ../include/ircd.h \
   ../include/struct.h ../include/ircd_defs.h ../include/ircd_events.h \
   ../include/ircd_signal.h ../include/s_conf.h ../include/client.h \
-  ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h
+  ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+  ../include/res.h
 ircd_snprintf.o: ircd_snprintf.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/channel.h \
-  ../include/ircd_snprintf.h ../include/struct.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/channel.h ../include/ircd_snprintf.h ../include/struct.h
 ircd_string.o: ircd_string.c ../config.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/ircd_defs.h ../include/ircd_log.h \
-  chattr.tab.c
+  ../include/res.h chattr.tab.c
 jupe.o: jupe.c ../config.h ../include/jupe.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
-  ../include/ircd_features.h ../include/ircd_log.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_alloc.h ../include/ircd_features.h \
+  ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
   ../include/s_misc.h ../include/send.h ../include/support.h \
   ../include/sys.h
-lex.yy.o: lex.yy.c ../include/ircd.h ../include/struct.h \
-  ../include/ircd_defs.h y.tab.h
+lex.yy.o: lex.yy.c ../config.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_defs.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/s_debug.h y.tab.h
 list.o: list.c ../config.h ../include/list.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/listener.h \
-  ../include/match.h ../include/numeric.h ../include/res.h \
-  ../include/ircd_addrinfo.h ../include/s_auth.h ../include/s_bsd.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/listener.h ../include/match.h \
+  ../include/numeric.h ../include/s_auth.h ../include/s_bsd.h \
   ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
   ../include/s_user.h ../include/send.h ../include/support.h \
   ../include/whowas.h
 listener.o: listener.c ../config.h ../include/listener.h \
-  ../include/ircd_defs.h ../include/ircd_events.h ../include/client.h \
-  ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
-  ../include/ircd_features.h ../include/ircd_osdep.h \
-  ../include/ircd_reply.h ../include/ircd_snprintf.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \
+  ../include/ircd_defs.h ../include/ircd_events.h ../include/res.h \
+  ../include/client.h ../include/dbuf.h ../include/msgq.h \
+  ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_alloc.h ../include/ircd_features.h \
+  ../include/ircd_osdep.h ../include/ircd_reply.h \
+  ../include/ircd_snprintf.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/match.h ../include/numeric.h \
   ../include/s_bsd.h ../include/s_conf.h ../include/s_misc.h \
   ../include/s_stats.h ../include/send.h ../include/sys.h
 m_account.o: m_account.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/msg.h ../include/numnicks.h \
-  ../include/s_debug.h ../include/s_user.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+  ../include/numnicks.h ../include/s_debug.h ../include/s_user.h \
+  ../include/send.h
 m_admin.o: m_admin.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
-  ../include/ircd_reply.h ../include/msg.h ../include/numeric.h \
-  ../include/numnicks.h ../include/s_conf.h ../include/s_user.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_features.h ../include/ircd_reply.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
+  ../include/s_user.h
 m_asll.o: m_asll.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
-  ../include/match.h ../include/msg.h ../include/send.h \
-  ../include/s_bsd.h ../include/s_user.h
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \
+  ../include/numnicks.h ../include/match.h ../include/msg.h \
+  ../include/send.h ../include/s_bsd.h ../include/s_user.h
 m_away.o: m_away.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_alloc.h ../include/ircd_reply.h \
+  ../include/ircd_handler.h ../include/res.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_reply.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
   ../include/send.h
 m_burst.o: m_burst.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_alloc.h ../include/ircd_features.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_features.h \
   ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/list.h ../include/match.h \
   ../include/msg.h ../include/numeric.h ../include/numnicks.h \
@@ -598,23 +595,23 @@ m_burst.o: m_burst.c ../config.h ../include/channel.h \
   ../include/support.h ../include/ircd_snprintf.h
 m_clearmode.o: m_clearmode.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/channel.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_alloc.h ../include/ircd_features.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/channel.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_features.h \
   ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/list.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
   ../include/send.h ../include/support.h
 m_close.o: m_close.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_reply.h ../include/numeric.h \
-  ../include/s_bsd.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+  ../include/numeric.h ../include/s_bsd.h ../include/send.h
 m_connect.o: m_connect.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/crule.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_features.h ../include/ircd_log.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/crule.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \
   ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/jupe.h ../include/match.h \
   ../include/msg.h ../include/numeric.h ../include/numnicks.h \
@@ -622,156 +619,164 @@ m_connect.o: m_connect.c ../config.h ../include/client.h \
   ../include/send.h
 m_cprivmsg.o: m_cprivmsg.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
   ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/s_user.h
 m_create.o: m_create.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
   ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
   ../include/s_user.h ../include/send.h
 m_defaults.o: m_defaults.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_reply.h ../include/numeric.h \
-  ../include/numnicks.h ../include/send.h ../include/supported.h \
-  ../include/channel.h ../include/version.h
-m_destruct.o: m_destruct.c ../config.h ../include/client.h \
-  ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
   ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/send.h \
-  ../include/channel.h ../include/destruct_event.h
+  ../include/supported.h ../include/channel.h ../include/version.h
+m_destruct.o: m_destruct.c ../config.h ../include/client.h \
+  ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+  ../include/numnicks.h ../include/send.h ../include/channel.h \
+  ../include/destruct_event.h
 m_desynch.o: m_desynch.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
-  ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
-  ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+  ../include/numnicks.h ../include/s_bsd.h ../include/send.h
 m_die.o: m_die.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_handler.h ../include/res.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
   ../include/numnicks.h ../include/s_bsd.h ../include/send.h
 m_endburst.o: m_endburst.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
   ../include/numnicks.h ../include/send.h
 m_error.o: m_error.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
-  ../include/s_debug.h ../include/s_misc.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_alloc.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \
+  ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
+  ../include/send.h
 m_get.o: m_get.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \
-  ../include/numnicks.h ../include/send.h
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
+  ../include/send.h
 m_gline.o: m_gline.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/gline.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/gline.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
   ../include/msg.h ../include/numeric.h ../include/numnicks.h \
   ../include/s_conf.h ../include/s_misc.h ../include/send.h \
   ../include/support.h
 m_help.o: m_help.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
-  ../include/numnicks.h ../include/send.h
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/send.h
 m_info.o: m_info.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_handler.h ../include/res.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
   ../include/numnicks.h ../include/s_misc.h ../include/s_user.h \
   ../include/s_conf.h ../include/send.h ../include/version.h
 m_invite.o: m_invite.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
   ../include/msg.h ../include/numeric.h ../include/numnicks.h \
   ../include/s_user.h ../include/send.h
 m_ison.o: m_ison.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/numeric.h ../include/send.h
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \
+  ../include/send.h
 m_join.o: m_join.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/gline.h ../include/hash.h ../include/ircd.h \
+  ../include/res.h ../include/gline.h ../include/hash.h ../include/ircd.h \
   ../include/struct.h ../include/ircd_chattr.h ../include/ircd_features.h \
   ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
   ../include/s_user.h ../include/send.h
 m_jupe.o: m_jupe.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/jupe.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
-  ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
-  ../include/s_misc.h ../include/send.h ../include/support.h
+  ../include/ircd_handler.h ../include/res.h ../include/jupe.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
+  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+  ../include/s_conf.h ../include/s_misc.h ../include/send.h \
+  ../include/support.h
 m_kick.o: m_kick.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
   ../include/numnicks.h ../include/send.h ../include/ircd_features.h
 m_kill.o: m_kill.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \
-  ../include/ircd_reply.h ../include/ircd_snprintf.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
-  ../include/numeric.h ../include/numnicks.h ../include/s_misc.h \
-  ../include/send.h ../include/whowas.h
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+  ../include/ircd_log.h ../include/ircd_reply.h \
+  ../include/ircd_snprintf.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+  ../include/numnicks.h ../include/s_misc.h ../include/send.h \
+  ../include/whowas.h
 m_links.o: m_links.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
-  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
-  ../include/s_user.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
+  ../include/send.h
 m_list.o: m_list.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_alloc.h ../include/ircd_chattr.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \
   ../include/ircd_features.h ../include/ircd_log.h \
   ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
   ../include/send.h
 m_lusers.o: m_lusers.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
-  ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \
-  ../include/s_user.h ../include/s_serv.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+  ../include/numnicks.h ../include/querycmds.h ../include/s_user.h \
+  ../include/s_serv.h ../include/send.h
 m_map.o: m_map.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_handler.h ../include/res.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
   ../include/ircd_snprintf.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/list.h ../include/match.h \
   ../include/msg.h ../include/numeric.h ../include/s_user.h \
@@ -779,15 +784,15 @@ m_map.o: m_map.c ../config.h ../include/client.h ../include/ircd_defs.h \
 m_mode.o: m_mode.c ../config.h ../include/handlers.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
   ../include/numnicks.h ../include/s_conf.h ../include/s_debug.h \
   ../include/s_user.h ../include/send.h
 m_motd.o: m_motd.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_handler.h ../include/res.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
   ../include/motd.h ../include/msg.h ../include/numeric.h \
   ../include/numnicks.h ../include/s_conf.h ../include/class.h \
@@ -795,300 +800,315 @@ m_motd.o: m_motd.c ../config.h ../include/client.h ../include/ircd_defs.h \
 m_names.o: m_names.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
   ../include/numnicks.h ../include/s_user.h ../include/send.h
 m_nick.o: m_nick.c ../config.h ../include/IPcheck.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
-  ../include/ircd_features.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
-  ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
-  ../include/s_user.h ../include/send.h ../include/sys.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_chattr.h ../include/ircd_features.h \
+  ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
+  ../include/s_misc.h ../include/s_user.h ../include/send.h \
+  ../include/sys.h
 m_notice.o: m_notice.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
   ../include/ircd_chattr.h ../include/ircd_relay.h \
   ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \
   ../include/msg.h ../include/numeric.h ../include/send.h \
   ../include/handlers.h
 m_oper.o: m_oper.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+  ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/ircd_crypt.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \
   ../include/s_conf.h ../include/s_debug.h ../include/s_user.h \
   ../include/s_misc.h ../include/send.h ../include/support.h
 m_opmode.o: m_opmode.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/channel.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/channel.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/send.h \
   ../include/s_conf.h
 m_part.o: m_part.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
   ../include/send.h
 m_pass.o: m_pass.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/ircd_reply.h \
+  ../include/ircd_handler.h ../include/res.h ../include/ircd_reply.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/send.h
 m_ping.o: m_ping.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \
-  ../include/struct.h ../include/msg.h ../include/numeric.h \
-  ../include/numnicks.h ../include/opercmds.h ../include/s_debug.h \
-  ../include/send.h
-m_pong.o: m_pong.c ../config.h ../include/client.h ../include/ircd_defs.h \
-  ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
-  ../include/numnicks.h ../include/opercmds.h ../include/s_user.h \
-  ../include/send.h
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/ircd.h ../include/struct.h \
+  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
+  ../include/opercmds.h ../include/s_debug.h ../include/send.h
+m_pong.o: m_pong.c ../config.h ../include/client.h ../include/ircd_defs.h \
+  ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
+  ../include/s_user.h ../include/send.h
 m_privmsg.o: m_privmsg.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_chattr.h ../include/ircd_features.h \
-  ../include/ircd_relay.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/match.h ../include/msg.h \
-  ../include/numeric.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
+  ../include/ircd_features.h ../include/ircd_relay.h \
+  ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \
+  ../include/msg.h ../include/numeric.h ../include/send.h
 m_privs.o: m_privs.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \
-  ../include/numnicks.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
+  ../include/send.h
 m_proto.o: m_proto.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \
-  ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
-  ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
-  ../include/s_misc.h ../include/send.h ../include/supported.h \
-  ../include/channel.h ../include/version.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+  ../include/ircd_chattr.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
+  ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
+  ../include/send.h ../include/supported.h ../include/channel.h \
+  ../include/version.h
 m_pseudo.o: m_pseudo.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
-  ../include/ircd_relay.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h \
-  ../include/ircd_snprintf.h ../include/msg.h ../include/numeric.h \
-  ../include/numnicks.h ../include/s_conf.h ../include/s_user.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_features.h ../include/ircd_relay.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/ircd_snprintf.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
+  ../include/s_user.h
 m_quit.o: m_quit.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/s_misc.h ../include/ircd_reply.h
+  ../include/res.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/s_misc.h \
+  ../include/ircd_reply.h
 m_rehash.o: m_rehash.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/motd.h \
-  ../include/numeric.h ../include/s_conf.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_log.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/motd.h ../include/numeric.h \
+  ../include/s_conf.h ../include/send.h
 m_reset.o: m_reset.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \
+  ../include/numnicks.h ../include/send.h
+m_restart.o: m_restart.c ../config.h ../include/client.h \
+  ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_log.h \
   ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
   ../include/send.h
-m_restart.o: m_restart.c ../config.h ../include/client.h \
-  ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_log.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \
-  ../include/numnicks.h ../include/send.h
 m_rping.o: m_rping.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
-  ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
-  ../include/s_user.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+  ../include/numnicks.h ../include/opercmds.h ../include/s_user.h \
+  ../include/send.h
 m_rpong.o: m_rpong.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
-  ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
-  ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+  ../include/numnicks.h ../include/opercmds.h ../include/send.h
 m_server.o: m_server.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_log.h \
-  ../include/ircd_features.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/jupe.h \
-  ../include/list.h ../include/match.h ../include/msg.h \
-  ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \
-  ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
-  ../include/s_misc.h ../include/s_serv.h ../include/send.h \
-  ../include/userload.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_log.h ../include/ircd_features.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/jupe.h ../include/list.h \
+  ../include/match.h ../include/msg.h ../include/numeric.h \
+  ../include/numnicks.h ../include/querycmds.h ../include/s_bsd.h \
+  ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
+  ../include/s_serv.h ../include/send.h ../include/userload.h
 m_set.o: m_set.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/numeric.h \
-  ../include/numnicks.h ../include/send.h
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/numeric.h ../include/numnicks.h \
+  ../include/send.h
 m_settime.o: m_settime.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
-  ../include/ircd_reply.h ../include/ircd_snprintf.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
-  ../include/msg.h ../include/numeric.h ../include/numnicks.h \
-  ../include/s_user.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_snprintf.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/list.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
+  ../include/send.h
 m_silence.o: m_silence.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/list.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
   ../include/send.h
 m_squit.o: m_squit.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
-  ../include/ircd_reply.h ../include/ircd_string.h ../include/numeric.h \
-  ../include/numnicks.h ../include/match.h ../include/s_debug.h \
-  ../include/s_misc.h ../include/s_user.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_chattr.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/numeric.h ../include/numnicks.h \
+  ../include/match.h ../include/s_debug.h ../include/s_misc.h \
+  ../include/s_user.h ../include/send.h
 m_stats.o: m_stats.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
-  ../include/numeric.h ../include/s_stats.h ../include/s_user.h \
-  ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+  ../include/s_stats.h ../include/s_user.h ../include/send.h
 m_time.o: m_time.c ../config.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_handler.h ../include/res.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/s_misc.h \
   ../include/s_user.h ../include/send.h
 m_topic.o: m_topic.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/send.h
 m_trace.o: m_trace.c ../config.h ../include/class.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
-  ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
-  ../include/s_conf.h ../include/s_user.h ../include/send.h \
-  ../include/version.h
-m_uping.o: m_uping.c ../config.h ../include/client.h \
-  ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_features.h ../include/ircd_reply.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
   ../include/msg.h ../include/numeric.h ../include/numnicks.h \
-  ../include/s_conf.h ../include/s_user.h ../include/send.h \
-  ../include/uping.h
+  ../include/s_bsd.h ../include/s_conf.h ../include/s_user.h \
+  ../include/send.h ../include/version.h
+m_uping.o: m_uping.c ../config.h ../include/client.h \
+  ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
+  ../include/s_user.h ../include/send.h ../include/uping.h
 m_user.o: m_user.c ../config.h ../include/handlers.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/numeric.h ../include/numnicks.h \
-  ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
-  ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
+  ../include/ircd_reply.h ../include/ircd_string.h ../include/numeric.h \
+  ../include/numnicks.h ../include/s_debug.h ../include/s_misc.h \
+  ../include/s_user.h ../include/send.h
 m_userhost.o: m_userhost.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
   ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/numeric.h ../include/s_user.h \
   ../include/struct.h
 m_userip.o: m_userip.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
   ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/ircd_features.h \
   ../include/numeric.h ../include/s_user.h ../include/struct.h
 m_version.o: m_version.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
-  ../include/ircd_reply.h ../include/ircd_snprintf.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
-  ../include/numeric.h ../include/numnicks.h ../include/s_debug.h \
-  ../include/s_user.h ../include/send.h ../include/supported.h \
-  ../include/channel.h ../include/version.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_snprintf.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
+  ../include/numnicks.h ../include/s_debug.h ../include/s_user.h \
+  ../include/send.h ../include/supported.h ../include/channel.h \
+  ../include/version.h
 m_wallchops.o: m_wallchops.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
   ../include/numnicks.h ../include/s_user.h ../include/send.h
 m_wallops.o: m_wallops.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
   ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
   ../include/send.h
 m_wallusers.o: m_wallusers.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
   ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
   ../include/send.h
 m_wallvoices.o: m_wallvoices.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
   ../include/numnicks.h ../include/s_user.h ../include/send.h
 m_who.o: m_who.c ../config.h ../include/channel.h ../include/ircd_defs.h \
   ../include/client.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
-  ../include/ircd_features.h ../include/ircd_log.h \
-  ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \
-  ../include/numeric.h ../include/numnicks.h ../include/send.h \
-  ../include/support.h ../include/whocmds.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_chattr.h ../include/ircd_features.h \
+  ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \
+  ../include/match.h ../include/numeric.h ../include/numnicks.h \
+  ../include/send.h ../include/support.h ../include/whocmds.h
 m_whois.o: m_whois.c ../config.h ../include/channel.h \
   ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/hash.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/res.h ../include/hash.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_features.h ../include/ircd_reply.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
   ../include/msg.h ../include/numeric.h ../include/numnicks.h \
   ../include/s_user.h ../include/send.h ../include/whocmds.h
 m_whowas.o: m_whowas.c ../config.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
-  ../include/numnicks.h ../include/s_user.h ../include/s_misc.h \
-  ../include/send.h ../include/whowas.h
-match.o: match.c ../config.h ../include/match.h ../include/ircd_chattr.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/s_user.h \
+  ../include/s_misc.h ../include/send.h ../include/whowas.h
+match.o: match.c ../config.h ../include/match.h ../include/res.h \
+  ../include/ircd_chattr.h ../include/ircd_string.h \
+  ../include/ircd_snprintf.h ../include/support.h
 memdebug.o: memdebug.c ../include/ircd.h ../include/struct.h \
   ../include/ircd_defs.h ../include/ircd_alloc.h ../include/client.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../config.h ../include/ircd_handler.h ../include/s_debug.h
+  ../config.h ../include/ircd_handler.h ../include/res.h \
+  ../include/s_debug.h
 motd.o: motd.c ../config.h ../include/motd.h ../include/class.h \
   ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/fileio.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_alloc.h ../include/ircd_features.h \
+  ../include/res.h ../include/fileio.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_features.h \
   ../include/ircd_reply.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \
@@ -1102,108 +1122,107 @@ msgq.o: msgq.c ../config.h ../include/msgq.h ../include/ircd_defs.h \
 numnicks.o: numnicks.c ../config.h ../include/numnicks.h \
   ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \
-  ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h
+  ../include/res.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_alloc.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/match.h ../include/s_bsd.h \
+  ../include/s_debug.h ../include/s_misc.h
 opercmds.o: opercmds.c ../config.h ../include/opercmds.h \
   ../include/class.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_chattr.h ../include/ircd_reply.h \
+  ../include/ircd_handler.h ../include/res.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_chattr.h ../include/ircd_reply.h \
   ../include/ircd_string.h ../include/listener.h ../include/match.h \
   ../include/msg.h ../include/numeric.h ../include/numnicks.h \
   ../include/s_conf.h ../include/send.h
 os_generic.o: os_generic.c ../config.h ../include/ircd_osdep.h \
-  ../include/msgq.h ../include/ircd_defs.h
+  ../include/msgq.h ../include/ircd_defs.h ../include/res.h \
+  ../include/s_bsd.h ../include/sys.h
 packet.o: packet.c ../config.h ../include/packet.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_chattr.h ../include/parse.h \
-  ../include/s_bsd.h ../include/s_misc.h ../include/send.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
+  ../include/parse.h ../include/s_bsd.h ../include/s_misc.h \
+  ../include/send.h
 parse.o: parse.c ../config.h ../include/parse.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/channel.h \
-  ../include/handlers.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \
-  ../include/ircd_features.h ../include/ircd_reply.h \
-  ../include/ircd_string.h ../include/msg.h ../include/numeric.h \
-  ../include/numnicks.h ../include/opercmds.h ../include/querycmds.h \
-  ../include/res.h ../include/listener.h ../include/ircd_addrinfo.h \
-  ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
-  ../include/s_misc.h ../include/s_numeric.h ../include/s_user.h \
-  ../include/send.h ../include/sys.h ../include/whocmds.h \
-  ../include/whowas.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/channel.h ../include/handlers.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+  ../include/ircd_chattr.h ../include/ircd_features.h \
+  ../include/ircd_reply.h ../include/ircd_string.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
+  ../include/querycmds.h ../include/s_bsd.h ../include/s_conf.h \
+  ../include/s_debug.h ../include/s_misc.h ../include/s_numeric.h \
+  ../include/s_user.h ../include/send.h ../include/sys.h \
+  ../include/whocmds.h ../include/whowas.h
 querycmds.o: querycmds.c ../config.h ../include/querycmds.h \
   ../include/ircd_features.h
 random.o: random.c ../config.h ../include/random.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
   ../include/ircd_log.h ../include/ircd_reply.h ../include/send.h
 s_auth.o: s_auth.c ../config.h ../include/s_auth.h \
   ../include/ircd_events.h ../include/client.h ../include/ircd_defs.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
-  ../include/IPcheck.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_alloc.h ../include/ircd_chattr.h \
+  ../include/res.h ../include/IPcheck.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \
   ../include/ircd_features.h ../include/ircd_log.h \
   ../include/ircd_osdep.h ../include/ircd_snprintf.h \
   ../include/ircd_string.h ../include/list.h ../include/numeric.h \
-  ../include/querycmds.h ../include/res.h ../include/listener.h \
-  ../include/ircd_addrinfo.h ../include/s_bsd.h ../include/s_debug.h \
+  ../include/querycmds.h ../include/s_bsd.h ../include/s_debug.h \
   ../include/s_misc.h ../include/send.h ../include/sys.h
 s_bsd.o: s_bsd.c ../config.h ../include/s_bsd.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/IPcheck.h \
-  ../include/channel.h ../include/class.h ../include/hash.h \
-  ../include/ircd_alloc.h ../include/ircd_log.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/IPcheck.h ../include/channel.h ../include/class.h \
+  ../include/hash.h ../include/ircd_alloc.h ../include/ircd_log.h \
   ../include/ircd_features.h ../include/ircd_osdep.h \
   ../include/ircd_reply.h ../include/ircd_snprintf.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/ircd.h \
   ../include/struct.h ../include/list.h ../include/listener.h \
   ../include/msg.h ../include/numeric.h ../include/numnicks.h \
   ../include/packet.h ../include/parse.h ../include/querycmds.h \
-  ../include/res.h ../include/ircd_addrinfo.h ../include/s_auth.h \
-  ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
-  ../include/s_user.h ../include/send.h ../include/support.h \
-  ../include/sys.h ../include/uping.h ../include/version.h
+  ../include/s_auth.h ../include/s_conf.h ../include/s_debug.h \
+  ../include/s_misc.h ../include/s_user.h ../include/send.h \
+  ../include/support.h ../include/sys.h ../include/uping.h \
+  ../include/version.h
 s_conf.o: s_conf.c ../config.h ../include/s_conf.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/IPcheck.h \
-  ../include/class.h ../include/crule.h ../include/ircd_features.h \
-  ../include/fileio.h ../include/gline.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
-  ../include/ircd_auth.h ../include/ircd_chattr.h ../include/ircd_log.h \
-  ../include/ircd_reply.h ../include/ircd_snprintf.h \
-  ../include/ircd_string.h ../include/list.h ../include/listener.h \
-  ../include/match.h ../include/motd.h ../include/numeric.h \
-  ../include/numnicks.h ../include/opercmds.h ../include/parse.h \
-  ../include/res.h ../include/ircd_addrinfo.h ../include/s_bsd.h \
-  ../include/s_debug.h ../include/s_misc.h ../include/send.h \
-  ../include/support.h ../include/sys.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/IPcheck.h ../include/class.h ../include/crule.h \
+  ../include/ircd_features.h ../include/fileio.h ../include/gline.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_alloc.h ../include/ircd_auth.h ../include/ircd_chattr.h \
+  ../include/ircd_log.h ../include/ircd_reply.h \
+  ../include/ircd_snprintf.h ../include/ircd_string.h ../include/list.h \
+  ../include/listener.h ../include/match.h ../include/motd.h \
+  ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
+  ../include/parse.h ../include/s_bsd.h ../include/s_debug.h \
+  ../include/s_misc.h ../include/send.h ../include/support.h \
+  ../include/sys.h
 s_debug.o: s_debug.c ../config.h ../include/s_debug.h \
   ../include/ircd_defs.h ../include/channel.h ../include/class.h \
   ../include/client.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/gline.h \
-  ../include/hash.h ../include/ircd_alloc.h ../include/ircd_features.h \
-  ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_reply.h \
-  ../include/ircd.h ../include/struct.h ../include/jupe.h \
-  ../include/list.h ../include/motd.h ../include/numeric.h \
-  ../include/numnicks.h ../include/res.h ../include/listener.h \
-  ../include/ircd_addrinfo.h ../include/s_bsd.h ../include/s_conf.h \
-  ../include/s_stats.h ../include/send.h ../include/sys.h \
-  ../include/whowas.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/gline.h ../include/hash.h ../include/ircd_alloc.h \
+  ../include/ircd_features.h ../include/ircd_log.h \
+  ../include/ircd_osdep.h ../include/ircd_reply.h ../include/ircd.h \
+  ../include/struct.h ../include/jupe.h ../include/list.h \
+  ../include/motd.h ../include/numeric.h ../include/numnicks.h \
+  ../include/s_bsd.h ../include/s_conf.h ../include/s_stats.h \
+  ../include/send.h ../include/sys.h ../include/whowas.h
 s_err.o: s_err.c ../config.h ../include/numeric.h ../include/s_debug.h \
   ../include/ircd_defs.h
 s_misc.o: s_misc.c ../config.h ../include/s_misc.h ../include/IPcheck.h \
   ../include/channel.h ../include/ircd_defs.h ../include/client.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_auth.h \
-  ../include/ircd_features.h ../include/ircd_log.h \
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+  ../include/ircd_auth.h ../include/ircd_features.h ../include/ircd_log.h \
   ../include/ircd_reply.h ../include/ircd_snprintf.h \
   ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
   ../include/match.h ../include/msg.h ../include/numeric.h \
   ../include/numnicks.h ../include/parse.h ../include/querycmds.h \
-  ../include/res.h ../include/listener.h ../include/ircd_addrinfo.h \
   ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
   ../include/s_stats.h ../include/s_user.h ../include/send.h \
   ../include/support.h ../include/sys.h ../include/uping.h \
@@ -1211,40 +1230,41 @@ s_misc.o: s_misc.c ../config.h ../include/s_misc.h ../include/IPcheck.h \
 s_numeric.o: s_numeric.c ../config.h ../include/s_numeric.h \
   ../include/channel.h ../include/ircd_defs.h ../include/client.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_features.h \
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_features.h \
   ../include/ircd_snprintf.h ../include/numnicks.h ../include/send.h
 s_serv.o: s_serv.c ../config.h ../include/s_serv.h ../include/IPcheck.h \
   ../include/channel.h ../include/ircd_defs.h ../include/client.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/gline.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
-  ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/ircd_chattr.h ../include/ircd_snprintf.h \
-  ../include/ircd_crypt.h ../include/jupe.h ../include/list.h \
-  ../include/match.h ../include/msg.h ../include/numeric.h \
-  ../include/numnicks.h ../include/parse.h ../include/querycmds.h \
-  ../include/ircd_features.h ../include/s_bsd.h ../include/s_conf.h \
-  ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
-  ../include/send.h ../include/sys.h ../include/userload.h
+  ../include/ircd_handler.h ../include/res.h ../include/gline.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_alloc.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/ircd_chattr.h \
+  ../include/ircd_snprintf.h ../include/ircd_crypt.h ../include/jupe.h \
+  ../include/list.h ../include/match.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/parse.h \
+  ../include/querycmds.h ../include/ircd_features.h ../include/s_bsd.h \
+  ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
+  ../include/s_user.h ../include/send.h ../include/sys.h \
+  ../include/userload.h
 s_stats.o: s_stats.c ../config.h ../include/class.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/gline.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
-  ../include/ircd_features.h ../include/ircd_crypt.h \
-  ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \
-  ../include/listener.h ../include/list.h ../include/match.h \
-  ../include/motd.h ../include/msg.h ../include/numeric.h \
-  ../include/numnicks.h ../include/res.h ../include/ircd_addrinfo.h \
-  ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
-  ../include/s_misc.h ../include/s_serv.h ../include/s_stats.h \
-  ../include/s_user.h ../include/send.h ../include/userload.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/gline.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_chattr.h ../include/ircd_features.h \
+  ../include/ircd_crypt.h ../include/ircd_log.h ../include/ircd_reply.h \
+  ../include/ircd_string.h ../include/listener.h ../include/list.h \
+  ../include/match.h ../include/motd.h ../include/msg.h \
+  ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
+  ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
+  ../include/s_serv.h ../include/s_stats.h ../include/s_user.h \
+  ../include/send.h ../include/userload.h
 s_user.o: s_user.c ../config.h ../include/s_user.h ../include/IPcheck.h \
   ../include/channel.h ../include/ircd_defs.h ../include/class.h \
   ../include/client.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
-  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
-  ../include/ircd_auth.h ../include/ircd_chattr.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/hash.h ../include/ircd.h ../include/struct.h \
+  ../include/ircd_alloc.h ../include/ircd_auth.h ../include/ircd_chattr.h \
   ../include/ircd_features.h ../include/ircd_log.h \
   ../include/ircd_reply.h ../include/ircd_snprintf.h \
   ../include/ircd_string.h ../include/list.h ../include/match.h \
@@ -1258,21 +1278,22 @@ s_user.o: s_user.c ../config.h ../include/s_user.h ../include/IPcheck.h \
 send.o: send.c ../config.h ../include/send.h ../include/channel.h \
   ../include/ircd_defs.h ../include/class.h ../include/client.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/ircd.h ../include/struct.h \
-  ../include/ircd_features.h ../include/ircd_snprintf.h \
-  ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \
-  ../include/match.h ../include/msg.h ../include/numnicks.h \
-  ../include/parse.h ../include/s_bsd.h ../include/s_debug.h \
-  ../include/s_misc.h ../include/s_user.h ../include/sys.h
+  ../include/ircd_handler.h ../include/res.h ../include/ircd.h \
+  ../include/struct.h ../include/ircd_features.h \
+  ../include/ircd_snprintf.h ../include/ircd_string.h \
+  ../include/ircd_chattr.h ../include/list.h ../include/match.h \
+  ../include/msg.h ../include/numnicks.h ../include/parse.h \
+  ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \
+  ../include/s_user.h ../include/sys.h
 support.o: support.c ../config.h ../include/support.h ../include/fileio.h \
   ../include/ircd.h ../include/struct.h ../include/ircd_defs.h \
   ../include/ircd_chattr.h ../include/ircd_snprintf.h ../include/s_bsd.h \
   ../include/s_debug.h ../include/send.h ../include/sys.h
 uping.o: uping.c ../config.h ../include/uping.h ../include/ircd_defs.h \
-  ../include/ircd_events.h ../include/client.h ../include/dbuf.h \
-  ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_log.h \
-  ../include/ircd_osdep.h ../include/ircd_string.h \
+  ../include/ircd_events.h ../include/res.h ../include/client.h \
+  ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+  ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_string.h \
   ../include/ircd_chattr.h ../include/match.h ../include/msg.h \
   ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \
   ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \
@@ -1280,41 +1301,43 @@ uping.o: uping.c ../config.h ../include/uping.h ../include/ircd_defs.h \
 userload.o: userload.c ../config.h ../include/userload.h \
   ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \
   ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \
-  ../include/ircd.h ../include/struct.h ../include/msg.h \
+  ../include/res.h ../include/ircd.h ../include/struct.h ../include/msg.h \
   ../include/numnicks.h ../include/querycmds.h ../include/ircd_features.h \
   ../include/s_misc.h ../include/s_stats.h ../include/send.h \
   ../include/sys.h
 whocmds.o: whocmds.c ../config.h ../include/whocmds.h \
   ../include/channel.h ../include/ircd_defs.h ../include/client.h \
   ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
-  ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_chattr.h ../include/ircd_features.h \
-  ../include/ircd_reply.h ../include/ircd_snprintf.h \
-  ../include/ircd_string.h ../include/list.h ../include/match.h \
-  ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \
-  ../include/random.h ../include/s_bsd.h ../include/s_conf.h \
-  ../include/s_misc.h ../include/s_user.h ../include/send.h \
-  ../include/support.h ../include/sys.h ../include/userload.h \
-  ../include/version.h ../include/whowas.h ../include/msg.h
+  ../include/ircd_handler.h ../include/res.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_chattr.h \
+  ../include/ircd_features.h ../include/ircd_reply.h \
+  ../include/ircd_snprintf.h ../include/ircd_string.h ../include/list.h \
+  ../include/match.h ../include/numeric.h ../include/numnicks.h \
+  ../include/querycmds.h ../include/random.h ../include/s_bsd.h \
+  ../include/s_conf.h ../include/s_misc.h ../include/s_user.h \
+  ../include/send.h ../include/support.h ../include/sys.h \
+  ../include/userload.h ../include/version.h ../include/whowas.h \
+  ../include/msg.h
 whowas.o: whowas.c ../config.h ../include/whowas.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \
-  ../include/ircd_features.h ../include/ircd_string.h ../include/list.h \
-  ../include/numeric.h ../include/s_debug.h ../include/s_misc.h \
-  ../include/s_user.h ../include/send.h ../include/support.h \
-  ../include/sys.h ../include/msg.h
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+  ../include/ircd_chattr.h ../include/ircd_features.h \
+  ../include/ircd_string.h ../include/list.h ../include/numeric.h \
+  ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \
+  ../include/send.h ../include/support.h ../include/sys.h \
+  ../include/msg.h
 y.tab.o: y.tab.c ../config.h ../include/s_conf.h ../include/client.h \
   ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
-  ../include/ircd_events.h ../include/ircd_handler.h ../include/class.h \
-  ../include/crule.h ../include/ircd_features.h ../include/fileio.h \
-  ../include/gline.h ../include/hash.h ../include/ircd.h \
-  ../include/struct.h ../include/ircd_alloc.h ../include/ircd_auth.h \
-  ../include/ircd_chattr.h ../include/ircd_log.h ../include/ircd_reply.h \
-  ../include/ircd_snprintf.h ../include/ircd_string.h ../include/list.h \
-  ../include/listener.h ../include/match.h ../include/motd.h \
-  ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \
-  ../include/parse.h ../include/res.h ../include/ircd_addrinfo.h \
+  ../include/ircd_events.h ../include/ircd_handler.h ../include/res.h \
+  ../include/class.h ../include/crule.h ../include/ircd_features.h \
+  ../include/fileio.h ../include/gline.h ../include/hash.h \
+  ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
+  ../include/ircd_auth.h ../include/ircd_chattr.h ../include/ircd_log.h \
+  ../include/ircd_reply.h ../include/ircd_snprintf.h \
+  ../include/ircd_string.h ../include/list.h ../include/listener.h \
+  ../include/match.h ../include/motd.h ../include/numeric.h \
+  ../include/numnicks.h ../include/opercmds.h ../include/parse.h \
   ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \
   ../include/send.h ../include/support.h ../include/sys.h
 engine_devpoll.o: engine_devpoll.c ../config.h ../include/ircd_events.h \
index 6b038274eefd2c2350c5d68be89a10ca5fb2c8fa..885e787a00a6d37d763aff060d7b5a276917bf42 100644 (file)
@@ -174,12 +174,11 @@ static char *make_nick_user_host(char *namebuf, const char *nick,
  * Create a string of form "foo!bar@123.456.789.123" given foo, bar and the
  * IP-number as the parameters.  If NULL, they become "*".
  */
-#define NUI_BUFSIZE    (NICKLEN + USERLEN + 16 + 3)
+#define NUI_BUFSIZE    (NICKLEN + USERLEN + SOCKIPLEN + 4)
 static char *make_nick_user_ip(char *ipbuf, char *nick, char *name,
-                              struct in_addr ip)
+                              const struct irc_in_addr *ip)
 {
-  ircd_snprintf(0, ipbuf, NUI_BUFSIZE, "%s!%s@%s", nick, name,
-               ircd_ntoa((const char*) &ip));
+  ircd_snprintf(0, ipbuf, NUI_BUFSIZE, "%s!%s@%s", nick, name, ircd_ntoa(ip));
   return ipbuf;
 }
 
@@ -480,7 +479,7 @@ static int is_banned(struct Client *cptr, struct Channel *chptr,
     if ((tmp->flags & CHFL_BAN_IPMASK)) {
       if (!ip_s)
         ip_s = make_nick_user_ip(nu_ip, cli_name(cptr),
-                                (cli_user(cptr))->username, cli_ip(cptr));
+                                (cli_user(cptr))->username, &cli_ip(cptr));
       if (match(tmp->value.ban.banstr, ip_s) == 0)
         break;
     }
index 7201b96933a62d2876639f0e2d47e83ff4b2db79..3fd81c946226004d5b35088cde31f48bb548f521 100644 (file)
@@ -141,43 +141,8 @@ make_gline(char *user, char *host, char *reason, time_t expire, time_t lastmod,
     else
       gline->gl_host = NULL;
 
-    if (*user != '$' && check_if_ipmask(host)) { /* mark if it's an IP mask */
-      int c_class;
-      char ipname[16];
-      int ad[4] = { 0 };
-      int bits2 = 0;
-      char *ch;
-      int seenwild;
-      int badmask=0;
-      
-      /* Sanity check for dodgy IP masks 
-       * Any mask featuring a digit after a wildcard will 
-       * not behave as expected. */
-      for (seenwild=0,ch=host;*ch;ch++) {
-        if (*ch=='*' || *ch=='?') 
-          seenwild=1;
-        if (IsDigit(*ch) && seenwild) {
-          badmask=1;
-          break;
-        }
-      }
-      
-      if (badmask) {
-        /* It's bad - let's make it match 0.0.0.0/32 */
-        gline->bits=32;
-        gline->ipnum.s_addr=0;
-      } else {
-        c_class = sscanf(host,"%d.%d.%d.%d/%d",
-                         &ad[0],&ad[1],&ad[2],&ad[3], &bits2);
-        if (c_class!=5)
-          gline->bits=c_class*8;
-        else
-          gline->bits=bits2;
-        ircd_snprintf(0, ipname, sizeof(ipname), "%d.%d.%d.%d", ad[0], ad[1],
-                      ad[2], ad[3]);
-        gline->ipnum.s_addr = inet_addr(ipname);
-      }
-      Debug((DEBUG_DEBUG,"IP gline: %08x/%i",gline->ipnum.s_addr,gline->bits));
+    if (*user != '$' && ipmask_parse(host, &gline->gl_addr, &gline->gl_bits)) {
+      Debug((DEBUG_DEBUG,"IP gline: %s/%u", ircd_ntoa(&gline->gl_addr), gline->gl_bits));
       gline->gl_flags |= GLINE_IPMASK;
     }
 
@@ -215,7 +180,7 @@ do_gline(struct Client *cptr, struct Client *sptr, struct Gline *gline)
     if ((acptr = LocalClientArray[fd])) {
       if (!cli_user(acptr))
        continue;
-       
+
       if (GlineIsRealName(gline)) { /* Realname Gline */
        Debug((DEBUG_DEBUG,"Realname Gline: %s %s",(cli_info(acptr)),
                                        gline->gl_user+2));
@@ -223,13 +188,16 @@ do_gline(struct Client *cptr, struct Client *sptr, struct Gline *gline)
             continue;
         Debug((DEBUG_DEBUG,"Matched!"));
       } else { /* Host/IP gline */
-        if (cli_user(acptr)->username && 
+        if (cli_user(acptr)->username &&
             match(gline->gl_user, (cli_user(acptr))->username) != 0)
-            continue;
-          
+          continue;
+
         if (GlineIsIpMask(gline)) {
-          Debug((DEBUG_DEBUG,"IP gline: %08x %08x/%i",(cli_ip(cptr)).s_addr,gline->ipnum.s_addr,gline->bits));
-          if (((cli_ip(acptr)).s_addr & NETMASK(gline->bits)) != gline->ipnum.s_addr)
+#ifdef DEBUGMODE
+          char tbuf1[SOCKIPLEN], tbuf2[SOCKIPLEN];
+          Debug((DEBUG_DEBUG,"IP gline: %s %s/%u", ircd_ntoa_r(tbuf1, &cli_ip(cptr)), ircd_ntoa_r(tbuf2, &gline->gl_addr), gline->gl_bits));
+#endif
+          if (!ipmask_check(&cli_ip(cptr), &gline->gl_addr, gline->gl_bits))
             continue;
         }
         else {
@@ -282,17 +250,24 @@ gline_checkmask(char *mask)
       ++mask;
       ipmask = strtoul(mask, &mask, 10);
 
-      if (*mask || dots != 3 || ipmask > 32 || /* sanity-check to date */
-         (flags & (MASK_WILDS | MASK_IP)) != MASK_IP)
-       return CHECK_REJECTED; /* how strange... */
-
-      if (ipmask < 32) /* it's a masked address; mark wilds */
-       flags |= MASK_WILDS;
+      /* sanity-check to date */
+      if (*mask || (flags & (MASK_WILDS | MASK_IP)) != MASK_IP)
+       return CHECK_REJECTED;
+      if (!dots) {
+        if (ipmask > 128)
+          return CHECK_REJECTED;
+        if (ipmask < 128)
+          flags |= MASK_WILDS;
+      } else {
+        if (dots != 3 || ipmask > 3)
+          return CHECK_REJECTED;
+        if (ipmask < 32)
+         flags |= MASK_WILDS;
+      }
 
       flags |= MASK_HALT; /* Halt the ipmask calculation */
-
       break; /* get out of the loop */
-    } else if (!IsDigit(*mask)) {
+    } else if (!IsIP6Char(*mask)) {
       flags &= ~MASK_IP; /* not an IP anymore! */
       ipmask = 0;
     }
@@ -343,7 +318,7 @@ gline_propagate(struct Client *cptr, struct Client *sptr, struct Gline *gline)
   return 0;
 }
 
-int 
+int
 gline_add(struct Client *cptr, struct Client *sptr, char *userhost,
          char *reason, time_t expire, time_t lastmod, unsigned int flags)
 {
@@ -355,28 +330,14 @@ gline_add(struct Client *cptr, struct Client *sptr, char *userhost,
   assert(0 != userhost);
   assert(0 != reason);
 
-  /* NO_OLD_GLINE allows *@#channel to work correctly */
-  if (*userhost == '#' || *userhost == '&'
-# ifndef NO_OLD_GLINE
-      || ((userhost[2] == '#' || userhost[2] == '&') && (userhost[1] == '@'))
-# endif /* OLD_GLINE */
-      ) {
+  if (*userhost == '#' || *userhost == '&') {
     if ((flags & GLINE_LOCAL) && !HasPriv(sptr, PRIV_LOCAL_BADCHAN))
       return send_reply(sptr, ERR_NOPRIVILEGES);
 
     flags |= GLINE_BADCHAN;
-# ifndef NO_OLD_GLINE
-    if ((userhost[2] == '#' || userhost[2] == '&') && (userhost[1] == '@'))
-      user = userhost + 2;
-    else
-# endif /* OLD_GLINE */
-      user = userhost;
+    user = userhost;
     host = 0;
-  } else if (*userhost == '$' 
-# ifndef NO_OLD_GLINE
-  || userhost[2] == '$'
-# endif /* OLD_GLINE */
-  ) {
+  } else if (*userhost == '$') {
     switch (*userhost == '$' ? userhost[1] : userhost[3]) {
       case 'R': flags |= GLINE_REALNAME; break;
       default:
@@ -593,11 +554,7 @@ gline_find(char *userhost, unsigned int flags)
   }
 
   if ((flags & (GLINE_BADCHAN | GLINE_ANY)) == GLINE_BADCHAN ||
-      *userhost == '#' || *userhost == '&'
-#ifndef NO_OLD_GLINE
-      || userhost[2] == '#' || userhost[2] == '&'
-#endif /* NO_OLD_GLINE */
-      )
+      *userhost == '#' || *userhost == '&')
     return 0;
 
   DupString(t_uh, userhost);
@@ -663,14 +620,17 @@ gline_lookup(struct Client *cptr, unsigned int flags)
     else {
       if (match(gline->gl_user, (cli_user(cptr))->username) != 0)
         continue;
-        
+
       if (GlineIsIpMask(gline)) {
-        Debug((DEBUG_DEBUG,"IP gline: %08x %08x/%i",(cli_ip(cptr)).s_addr,gline->ipnum.s_addr,gline->bits));
-        if (((cli_ip(cptr)).s_addr & NETMASK(gline->bits)) != gline->ipnum.s_addr)
+#ifdef DEBUGMODE
+        char tbuf1[SOCKIPLEN], tbuf2[SOCKIPLEN];
+        Debug((DEBUG_DEBUG,"IP gline: %s %s/%u", ircd_ntoa_r(tbuf1, &cli_ip(cptr)), ircd_ntoa_r(tbuf2, &gline->gl_addr), gline->gl_bits));
+#endif
+        if (!ipmask_check(&cli_ip(cptr), &gline->gl_addr, gline->gl_bits))
           continue;
       }
       else {
-        if (match(gline->gl_host, (cli_user(cptr))->realhost) != 0) 
+        if (match(gline->gl_host, (cli_user(cptr))->realhost) != 0)
           continue;
       }
     }
@@ -822,7 +782,7 @@ gline_memory_count(size_t *gl_size)
 {
   struct Gline *gline;
   unsigned int gl = 0;
-  
+
   for (gline = GlobalGlineList; gline; gline = gline->gl_next)
   {
     gl++;
@@ -833,4 +793,3 @@ gline_memory_count(size_t *gl_size)
   }
   return gl;
 }
-
index 33dbfaf73d776dbfd9d6ec2be7066f97a6fa95df..b8c7cb4b985f9e35c178c08801119e93215b4ec8 100644 (file)
@@ -256,7 +256,7 @@ static void try_connections(struct Event* ev) {
   Debug((DEBUG_NOTICE, "Connection check at   : %s", myctime(CurrentTime)));
   for (aconf = GlobalConfList; aconf; aconf = aconf->next) {
     /* Also when already connecting! (update holdtimes) --SRB */
-    if (!(aconf->status & CONF_SERVER) || aconf->port == 0 || aconf->hold == 0)
+    if (!(aconf->status & CONF_SERVER) || aconf->address.port == 0 || aconf->hold == 0)
       continue;
 
     /* Also skip juped servers */
index 23a90700bc3e1dc19ae6d3e7391734a63c5ffc62..31fc36683972c9d5603d92d2d1e027eae64b9b97 100644 (file)
@@ -89,8 +89,7 @@ struct IAuth {
   char i_buffer[BUFSIZE+1];             /* partial unprocessed line from server */
   char i_passwd[PASSWDLEN+1];           /* password for connection */
   char i_host[HOSTLEN+1];               /* iauth server hostname */
-  uint32_t i_addr;                      /* iauth server ip address */
-  unsigned short i_port;                /* iauth server port */
+  struct irc_sockaddr i_addr;           /* iauth server ip address and port */
   struct IAuth *i_next;                 /* next connection in list */
 };
 
@@ -133,7 +132,7 @@ struct IAuth {
 #define i_passwd(iauth) ((iauth)->i_passwd)
 #define i_host(iauth) ((iauth)->i_host)
 #define i_addr(iauth) ((iauth)->i_addr)
-#define i_port(iauth) ((iauth)->i_port)
+#define i_port(iauth) ((iauth)->i_addr.port)
 #define i_next(iauth) ((iauth)->i_next)
 
 struct IAuthCmd {
@@ -182,8 +181,7 @@ struct IAuth *iauth_connect(char *host, unsigned short port, char *passwd, time_
     msgq_init(&i_sendQ(iauth));
     ircd_strncpy(i_host(iauth), host, HOSTLEN);
     i_port(iauth) = port;
-    i_addr(iauth) = INADDR_NONE;
-    i_next(iauth) = iauth_active;
+    memset(&i_addr(iauth), 0, sizeof(i_addr(iauth)));
     iauth_active = iauth;
     i_reconnect(iauth) = reconnect;
     iauth_reconnect(iauth);
@@ -328,13 +326,10 @@ static void iauth_dns_callback(void *vptr, struct DNSReply *he)
   struct IAuth *iauth = vptr;
   if (!he) {
     sendto_opmask_butone(0, SNO_OLDSNO, "IAuth connection to %s failed: host lookup failed", i_host(iauth));
-  } else if (he->h_addrtype != AF_INET) {
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth connection to %s failed: bad host type %d", i_host(iauth), he->h_addrtype);
   } else {
-    struct sockaddr_in *sin = (struct sockaddr_in*)&he->addr;
-    i_addr(iauth) = sin->sin_addr.s_addr;
-    if (INADDR_NONE == i_addr(iauth)) {
-      sendto_opmask_butone(0, SNO_OLDSNO, "IAuth connection to %s failed: host came back as INADDR_NONE", i_host(iauth));
+    memcpy(&i_addr(iauth).addr, &he->addr, sizeof(i_addr(iauth).addr));
+    if (!irc_in_addr_valid(&i_addr(iauth).addr)) {
+      sendto_opmask_butone(0, SNO_OLDSNO, "IAuth connection to %s failed: host came back as unresolved", i_host(iauth));
       return;
     }
     iauth_reconnect(iauth);
@@ -357,46 +352,25 @@ static void iauth_schedule_reconnect(struct IAuth *iauth)
 
 static void iauth_reconnect(struct IAuth *iauth)
 {
-  extern struct sockaddr_in VirtualHost;
-  struct sockaddr_in sin;
   IOResult result;
   int fd;
 
-  if (INADDR_NONE == i_addr(iauth)) {
-    i_addr(iauth) = inet_addr(i_host(iauth));
-    if (INADDR_NONE == i_addr(iauth)) {
-      i_query(iauth).vptr = iauth;
-      i_query(iauth).callback = iauth_dns_callback;
-      gethost_byname(i_host(iauth), &i_query(iauth));
-      return;
-    }
-  }
-  fd = socket(AF_INET, SOCK_STREAM, 0);
-  if (0 > fd) {
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth reconnect unable to allocate socket: %s", strerror(errno));
+  if (!irc_in_addr_valid(&i_addr(iauth).addr)
+      && !ircd_aton(&i_addr(iauth).addr, i_host(iauth))) {
+    i_query(iauth).vptr = iauth;
+    i_query(iauth).callback = iauth_dns_callback;
+    gethost_byname(i_host(iauth), &i_query(iauth));
     return;
   }
-  if (feature_bool(FEAT_VIRTUAL_HOST)
-      && bind(fd, (struct sockaddr*)&VirtualHost, sizeof(VirtualHost)) != 0) {
-    close(fd);
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth reconnect unable to bind vhost: %s", strerror(errno));
+  fd = os_socket((feature_bool(FEAT_VIRTUAL_HOST) ? &VirtualHost : NULL), SOCK_STREAM, "IAuth");
+  if (fd < 0)
     return;
-  }
   if (!os_set_sockbufs(fd, SERVER_TCP_WINDOW, SERVER_TCP_WINDOW)) {
     close(fd);
     sendto_opmask_butone(0, SNO_OLDSNO, "IAuth reconnect unable to set socket buffers: %s", strerror(errno));
     return;
   }
-  if (!os_set_nonblocking(fd)) {
-    close(fd);
-    sendto_opmask_butone(0, SNO_OLDSNO, "IAuth reconnect unable to make socket non-blocking: %s", strerror(errno));
-    return;
-  }
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_family = AF_INET;
-  sin.sin_addr.s_addr = i_addr(iauth);
-  sin.sin_port = htons(i_port(iauth));
-  result = os_connect_nonb(fd, &sin);
+  result = os_connect_nonb(fd, &i_addr(iauth));
   if (result == IO_FAILURE) {
     close(fd);
     sendto_opmask_butone(0, SNO_OLDSNO, "IAuth reconnect unable to initiate connection: %s", strerror(errno));
diff --git a/ircd/ircd_getaddrinfo.c b/ircd/ircd_getaddrinfo.c
deleted file mode 100644 (file)
index 3aff6c1..0000000
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "ircd_addrinfo.h"
-#include <stddef.h> /* for offsetof() */
-#include <stdlib.h> /* for free() */
-#include <string.h> /* for memset() */
-#include <unistd.h> /* for close() */
-#include <arpa/inet.h> /* for inet_aton(), inet_pton() */
-#include <errno.h> /* for errno */
-
-#ifndef AI_MASK
-#define AI_MASK (AI_NUMERICHOST | AI_PASSIVE)
-#endif
-
-/*  $Id$ */
-
-static const char in_addrany[]  = { 0, 0, 0, 0 };
-static const char in_loopback[] = { 127, 0, 0, 1 };
-static const char in6_addrany[] = {
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-static const char in6_loopback[] = {
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
-};
-
-static const struct afd {
-       int a_af;
-       int a_addrlen;
-       int a_socklen;
-       int a_off;
-       const char *a_addrany;
-       const char *a_loopback;
-       int a_scoped;
-} afdl [] = {
-#define        N_INET6 0
-#ifdef IPV6
-       {PF_INET6, sizeof(struct in6_addr),
-        sizeof(struct sockaddr_in6),
-        offsetof(struct sockaddr_in6, sin6_addr),
-        in6_addrany, in6_loopback, 1},
-#endif
-#define        N_INET 1
-       {PF_INET, sizeof(struct in_addr),
-        sizeof(struct sockaddr_in),
-        offsetof(struct sockaddr_in, sin_addr),
-        in_addrany, in_loopback, 0},
-       {0, 0, 0, 0, NULL, NULL, 0},
-};
-
-struct explore {
-       int e_af;
-       int e_socktype;
-       int e_protocol;
-       const char *e_protostr;
-       int e_wild;
-#define WILD_AF(ex)            ((ex)->e_wild & 0x01)
-#define WILD_SOCKTYPE(ex)      ((ex)->e_wild & 0x02)
-#define WILD_PROTOCOL(ex)      ((ex)->e_wild & 0x04)
-};
-
-#define ANY 0
-
-static const struct explore explore[] = {
-#ifdef IPV6
-       { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
-       { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
-       { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
-#endif
-       { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
-       { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
-       { PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
-       { PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
-       { PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
-       { PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 },
-       { -1, 0, 0, NULL, 0 },
-};
-
-#define PTON_MAX       16
-
-static int str_isnumber(const char *);
-static int explore_null(const struct addrinfo *,
-       const char *, struct addrinfo **);
-static int explore_numeric(const struct addrinfo *, const char *,
-       const char *, struct addrinfo **);
-static struct addrinfo *get_ai(const struct addrinfo *,
-       const struct afd *, const char *);
-static int get_portmatch(const struct addrinfo *, const char *);
-static int get_port(struct addrinfo *, const char *, int);
-static const struct afd *find_afd(int);
-#if 0
-/* We will need this should we ever want gai_strerror().
- * Note though that GNU libc doesn't define EAI_BADHINTS. */
-static char *ai_errlist[] = {
-       "Success",
-       "Address family for hostname not supported",    /* EAI_ADDRFAMILY */
-       "Temporary failure in name resolution",         /* EAI_AGAIN      */
-       "Invalid value for ai_flags",                   /* EAI_BADFLAGS   */
-       "Non-recoverable failure in name resolution",   /* EAI_FAIL       */
-       "ai_family not supported",                      /* EAI_FAMILY     */
-       "Memory allocation failure",                    /* EAI_MEMORY     */
-       "No address associated with hostname",          /* EAI_NODATA     */
-       "hostname nor servname provided, or not known", /* EAI_NONAME     */
-       "servname not supported for ai_socktype",       /* EAI_SERVICE    */
-       "ai_socktype not supported",                    /* EAI_SOCKTYPE   */
-       "System error returned in errno",               /* EAI_SYSTEM     */
-       "Invalid value for hints",                      /* EAI_BADHINTS   */
-       "Resolved protocol is unknown",                 /* EAI_PROTOCOL   */
-       "Unknown error",                                /* EAI_MAX        */
-};
-#endif
-/* XXX macros that make external reference is BAD. */
-
-#define GET_AI(ai, afd, addr) \
-do { \
-       /* external reference: pai, error, and label free */ \
-       (ai) = get_ai(pai, (afd), (addr)); \
-       if ((ai) == NULL) { \
-               error = EAI_MEMORY; \
-               goto free; \
-       } \
-} while (/*CONSTCOND*/0)
-
-#define GET_PORT(ai, serv) \
-do { \
-       /* external reference: error and label free */ \
-       error = get_port((ai), (serv), 0); \
-       if (error != 0) \
-               goto free; \
-} while (/*CONSTCOND*/0)
-
-#define ERR(err) \
-do { \
-       /* external reference: error, and label bad */ \
-       error = (err); \
-       goto bad; \
-       /*NOTREACHED*/ \
-} while (/*CONSTCOND*/0)
-
-#define MATCH_FAMILY(x, y, w) \
-       ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
-#define MATCH(x, y, w) \
-       ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
-
-#if 0
-/* We will need this should we ever want gai_strerror() */
-char *
-irc_gai_strerror(int ecode)
-{
-       if (ecode < 0 || ecode > EAI_MAX)
-               ecode = EAI_MAX;
-       return ai_errlist[ecode];
-}
-#endif
-
-void
-irc_freeaddrinfo(struct addrinfo *ai)
-{
-       struct addrinfo *next;
-
-       do {
-               next = ai->ai_next;
-               if (ai->ai_canonname)
-                       free(ai->ai_canonname);
-               /* no need to free(ai->ai_addr) */
-               free(ai);
-               ai = next;
-       } while (ai);
-}
-
-static int
-str_isnumber(const char *p)
-{
-       char *ep;
-
-       if (*p == '\0')
-               return 0;
-       ep = NULL;
-       errno = 0;
-       (void)strtoul(p, &ep, 10);
-       if (errno == 0 && ep && *ep == '\0')
-               return 1;
-       else
-               return 0;
-}
-
-int
-irc_getaddrinfo(const char *hostname, const char *servname,
-                const struct addrinfo *hints, struct addrinfo **res)
-{
-  struct addrinfo sentinel;
-  struct addrinfo *cur;
-  int error = 0;
-  struct addrinfo ai;
-  struct addrinfo ai0;
-  struct addrinfo *pai;
-  const struct explore *ex;
-
-  memset(&sentinel, 0, sizeof(sentinel));
-  cur = &sentinel;
-  pai = &ai;
-  pai->ai_flags = 0;
-  pai->ai_family = PF_UNSPEC;
-  pai->ai_socktype = ANY;
-  pai->ai_protocol = ANY;
-  pai->ai_addrlen = 0;
-  pai->ai_canonname = NULL;
-  pai->ai_addr = NULL;
-  pai->ai_next = NULL;
-
-  if (hostname == NULL && servname == NULL)
-    return EAI_NONAME;
-       if (hints) {
-               /* error check for hints */
-               if (hints->ai_addrlen || hints->ai_canonname ||
-                   hints->ai_addr || hints->ai_next)
-                {
-#ifdef EAI_BADHINTS
-                       ERR(EAI_BADHINTS); /* xxx */
-#else
-                       errno = EINVAL;
-                       ERR(EAI_SYSTEM);
-#endif
-                }
-               if (hints->ai_flags & ~AI_MASK)
-                       ERR(EAI_BADFLAGS);
-               switch (hints->ai_family) {
-               case PF_UNSPEC:
-               case PF_INET:
-#ifdef IPV6
-               case PF_INET6:
-#endif
-                       break;
-               default:
-                       ERR(EAI_FAMILY);
-               }
-               memcpy(pai, hints, sizeof(*pai));
-
-               /*
-                * if both socktype/protocol are specified, check if they
-                * are meaningful combination.
-                */
-               if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
-                       for (ex = explore; ex->e_af >= 0; ex++) {
-                               if (pai->ai_family != ex->e_af)
-                                       continue;
-                               if (ex->e_socktype == ANY)
-                                       continue;
-                               if (ex->e_protocol == ANY)
-                                       continue;
-                               if (pai->ai_socktype == ex->e_socktype &&
-                                   pai->ai_protocol != ex->e_protocol) {
-#ifdef EAI_BADHINTS
-                                       ERR(EAI_BADHINTS); /* xxx */
-#else
-                                       errno = EINVAL;
-                                       ERR(EAI_SYSTEM);
-#endif
-                               }
-                       }
-               }
-       }
-
-       /*
-        * check for special cases.  (1) numeric servname is disallowed if
-        * socktype/protocol are left unspecified. (2) servname is disallowed
-        * for raw and other inet{,6} sockets.
-        */
-       if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
-#ifdef IPV6
-           || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
-#endif
-           ) {
-               ai0 = *pai;     /* backup *pai */
-
-               if (pai->ai_family == PF_UNSPEC) {
-#ifdef IPV6
-                       pai->ai_family = PF_INET6;
-#else
-                       pai->ai_family = PF_INET;
-#endif
-               }
-               error = get_portmatch(pai, servname);
-               if (error)
-                       ERR(error);
-
-               *pai = ai0;
-       }
-
-       ai0 = *pai;
-
-       /* NULL hostname, or numeric hostname */
-       for (ex = explore; ex->e_af >= 0; ex++) {
-               *pai = ai0;
-
-               /* PF_UNSPEC entries are prepared for DNS queries only */
-               if (ex->e_af == PF_UNSPEC)
-                       continue;
-
-               if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
-                       continue;
-               if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
-                       continue;
-               if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
-                       continue;
-
-               if (pai->ai_family == PF_UNSPEC)
-                       pai->ai_family = ex->e_af;
-               if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
-                       pai->ai_socktype = ex->e_socktype;
-               if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
-                       pai->ai_protocol = ex->e_protocol;
-
-               if (hostname == NULL)
-                       error = explore_null(pai, servname, &cur->ai_next);
-               else
-                       error = explore_numeric(pai, hostname, servname, &cur->ai_next);
-
-               if (error)
-                       goto free;
-
-               while (cur && cur->ai_next)
-                       cur = cur->ai_next;
-       }
-
-       /*
-        * XXX
-        * If numeric representation of AF1 can be interpreted as FQDN
-        * representation of AF2, we need to think again about the code below.
-        */
-       if (sentinel.ai_next)
-               goto good;
-
-       if (pai->ai_flags & AI_NUMERICHOST)
-               ERR(EAI_NONAME);
-       if (hostname == NULL)
-               ERR(EAI_NODATA);
-
-       /* XXX */
-       if (sentinel.ai_next)
-               error = 0;
-
-       if (error)
-               goto free;
-       if (error == 0) {
-               if (sentinel.ai_next) {
- good:
-                       *res = sentinel.ai_next;
-                       return 0;
-               } else
-                       error = EAI_FAIL;
-       }
- free:
- bad:
-       if (sentinel.ai_next)
-               irc_freeaddrinfo(sentinel.ai_next);
-       *res = NULL;
-       return error;
-}
-
-/*
- * hostname == NULL.
- * passive socket -> anyaddr (0.0.0.0 or ::)
- * non-passive socket -> localhost (127.0.0.1 or ::1)
- */
-static int
-explore_null(const struct addrinfo *pai, const char *servname, struct addrinfo **res)
-{
-  int s;
-  const struct afd *afd;
-  struct addrinfo *cur;
-  struct addrinfo sentinel;
-  int error;
-
-       *res = NULL;
-       sentinel.ai_next = NULL;
-       cur = &sentinel;
-
-       /*
-        * filter out AFs that are not supported by the kernel
-        * XXX errno?
-        */
-       s = socket(pai->ai_family, SOCK_DGRAM, 0);
-       if (s < 0) {
-               if (errno != EMFILE)
-                       return 0;
-       } else
-               close(s);
-
-       /*
-        * if the servname does not match socktype/protocol, ignore it.
-        */
-       if (get_portmatch(pai, servname) != 0)
-               return 0;
-
-       afd = find_afd(pai->ai_family);
-       if (afd == NULL)
-               return 0;
-
-       if (pai->ai_flags & AI_PASSIVE) {
-               GET_AI(cur->ai_next, afd, afd->a_addrany);
-               GET_PORT(cur->ai_next, servname);
-       } else {
-               GET_AI(cur->ai_next, afd, afd->a_loopback);
-               GET_PORT(cur->ai_next, servname);
-       }
-       cur = cur->ai_next;
-
-       *res = sentinel.ai_next;
-       return 0;
-
-free:
-       if (sentinel.ai_next)
-               irc_freeaddrinfo(sentinel.ai_next);
-       return error;
-}
-
-/*
- * numeric hostname
- */
-static int
-explore_numeric(const struct addrinfo *pai, const char *hostname,
-                const char *servname, struct addrinfo **res)
-{
-  const struct afd *afd;
-  struct addrinfo *cur;
-  struct addrinfo sentinel;
-  int error;
-  char pton[PTON_MAX];
-
-  *res = NULL;
-  sentinel.ai_next = NULL;
-  cur = &sentinel;
-
-       /*
-        * if the servname does not match socktype/protocol, ignore it.
-        */
-       if (get_portmatch(pai, servname) != 0)
-               return 0;
-
-       afd = find_afd(pai->ai_family);
-       if (afd == NULL)
-               return 0;
-
-       switch (afd->a_af) {
-#if 1 /*X/Open spec*/
-       case AF_INET:
-               if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
-                       if (pai->ai_family == afd->a_af ||
-                           pai->ai_family == PF_UNSPEC /*?*/) {
-                               GET_AI(cur->ai_next, afd, pton);
-                               GET_PORT(cur->ai_next, servname);
-                               while (cur && cur->ai_next)
-                                       cur = cur->ai_next;
-                       } else
-                               ERR(EAI_FAMILY);        /*xxx*/
-               }
-               break;
-#endif
-       default:
-               if (inet_pton(afd->a_af, hostname, pton) == 1) {
-                       if (pai->ai_family == afd->a_af ||
-                           pai->ai_family == PF_UNSPEC /*?*/) {
-                               GET_AI(cur->ai_next, afd, pton);
-                               GET_PORT(cur->ai_next, servname);
-                               while (cur && cur->ai_next)
-                                       cur = cur->ai_next;
-                       } else
-                               ERR(EAI_FAMILY);        /* XXX */
-               }
-               break;
-       }
-
-       *res = sentinel.ai_next;
-       return 0;
-
-free:
-bad:
-       if (sentinel.ai_next)
-               irc_freeaddrinfo(sentinel.ai_next);
-       return error;
-}
-
-static struct addrinfo *
-get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
-{
-  char *p;
-  struct addrinfo *ai;
-       
-    ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
-               + (afd->a_socklen));
-       if (ai == NULL)
-               return NULL;
-
-       memcpy(ai, pai, sizeof(struct addrinfo));
-       ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
-       memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
-       ai->ai_addrlen = afd->a_socklen;
-       ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
-       p = (char *)(void *)(ai->ai_addr);
-       memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
-       return ai;
-}
-
-static int
-get_portmatch(const struct addrinfo *ai, const char *servname)
-{
-  /* get_port does not touch first argument. when matchonly == 1. */
-  /* LINTED const cast */
-  return(get_port((struct addrinfo *)ai, servname, 1));
-}
-
-static int
-get_port(struct addrinfo *ai, const char *servname, int matchonly)
-{
-  const char *proto;
-  struct servent *sp;
-  int port;
-  int allownumeric;
-
-  if (servname == NULL)
-    return 0;
-       switch (ai->ai_family) {
-       case AF_INET:
-#ifdef AF_INET6
-       case AF_INET6:
-#endif
-               break;
-       default:
-               return 0;
-       }
-
-       switch (ai->ai_socktype) {
-       case SOCK_RAW:
-               return EAI_SERVICE;
-       case SOCK_DGRAM:
-       case SOCK_STREAM:
-               allownumeric = 1;
-               break;
-       case ANY:
-               allownumeric = 0;
-               break;
-       default:
-               return EAI_SOCKTYPE;
-       }
-
-       if (str_isnumber(servname)) {
-               if (!allownumeric)
-                       return EAI_SERVICE;
-               port = atoi(servname);
-               if (port < 0 || port > 65535)
-                       return EAI_SERVICE;
-               port = htons(port);
-       } else {
-               switch (ai->ai_socktype) {
-               case SOCK_DGRAM:
-                       proto = "udp";
-                       break;
-               case SOCK_STREAM:
-                       proto = "tcp";
-                       break;
-               default:
-                       proto = NULL;
-                       break;
-               }
-
-               if ((sp = getservbyname(servname, proto)) == NULL)
-                       return EAI_SERVICE;
-               port = sp->s_port;
-       }
-
-       if (!matchonly) {
-               switch (ai->ai_family) {
-               case AF_INET:
-                       ((struct sockaddr_in *)(void *)
-                           ai->ai_addr)->sin_port = port;
-                       break;
-#ifdef IPV6
-               case AF_INET6:
-                       ((struct sockaddr_in6 *)(void *)
-                           ai->ai_addr)->sin6_port = port;
-                       break;
-#endif
-               }
-       }
-
-       return 0;
-}
-
-static const struct afd *
-find_afd(int af)
-{
-  const struct afd *afd;
-
-  if (af == PF_UNSPEC)
-    return(NULL);
-
-  for (afd = afdl; afd->a_af; afd++)
-  {
-    if (afd->a_af == af)
-      return(afd);
-  }
-
-  return(NULL);
-}
diff --git a/ircd/ircd_getnameinfo.c b/ircd/ircd_getnameinfo.c
deleted file mode 100644 (file)
index 2a514a1..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Issues to be discussed:
- * - Thread safe-ness must be checked
- * - RFC2553 says that we should raise error on short buffer.  X/Open says
- *   we need to truncate the result.  We obey RFC2553 (and X/Open should be
- *   modified).  ipngwg rough consensus seems to follow RFC2553.
- * - What is "local" in NI_FQDN?
- * - NI_NAMEREQD and NI_NUMERICHOST conflict with each other.
- * - (KAME extension) always attach textual scopeid (fe80::1%lo0), if
- *   sin6_scope_id is filled - standardization status?
- *   XXX breaks backward compat for code that expects no scopeid.
- *   beware on merge.
- */
-
-#include "ircd_addrinfo.h"
-#include "ircd_string.h"
-#include <stddef.h> /* for offsetof() */
-#include <stdio.h> /* for snprintf() */
-#include <string.h> /* for strlen() */
-#include <arpa/inet.h> /* for inet_aton(), inet_pton() */
-
-/*  $Id$ */
-
-static const struct afd {
-  int a_af;
-  int a_addrlen;
-  socklen_t a_socklen;
-  int a_off;
-} afdl [] = {
-#ifdef IPV6
-    {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
-             offsetof(struct sockaddr_in6, sin6_addr)},
-#endif
-    {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
-            offsetof(struct sockaddr_in, sin_addr)},
-    {0, 0, 0, 0},
-};
-
-struct sockinet
-{
-  unsigned char si_len;
-  unsigned char si_family;
-  unsigned short si_port;
-};
-
-#ifdef IPV6
-static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
-    size_t, int);
-#endif
-
-int
-irc_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
-                size_t hostlen, char *serv, size_t servlen, int flags)
-{
-  const struct afd *afd;
-  struct servent *sp;
-  unsigned short port;
-  int family, i;
-  const char *addr;
-  uint32_t v4a;
-  char numserv[512];
-  char numaddr[512];
-
-  if (sa == NULL)
-    return EAI_FAIL;
-
-/*     if (sa->sa_len != salen)
-               return EAI_FAIL;
-*/
-       family = sa->sa_family;
-       for (i = 0; afdl[i].a_af; i++)
-               if (afdl[i].a_af == family) {
-                       afd = &afdl[i];
-                       goto found;
-               }
-       return EAI_FAMILY;
-
- found:
-       if (salen != afd->a_socklen)
-               return EAI_FAIL;
-
-       /* network byte order */
-       port = ((const struct sockinet *)sa)->si_port;
-       addr = (const char *)sa + afd->a_off;
-
-       if (serv == NULL || servlen == 0) {
-               /*
-                * do nothing in this case.
-                * in case you are wondering if "&&" is more correct than
-                * "||" here: rfc2553bis-03 says that serv == NULL OR
-                * servlen == 0 means that the caller does not want the result.
-                */
-       } else {
-               if (flags & NI_NUMERICSERV)
-                       sp = NULL;
-               else {
-                       sp = getservbyport(port,
-                               (flags & NI_DGRAM) ? "udp" : "tcp");
-               }
-               if (sp) {
-                       if (strlen(sp->s_name) + 1 > servlen)
-                               return EAI_MEMORY;
-                       ircd_strncpy(serv, sp->s_name, servlen);
-               } else {
-                       snprintf(numserv, sizeof(numserv), "%u", ntohs(port));
-                       if (strlen(numserv) + 1 > servlen)
-                               return EAI_MEMORY;
-                       ircd_strncpy(serv, numserv, servlen);
-               }
-       }
-
-       switch (sa->sa_family) {
-       case AF_INET:
-               v4a =
-                   ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr);
-               if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
-                       flags |= NI_NUMERICHOST;
-               v4a >>= IN_CLASSA_NSHIFT;
-               if (v4a == 0)
-                       flags |= NI_NUMERICHOST;
-               break;
-#ifdef IPV6
-       case AF_INET6:
-           {
-               const struct sockaddr_in6 *sin6;
-               sin6 = (const struct sockaddr_in6 *)sa;
-               switch (sin6->sin6_addr.s6_addr[0]) {
-               case 0x00:
-                       if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
-                               ;
-                       else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
-                               ;
-                       else
-                               flags |= NI_NUMERICHOST;
-                       break;
-               default:
-                       if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
-                               flags |= NI_NUMERICHOST;
-                       }
-                       else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
-                               flags |= NI_NUMERICHOST;
-                       break;
-               }
-           }
-               break;
-#endif
-       }
-       if (host == NULL || hostlen == 0) {
-               /*
-                * do nothing in this case.
-                * in case you are wondering if "&&" is more correct than
-                * "||" here: rfc2553bis-03 says that host == NULL or
-                * hostlen == 0 means that the caller does not want the result.
-                */
-       } else if (flags & NI_NUMERICHOST) {
-               size_t numaddrlen;
-
-               /* NUMERICHOST and NAMEREQD conflicts with each other */
-               if (flags & NI_NAMEREQD)
-                       return EAI_NONAME;
-
-               switch(afd->a_af) {
-#ifdef IPV6
-               case AF_INET6:
-               {
-                       int error;
-
-                       if ((error = ip6_parsenumeric(sa, addr, host,
-                                                     hostlen, flags)) != 0)
-                               return(error);
-                       break;
-               }
-#endif
-               default:
-                       if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
-                           == NULL)
-                               return EAI_SYSTEM;
-                       numaddrlen = strlen(numaddr);
-                       if (numaddrlen + 1 > hostlen) /* don't forget terminator */
-                               return EAI_MEMORY;
-                       ircd_strncpy(host, numaddr, hostlen);
-                       break;
-               }
-       }
-       return(0);
-}
-
-#ifdef IPV6
-static int
-ip6_parsenumeric(const struct sockaddr *sa, const char *addr,
-                 char *host, size_t hostlen, int flags)
-{
-  size_t numaddrlen;
-  char numaddr[512];
-
-  if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) == NULL)
-    return(EAI_SYSTEM);
-
-  numaddrlen = strlen(numaddr);
-
-  if (numaddrlen + 1 > hostlen) /* don't forget terminator */
-    return(EAI_MEMORY);
-
-  if (*numaddr == ':')
-  {
-    *host = '0';
-    ircd_strncpy(host+1, numaddr, hostlen-1);
-  }
-  else
-    ircd_strncpy(host, numaddr, hostlen);
-
-  return(0);
-}
-#endif
index c8943b4e81255df00ee4160d645a8d16407ae052..458e571cdd867cd1a4052c7725514d3524e2e7f0 100644 (file)
@@ -23,6 +23,7 @@
 %{
 #include <unistd.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include "config.h"
 #include "ircd.h"
 #include "ircd_string.h"
@@ -42,6 +43,7 @@ static struct lexer_token {
   TOKEN(CONTACT),
   TOKEN(CLASS),
   TOKEN(PINGFREQ),
+  TOKEN(CONNECT),
   TOKEN(CONNECTFREQ),
   TOKEN(MAXLINKS),
   TOKEN(SENDQ),
index b3ce75b027f7d35715938496c3b3688b4531eb02..e1a0ace201f675f271bcda7cd754158d01731f92 100644 (file)
@@ -295,9 +295,7 @@ generaldesc: DESCRIPTION '=' QSTRING ';'
 
 generalvhost: VHOST '=' QSTRING ';'
 {
-  if (INADDR_NONE ==
-      (localConf.vhost_address.s_addr = inet_addr(yylval.text)))
-    localConf.vhost_address.s_addr = INADDR_ANY;
+  ircd_aton(&localConf.vhost_address, yylval.text);
 };
 
 adminblock: ADMIN '{' adminitems '}'
@@ -389,20 +387,18 @@ connectblock: CONNECT
  port = 0;
 } '{' connectitems '}'
 {
- if (name != NULL && pass != NULL && host != NULL && c_class != NULL && 
-     /*ccount < MAXCONFLINKS &&*/ !strchr(host, '*') &&
-     !strchr(host, '?'))
+ if (name != NULL && pass != NULL && host != NULL && c_class != NULL
+     && !strchr(host, '*') && !strchr(host, '?'))
  {
    aconf = make_conf();
    aconf->status = CONF_SERVER;
    aconf->name = name;
    aconf->passwd = pass;
    aconf->conn_class = c_class;
-   aconf->port = port;
+   aconf->address.port = port;
    aconf->status = CONF_SERVER;
    aconf->host = host;
    aconf->next = GlobalConfList;
-   aconf->ipnum.s_addr = INADDR_NONE;
    lookup_confhost(aconf);
    GlobalConfList = aconf;
  }
@@ -768,25 +764,7 @@ killuhost: HOST '=' QSTRING ';'
   }
   DupString(dconf->hostmask, h);
   DupString(dconf->usermask, u);
-  if (strchr(yylval.text, '.'))
-  {
-    int  c_class;
-    char ipname[16];
-    int  ad[4] = { 0 };
-    int  bits2 = 0;
-    dconf->flags |= DENY_FLAGS_IP;
-    c_class = sscanf(dconf->hostmask, "%d.%d.%d.%d/%d",
-                     &ad[0], &ad[1], &ad[2], &ad[3], &bits2);
-    if (c_class != 5) {
-      dconf->bits = c_class * 8;
-    }
-    else {
-      dconf->bits = bits2;
-    }
-    ircd_snprintf(0, ipname, sizeof(ipname), "%d.%d.%d.%d", ad[0], ad[1],
-                 ad[2], ad[3]);
-    dconf->address = inet_addr(ipname);
-  }
+  ipmask_parse(dconf->hostmask, &dconf->address, &dconf->bits);
 };
 
 killreal: REAL '=' QSTRING ';'
index 2843fe2dc3ffdd2f1fc05bbebad90144947df6a7..57a50e42b3c71fc4d6de61f57affd96b0625fa2c 100644 (file)
 #include "numeric.h"
 #include "fileio.h" /* for fbopen / fbclose / fbputs */
 #include "s_bsd.h"
+#include "s_debug.h"
 #include "s_stats.h"
 #include "send.h"
 #include "sys.h"
 #include "res.h"
 #include "ircd_reslib.h"
-#include "ircd_addrinfo.h"
 
 #include <assert.h>
 #include <string.h>
@@ -70,9 +70,7 @@ typedef enum
   REQ_IDLE,  /* We're doing not much at all */
   REQ_PTR,   /* Looking up a PTR */
   REQ_A,     /* Looking up an A, possibly because AAAA failed */
-#ifdef IPV6
   REQ_AAAA,  /* Looking up an AAAA */
-#endif
   REQ_CNAME, /* We got a CNAME in response, we better get a real answer next */
   REQ_INT    /* ip6.arpa failed, falling back to ip6.int */
 } request_state;
@@ -83,7 +81,7 @@ struct dlink
     struct dlink *next;
 };
 
-struct reslist 
+struct reslist
 {
   struct dlink node;
   int id;
@@ -96,7 +94,7 @@ struct reslist
   char resend;             /* send flag. 0 == dont resend */
   time_t sentat;
   time_t timeout;
-  struct irc_ssaddr addr;
+  struct irc_in_addr addr;
   char *name;
   struct DNSQuery query;   /* query callback for this request */
 };
@@ -108,7 +106,7 @@ static struct reslist *make_request(const struct DNSQuery *query);
 static void do_query_name(const struct DNSQuery *query,
                           const char* name, struct reslist *request, int);
 static void do_query_number(const struct DNSQuery *query,
-                            const struct irc_ssaddr *,
+                            const struct irc_in_addr *,
                             struct reslist *request);
 static void query_name(const char *name, int query_class, int query_type, 
                        struct reslist *request);
@@ -120,7 +118,7 @@ static struct DNSReply *make_dnsreply(struct reslist *request);
 static void res_readreply(struct Event *ev);
 static void timeout_resolver(struct Event *notused);
 
-extern struct irc_ssaddr irc_nsaddr_list[IRCD_MAXNS];
+extern struct irc_sockaddr irc_nsaddr_list[IRCD_MAXNS];
 extern int irc_nscount;
 extern char irc_domain[HOSTLEN];
 
@@ -136,52 +134,14 @@ extern char irc_domain[HOSTLEN];
  *      revised for ircd, cryogen(stu) may03
  */
 static int
-res_ourserver(const struct irc_ssaddr *inp) 
+res_ourserver(const struct irc_sockaddr *inp)
 {
-#ifdef IPV6
-  struct sockaddr_in6 *v6;
-  struct sockaddr_in6 *v6in = (struct sockaddr_in6 *)inp;
-#endif
-  struct sockaddr_in *v4;
-  struct sockaddr_in *v4in = (struct sockaddr_in *)inp; 
   int ns;
 
   for (ns = 0;  ns < irc_nscount;  ns++)
-  {
-    const struct irc_ssaddr *srv = &irc_nsaddr_list[ns];
-#ifdef IPV6
-    v6 = (struct sockaddr_in6 *)srv;
-#endif
-    v4 = (struct sockaddr_in *)srv;
-
-    /* could probably just memcmp(srv, inp, srv.ss_len) here
-     * but we'll air on the side of caution - stu
-     *
-     */
-    switch (srv->ss.ss_family)
-    {
-#ifdef IPV6
-      case AF_INET6:
-        if (srv->ss.ss_family == inp->ss.ss_family)
-          if (v6->sin6_port == v6in->sin6_port)
-            if ((memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr, 
-                    sizeof(struct in6_addr)) == 0) || 
-                (memcmp(&v6->sin6_addr.s6_addr, &in6addr_any, 
-                        sizeof(struct in6_addr)) == 0))
-              return(1);
-        break;
-#endif
-      case AF_INET:
-        if (srv->ss.ss_family == inp->ss.ss_family)
-          if (v4->sin_port == v4in->sin_port)
-            if ((v4->sin_addr.s_addr == INADDR_ANY) || 
-                (v4->sin_addr.s_addr == v4in->sin_addr.s_addr))
-              return(1);
-        break;
-      default:
-        break;
-    }
-  }
+    if (!irc_in_addr_cmp(&inp->addr, &irc_nsaddr_list[ns].addr)
+        && inp->port == irc_nsaddr_list[ns].port)
+      return 1;
 
   return(0);
 }
@@ -196,16 +156,15 @@ start_resolver(void)
   irc_res_init();
 
   if (!request_list.next)
-      request_list.next = request_list.prev = &request_list;
+    request_list.next = request_list.prev = &request_list;
 
   if (!s_active(&res_socket))
   {
     int fd;
-    fd = socket(irc_nsaddr_list[0].ss.ss_family, SOCK_DGRAM, 0);
-    if (fd < 0) {} /* TODO: bail on socket() failure */
-    if (!os_set_nonblocking(fd)) {} /* TODO: bail on failure */
+    fd = os_socket(NULL, SOCK_DGRAM, "Resolver UDP socket");
+    if (fd < 0) return;
     if (!socket_add(&res_socket, res_readreply, NULL, SS_DATAGRAM,
-                    SOCK_EVENT_READABLE, fd)) {} /* TODO: bail on socket_add() failure */
+                    SOCK_EVENT_READABLE, fd)) return;
     timer_init(&res_timeout);
     timer_add(&res_timeout, timeout_resolver, NULL, TT_PERIODIC, 1);
   }
@@ -338,6 +297,7 @@ timeout_query_list(time_t now)
     {
       if (--request->retries <= 0)
       {
+        Debug((DEBUG_DNS, "Request %p out of retries; destroying", request));
         (*request->query.callback)(request->query.vptr, 0);
         rem_request(request);
         continue;
@@ -382,8 +342,10 @@ delete_resolver_queries(const void *vptr)
   {
     next_ptr = ptr->next;
     request = (struct reslist*)ptr;
-    if (vptr == request->query.vptr)
+    if (vptr == request->query.vptr) {
+      Debug((DEBUG_DNS, "Removing request %p with vptr %p", request, vptr));
       rem_request(request);
+    }
   }
 }
 
@@ -408,12 +370,8 @@ send_res_msg(const char *msg, int len, int rcount)
     max_queries = 1;
 
   for (i = 0; i < max_queries; i++)
-  {
-    if (sendto(s_fd(&res_socket), msg, len, 0, 
-        (struct sockaddr*)&(irc_nsaddr_list[i]), 
-        irc_nsaddr_list[i].ss_len) == len) 
+    if (os_sendto_nonb(s_fd(&res_socket), msg, len, NULL, 0, &irc_nsaddr_list[i]) == IO_SUCCESS)
       ++sent;
-  }
 
   return(sent);
 }
@@ -431,10 +389,13 @@ find_id(int id)
   {
     request = (struct reslist*)ptr;
 
-    if (request->id == id)
+    if (request->id == id) {
+      Debug((DEBUG_DNS, "find_id(%d) -> %p", id, request));
       return(request);
+    }
   }
 
+  Debug((DEBUG_DNS, "find_id(%d) -> NULL", id, request));
   return(NULL);
 }
 
@@ -462,27 +423,11 @@ gethost_byname(const char *name, const struct DNSQuery *query)
  * gethost_byaddr - get host name from address
  */
 void
-gethost_byaddr(const struct irc_ssaddr *addr, const struct DNSQuery *query)
+gethost_byaddr(const struct irc_in_addr *addr, const struct DNSQuery *query)
 {
   do_query_number(query, addr, NULL);
 }
 
-/*
- * gethost_byinaddr - kludgy hack for IPv4-only compatibility
- */
-void
-gethost_byinaddr(const struct in_addr *addr, const struct DNSQuery *query)
-{
-  struct irc_ssaddr new_addr;
-  struct sockaddr_in *sin;
-  memset(&new_addr, 0, sizeof(new_addr));
-  sin = (struct sockaddr_in*)&new_addr.ss;
-  sin->sin_family = AF_INET;
-  memcpy(&sin->sin_addr, addr, sizeof(sin->sin_addr));
-  new_addr.ss_len = sizeof(*sin);
-  gethost_byaddr(&new_addr, query);
-}
-
 /*
  * do_query_name - nameserver lookup name
  */
@@ -510,6 +455,7 @@ do_query_name(const struct DNSQuery *query, const char *name,
   }
 
   request->type = type;
+  Debug((DEBUG_DNS, "Requesting DNS %s %s as %p", (request->state == REQ_AAAA ? "AAAA" : "A"), host_name, request));
   query_name(host_name, C_IN, type, request);
 }
 
@@ -517,35 +463,29 @@ do_query_name(const struct DNSQuery *query, const char *name,
  * do_query_number - Use this to do reverse IP# lookups.
  */
 static void
-do_query_number(const struct DNSQuery *query, const struct irc_ssaddr *addr,
+do_query_number(const struct DNSQuery *query, const struct irc_in_addr *addr,
                 struct reslist *request)
 {
   char ipbuf[128];
   const unsigned char *cp;
-#ifdef IPV6
-  const char *intarpa;
-#endif
-  if (addr->ss.ss_family == AF_INET)
-  {
-    struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
-    cp = (const unsigned char*)&v4->sin_addr.s_addr;
 
-    ircd_snprintf(NULL, ipbuf, sizeof(ipbuf),
-                  "%u.%u.%u.%u.in-addr.arpa.",
+  if (irc_in_addr_is_ipv4(addr))
+  {
+    cp = (const unsigned char*)&addr->in6_16[6];
+    ircd_snprintf(NULL, ipbuf, sizeof(ipbuf), "%u.%u.%u.%u.in-addr.arpa.",
                   (unsigned int)(cp[3]), (unsigned int)(cp[2]),
                   (unsigned int)(cp[1]), (unsigned int)(cp[0]));
   }
-#ifdef IPV6
-  else if (addr->ss.ss_family == AF_INET6)
+  else
   {
-    struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
-    cp = (const unsigned char *)&v6->sin6_addr.s6_addr;
+    const char *intarpa;
 
     if (request != NULL && request->state == REQ_INT)
       intarpa = "int";
     else
       intarpa = "arpa";
 
+    cp = (const unsigned char *)&addr->in6_16[0];
     ircd_snprintf(NULL, ipbuf, sizeof(ipbuf),
                   "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
                   "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.%s.",
@@ -566,15 +506,14 @@ do_query_number(const struct DNSQuery *query, const struct irc_ssaddr *addr,
                   (unsigned int)(cp[1]&0xf), (unsigned int)(cp[1]>>4),
                   (unsigned int)(cp[0]&0xf), (unsigned int)(cp[0]>>4), intarpa);
   }
-#endif
   if (request == NULL)
   {
     request       = make_request(query);
     request->type = T_PTR;
-    memcpy(&request->addr, addr, sizeof(struct irc_ssaddr));
+    memcpy(&request->addr, addr, sizeof(request->addr));
     request->name = (char *)MyMalloc(HOSTLEN + 1);
   }
-
+  Debug((DEBUG_DNS, "Requesting DNS PTR %s as %p", ipbuf, request));
   query_name(ipbuf, C_IN, T_PTR, request);
 }
 
@@ -590,7 +529,7 @@ query_name(const char *name, int query_class, int type,
 
   memset(buf, 0, sizeof(buf));
 
-  if ((request_len = irc_res_mkquery(name, query_class, type, 
+  if ((request_len = irc_res_mkquery(name, query_class, type,
       (unsigned char *)buf, sizeof(buf))) > 0)
   {
     HEADER *header = (HEADER *)buf;
@@ -639,12 +578,10 @@ resend_query(struct reslist *request)
     case T_A:
       do_query_name(NULL, request->name, request, request->type);
       break;
-#ifdef IPV6
     case T_AAAA:
       /* didnt work, try A */
       if (request->state == REQ_AAAA)
         do_query_name(NULL, request->name, request, T_A);
-#endif
     default:
       break;
   }
@@ -662,10 +599,7 @@ proc_answer(struct reslist *request, HEADER* header, char* buf, char* eob)
   int type;                    /* answer type */
   int n;                       /* temp count */
   int rd_length;
-  struct sockaddr_in *v4;      /* conversion */
-#ifdef IPV6
-  struct sockaddr_in6 *v6;
-#endif
+
   current = (unsigned char *)buf + sizeof(HEADER);
 
   for (; header->qdcount > 0; --header->qdcount)
@@ -724,8 +658,8 @@ proc_answer(struct reslist *request, HEADER* header, char* buf, char* eob)
     rd_length = irc_ns_get16(current);
     current += RDLENGTH_SIZE;
 
-    /* 
-     * Wait to set request->type until we verify this structure 
+    /*
+     * Wait to set request->type until we verify this structure
      */
     switch (type)
     {
@@ -738,25 +672,18 @@ proc_answer(struct reslist *request, HEADER* header, char* buf, char* eob)
          */
         if (rd_length != sizeof(struct in_addr))
           return(0);
-        v4 = (struct sockaddr_in *)&request->addr;
-        request->addr.ss_len = sizeof(struct sockaddr_in);
-        v4->sin_family = AF_INET;
-        memcpy(&v4->sin_addr, current, sizeof(struct in_addr));
+        memset(&request->addr, 0, sizeof(request->addr));
+        memcpy(&request->addr.in6_16[6], current, sizeof(struct in_addr));
         return(1);
         break;
-#ifdef IPV6
       case T_AAAA:
         if (request->type != T_AAAA)
           return(0);
-        if (rd_length != sizeof(struct in6_addr))
+        if (rd_length != sizeof(struct irc_in_addr))
           return(0);
-        request->addr.ss_len = sizeof(struct sockaddr_in6);
-        v6 = (struct sockaddr_in6 *)&request->addr;
-        v6->sin6_family = AF_INET6;
-        memcpy(&v6->sin6_addr, current, sizeof(struct in6_addr));
+        memcpy(&request->addr, current, sizeof(struct irc_in_addr));
         return(1);
         break;
-#endif
       case T_PTR:
         if (request->type != T_PTR)
           return(0);
@@ -771,9 +698,9 @@ proc_answer(struct reslist *request, HEADER* header, char* buf, char* eob)
 
         return(1);
         break;
-      case T_CNAME: /* first check we already havent started looking 
+      case T_CNAME: /* first check we already havent started looking
                        into a cname */
-        if (request->type != T_PTR) 
+        if (request->type != T_PTR)
           return(0);
 
         if (request->state == REQ_CNAME)
@@ -789,7 +716,7 @@ proc_answer(struct reslist *request, HEADER* header, char* buf, char* eob)
         request->state = REQ_CNAME;
         current += rd_length;
         break;
-        
+
       default:
         /* XXX I'd rather just throw away the entire bogus thing
          * but its possible its just a broken nameserver with still
@@ -809,22 +736,20 @@ proc_answer(struct reslist *request, HEADER* header, char* buf, char* eob)
 static void
 res_readreply(struct Event *ev)
 {
+  struct irc_sockaddr lsin;
   struct Socket *sock;
   char buf[sizeof(HEADER) + MAXPACKET];
   HEADER *header;
   struct reslist *request = NULL;
   struct DNSReply *reply  = NULL;
-  int rc;
+  unsigned int rc;
   int answer_count;
-  socklen_t len = sizeof(struct irc_ssaddr);
-  struct irc_ssaddr lsin;
 
   assert(ev_socket(ev) == &res_socket);
   sock = ev_socket(ev);
 
-  rc = recvfrom(s_fd(sock), buf, sizeof(buf), 0, (struct sockaddr *)&lsin, &len);
-  /* Better to cast the sizeof instead of rc */
-  if (rc <= (int)(sizeof(HEADER)))
+  if (IO_SUCCESS != os_recvfrom_nonb(s_fd(sock), buf, sizeof(buf), &rc, &lsin)
+      || (rc <= sizeof(HEADER)))
     return;
 
   /*
@@ -855,40 +780,39 @@ res_readreply(struct Event *ev)
       resend_query(request);
     else
     {
-      /* 
+      /*
        * If we havent already tried this, and we're looking up AAAA, try A
        * now
        */
 
-#ifdef IPV6
       if (request->state == REQ_AAAA && request->type == T_AAAA)
       {
         request->timeout += 4;
         resend_query(request);
       }
       else if (request->type == T_PTR && request->state != REQ_INT &&
-               request->addr.ss.ss_family == AF_INET6)
+               !irc_in_addr_is_ipv4(&request->addr))
       {
         request->state = REQ_INT;
         request->timeout += 4;
         resend_query(request);
       }
       else
-#endif
       {
         /*
          * If a bad error was returned, we stop here and dont send
          * send any more (no retries granted).
          */
+          Debug((DEBUG_DNS, "Request %p has bad response (state %d type %d)", request, request->state, request->type));
         (*request->query.callback)(request->query.vptr, 0);
        rem_request(request);
-      } 
+      }
     }
 
     return;
   }
   /*
-   * If this fails there was an error decoding the received packet, 
+   * If this fails there was an error decoding the received packet,
    * try it again and hope it works the next time.
    */
   answer_count = proc_answer(request, header, buf, buf + rc);
@@ -903,6 +827,7 @@ res_readreply(struct Event *ev)
          * got a PTR response with no name, something bogus is happening
          * don't bother trying again, the client address doesn't resolve
          */
+        Debug((DEBUG_DNS, "Request %p PTR had empty name", request));
         (*request->query.callback)(request->query.vptr, reply);
         rem_request(request);
         return;
@@ -910,15 +835,15 @@ res_readreply(struct Event *ev)
 
       /*
        * Lookup the 'authoritative' name that we were given for the
-       * ip#. 
-       *
+       * ip#.
        */
 #ifdef IPV6
-      if (request->addr.ss.ss_family == AF_INET6)
+      if (!irc_in_addr_is_ipv4(&request->addr))
         gethost_byname_type(request->name, &request->query, T_AAAA);
       else
 #endif
       gethost_byname_type(request->name, &request->query, T_A);
+      Debug((DEBUG_DNS, "Request %p switching to forward resolution", request));
       rem_request(request);
     }
     else
@@ -928,6 +853,7 @@ res_readreply(struct Event *ev)
        */
       reply = make_dnsreply(request);
       (*request->query.callback)(request->query.vptr, (reply) ? reply : 0);
+      Debug((DEBUG_DNS, "Request %p got forward resolution", request));
       rem_request(request);
     }
   }
@@ -939,6 +865,7 @@ res_readreply(struct Event *ev)
     assert(0);
 
     /* XXX don't leak it */
+    Debug((DEBUG_DNS, "Request %p was unexpected(!)", request));
     rem_request(request);
   }
 }
@@ -964,10 +891,8 @@ report_dns_servers(struct Client *source_p, struct StatDesc *sd, int stat, char
 
   for (i = 0; i < irc_nscount; i++)
   {
-    irc_getnameinfo((struct sockaddr *)&(irc_nsaddr_list[i]),
-                    irc_nsaddr_list[i].ss_len, ipaddr, sizeof(ipaddr), NULL, 0,
-                    NI_NUMERICHOST);
-    send_reply(source_p, RPL_STATSALINE, ipaddr); 
+    ircd_ntoa_r(ipaddr, &irc_nsaddr_list[i].addr);
+    send_reply(source_p, RPL_STATSALINE, ipaddr);
   }
 }
 
@@ -983,7 +908,7 @@ cres_mem(struct Client* sptr)
     request = (struct reslist*)dlink;
     request_mem += sizeof(*request);
     if (request->name)
-      request_mem += strlen(request->name) + 1; 
+      request_mem += strlen(request->name) + 1;
     ++request_count;
   }
 
@@ -991,3 +916,41 @@ cres_mem(struct Client* sptr)
             ":Resolver: requests %d(%d)", request_count, request_mem);
   return request_mem;
 }
+
+int irc_in_addr_valid(const struct irc_in_addr *addr)
+{
+  unsigned int ii;
+  unsigned short val;
+
+  val = addr->in6_16[0];
+  if (val != 0 || val != 0xffff)
+    return 1;
+  for (ii = 1; ii < 8; ii++)
+    if (addr->in6_16[ii] != val)
+      return 1;
+  return 0;
+}
+
+int irc_in_addr_cmp(const struct irc_in_addr *a, const struct irc_in_addr *b)
+{
+  if (irc_in_addr_is_ipv4(a))
+    return a->in6_16[6] != b->in6_16[6]
+        || a->in6_16[7] != b->in6_16[7]
+        || !irc_in_addr_is_ipv4(b);
+  else
+    return memcmp(a, b, sizeof(*a));
+}
+
+int irc_in_addr_is_loopback(const struct irc_in_addr *addr)
+{
+  if (addr->in6_16[0] != 0
+    || addr->in6_16[1] != 0
+    || addr->in6_16[2] != 0
+    || addr->in6_16[3] != 0
+    || addr->in6_16[4] != 0)
+    return 0;
+  if ((addr->in6_16[5] == 0xffff) || (addr->in6_16[5] == 0 && addr->in6_16[6] != 0))
+    return (ntohs(addr->in6_16[6]) & 0xff00) == 0x7f00;
+  else
+    return addr->in6_16[5] == 0 && addr->in6_16[6] == 0 && htons(addr->in6_16[7]) == 1;
+}
index 699a2d899d90343d7a187aba1900dcf2640e4bd8..ba953bb3f1a4e4f2d2453e7389f801538fd8a63e 100644 (file)
@@ -86,7 +86,6 @@
 #include "ircd_defs.h"
 #include "fileio.h"
 #include "ircd_string.h"
-#include "ircd_addrinfo.h"
 
 #include <ctype.h>
 #include <errno.h>
 
 /* $Id$ */
 
-struct irc_ssaddr irc_nsaddr_list[IRCD_MAXNS];
+struct irc_sockaddr irc_nsaddr_list[IRCD_MAXNS];
 int irc_nscount = 0;
 char irc_domain[HOSTLEN + 1];
 
@@ -221,26 +220,18 @@ parse_resvconf(void)
 static void
 add_nameserver(char *arg)
 {
-  struct addrinfo hints, *res;
+  struct irc_sockaddr res;
+
   /* Done max number of nameservers? */
   if ((irc_nscount + 1) >= IRCD_MAXNS)
     return;
 
-  memset(&hints, 0, sizeof(hints));
-  hints.ai_family   = PF_UNSPEC;
-  hints.ai_socktype = SOCK_DGRAM;
-  hints.ai_flags    = AI_PASSIVE | AI_NUMERICHOST;
-
-  if (irc_getaddrinfo(arg, "domain", &hints, &res))
-    return;
-
-  if (res == NULL)
-    return;
-
-  memcpy(&irc_nsaddr_list[irc_nscount].ss, res->ai_addr, res->ai_addrlen);
-  irc_nsaddr_list[irc_nscount].ss_len = res->ai_addrlen;
+  /* Failure converting from numeric string? */
+  if (!ircd_aton(&res.addr, arg))
+      return;
+  res.port = 53;
+  memcpy(&irc_nsaddr_list[irc_nscount], &res, sizeof(irc_nsaddr_list[irc_nscount]));
   irc_nscount++;
-  irc_freeaddrinfo(res);
 }
 
 /*
index dc3886ef51ed680809a08e2b28001a94b0a3d0da..dc9a4613cc0da973ada4699499ddd51c182893a4 100644 (file)
 #include "ircd_defs.h"
 #include "ircd_chattr.h"
 #include "ircd_log.h"
+#include "res.h"
+
 #include <assert.h>
 #include <string.h>
 #include <regex.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
 /*
  * include the character attribute tables here
  */
@@ -385,7 +390,7 @@ char* host_from_uh(char* host, const char* userhost, size_t n)
   return host;
 }
 
-/* 
+/*
  * this new faster inet_ntoa was ripped from:
  * From: Thomas Helvey <tomh@inxpress.net>
  */
@@ -430,40 +435,229 @@ static const char* IpQuadTab[] =
  *      argv 11/90).
  *  inet_ntoa --  its broken on some Ultrix/Dynix too. -avalon
  */
-const char* ircd_ntoa(const char* in)
+const char* ircd_ntoa(const struct irc_in_addr* in)
 {
-  static char buf[20];
+  static char buf[SOCKIPLEN];
   return ircd_ntoa_r(buf, in);
 }
 
+/* This doesn't really belong here, but otherwise umkpasswd breaks. */
+int irc_in_addr_is_ipv4(const struct irc_in_addr *addr)
+{
+  return addr->in6_16[0] == 0
+    && addr->in6_16[1] == 0
+    && addr->in6_16[2] == 0
+    && addr->in6_16[3] == 0
+    && addr->in6_16[4] == 0
+    && (addr->in6_16[5] == 0 || addr->in6_16[5] == 0xffff)
+    && addr->in6_16[6] != 0;
+}
+
 /*
  * reentrant version of above
  */
-const char* ircd_ntoa_r(char* buf, const char* in)
+const char* ircd_ntoa_r(char* buf, const struct irc_in_addr* in)
 {
-  char*                p = buf;
-  const unsigned char* a = (const unsigned char*)in;
-  const char*          n;
-
-  assert(0 != buf);
-  assert(0 != in);
-
-  n = IpQuadTab[*a++];
-  while ((*p = *n++))
-    ++p;
-  *p++ = '.';
-  n = IpQuadTab[*a++];
-  while ((*p = *n++))
-    ++p;
-  *p++ = '.';
-  n = IpQuadTab[*a++];
-  while ((*p = *n++))
-    ++p;
-  *p++ = '.';
-  n = IpQuadTab[*a];
-  while ((*p = *n++))
-    ++p;
-  return buf;
+    assert(buf != NULL);
+    assert(in != NULL);
+
+    if (irc_in_addr_is_ipv4(in)) {
+      unsigned int pos, len;
+      unsigned char *pch;
+
+      pch = (unsigned char*)&in->in6_16[6];
+      len = strlen(IpQuadTab[*pch]);
+      memcpy(buf, IpQuadTab[*pch++], len);
+      pos = len;
+      buf[pos++] = '.';
+      len = strlen(IpQuadTab[*pch]);
+      memcpy(buf+pos, IpQuadTab[*pch++], len);
+      pos += len;
+      buf[pos++] = '.';
+      len = strlen(IpQuadTab[*pch]);
+      memcpy(buf+pos, IpQuadTab[*pch++], len);
+      pos += len;
+      buf[pos++] = '.';
+      len = strlen(IpQuadTab[*pch]);
+      memcpy(buf+pos, IpQuadTab[*pch++], len);
+      buf[pos + len] = '\0';
+      return buf;
+    } else {
+      static const char hexdigits[] = "0123456789abcdef";
+      unsigned int pos, part, max_start, max_zeros, curr_zeros, ii;
+
+      /* Find longest run of zeros. */
+      for (max_start = ii = 1, max_zeros = curr_zeros = 0; ii < 8; ++ii) {
+        if (!in->in6_16[ii])
+          curr_zeros++;
+        else if (curr_zeros > max_zeros) {
+          max_start = ii - curr_zeros;
+          max_zeros = curr_zeros;
+          curr_zeros = 0;
+        }
+      }
+      if (curr_zeros > max_zeros) {
+        max_start = ii - curr_zeros;
+        max_zeros = curr_zeros;
+      }
+
+      /* Print out address. */
+#define APPEND(CH) do { buf[pos++] = (CH); } while (0)
+      for (pos = ii = 0; (ii < 8); ++ii) {
+        if ((max_zeros > 0) && (ii == max_start)) {
+          APPEND(':');
+          ii += max_zeros - 1;
+          continue;
+        }
+        part = ntohs(in->in6_16[ii]);
+        if (part >= 0x1000)
+          APPEND(hexdigits[part >> 12]);
+        if (part >= 0x100)
+          APPEND(hexdigits[(part >> 8) & 15]);
+        if (part >= 0x10)
+          APPEND(hexdigits[(part >> 4) & 15]);
+        APPEND(hexdigits[part & 15]);
+        if (ii < 7)
+          APPEND(':');
+      }
+      if (max_zeros + max_start == 8)
+        APPEND(':');
+#undef APPEND
+
+      /* Nul terminate and return number of characters used. */
+      buf[pos++] = '\0';
+      return buf;
+    }
 }
 
+static unsigned int
+ircd_aton_ip4(const char *input, unsigned int *output)
+{
+  unsigned int dots = 0, pos = 0, part = 0, ip = 0;
 
+  /* Intentionally no support for bizarre IPv4 formats (plain
+   * integers, octal or hex components) -- only vanilla dotted
+   * decimal quads.
+   */
+  if (input[0] == '.')
+    return 0;
+  while (1) {
+    if (IsDigit(input[pos])) {
+      part = part * 10 + input[pos++] - '0';
+      if (part > 255)
+        return 0;
+      if ((dots == 3) && !IsDigit(input[pos])) {
+        *output = htonl(ip | part);
+        return pos;
+      }
+    } else if (input[pos] == '.') {
+      if (input[++pos] == '.')
+        return 0;
+      ip |= part << (24 - 8 * dots++);
+      part = 0;
+    } else
+      return 0;
+  }
+}
+
+/* ircd_aton - Parse a numeric IPv4 or IPv6 address into an irc_in_addr.
+ * Returns number of characters used by address, or 0 if the address was
+ * unparseable or malformed.
+ */
+int
+ircd_aton(struct irc_in_addr *ip, const char *input)
+{
+  char *colon;
+  char *dot;
+
+  assert(ip);
+  assert(input);
+  memset(ip, 0, sizeof(*ip));
+  colon = strchr(input, ':');
+  dot = strchr(input, '.');
+
+  if (colon && (!dot || (dot > colon))) {
+    unsigned int part = 0, pos = 0, ii = 0, colon = 8;
+    const char *part_start = NULL;
+
+    /* Parse IPv6, possibly like ::127.0.0.1.
+     * This is pretty straightforward; the only trick is borrowed
+     * from Paul Vixie (BIND): when it sees a "::" continue as if
+     * it were a single ":", but note where it happened, and fill
+     * with zeros afterwards.
+     */
+    if (input[pos] == ':') {
+      if ((input[pos+1] != ':') || (input[pos+2] == ':'))
+        return 0;
+      colon = 0;
+      pos += 2;
+    }
+    while (ii < 8) {
+      unsigned char chval;
+
+      switch (input[pos]) {
+      case '0': case '1': case '2': case '3': case '4':
+      case '5': case '6': case '7': case '8': case '9':
+          chval = input[pos] - '0';
+      use_chval:
+        part = (part << 4) | chval;
+        if (part > 0xffff)
+          return 0;
+        pos++;
+        break;
+      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+          chval = input[pos] - 'A' + 10;
+          goto use_chval;
+      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+          chval = input[pos] - 'a' + 10;
+          goto use_chval;
+      case ':':
+        part_start = input + ++pos;
+        if (input[pos] == '.')
+          return 0;
+        ip->in6_16[ii++] = htons(part);
+        part = 0;
+        if (input[pos] == ':') {
+          if (colon < 8)
+            return 0;
+          colon = ii;
+          pos++;
+        }
+        break;
+      case '.': {
+        uint32_t ip4;
+        unsigned int len;
+        len = ircd_aton_ip4(input + pos, &ip4);
+        if (!len || (ii > 6))
+          return 0;
+        ip->in6_16[ii++] = htons(ntohl(ip4) >> 16);
+        ip->in6_16[ii++] = htons(ntohl(ip4) & 65535);
+        pos += len;
+        break;
+      }
+      default: {
+        unsigned int jj;
+        if (colon >= 8)
+          return 0;
+        /* Shift stuff after "::" up and fill middle with zeros. */
+        ip->in6_16[ii++] = htons(part);
+        for (jj = 0; jj < ii - colon; jj++)
+          ip->in6_16[7 - jj] = ip->in6_16[ii - jj - 1];
+        for (jj = 0; jj < 8 - ii; jj++)
+          ip->in6_16[colon + jj] = 0;
+        return pos;
+      }
+      }
+    }
+    return pos;
+  } else if (dot) {
+    unsigned int addr;
+    int len = ircd_aton_ip4(input, &addr);
+    if (len) {
+      ip->in6_16[6] = htons(ntohl(addr) >> 16);
+      ip->in6_16[7] = htons(ntohl(addr) & 65535);
+      return len;
+    }
+  }
+  return 0; /* parse failed */
+}
index 6b67d0ca8a0f1c9a80e0b642f19e29805ffd5c51..0556ce98eb82f0155d7f0589e6c93bd0038ec51e 100644 (file)
@@ -30,6 +30,7 @@
 #include "ircd_reply.h"
 #include "ircd_snprintf.h"
 #include "ircd_string.h"
+#include "match.h"
 #include "numeric.h"
 #include "s_bsd.h"
 #include "s_conf.h"
@@ -56,17 +57,17 @@ struct Listener* ListenerPollList = 0;
 
 static void accept_connection(struct Event* ev);
 
-static struct Listener* make_listener(int port, struct in_addr addr)
+static struct Listener* make_listener(int port, const struct irc_in_addr *addr)
 {
-  struct Listener* listener = 
+  struct Listener* listener =
     (struct Listener*) MyMalloc(sizeof(struct Listener));
   assert(0 != listener);
 
   memset(listener, 0, sizeof(struct Listener));
 
   listener->fd          = -1;
-  listener->port        = port;
-  listener->addr.s_addr = addr.s_addr;
+  listener->addr.port   = port;
+  memcpy(&listener->addr.addr, addr, sizeof(listener->addr.addr));
 
 #ifdef NULL_POINTER_NOT_ZERO
   listener->next = NULL;
@@ -91,7 +92,7 @@ const char* get_listener_name(const struct Listener* listener)
 {
   static char buf[HOSTLEN + PORTNAMELEN + 4];
   assert(0 != listener);
-  ircd_snprintf(0, buf, sizeof(buf), "%s:%u", cli_name(&me), listener->port);
+  ircd_snprintf(0, buf, sizeof(buf), "%s:%u", cli_name(&me), listener->addr.port);
   return buf;
 }
 
@@ -132,7 +133,7 @@ void show_ports(struct Client* sptr, struct StatDesc* sd, int stat,
     port = atoi(param);
 
   for (listener = ListenerPollList; listener; listener = listener->next) {
-    if (port && port != listener->port)
+    if (port && port != listener->addr.port)
       continue;
     flags[0] = (listener->server) ? 'S' : 'C';
     if (listener->hidden) {
@@ -144,7 +145,7 @@ void show_ports(struct Client* sptr, struct StatDesc* sd, int stat,
     else
       flags[1] = '\0';
 
-    send_reply(sptr, RPL_STATSPLINE, listener->port, listener->ref_count,
+    send_reply(sptr, RPL_STATSPLINE, listener->addr.port, listener->ref_count,
               flags, (listener->active) ? "active" : "disabled");
     if (--count == 0)
       break;
@@ -168,41 +169,14 @@ void show_ports(struct Client* sptr, struct StatDesc* sd, int stat,
 
 static int inetport(struct Listener* listener)
 {
-  struct sockaddr_in sin;
   int                fd;
 
   /*
    * At first, open a new socket
    */
-  if (-1 == (fd = socket(AF_INET, SOCK_STREAM, 0))) {
-    report_error(SOCKET_ERROR_MSG, get_listener_name(listener), errno);
+  fd = os_socket(&listener->addr, SOCK_STREAM, get_listener_name(listener));
+  if (fd < 0)
     return 0;
-  }
-  else if (fd > MAXCLIENTS - 1) {
-    report_error(CONNLIMIT_ERROR_MSG, get_listener_name(listener), 0);
-    close(fd);
-    return 0;
-  }
-
-  if (!os_set_reuseaddr(fd)) {
-    report_error(REUSEADDR_ERROR_MSG, get_listener_name(listener), errno);
-    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.
-   */
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_family = AF_INET;
-  sin.sin_addr   = listener->addr;
-  sin.sin_port   = htons(listener->port);
-
-  if (bind(fd, (struct sockaddr*) &sin, sizeof(sin))) {
-    report_error(BIND_ERROR_MSG, get_listener_name(listener), errno);
-    close(fd);
-    return 0;
-  }
   /*
    * Set the buffer sizes for the listener. Accepted connections
    * inherit the accepting sockets settings for SO_RCVBUF S_SNDBUF
@@ -222,14 +196,6 @@ static int inetport(struct Listener* listener)
     close(fd);
     return 0;
   }
-  /*
-   * XXX - this should always work, performance will suck if it doesn't
-   */
-  if (!os_set_nonblocking(fd)) {
-    report_error(NONB_ERROR_MSG, get_listener_name(listener), errno);
-    close(fd);
-    return 0;
-  }
   /*
    * Set the TOS bits - this is nonfatal if it doesn't stick.
    */
@@ -255,70 +221,27 @@ static int inetport(struct Listener* listener)
  * XXX - this function does N comparisons so if the list is huge
  * we may want to do something else for this. (rehash and init use this)
  */
-static struct Listener* find_listener(int port, struct in_addr addr)
+static struct Listener* find_listener(int port, const struct irc_in_addr *addr)
 {
   struct Listener* listener;
   for (listener = ListenerPollList; listener; listener = listener->next) {
-    if (port == listener->port && addr.s_addr == listener->addr.s_addr)
+    if (port == listener->addr.port && !memcmp(addr, &listener->addr.addr, sizeof(*addr)))
       return listener;
   }
   return 0;
 }
 
 /*
- * set_listener_mask - set the connection mask for this listener
- */
-static void set_listener_mask(struct Listener* listener, const char* mask)
-{
-  int  ad[4];
-  char ipname[20];
-
-  assert(0 != listener);
-
-  if (EmptyString(mask) || 0 == strcmp(mask, "*")) {
-    listener->mask.s_addr = 0;
-    return;
-  }
-  ad[0] = ad[1] = ad[2] = ad[3] = 0;
-  /*
-   * do it this way because building ip# from separate values for each
-   * byte requires endian knowledge or some nasty messing. Also means
-   * easy conversion of "*" 0.0.0.0 or 134.* to 134.0.0.0 :-)
-   */
-  sscanf(mask, "%d.%d.%d.%d", &ad[0], &ad[1], &ad[2], &ad[3]);
-  ircd_snprintf(0, ipname, sizeof(ipname), "%d.%d.%d.%d", ad[0], ad[1], ad[2],
-               ad[3]);
-  listener->mask.s_addr = inet_addr(ipname);
-}
-
-/*
- * connection_allowed - spin through mask and addr passed to see if connect 
- * allowed on a listener, uses mask generated by set_listener_mask
- */
-static int connection_allowed(const char* addr, const char* mask)
-{
-  int i = 4;
-  for ( ; i > 0; --i) {
-    if (*mask && *addr != *mask)
-      break;
-    ++addr;
-    ++mask;
-  }
-  return (0 == i);
-}
-
-
-/*
- * add_listener- create a new listener 
+ * 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, const char* mask,
-                  int is_server, int is_hidden) 
+                  int is_server, int is_hidden)
 {
   struct Listener* listener;
-  struct in_addr   vaddr;
+  struct irc_in_addr vaddr;
 
   /*
    * if no port in conf line, don't bother
@@ -326,35 +249,40 @@ void add_listener(int port, const char* vhost_ip, const char* mask,
   if (0 == port)
     return;
 
-  vaddr.s_addr = INADDR_ANY;
+  memset(&vaddr, 0, sizeof(vaddr));
 
-  if (!EmptyString(vhost_ip) && strcmp(vhost_ip,"*") != 0) {
-    vaddr.s_addr = inet_addr(vhost_ip);
-    if (INADDR_NONE == vaddr.s_addr)
+  if (!EmptyString(vhost_ip)
+      && strcmp(vhost_ip, "*")
+      && !ircd_aton(&vaddr, vhost_ip))
       return;
-  }
 
-  if ((listener = find_listener(port, vaddr))) {
+  if ((listener = find_listener(port, &vaddr))) {
     /*
-     * set active flag and change connect mask here, it's the only thing 
+     * set active flag and change connect mask here, it's the only thing
      * that can change on a rehash
      */
     listener->active = 1;
-    set_listener_mask(listener, mask);
+    if (mask)
+      ipmask_parse(mask, &listener->mask, &listener->mask_bits);
+    else
+      listener->mask_bits = 0;
     listener->hidden = is_hidden;
     listener->server = is_server;
     return;
   }
 
-  listener = make_listener(port, vaddr);
+  listener = make_listener(port, &vaddr);
 
   if (inetport(listener)) {
     listener->active = 1;
-    set_listener_mask(listener, mask);
+    if (mask)
+      ipmask_parse(mask, &listener->mask, &listener->mask_bits);
+    else
+      listener->mask_bits = 0;
     listener->hidden = is_hidden;
     listener->server = is_server;
     listener->next   = ListenerPollList;
-    ListenerPollList = listener; 
+    ListenerPollList = listener;
   }
   else
     free_listener(listener);
@@ -426,10 +354,9 @@ void release_listener(struct Listener* listener)
  */
 static void accept_connection(struct Event* ev)
 {
-  struct Listener* listener;
-  struct sockaddr_in addr = { 0 };
-  unsigned int       addrlen = sizeof(struct sockaddr_in);
-  int                fd;
+  struct Listener*    listener;
+  struct irc_sockaddr addr;
+  int                 fd;
 
   assert(0 != ev_socket(ev));
   assert(0 != s_data(ev_socket(ev)));
@@ -462,8 +389,7 @@ static void accept_connection(struct Event* ev)
      */
     while (1)
     {
-      if ((fd = accept(listener->fd, (struct sockaddr*) &addr, &addrlen))
-          == -1)
+      if ((fd = os_accept(listener->fd, &addr)) == -1)
       {
         if (errno == EAGAIN ||
 #ifdef EWOULDBLOCK
@@ -507,8 +433,7 @@ static void accept_connection(struct Event* ev)
       /*
        * check to see if connection is allowed for this address mask
        */
-      if (!connection_allowed((const char*) &addr,
-                              (const char*) &listener->mask))
+      if (!ipmask_check(&addr.addr, &listener->mask, listener->mask_bits))
       {
         ++ServerStats->is_ref;
         send(fd, "ERROR :Use another port\r\n", 25, 0);
index b7dfd3ce5c91f06ec8a75c5ea23f9ca9a8c41c0f..55feddd1732b495b2472ad8754d0a7ade56fbf11 100644 (file)
@@ -185,13 +185,12 @@ int ms_connect(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   /*
    * save the old port
    */
-  tmpport = aconf->port;
-  if (port) { 
-    aconf->port = port;
-  }
-  else {
-    port = aconf->port;
-  }
+  tmpport = aconf->address.port;
+  if (port)
+    aconf->address.port = port;
+  else
+    port = aconf->address.port;
+
   /*
    * Notify all operators about remote connect requests
    */
@@ -210,7 +209,7 @@ int ms_connect(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :*** Connection to %s failed",
                  sptr, aconf->name);
   }
-  aconf->port = tmpport;
+  aconf->address.port = tmpport;
   return 0;
 }
 
@@ -314,7 +313,7 @@ int mo_connect(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
    *  use the default from configuration structure. If missing
    *  from there, then use the precompiled default.
    */
-  port = aconf->port;
+  port = aconf->address.port;
   if (parc > 2) {
     assert(0 != parv[2]);
     if (0 == (port = atoi(parv[2]))) {
@@ -329,8 +328,8 @@ int mo_connect(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     return 0;
   }
 
-  tmpport = aconf->port;
-  aconf->port = port;
+  tmpport = aconf->address.port;
+  aconf->address.port = port;
 
   if (connect_server(aconf, sptr)) {
     sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :*** Connecting to %s.", sptr,
@@ -340,6 +339,6 @@ int mo_connect(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :*** Connection to %s failed",
                  sptr, aconf->name);
   }
-  aconf->port = tmpport;
+  aconf->address.port = tmpport;
   return 0;
 }
index e7b08f793afb1ea4f041b3fd1039eee770476f12..d993a66f3d16b54402cfe28e14141673ad960960 100644 (file)
@@ -247,7 +247,7 @@ int m_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
    */
   if (IsUnknown(acptr) && MyConnect(acptr)) {
     ++ServerStats->is_ref;
-    IPcheck_connect_fail(cli_ip(acptr));
+    IPcheck_connect_fail(&cli_ip(acptr));
     exit_client(cptr, acptr, &me, "Overridden by other sign on");
     return set_nick_name(cptr, sptr, nick, parc, parv);
   }
@@ -377,7 +377,7 @@ int ms_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   if (IsUnknown(acptr) && MyConnect(acptr))
   {
     ServerStats->is_ref++;
-    IPcheck_connect_fail(cli_ip(acptr));
+    IPcheck_connect_fail(&cli_ip(acptr));
     exit_client(cptr, acptr, &me, "Overridden by other sign on");
     return set_nick_name(cptr, sptr, nick, parc, parv);
   }
@@ -401,13 +401,15 @@ int ms_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
    */
   if (IsServer(sptr))
   {
+    struct irc_in_addr ip;
     /*
      * A new NICK being introduced by a neighbouring
      * server (e.g. message type ":server NICK new ..." received)
      *
      * compare IP address and username
      */
-    differ =  (cli_ip(acptr).s_addr != htonl(base64toint(parv[parc - 3]))) ||
+    base64toip(parv[parc - 3], &ip);
+    differ =  (0 != memcmp(&cli_ip(acptr), &ip, sizeof(cli_ip(acptr)))) ||
               (0 != ircd_strcmp(cli_user(acptr)->username, parv[4]));
     sendto_opmask_butone(0, SNO_OLDSNO, "Nick collision on %C (%C %Tu <- "
                         "%C %Tu (%s user@host))", acptr, cli_from(acptr),
@@ -421,8 +423,8 @@ int ms_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
      *
      * compare IP address and username
      */
-    differ =  (cli_ip(acptr).s_addr != cli_ip(sptr).s_addr) ||
-              (0 != ircd_strcmp(cli_user(acptr)->username, cli_user(sptr)->username));              
+    differ =  (0 != memcmp(&cli_ip(acptr), &cli_ip(sptr), sizeof(cli_ip(acptr)))) ||
+              (0 != ircd_strcmp(cli_user(acptr)->username, cli_user(sptr)->username));
     sendto_opmask_butone(0, SNO_OLDSNO, "Nick change collision from %C to "
                         "%C (%C %Tu <- %C %Tu)", sptr, acptr, cli_from(acptr),
                         cli_lastnick(acptr), cptr, lastnick);
index a180c0559f22bc77160a388dba7c19d050f4d10f..cc2e47cedf17d09513bc9691752506a6d0f20f7c 100644 (file)
@@ -144,9 +144,9 @@ int m_oper(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     return need_more_params(sptr, "OPER");
 
   aconf = find_conf_exact(name, cli_username(sptr), cli_sockhost(sptr), CONF_OPERATOR);
-  if (!aconf) 
+  if (!aconf)
     aconf = find_conf_exact(name, cli_username(sptr),
-                            ircd_ntoa((const char*) &(cli_ip(cptr))), CONF_OPERATOR);
+                            ircd_ntoa(&cli_ip(cptr)), CONF_OPERATOR);
 
   if (!aconf || IsIllegal(aconf))
   {
index 3568112e1436fbb2bde5c40fff919ba0e2c68362..80078ff2c54b7420fbbe3b403fe63448e3d80e78 100644 (file)
@@ -100,7 +100,7 @@ static void userip_formatter(struct Client* cptr, struct Client *sptr, struct Ms
              cli_user(cptr)->away ? '-' : '+', cli_user(cptr)->username,
              HasHiddenHost(cptr) && !IsAnOper(sptr) && (sptr != cptr) ?
              feature_str(FEAT_HIDDEN_IP) :
-             ircd_ntoa((const char*) &(cli_ip(cptr))));
+             ircd_ntoa(&cli_ip(cptr)));
 }
 
 /*
index 797b5a87e581be327f8c113c3b7c3af810e8193e..c4fd81f2a93a805fa891865905f2d9648b6bb990 100644 (file)
@@ -351,12 +351,14 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
      real mask and try to match all relevant fields */
   if (!(commas || (counter < 1)))
   {
+    struct irc_in_addr imask;
     int minlen, cset;
-    static struct in_mask imask;
+    unsigned char ibits;
+
     if (mask)
     {
       matchcomp(mymask, &minlen, &cset, mask);
-      if (matchcompIP(&imask, mask))
+      if (!ipmask_parse(mask, &imask, &ibits))
         matchsel &= ~WHO_FIELD_NIP;
       if ((minlen > NICKLEN) || !(cset & NTL_IRCNK))
         matchsel &= ~WHO_FIELD_NIC;
@@ -401,9 +403,7 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
               || matchexec(cli_info(acptr), mymask, minlen))
               && ((!(matchsel & WHO_FIELD_NIP))
              || (HasHiddenHost(acptr) && !IsAnOper(sptr))
-              || ((((cli_ip(acptr).s_addr & imask.mask.s_addr) !=
-              imask.bits.s_addr)) || (imask.fall
-              && matchexec(ircd_ntoa((const char*) &(cli_ip(acptr))), mymask, minlen)))))
+              || !ipmask_check(&cli_ip(acptr), &imask, ibits)))
             continue;
           if (!SHOW_MORE(sptr, counter))
             break;
@@ -439,9 +439,7 @@ int m_who(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
             || matchexec(cli_info(acptr), mymask, minlen))
             && ((!(matchsel & WHO_FIELD_NIP))
            || (HasHiddenHost(acptr) && !IsAnOper(sptr))
-            || ((((cli_ip(acptr).s_addr & imask.mask.s_addr) != imask.bits.s_addr))
-            || (imask.fall
-            && matchexec(ircd_ntoa((const char*) &(cli_ip(acptr))), mymask, minlen)))))
+            || !ipmask_check(&cli_ip(acptr), &imask, ibits)))
           continue;
         if (!SHOW_MORE(sptr, counter))
           break;
index 0230e8a81ed4794702c5ceb182135de8313eaeb7..5660ba66e344445fd786dd921d9d99111f816691 100644 (file)
@@ -209,15 +209,15 @@ static void do_whois(struct Client* sptr, struct Client *acptr, int parc)
 
     if (HasHiddenHost(acptr) && (IsAnOper(sptr) || acptr == sptr))
       send_reply(sptr, RPL_WHOISACTUALLY, name, user->username,
-                 user->realhost, ircd_ntoa((const char*) &(cli_ip(acptr))));
-    
+                 user->realhost, ircd_ntoa(&cli_ip(acptr)));
+
     /* Hint: if your looking to add more flags to a user, eg +h, here's
      *       probably a good place to add them :)
      */
-     
+
     if (MyConnect(acptr) && (!feature_bool(FEAT_HIS_WHOIS_IDLETIME) ||
                              (sptr == acptr || IsAnOper(sptr) || parc >= 3)))
-       send_reply(sptr, RPL_WHOISIDLE, name, CurrentTime - user->last, 
+       send_reply(sptr, RPL_WHOISIDLE, name, CurrentTime - user->last,
                   cli_firsttime(acptr));
   }
 }
index 821c22252db242b1877cb60d646ccd33ce2b6607..5cb91da54b3dea2059ac4df0ba1edf2b7b6b2206 100644 (file)
 
 #include "match.h"
 #include "ircd_chattr.h"
+#include "ircd_string.h"
+#include "ircd_snprintf.h"
+#include "support.h"
+
 /*
  * mmatch()
  *
@@ -788,195 +792,72 @@ int mmexec(const char *wcm, int wminlen, const char *rcm, int rminlen)
   return 1;                     /* Auch... something left out ? Fail */
 }
 
-/*
- * matchcompIP()
- * Compiles an IP mask into an in_mask structure
- * The given <mask> can either be:
- * - An usual irc type mask, containing * and or ?
- * - An ip number plus a /bitnumber part, that will only consider
- *   the first "bitnumber" bits of the IP (bitnumber must be in 0-31 range)
- * - An ip numer plus a /ip.bit.mask.values that will consider
- *   only the bits marked as 1 in the ip.bit.mask.values
- * In the last two cases both the ip number and the bitmask can specify
- * less than 4 bytes, the missing bytes then default to zero, note that
- * this is *different* from the way inet_aton() does and that this does
- * NOT happen for normal IPmasks (not containing '/')
- * If the returned value is zero the produced in_mask might match some IP,
- * if it's nonzero it will never match anything (and the imask struct is
- * set so that always fails).
- *
- * The returned structure contains 3 fields whose meaning is the following:
- * im.mask = The bits considered significative in the IP
- * im.bits = What these bits should look like to have a match
- * im.fall = If zero means that the above information used as 
- *           ((IP & im.mask) == im.bits) is enough to tell if the compiled
- *           mask matches the given IP, nonzero means that it is needed,
- *           in case they did match, to call also the usual text match
- *           functions, because the mask wasn't "completely compiled"
- *
- * They should be used like:
- * matchcompIP(&im, mask);
- * if ( ((IP & im.mask)!=im.bits)) || (im.fall&&match(mask,inet_ntoa(IP))) )
- *    { handle_non_match } else { handle_match };
- * instead of:
- * if ( match(mask, inet_ntoa(IP)) )
- *    { handle_non_match } else { handle_match };
- * 
- * Note: This function could be smarter when dealing with complex masks,
- *       this implementation is quite lazy and understands only very simple
- *       cases, whatever contains a ? anywhere or contains a '*' that isn't
- *       part of a trailing '.*' will fallback to text-match, this could be 
- *       avoided for masks like 12?3.5.6 12.*.3.4 1.*.*.2 72?72?72?72 and
- *       so on that "could" be completely compiled to IP masks.
- *       If you try to improve this be aware of the fact that ? and *
- *       could match both dots and digits and we _must_ always reject
- *       what doesn't match in textform (like leading zeros and so on),
- *       so it's a LOT more tricky than it might seem. By now most common
- *       cases are optimized.
- */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
-int matchcompIP(struct in_mask *imask, const char *mask)
+static int ipmask_parse_ipv4(const char *in, struct in_addr *out)
 {
-  const char *m = mask;
-  unsigned int bits = 0;
-  unsigned int filt = 0;
-  int unco = 0;
-  int digits = 0;
-  int shift = 24;
-  int tmp = 0;
-
-  do
-  {
-    switch (*m)
-    {
-      case '\\':
-        if ((m[1] == '\\') || (m[1] == '*') || (m[1] == '?')
-            || (m[1] == '\0'))
-          break;
-        continue;
-      case '0':
-      case '1':
-      case '2':
-      case '3':
-      case '4':
-      case '5':
-      case '6':
-      case '7':
-      case '8':
-      case '9':
-        if (digits && !tmp)     /* Leading zeros */
-          break;
-        digits++;
-        tmp *= 10;
-        tmp += (*m - '0');      /* Can't overflow, INT_MAX > 2559 */
-        if (tmp > 255)
-          break;
-        continue;
-      case '\0':
-        filt = 0xFFFFFFFF;
-        /* Intentional fallthrough */
-      case '.':
-        if ((!shift) != (!*m))
-          break;
-        /* Intentional fallthrough */
-      case '/':
-        bits |= (tmp << shift);
-        shift -= 8;
-        digits = 0;
-        tmp = 0;
-        if (*m != '/')
-          continue;
-        shift = 24;
-        do
-        {
-          m++;
-          if (IsDigit(*m))
-          {
-            if (digits && !tmp) /* Leading zeros */
-              break;
-            digits++;
-            tmp *= 10;
-            tmp += (*m - '0');  /* Can't overflow, INT_MAX > 2559 */
-            if (tmp > 255)
-              break;
-          }
-          else
-          {
-            switch (*m)
-            {
-              case '.':
-              case '\0':
-                if ((!shift) && (*m))
-                  break;
-                filt |= (tmp << shift);
-                shift -= 8;
-                tmp = 0;
-                digits = 0;
-                continue;
-              default:
-                break;
-            }
-            break;
-          }
-        }
-        while (*m);
-        if (*m)
-          break;
-        if (filt && (!(shift < 16)) && (!(filt & 0xE0FFFFFF)))
-          filt = 0xFFFFFFFF << (32 - ((filt >> 24)));
-        bits &= filt;
-        continue;
-      case '?':
-        unco = 1;
-        /* Intentional fallthrough */
-      case '*':
-        if (digits)
-          unco = 1;
-        filt = (0xFFFFFFFF << (shift)) << 8;
-        while (*++m)
-        {
-          if (IsDigit(*m))
-            unco = 1;
-          else
-          {
-            switch (*m)
-            {
-              case '.':
-                if (m[1] != '*')
-                  unco = 1;
-                if (!shift)
-                  break;
-                shift -= 8;
-                continue;
-              case '?':
-                unco = 1;
-              case '*':
-                continue;
-              default:
-                break;
-            }
-            break;
-          }
-        }
-        if (*m)
-          break;
-        continue;
-      default:
-        break;
-    }
-
-    /* If we get here there is some error and this can't ever match */
-    filt = 0;
-    bits = ~0;
-    unco = 0;
-    break;                      /* This time break the loop :) */
+  int class;
+  char ipname[16];
+  int ad[4] = { 0 };
+  int bits = 0;
+
+  class = sscanf(in, "%d.%d.%d.%d/%d", &ad[0], &ad[1], &ad[2], &ad[3], &bits);
+  if (class != 5)
+    bits = class * 8;
+  ircd_snprintf(0, ipname, sizeof(ipname), "%d.%d.%d.%d", ad[0], ad[1], ad[2], ad[3]);
+  out->s_addr = inet_addr(ipname);
+  return bits;
+}
 
+int ipmask_parse(const char *in, struct irc_in_addr *mask, unsigned char *bits_ptr)
+{
+  struct in_addr ipv4;
+  char *p;
+  int bits = 0;
+
+  if (check_if_ipmask(in)) {
+    bits = ipmask_parse_ipv4(in, &ipv4);
+    mask->in6_16[0] = mask->in6_16[1] = mask->in6_16[2] = 0;
+    mask->in6_16[3] = mask->in6_16[4] = mask->in6_16[5] = 0;
+    memcpy(&mask->in6_16[6], &ipv4.s_addr, sizeof(ipv4.s_addr));
+    bits += 96;
+  } else {
+    if (!(p = strchr(in, '/')))
+      bits = 128;
+    else
+      *p = 0;
+    if (!ircd_aton(mask, in)) {
+      if (p)
+        *p = '/';
+      return 0;
+    }
+    if (p) {
+      bits = atoi(p + 1);
+      *p = '/';
+    }
   }
-  while (*m++);
 
-  imask->bits.s_addr = htonl(bits);
-  imask->mask.s_addr = htonl(filt);
-  imask->fall = unco;
-  return ((bits & ~filt) ? -1 : 0);
+  if (bits_ptr)
+    *bits_ptr = bits;
+  return 1;
+}
 
+int ipmask_check(const struct irc_in_addr *addr, const struct irc_in_addr *mask, unsigned char bits)
+{
+  int k;
+
+  for (k = 0; k < 8; k++) {
+    if (bits < 16)
+      return (addr->in6_16[k] & ((unsigned char) (0xffff << (16-bits)))) == mask->in6_16[k];
+    if (addr->in6_16[k] != mask->in6_16[k])
+      return 0;
+    if (!(bits -= 16))
+      return 1;
+  }
+  return -1;
 }
index 8574fe71773f6d5b7ca69c9285407bca217cae08..781ff6f8a263513a9f591fb5ae32af66110b6174 100644 (file)
@@ -369,4 +369,74 @@ struct Client* find_match_server(char *mask)
   return 0;
 }
 
+const char* iptobase64(char* buf, const struct irc_in_addr* addr, unsigned int count)
+{
+  if (irc_in_addr_is_ipv4(addr)) {
+    assert(count >= 6);
+    inttobase64(buf, (htons(addr->in6_16[6]) << 16) | htons(addr->in6_16[7]), 6);
+  } else {
+    unsigned int max_start, max_zeros, curr_zeros, zero, ii;
+    char *output = buf;
+
+    assert(count >= 25);
+    /* Can start by printing out the leading non-zero parts. */
+    for (ii = 0; (addr->in6_16[ii]) && (ii < 8); ++ii) {
+      inttobase64(output, ntohs(addr->in6_16[ii]), 3);
+      output += 3;
+    }
+    /* Find the longest run of zeros. */
+    for (max_start = zero = ii, max_zeros = curr_zeros = 0; ii < 8; ++ii) {
+      if (!addr->in6_16[ii])
+        curr_zeros++;
+      else if (curr_zeros > max_zeros) {
+        max_start = ii - curr_zeros;
+        max_zeros = curr_zeros;
+        curr_zeros = 0;
+      }
+    }
+    if (curr_zeros > max_zeros) {
+      max_start = ii - curr_zeros;
+      max_zeros = curr_zeros;
+      curr_zeros = 0;
+    }
+    /* Print the rest of the address */
+    for (ii = zero; ii < 8; ) {
+      if ((ii == max_start) && max_zeros) {
+        *output++ = '_';
+        ii += max_zeros;
+      } else {
+        inttobase64(output, ntohs(addr->in6_16[ii]), 3);
+        output += 3;
+        ii++;
+      }
+    }
+    *output = '\0';
+  }
+  return buf;
+}
 
+void base64toip(const char* input, struct irc_in_addr* addr)
+{
+  memset(addr, 0, sizeof(*addr));
+  if (strlen(input) == 6) {
+    unsigned int in = base64toint(input);
+    addr->in6_16[6] = htons(in >> 16);
+    addr->in6_16[7] = htons(in & 65535);
+  } else {
+    unsigned int pos = 0;
+    do {
+      if (*input == '_') {
+        unsigned int left;
+        for (left = (strlen(input) - 1) / 3; left; left--)
+          addr->in6_16[pos++] = 0;
+        input++;
+      } else {
+        unsigned short accum = convert2n[(unsigned char)*input++];
+        accum = (accum << NUMNICKLOG) | convert2n[(unsigned char)*input++];
+        accum = (accum << NUMNICKLOG) | convert2n[(unsigned char)*input++];
+        addr->in6_16[pos++] = ntohs(accum);
+        input += 3;
+      }
+    } while (pos < 8);
+  }
+}
diff --git a/ircd/os_bsd.c b/ircd/os_bsd.c
deleted file mode 100644 (file)
index 09850d9..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * IRC - Internet Relay Chat, ircd/os_generic.c
- * Copyright (C) 1999 Thomas Helvey
- *
- * 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- *
- */
-#include "config.h"
-
-#define _XOPEN_SOURCE  /* make limits.h #define IOV_MAX */
-
-#include "ircd_osdep.h"
-#include "msgq.h"
-
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <errno.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <unistd.h>
-
-#ifndef IOV_MAX
-#define IOV_MAX 16     /* minimum required */
-#endif
-
-#ifdef HPUX
-#include <sys/syscall.h>
-#define getrusage(a,b) syscall(SYS_GETRUSAGE, a, b)
-#endif
-
-/*
- * This is part of the STATS replies. There is no offical numeric for this
- * since this isnt an official command, in much the same way as HASH isnt.
- * It is also possible that some systems wont support this call or have
- * different field names for "struct rusage".
- * -avalon
- */
-int os_get_rusage(struct Client *cptr, int uptime, EnumFn enumerator)
-{
-#ifdef HAVE_GETRUSAGE
-  char buf[256];
-  struct rusage rus;
-  time_t secs;
-
-#ifdef  hz
-#  define hzz hz
-#else
-#  ifdef HZ
-#    define hzz HZ
-#  else
-  int hzz = 1;
-#  ifdef HPUX
-  hzz = sysconf(_SC_CLK_TCK);
-#  endif
-#endif
-#endif
-
-  assert(0 != enumerator);
-  if (getrusage(RUSAGE_SELF, &rus) == -1)
-    return 0;
-
-  secs = rus.ru_utime.tv_sec + rus.ru_stime.tv_sec;
-  if (secs == 0)
-    secs = 1;
-
-  sprintf(buf, "CPU Secs %ld:%ld User %ld:%ld System %ld:%ld",
-          secs / 60, secs % 60,
-          rus.ru_utime.tv_sec / 60, rus.ru_utime.tv_sec % 60,
-          rus.ru_stime.tv_sec / 60, rus.ru_stime.tv_sec % 60);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "RSS %ld ShMem %ld Data %ld Stack %ld",
-          rus.ru_maxrss,
-          rus.ru_ixrss / (uptime * hzz), rus.ru_idrss / (uptime * hzz),
-          rus.ru_isrss / (uptime * hzz));
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Swaps %ld Reclaims %ld Faults %ld",
-          rus.ru_nswap, rus.ru_minflt, rus.ru_majflt);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Block in %ld out %ld", rus.ru_inblock, rus.ru_oublock);
-  (*enumerator)(cptr, buf);
-  
-  sprintf(buf, "Msg Rcv %ld Send %ld", rus.ru_msgrcv, rus.ru_msgsnd);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Signals %ld Context Vol. %ld Invol %ld",
-          rus.ru_nsignals, rus.ru_nvcsw, rus.ru_nivcsw);
-  (*enumerator)(cptr, buf);
-
-#else /* HAVE_GETRUSAGE */
-#if HAVE_TIMES
-  char buf[256];
-  struct tms tmsbuf;
-  time_t secs, mins;
-  int hzz = 1, ticpermin;
-  int umin, smin, usec, ssec;
-
-  assert(0 != enumerator);
-#ifdef HPUX
-  hzz = sysconf(_SC_CLK_TCK);
-#endif
-  ticpermin = hzz * 60;
-
-  umin = tmsbuf.tms_utime / ticpermin;
-  usec = (tmsbuf.tms_utime % ticpermin) / (float)hzz;
-  smin = tmsbuf.tms_stime / ticpermin;
-  ssec = (tmsbuf.tms_stime % ticpermin) / (float)hzz;
-  secs = usec + ssec;
-  mins = (secs / 60) + umin + smin;
-  secs %= hzz;
-
-  if (times(&tmsbuf) == -1)
-    return 0;
-  secs = tmsbuf.tms_utime + tmsbuf.tms_stime;
-
-  sprintf(buf, "CPU Secs %d:%d User %d:%d System %d:%d", 
-          mins, secs, umin, usec, smin, ssec);
-  (*enumerator)(cptr, buf);
-#endif /* HAVE_TIMES */
-#endif /* HAVE_GETRUSAGE */
-  return 1;
-}
-
-int os_get_sockerr(int fd)
-{
-  int    err = 0;
-#if defined(SO_ERROR)
-  unsigned int len = sizeof(err);
-  getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len);
-#endif
-  return err;
-}
-
-/*
- * set_non_blocking
- *
- * Set the client connection into non-blocking mode. If your
- * system doesn't support this, you can make this a dummy
- * function (and get all the old problems that plagued the
- * blocking version of IRC--not a problem if you are a
- * lightly loaded node...)
- */
-int os_set_nonblocking(int fd)
-{
-  int res;
-#ifndef NBLOCK_SYSV
-  int nonb = 0;
-#endif
-
-  /*
-   * NOTE: consult ALL your relevant manual pages *BEFORE* changing
-   * these ioctl's. There are quite a few variations on them,
-   * as can be seen by the PCS one. They are *NOT* all the same.
-   * Heed this well. - Avalon.
-   */
-#ifdef  NBLOCK_POSIX
-  nonb |= O_NONBLOCK;
-#endif
-#ifdef  NBLOCK_BSD
-  nonb |= O_NDELAY;
-#endif
-#ifdef  NBLOCK_SYSV
-  /* This portion of code might also apply to NeXT. -LynX */
-  res = 1;
-
-  if (ioctl(fd, FIONBIO, &res) == -1)
-    return 0;
-#else
-  if ((res = fcntl(fd, F_GETFL, 0)) == -1)
-    return 0;
-  else if (fcntl(fd, F_SETFL, res | nonb) == -1)
-    return 0;
-#endif
-  return 1;
-}
-
-
-/*
- *  set_sock_opts
- */
-int os_set_reuseaddr(int fd)
-{
-  unsigned int opt = 1;
-  return (0 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 
-                          (const char*) &opt, sizeof(opt)));
-}
-
-int os_set_sockbufs(int fd, unsigned int ssize, unsigned int rsize)
-{
-  unsigned int sopt = ssize;
-  unsigned int ropt = rsize;
-  return (0 == setsockopt(fd, SOL_SOCKET, SO_RCVBUF, 
-                          (const char*) &ropt, sizeof(ropt)) &&
-          0 == setsockopt(fd, SOL_SOCKET, SO_SNDBUF, 
-                          (const char*) &sopt, sizeof(sopt)));
-}
-
-int os_set_tos(int fd,int tos)
-{
-  unsigned int opt = tos;
-  return (0 == setsockopt(fd, IPPROTO_IP, IP_TOS, &opt, sizeof(opt)));
-}
-
-int os_disable_options(int fd)
-{
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
-  return (0 == setsockopt(fd, IPPROTO_IP, IP_OPTIONS, NULL, 0));
-#else
-  return 1;
-#endif
-}
-
-/*
- * Try and find the correct name to use with getrlimit() for setting the max.
- * number of files allowed to be open by this process.
- */
-#ifdef RLIMIT_FDMAX
-#define RLIMIT_FD_MAX   RLIMIT_FDMAX
-#else
-#ifdef RLIMIT_NOFILE
-#define RLIMIT_FD_MAX RLIMIT_NOFILE
-#else
-#ifdef RLIMIT_OPEN_MAX
-#define RLIMIT_FD_MAX RLIMIT_OPEN_MAX
-#else
-#undef RLIMIT_FD_MAX
-#endif
-#endif
-#endif
-
-int os_set_fdlimit(unsigned int max_descriptors)
-{
-#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX)
-  struct rlimit limit;
-
-  if (!getrlimit(RLIMIT_FD_MAX, &limit)) {
-    if (limit.rlim_max < MAXCONNECTIONS)
-      return limit.rlim_max;
-    limit.rlim_cur = limit.rlim_max;    /* make soft limit the max */
-    return setrlimit(RLIMIT_FD_MAX, &limit);
-  }
-#endif /* defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX) */
-  return 0;
-}
-
-IOResult os_recv_nonb(int fd, char* buf, unsigned int length, 
-                 unsigned int* count_out)
-{
-  int res;
-  assert(0 != buf);
-  assert(0 != count_out);
-  *count_out = 0;
-  errno = 0;
-
-  if (0 < (res = recv(fd, buf, length, 0))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (res < 0) {
-    if (EWOULDBLOCK == errno || EAGAIN == errno)
-      return IO_BLOCKED;
-    else
-      return IO_FAILURE;
-  } 
-  /*
-   * 0   == client closed the connection
-   * < 1 == error
-   */
-  return IO_FAILURE;
-}
-
-IOResult os_recvfrom_nonb(int fd, char* buf, unsigned int length, 
-                          unsigned int* length_out, struct sockaddr_in* sin_out)
-{
-  int    res;
-  unsigned int len = sizeof(struct sockaddr_in);
-  assert(0 != buf);
-  assert(0 != length_out);
-  assert(0 != sin_out);
-  errno = 0;
-  *length_out = 0;
-
-  res = recvfrom(fd, buf, length, 0, (struct sockaddr*) sin_out, &len);
-  if (-1 == res) {
-    if (EWOULDBLOCK == errno || ENOMEM == errno)
-      return IO_BLOCKED;
-    return IO_FAILURE;
-  }
-  *length_out = res;
-  return IO_SUCCESS;
-}
-
-IOResult os_send_nonb(int fd, const char* buf, unsigned int length, 
-                 unsigned int* count_out)
-{
-  int res;
-  assert(0 != buf);
-  assert(0 != count_out);
-  *count_out = 0;
-  errno = 0;
-
-  if (-1 < (res = send(fd, buf, length, 0))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (EWOULDBLOCK == errno || EAGAIN == errno || 
-           ENOMEM == errno || ENOBUFS == errno)
-    return IO_BLOCKED;
-  return IO_FAILURE;
-}
-
-IOResult os_sendv_nonb(int fd, struct MsgQ* buf, unsigned int* count_in,
-                      unsigned int* count_out)
-{
-  int res;
-  int count;
-  struct iovec iov[IOV_MAX];
-
-  assert(0 != buf);
-  assert(0 != count_in);
-  assert(0 != count_out);
-
-  *count_in = 0;
-  *count_out = 0;
-  errno = 0;
-
-  count = msgq_mapiov(buf, iov, IOV_MAX, count_in);
-
-  if (-1 < (res = writev(fd, iov, count))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (EWOULDBLOCK == errno || EAGAIN == errno ||
-          ENOMEM == errno || ENOBUFS == errno)
-    return IO_BLOCKED;
-
-  return IO_FAILURE;
-}
-
-IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin)
-{
-  if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in)))
-    return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
-  return IO_SUCCESS;
-}
-      
-int os_get_sockname(int fd, struct sockaddr_in* sin_out)
-{
-  unsigned int len = sizeof(struct sockaddr_in);
-  assert(0 != sin_out);
-  return (0 == getsockname(fd, (struct sockaddr*) sin_out, &len));
-}
-
-int os_get_peername(int fd, struct sockaddr_in* sin_out)
-{
-  unsigned int len = sizeof(struct sockaddr_in);
-  assert(0 != sin_out);
-  return (0 == getpeername(fd, (struct sockaddr*) sin_out, &len));
-}
-
-int os_set_listen(int fd, int backlog)
-{
-  return (0 == listen(fd, backlog));
-}
-
-
index ccd9e808c5aa9852375b24814d1bd03f82c307b5..99750a3d32db3f91d0f42787ce08ad2e7ce0a29b 100644 (file)
 #include "config.h"
 
 #define _XOPEN_SOURCE  500 /* make limits.h #define IOV_MAX */
+#define __EXTENSIONS__  1   /* make Solaris netinet/in.h know IPv6 */
 
 #include "ircd_osdep.h"
 #include "msgq.h"
+#include "res.h"
+#include "s_bsd.h"
+#include "sys.h"
 
 /* Include file dependency notes:
  * FreeBSD requires struct timeval from sys/time.h before struct
 #define getrusage(a,b) syscall(SYS_GETRUSAGE, a, b)
 #endif
 
+#ifdef IPV6
+#define sockaddr_native sockaddr_in6
+
+void sockaddr_to_irc(const struct sockaddr_in6 *v6, struct irc_sockaddr *irc)
+{
+    assert(v6->sin6_family == AF_INET6);
+    memcpy(&irc->addr.in6_16[0], &v6->sin6_addr, sizeof(v6->sin6_addr));
+    irc->port = ntohs(v6->sin6_port);
+}
+
+void sockaddr_from_irc(struct sockaddr_in6 *v6, const struct irc_sockaddr *irc, int persist)
+{
+    memset(v6, 0, sizeof(*v6));
+    v6->sin6_family = AF_INET6;
+    memcpy(&v6->sin6_addr, &irc->addr.in6_16[0], sizeof(v6->sin6_addr));
+    if (persist && irc_in_addr_is_ipv4(&irc->addr))
+        v6->sin6_addr.s6_addr[10] = v6->sin6_addr.s6_addr[11] = '\xff';
+    v6->sin6_port = htons(irc->port);
+}
+
+#else
+#define sockaddr_native sockaddr_in
+
+void sockaddr_to_irc(const struct sockaddr_in *v4, struct irc_sockaddr *irc)
+{
+    assert(v4->sin_family == AF_INET);
+    memset(&irc->addr, 0, 6*sizeof(irc->addr.in6_16[0]));
+    memcpy(&irc->addr.in6_16[6], &v4->sin_addr, sizeof(v4->sin_addr));
+    irc->port = ntohs(v4->sin_port);
+}
+
+void sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, int persist)
+{
+    v4->sin_family = AF_INET6;
+    assert(!irc->addr.in6_16[0] && !irc->addr.in6_16[1] && !irc->addr.in6_16[2] && !irc->addr.in6_16[3] && !irc->addr.in6_16[4] && (!irc->addr.in6_16[5] || irc->addr.in6_16[5] == 0xffff));
+    memcpy(&v4->sin_addr, &irc->addr.in6_16[7], sizeof(v4->sin_addr));
+    v4->sin_port = htons(irc->port);
+    (void)persist;
+}
+
+#endif
+
 /*
  * This is part of the STATS replies. There is no offical numeric for this
  * since this isnt an official command, in much the same way as HASH isnt.
@@ -327,17 +373,19 @@ IOResult os_recv_nonb(int fd, char* buf, unsigned int length,
 }
 
 IOResult os_recvfrom_nonb(int fd, char* buf, unsigned int length,
-                          unsigned int* length_out, struct sockaddr_in* sin_out)
+                          unsigned int* length_out,
+                          struct irc_sockaddr* addr_out)
 {
+  struct sockaddr_native addr;
+  unsigned int len = sizeof(addr);
   int    res;
-  unsigned int len = sizeof(struct sockaddr_in);
   assert(0 != buf);
   assert(0 != length_out);
-  assert(0 != sin_out);
+  assert(0 != addr_out);
   errno = 0;
   *length_out = 0;
 
-  res = recvfrom(fd, buf, length, 0, (struct sockaddr*) sin_out, &len);
+  res = recvfrom(fd, buf, length, 0, (struct sockaddr*) &addr, &len);
   if (-1 == res) {
     if (EWOULDBLOCK == errno || ENOMEM == errno
 #ifdef ENOMEM
@@ -350,10 +398,47 @@ IOResult os_recvfrom_nonb(int fd, char* buf, unsigned int length,
       return IO_BLOCKED;
     return IO_FAILURE;
   }
+  sockaddr_to_irc(&addr, addr_out);
   *length_out = res;
   return IO_SUCCESS;
 }
 
+/*
+ * os_sendto_nonb - non blocking send to a UDP socket
+ * returns:
+ *  1  if data was written, *count_out contains number of bytes
+ *  0  if sendto call blocked
+ *  -1 if an unrecoverable error occurred
+ */
+IOResult os_sendto_nonb(int fd, const char* buf, unsigned int length,
+                        unsigned int* count_out, unsigned int flags,
+                        const struct irc_sockaddr* peer)
+{
+  struct sockaddr_native addr;
+  int res;
+  assert(0 != buf);
+  if (count_out)
+    *count_out = 0;
+  errno = 0;
+
+  sockaddr_from_irc(&addr, peer, 1);
+  if (-1 < (res = sendto(fd, buf, length, flags, (struct sockaddr*)&addr, sizeof(addr)))) {
+    if (count_out)
+      *count_out = (unsigned) res;
+    return IO_SUCCESS;
+  }
+  else if (EWOULDBLOCK == errno || EAGAIN == errno
+#ifdef ENOMEM
+          || ENOMEM == errno
+#endif
+#ifdef ENOBUFS
+          || ENOBUFS == errno
+#endif
+      )
+    return IO_BLOCKED;
+  return IO_FAILURE;
+}
+
 /*
  * os_send_nonb - non blocking read of a connection
  * returns:
@@ -422,25 +507,92 @@ IOResult os_sendv_nonb(int fd, struct MsgQ* buf, unsigned int* count_in,
   return IO_FAILURE;
 }
 
-IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin)
+int os_socket(const struct irc_sockaddr* local, int type, const char* port_name)
+{
+  int family, fd;
+#ifdef IPV6
+  family = AF_INET6;
+#else
+  family = AF_INET;
+#endif
+  fd = socket(family, type, 0);
+  if (fd < 0) {
+    report_error(SOCKET_ERROR_MSG, port_name, errno);
+    return -1;
+  }
+  if (fd > MAXCLIENTS - 1) {
+    report_error(CONNLIMIT_ERROR_MSG, port_name, 0);
+    close(fd);
+    return -1;
+  }
+  if (!os_set_reuseaddr(fd)) {
+    report_error(REUSEADDR_ERROR_MSG, port_name, errno);
+    close(fd);
+    return -1;
+  }
+  if (!os_set_nonblocking(fd)) {
+    report_error(NONB_ERROR_MSG, port_name, errno);
+    close(fd);
+    return -1;
+  }
+  if (local) {
+    struct sockaddr_native addr;
+    sockaddr_from_irc(&addr, local, 1);
+    if (bind(fd, (struct sockaddr*)&addr, sizeof(addr))) {
+      report_error(BIND_ERROR_MSG, port_name, errno);
+      close(fd);
+      return -1;
+    }
+  }
+  return fd;
+}
+
+int os_accept(int fd, struct irc_sockaddr* peer)
 {
-  if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in)))
+  struct sockaddr_native addr;
+  socklen_t addrlen;
+  int new_fd;
+
+  addrlen = sizeof(addr);
+  new_fd = accept(fd, (struct sockaddr*)&addr, &addrlen);
+  if (new_fd < 0)
+    memset(peer, 0, sizeof(*peer));
+  else
+    sockaddr_to_irc(&addr, peer);
+  return new_fd;
+}
+
+IOResult os_connect_nonb(int fd, const struct irc_sockaddr* sin)
+{
+  struct sockaddr_native addr;
+  sockaddr_from_irc(&addr, sin, 1);
+  if (connect(fd, (struct sockaddr*) &addr, sizeof(addr)))
     return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
   return IO_SUCCESS;
 }
 
-int os_get_sockname(int fd, struct sockaddr_in* sin_out)
+int os_get_sockname(int fd, struct irc_sockaddr* sin_out)
 {
-  unsigned int len = sizeof(struct sockaddr_in);
+  struct sockaddr_native addr;
+  unsigned int len = sizeof(addr);
+
   assert(0 != sin_out);
-  return (0 == getsockname(fd, (struct sockaddr*) sin_out, &len));
+  if (getsockname(fd, (struct sockaddr*) &addr, &len))
+    return 0;
+  sockaddr_to_irc(&addr, sin_out);
+  return 1;
 }
 
-int os_get_peername(int fd, struct sockaddr_in* sin_out)
+int os_get_peername(int fd, struct irc_sockaddr* sin_out)
 {
-  unsigned int len = sizeof(struct sockaddr_in);
+  struct sockaddr_native addr;
+  unsigned int len = sizeof(addr);
+
   assert(0 != sin_out);
-  return (0 == getpeername(fd, (struct sockaddr*) sin_out, &len));
+  if (getpeername(fd, (struct sockaddr*) &addr, &len))
+    return 0;
+  sockaddr_to_irc(&addr, sin_out);
+  return 1;
 }
 
 int os_set_listen(int fd, int backlog)
diff --git a/ircd/os_linux.c b/ircd/os_linux.c
deleted file mode 100644 (file)
index 2c24bb1..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * IRC - Internet Relay Chat, ircd/os_linux.c
- * Copyright (C) 1999 Thomas Helvey
- *
- * 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- *
- */
-#include "config.h"
-
-#define _XOPEN_SOURCE  /* make limits.h #define IOV_MAX */
-
-#include "ircd_osdep.h"
-#include "msgq.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/times.h>
-#include <sys/uio.h>
-#include <sys/param.h>
-#include <unistd.h>
-
-/*
- * This is part of the STATS replies. There is no offical numeric for this
- * since this isnt an official command, in much the same way as HASH isnt.
- * It is also possible that some systems wont support this call or have
- * different field names for "struct rusage".
- * -avalon
- */
-int os_get_rusage(struct Client *cptr, int uptime, EnumFn enumerator)
-{
-  char buf[256];
-  struct rusage rus;
-  struct tms tmsbuf;
-  time_t secs;
-  time_t mins;
-  int umin;
-  int smin;
-  int usec;
-  int ssec;
-  int ticpermin = HZ * 60;
-  unsigned int tick_count = uptime * HZ;
-
-  if (0 == tick_count)
-    ++tick_count;
-
-  assert(0 != enumerator);
-  if (getrusage(RUSAGE_SELF, &rus) == -1)
-    return 0;
-
-  secs = rus.ru_utime.tv_sec + rus.ru_stime.tv_sec;
-  if (secs == 0)
-    secs = 1;
-
-  sprintf(buf, "CPU Secs %ld:%ld User %ld:%ld System %ld:%ld",
-          secs / 60, secs % 60,
-          rus.ru_utime.tv_sec / 60, rus.ru_utime.tv_sec % 60,
-          rus.ru_stime.tv_sec / 60, rus.ru_stime.tv_sec % 60);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "RSS %ld ShMem %ld Data %ld Stack %ld",
-          rus.ru_maxrss,
-          rus.ru_ixrss / tick_count, rus.ru_idrss / tick_count,
-          rus.ru_isrss / tick_count);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Swaps %ld Reclaims %ld Faults %ld",
-          rus.ru_nswap, rus.ru_minflt, rus.ru_majflt);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Block in %ld out %ld", rus.ru_inblock, rus.ru_oublock);
-  (*enumerator)(cptr, buf);
-  
-  sprintf(buf, "Msg Rcv %ld Send %ld", rus.ru_msgrcv, rus.ru_msgsnd);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Signals %ld Context Vol. %ld Invol %ld",
-          rus.ru_nsignals, rus.ru_nvcsw, rus.ru_nivcsw);
-  (*enumerator)(cptr, buf);
-
-  if (times(&tmsbuf) == -1)
-    return 0;
-
-  umin = tmsbuf.tms_utime / ticpermin;
-  usec = (tmsbuf.tms_utime % ticpermin) / (float)HZ;
-  smin = tmsbuf.tms_stime / ticpermin;
-  ssec = (tmsbuf.tms_stime % ticpermin) / (float)HZ;
-  secs = usec + ssec;
-  mins = (secs / 60) + umin + smin;
-  secs %= HZ;
-
-  sprintf(buf, "CPU Secs %ld:%ld User %d:%d System %d:%d", 
-          mins, secs, umin, usec, smin, ssec);
-  (*enumerator)(cptr, buf);
-  return 1;
-}
-
-int os_get_sockerr(int fd)
-{
-  int    err = 0;
-  unsigned int len = sizeof(err);
-  getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len);
-  return err;
-}
-
-/*
- * set_non_blocking
- *
- * Set the client connection into non-blocking mode. If your
- * system doesn't support this, you can make this a dummy
- * function (and get all the old problems that plagued the
- * blocking version of IRC--not a problem if you are a
- * lightly loaded node...)
- */
-int os_set_nonblocking(int fd)
-{
-  int res = 1;
-  return (0 == ioctl(fd, FIONBIO, &res));
-}
-
-
-/*
- *  set_sock_opts
- */
-int os_set_reuseaddr(int fd)
-{
-  unsigned int opt = 1;
-  return (0 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)));
-}
-
-int os_set_sockbufs(int fd, unsigned int ssize, unsigned int rsize)
-{
-  unsigned int sopt = ssize;
-  unsigned int ropt = rsize;
-  return (0 == setsockopt(fd, SOL_SOCKET, SO_RCVBUF, 
-                          (const char*) &ropt, sizeof(ropt)) &&
-          0 == setsockopt(fd, SOL_SOCKET, SO_SNDBUF, 
-                          (const char*) &sopt, sizeof(sopt)));
-}
-
-int os_set_tos(int fd,int tos)
-{
-  unsigned int opt = tos;
-  return (0 == setsockopt(fd, SOL_IP, IP_TOS, &opt, sizeof(opt)));
-}
-
-int os_disable_options(int fd)
-{
-  return (0 == setsockopt(fd, IPPROTO_IP, IP_OPTIONS, NULL, 0));
-}
-
-int os_set_fdlimit(unsigned int max_descriptors)
-{
-  struct rlimit limit;
-
-  if (!getrlimit(RLIMIT_NOFILE, &limit)) {
-    if (limit.rlim_max < max_descriptors)
-      return limit.rlim_max;
-    limit.rlim_cur = limit.rlim_max;    /* make soft limit the max */
-    return setrlimit(RLIMIT_NOFILE, &limit);
-  }
-  return 0;
-}
-
-/*
- * os_recv_nonb - non blocking read of a connection
- * returns:
- *  1  if data was read or socket is blocked (recoverable error)
- *    count_out > 0 if data was read
- *   
- *  0  if socket closed from other end
- *  -1 if an unrecoverable error occurred
- */
-IOResult os_recv_nonb(int fd, char* buf, unsigned int length, 
-                 unsigned int* count_out)
-{
-  int res;
-  assert(0 != buf);
-  assert(0 != count_out);
-  *count_out = 0;
-  errno = 0;
-
-  if (0 < (res = recv(fd, buf, length, 0))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (res < 0) {
-    if (EWOULDBLOCK == errno || EAGAIN == errno)
-      return IO_BLOCKED;
-    else
-      return IO_FAILURE;
-  } 
-  /*
-   * 0   == client closed the connection
-   * < 1 == error
-   */
-  return IO_FAILURE;
-}
-
-IOResult os_recvfrom_nonb(int fd, char* buf, unsigned int length, 
-                          unsigned int* length_out, struct sockaddr_in* sin_out)
-{
-  int    res;
-  unsigned int len = sizeof(struct sockaddr_in);
-  assert(0 != buf);
-  assert(0 != length_out);
-  assert(0 != sin_out);
-  errno = 0;
-
-  res = recvfrom(fd, buf, length, 0, (struct sockaddr*) sin_out, &len);
-  if (-1 == res) {
-    if (EWOULDBLOCK == errno || ENOMEM == errno)
-      return IO_BLOCKED;
-    return IO_FAILURE;
-  }
-  *length_out = res;
-  return IO_SUCCESS;
-}
-
-/*
- * os_send_nonb - non blocking read of a connection
- * returns:
- *  1  if data was written
- *    count_out contains amount written
- *   
- *  0  if write call blocked, recoverable error
- *  -1 if an unrecoverable error occurred
- */
-IOResult os_send_nonb(int fd, const char* buf, unsigned int length, 
-                 unsigned int* count_out)
-{
-  int res;
-  assert(0 != buf);
-  assert(0 != count_out);
-  *count_out = 0;
-  errno = 0;
-
-  if (-1 < (res = send(fd, buf, length, 0))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (EAGAIN == errno || ENOMEM == errno || ENOBUFS == errno)
-    return IO_BLOCKED;
-
-  return IO_FAILURE;
-}
-
-/*
- * os_sendv_nonb - non blocking writev to a connection
- * returns:
- *  1  if data was written
- *    count_out contains amount written
- *   
- *  0  if write call blocked, recoverable error
- *  -1 if an unrecoverable error occurred
- */
-IOResult os_sendv_nonb(int fd, struct MsgQ* buf, unsigned int* count_in,
-                      unsigned int* count_out)
-{
-  int res;
-  int count;
-  struct iovec iov[IOV_MAX];
-
-  assert(0 != buf);
-  assert(0 != count_in);
-  assert(0 != count_out);
-
-  *count_in = 0;
-  *count_out = 0;
-  errno = 0;
-
-  count = msgq_mapiov(buf, iov, IOV_MAX, count_in);
-
-  if (-1 < (res = writev(fd, iov, count))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (EAGAIN == errno || ENOMEM == errno || ENOBUFS == errno)
-    return IO_BLOCKED;
-
-  return IO_FAILURE;
-}
-
-
-IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin)
-{
-  if (connect(fd, (const struct sockaddr*) sin, sizeof(struct sockaddr_in)))
-    return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
-  return IO_SUCCESS;
-}
-      
-int os_get_sockname(int fd, struct sockaddr_in* sin_out)
-{
-  unsigned int len = sizeof(struct sockaddr_in);
-  assert(0 != sin_out);
-  return (0 == getsockname(fd, (struct sockaddr*) sin_out, &len));
-}
-
-int os_get_peername(int fd, struct sockaddr_in* sin_out)
-{
-  unsigned int len = sizeof(struct sockaddr_in);
-  assert(0 != sin_out);
-  return (0 == getpeername(fd, (struct sockaddr*) sin_out, &len));
-}
-
-int os_set_listen(int fd, int backlog)
-{
-  /*
-   * for linux 2.2 backlog is the number of connections ready to be accepted
-   * not the max syn requests, there is a kernel tweak there to set the max
-   * syn request queue length
-   */
-  return (0 == listen(fd, backlog));
-}
-
diff --git a/ircd/os_openbsd.c b/ircd/os_openbsd.c
deleted file mode 100644 (file)
index 27c5ded..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * IRC - Internet Relay Chat, ircd/os_openbsd.c
- * Copyright (C) 2001 Joseph Bongaarts
- *
- * 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- *
- */
-#include "config.h"
-
-#define _XOPEN_SOURCE /* Need this for IOV_MAX */
-
-/* These typedef's are needed for socket.h to be happy. Bleep PROMISES to make
- * to make this less hackish in the future... HONEST. -GW
- */
-typedef unsigned char u_char;
-typedef unsigned short u_short;
-typedef unsigned int u_int;
-typedef unsigned long u_long;
-
-#include "ircd_osdep.h"
-#include "msgq.h"
-
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <errno.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <unistd.h>
-
-#ifndef IOV_MAX
-#define IOV_MAX 16     /* minimum required */
-#endif
-
-#ifdef HPUX
-#include <sys/syscall.h>
-#define getrusage(a,b) syscall(SYS_GETRUSAGE, a, b)
-#endif
-
-/*
- * This is part of the STATS replies. There is no offical numeric for this
- * since this isnt an official command, in much the same way as HASH isnt.
- * It is also possible that some systems wont support this call or have
- * different field names for "struct rusage".
- * -avalon
- */
-int os_get_rusage(struct Client *cptr, int uptime, EnumFn enumerator)
-{
-  char buf[256];
-#ifdef HAVE_GETRUSAGE
-  struct rusage rus;
-  time_t secs;
-
-#ifdef  hz
-#  define hzz hz
-#else
-#  ifdef HZ
-#    define hzz HZ
-#  else
-  int hzz = 1;
-#  ifdef HPUX
-  hzz = sysconf(_SC_CLK_TCK);
-#  endif
-#endif
-#endif
-
-  assert(0 != enumerator);
-  if (getrusage(RUSAGE_SELF, &rus) == -1)
-    return 0;
-
-  secs = rus.ru_utime.tv_sec + rus.ru_stime.tv_sec;
-  if (secs == 0)
-    secs = 1;
-
-  sprintf(buf, "CPU Secs %ld:%ld User %ld:%ld System %ld:%ld",
-          secs / 60, secs % 60,
-          rus.ru_utime.tv_sec / 60, rus.ru_utime.tv_sec % 60,
-          rus.ru_stime.tv_sec / 60, rus.ru_stime.tv_sec % 60);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "RSS %ld ShMem %ld Data %ld Stack %ld",
-          rus.ru_maxrss,
-          rus.ru_ixrss / (uptime * hzz), rus.ru_idrss / (uptime * hzz),
-          rus.ru_isrss / (uptime * hzz));
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Swaps %ld Reclaims %ld Faults %ld",
-          rus.ru_nswap, rus.ru_minflt, rus.ru_majflt);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Block in %ld out %ld", rus.ru_inblock, rus.ru_oublock);
-  (*enumerator)(cptr, buf);
-  
-  sprintf(buf, "Msg Rcv %ld Send %ld", rus.ru_msgrcv, rus.ru_msgsnd);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Signals %ld Context Vol. %ld Invol %ld",
-          rus.ru_nsignals, rus.ru_nvcsw, rus.ru_nivcsw);
-  (*enumerator)(cptr, buf);
-
-#else /* HAVE_GETRUSAGE */
-#if HAVE_TIMES
-  struct tms tmsbuf;
-  time_t secs, mins;
-  int hzz = 1, ticpermin;
-  int umin, smin, usec, ssec;
-
-  assert(0 != enumerator);
-#ifdef HPUX
-  hzz = sysconf(_SC_CLK_TCK);
-#endif
-  ticpermin = hzz * 60;
-
-  umin = tmsbuf.tms_utime / ticpermin;
-  usec = (tmsbuf.tms_utime % ticpermin) / (float)hzz;
-  smin = tmsbuf.tms_stime / ticpermin;
-  ssec = (tmsbuf.tms_stime % ticpermin) / (float)hzz;
-  secs = usec + ssec;
-  mins = (secs / 60) + umin + smin;
-  secs %= hzz;
-
-  if (times(&tmsbuf) == -1)
-    return 0;
-  secs = tmsbuf.tms_utime + tmsbuf.tms_stime;
-
-  sprintf(buf, "CPU Secs %d:%d User %d:%d System %d:%d", 
-          mins, secs, umin, usec, smin, ssec);
-  (*enumerator)(cptr, buf);
-#endif /* HAVE_TIMES */
-#endif /* HAVE_GETRUSAGE */
-  return 1;
-}
-
-int os_get_sockerr(int fd)
-{
-  int    err = 0;
-#if defined(SO_ERROR)
-  unsigned int len = sizeof(err);
-  getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len);
-#endif
-  return err;
-}
-
-/*
- * set_non_blocking
- *
- * Set the client connection into non-blocking mode. If your
- * system doesn't support this, you can make this a dummy
- * function (and get all the old problems that plagued the
- * blocking version of IRC--not a problem if you are a
- * lightly loaded node...)
- */
-int os_set_nonblocking(int fd)
-{
-  int res;
-#ifndef NBLOCK_SYSV
-  int nonb = 0;
-#endif
-
-  /*
-   * NOTE: consult ALL your relevant manual pages *BEFORE* changing
-   * these ioctl's. There are quite a few variations on them,
-   * as can be seen by the PCS one. They are *NOT* all the same.
-   * Heed this well. - Avalon.
-   */
-#ifdef  NBLOCK_POSIX
-  nonb |= O_NONBLOCK;
-#endif
-#ifdef  NBLOCK_BSD
-  nonb |= O_NDELAY;
-#endif
-#ifdef  NBLOCK_SYSV
-  /* This portion of code might also apply to NeXT. -LynX */
-  res = 1;
-
-  if (ioctl(fd, FIONBIO, &res) == -1)
-    return 0;
-#else
-  if ((res = fcntl(fd, F_GETFL, 0)) == -1)
-    return 0;
-  else if (fcntl(fd, F_SETFL, res | nonb) == -1)
-    return 0;
-#endif
-  return 1;
-}
-
-
-/*
- *  set_sock_opts
- */
-int os_set_reuseaddr(int fd)
-{
-  unsigned int opt = 1;
-  return (0 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 
-                          (const char*) &opt, sizeof(opt)));
-}
-
-int os_set_sockbufs(int fd, unsigned int ssize, unsigned int rsize)
-{
-  unsigned int sopt = ssize;
-  unsigned int ropt = rsize;
-  return (0 == setsockopt(fd, SOL_SOCKET, SO_RCVBUF, 
-                          (const char*) &ropt, sizeof(ropt)) &&
-          0 == setsockopt(fd, SOL_SOCKET, SO_SNDBUF, 
-                          (const char*) &sopt, sizeof(sopt)));
-}
-
-int os_set_tos(int fd,int tos)
-{
-  unsigned int opt = tos;
-  return (0 == setsockopt(fd, IPPROTO_IP, IP_TOS, &opt, sizeof(opt)));
-}
-
-int os_disable_options(int fd)
-{
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
-  return (0 == setsockopt(fd, IPPROTO_IP, IP_OPTIONS, NULL, 0));
-#else
-  return 1;
-#endif
-}
-
-/*
- * Try and find the correct name to use with getrlimit() for setting the max.
- * number of files allowed to be open by this process.
- */
-#ifdef RLIMIT_FDMAX
-#define RLIMIT_FD_MAX   RLIMIT_FDMAX
-#else
-#ifdef RLIMIT_NOFILE
-#define RLIMIT_FD_MAX RLIMIT_NOFILE
-#else
-#ifdef RLIMIT_OPEN_MAX
-#define RLIMIT_FD_MAX RLIMIT_OPEN_MAX
-#else
-#undef RLIMIT_FD_MAX
-#endif
-#endif
-#endif
-
-int os_set_fdlimit(unsigned int max_descriptors)
-{
-#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX)
-  struct rlimit limit;
-
-  if (!getrlimit(RLIMIT_FD_MAX, &limit)) {
-    if (limit.rlim_max < MAXCONNECTIONS)
-      return limit.rlim_max;
-    limit.rlim_cur = limit.rlim_max;    /* make soft limit the max */
-    return setrlimit(RLIMIT_FD_MAX, &limit);
-  }
-#endif /* defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX) */
-  return 0;
-}
-
-IOResult os_recv_nonb(int fd, char* buf, unsigned int length, 
-                 unsigned int* count_out)
-{
-  int res;
-  assert(0 != buf);
-  assert(0 != count_out);
-  *count_out = 0;
-  errno = 0;
-
-  if (0 < (res = recv(fd, buf, length, 0))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (res < 0) {
-    if (EWOULDBLOCK == errno || EAGAIN == errno)
-      return IO_BLOCKED;
-    else
-      return IO_FAILURE;
-  } 
-  /*
-   * 0   == client closed the connection
-   * < 1 == error
-   */
-  return IO_FAILURE;
-}
-
-IOResult os_recvfrom_nonb(int fd, char* buf, unsigned int length, 
-                          unsigned int* length_out, struct sockaddr_in* sin_out)
-{
-  int    res;
-  unsigned int len = sizeof(struct sockaddr_in);
-  assert(0 != buf);
-  assert(0 != length_out);
-  assert(0 != sin_out);
-  errno = 0;
-  *length_out = 0;
-
-  res = recvfrom(fd, buf, length, 0, (struct sockaddr*) sin_out, &len);
-  if (-1 == res) {
-    if (EWOULDBLOCK == errno || ENOMEM == errno)
-      return IO_BLOCKED;
-    return IO_FAILURE;
-  }
-  *length_out = res;
-  return IO_SUCCESS;
-}
-
-IOResult os_send_nonb(int fd, const char* buf, unsigned int length, 
-                 unsigned int* count_out)
-{
-  int res;
-  assert(0 != buf);
-  assert(0 != count_out);
-  *count_out = 0;
-  errno = 0;
-
-  if (-1 < (res = send(fd, buf, length, 0))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (EWOULDBLOCK == errno || EAGAIN == errno || 
-           ENOMEM == errno || ENOBUFS == errno)
-    return IO_BLOCKED;
-  return IO_FAILURE;
-}
-
-IOResult os_sendv_nonb(int fd, struct MsgQ* buf, unsigned int* count_in,
-                      unsigned int* count_out)
-{
-  int res;
-  int count;
-  struct iovec iov[IOV_MAX];
-
-  assert(0 != buf);
-  assert(0 != count_in);
-  assert(0 != count_out);
-
-  *count_in = 0;
-  *count_out = 0;
-  errno = 0;
-
-  count = msgq_mapiov(buf, iov, IOV_MAX, count_in);
-
-  if (-1 < (res = writev(fd, iov, count))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (EWOULDBLOCK == errno || EAGAIN == errno ||
-          ENOMEM == errno || ENOBUFS == errno)
-    return IO_BLOCKED;
-
-  return IO_FAILURE;
-}
-
-IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin)
-{
-  if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in)))
-    return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
-  return IO_SUCCESS;
-}
-      
-int os_get_sockname(int fd, struct sockaddr_in* sin_out)
-{
-  unsigned int len = sizeof(struct sockaddr_in);
-  assert(0 != sin_out);
-  return (0 == getsockname(fd, (struct sockaddr*) sin_out, &len));
-}
-
-int os_get_peername(int fd, struct sockaddr_in* sin_out)
-{
-  unsigned int len = sizeof(struct sockaddr_in);
-  assert(0 != sin_out);
-  return (0 == getpeername(fd, (struct sockaddr*) sin_out, &len));
-}
-
-int os_set_listen(int fd, int backlog)
-{
-  return (0 == listen(fd, backlog));
-}
-
-
diff --git a/ircd/os_solaris.c b/ircd/os_solaris.c
deleted file mode 100644 (file)
index 9452c0c..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * IRC - Internet Relay Chat, ircd/os_solaris.c
- * Copyright (C) 1999 Thomas Helvey
- *
- * 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- *
- */
-#include "config.h"
-
-#include "ircd_osdep.h"
-#include "msgq.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <limits.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <string.h>
-#include <stropts.h>
-#include <sys/filio.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/resource.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-
-/*
- * This is part of the STATS replies. There is no offical numeric for this
- * since this isnt an official command, in much the same way as HASH isnt.
- * It is also possible that some systems wont support this call or have
- * different field names for "struct rusage".
- * -avalon
- */
-int os_get_rusage(struct Client *cptr, int uptime, EnumFn enumerator)
-{
-  char buf[256];
-  struct rusage rus;
-  time_t secs;
-  int    hz = HZ;
-  int    upticks = uptime * hz;
-
-  assert(0 != enumerator);
-  if (getrusage(RUSAGE_SELF, &rus) == -1)
-    return 0;
-
-  secs = rus.ru_utime.tv_sec + rus.ru_stime.tv_sec;
-  if (secs == 0)
-    secs = 1;
-
-  sprintf(buf, "CPU Secs %ld:%ld User %ld:%ld System %ld:%ld",
-          secs / 60, secs % 60,
-          rus.ru_utime.tv_sec / 60, rus.ru_utime.tv_sec % 60,
-          rus.ru_stime.tv_sec / 60, rus.ru_stime.tv_sec % 60);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "RSS %ld ShMem %ld Data %ld Stack %ld",
-          rus.ru_maxrss,
-          rus.ru_ixrss / upticks, rus.ru_idrss / upticks,
-          rus.ru_isrss / upticks);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Swaps %ld Reclaims %ld Faults %ld",
-          rus.ru_nswap, rus.ru_minflt, rus.ru_majflt);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Block in %ld out %ld", rus.ru_inblock, rus.ru_oublock);
-  (*enumerator)(cptr, buf);
-  
-  sprintf(buf, "Msg Rcv %ld Send %ld", rus.ru_msgrcv, rus.ru_msgsnd);
-  (*enumerator)(cptr, buf);
-
-  sprintf(buf, "Signals %ld Context Vol. %ld Invol %ld",
-          rus.ru_nsignals, rus.ru_nvcsw, rus.ru_nivcsw);
-  (*enumerator)(cptr, buf);
-
-  return 1;
-}
-
-int os_get_sockerr(int fd)
-{
-  int err = 0;
-  int len = sizeof(err);
-  getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*) &err, &len);
-  return err;
-}
-
-/*
- * set_non_blocking
- *
- * Set the client connection into non-blocking mode. If your
- * system doesn't support this, you can make this a dummy
- * function (and get all the old problems that plagued the
- * blocking version of IRC--not a problem if you are a
- * lightly loaded node...)
- */
-int os_set_nonblocking(int fd)
-{
-  int res = 1;
-  return (0 == ioctl(fd, FIONBIO, &res));
-}
-
-/*
- *  set_sock_opts
- */
-int os_set_reuseaddr(int fd)
-{
-  unsigned int opt = 1;
-  return (0 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 
-                          (const char*) &opt, sizeof(opt)));
-}
-
-int os_set_sockbufs(int fd, unsigned int ssize, unsigned int rsize)
-{
-  unsigned int sopt = ssize;
-  unsigned int ropt = rsize;
-  return (0 == setsockopt(fd, SOL_SOCKET, SO_RCVBUF, 
-                          (const char*) &ropt, sizeof(ropt)) &&
-          0 == setsockopt(fd, SOL_SOCKET, SO_SNDBUF, 
-                          (const char*) &sopt, sizeof(sopt)));
-}
-
-int os_set_tos(int fd,int tos)
-{
-  unsigned int opt = tos;
-  return (0 == setsockopt(fd, IPPROTO_IP, IP_TOS, &opt, sizeof(opt)));
-}
-
-int os_disable_options(int fd)
-{
-  return (0 == setsockopt(fd, IPPROTO_IP, IP_OPTIONS, NULL, 0));
-}
-
-int os_set_fdlimit(unsigned int max_descriptors)
-{
-  struct rlimit limit;
-
-  if (!getrlimit(RLIMIT_NOFILE, &limit)) {
-    if (limit.rlim_max < max_descriptors)
-      return limit.rlim_max;
-    limit.rlim_cur = limit.rlim_max;    /* make soft limit the max */
-    return setrlimit(RLIMIT_NOFILE, &limit);
-  }
-  return 0;
-}
-
-IOResult os_recv_nonb(int fd, char* buf, unsigned int length, 
-                 unsigned int* count_out)
-{
-  int res;
-  assert(0 != buf);
-  assert(0 != count_out);
-  *count_out = 0;
-  errno = 0;
-
-  if (0 < (res = recv(fd, buf, length, 0))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (res < 0) {
-    if (EAGAIN == errno || ENOBUFS == errno || 
-        ENOMEM == errno || ENOSR == errno)
-      return IO_BLOCKED;
-    else
-      return IO_FAILURE;
-  } 
-  /*
-   * 0   == client closed the connection
-   * < 1 == error
-   */
-  return IO_FAILURE;
-}
-
-IOResult os_recvfrom_nonb(int fd, char* buf, unsigned int length, 
-                          unsigned int* length_out, struct sockaddr_in* sin_out)
-{
-  int    res;
-  unsigned int len = sizeof(struct sockaddr_in);
-  assert(0 != buf);
-  assert(0 != length_out);
-  assert(0 != sin_out);
-  errno = 0;
-
-  res = recvfrom(fd, buf, length, 0, (struct sockaddr*) sin_out, &len);
-  if (-1 == res) {
-    if (EAGAIN == errno || ENOBUFS == errno || 
-        ENOMEM == errno || ENOSR == errno)
-      return IO_BLOCKED;
-    return IO_FAILURE;
-  }
-  *length_out = res;
-  return IO_SUCCESS;
-}
-
-IOResult os_send_nonb(int fd, const char* buf, unsigned int length, 
-                 unsigned int* count_out)
-{
-  int res;
-  assert(0 != buf);
-  assert(0 != count_out);
-  *count_out = 0;
-  errno = 0;
-
-  if (-1 < (res = send(fd, buf, length, 0))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (EAGAIN == errno || ENOBUFS == errno || 
-           ENOMEM == errno || ENOSR == errno)
-    return IO_BLOCKED;
-
-  return IO_FAILURE;
-}
-
-IOResult os_sendv_nonb(int fd, struct MsgQ* buf, unsigned int* count_in,
-                      unsigned int* count_out)
-{
-  int res;
-  int count;
-  struct iovec iov[IOV_MAX];
-
-  assert(0 != buf);
-  assert(0 != count_in);
-  assert(0 != count_out);
-
-  *count_in = 0;
-  *count_out = 0;
-  errno = 0;
-
-  count = msgq_mapiov(buf, iov, IOV_MAX, count_in);
-
-  if (-1 < (res = writev(fd, iov, count))) {
-    *count_out = (unsigned) res;
-    return IO_SUCCESS;
-  }
-  else if (EAGAIN == errno || ENOBUFS == errno ||
-          ENOMEM == errno || ENOSR == errno)
-    return IO_BLOCKED;
-
-  return IO_FAILURE;
-}
-
-IOResult os_connect_nonb(int fd, const struct sockaddr_in* sin)
-{
-  if (connect(fd, (struct sockaddr*) sin, sizeof(struct sockaddr_in)))
-    return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
-  return IO_SUCCESS;
-}
-      
-int os_get_sockname(int fd, struct sockaddr_in* sin_out)
-{
-  int len = sizeof(struct sockaddr_in);
-  assert(0 != sin_out);
-  return (0 == getsockname(fd, (struct sockaddr*) sin_out, &len));
-}
-
-int os_get_peername(int fd, struct sockaddr_in* sin_out)
-{
-  int len = sizeof(struct sockaddr_in);
-  assert(0 != sin_out);
-  return (0 == getpeername(fd, (struct sockaddr*) sin_out, &len));
-}
-
-int os_set_listen(int fd, int backlog)
-{
-  return (0 == listen(fd, backlog));
-}
-
diff --git a/ircd/res_adns.c b/ircd/res_adns.c
deleted file mode 100644 (file)
index d64ea6b..0000000
+++ /dev/null
@@ -1,786 +0,0 @@
-/*
- * src/res.c (C)opyright 1992 Darren Reed. All rights reserved.
- * This file may not be distributed without the author's permission in any
- * shape or form. The author takes no responsibility for any damage or loss
- * of property which results from the use of this software.
- *
- * $Id$
- *
- * July 1999 - Rewrote a bunch of stuff here. Change hostent builder code,
- *     added callbacks and reference counting of returned hostents.
- *     --Bleep (Thomas Helvey <tomh@inxpress.net>)
- */
-#include "config.h"
-
-#include "adns.h"
-#include "res.h"
-#include "client.h"
-#include "ircd.h"
-#include "ircd_alloc.h"
-#include "ircd_events.h"
-#include "ircd_log.h"
-#include "ircd_osdep.h"
-#include "ircd_reply.h"
-#include "ircd_snprintf.h"
-#include "ircd_string.h"
-#include "msg.h"
-#include "numeric.h"
-#include "s_bsd.h"
-#include "s_debug.h"
-#include "s_misc.h"
-#include "send.h"
-#include "struct.h"
-#include "support.h"
-#include "sys.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <regex.h>
-
-#include <arpa/nameser.h>
-#include <resolv.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-
-#include <limits.h>
-#if (CHAR_BIT != 8)
-#error this code needs to be able to address individual octets 
-#endif
-
-/*
- * Some systems do not define INADDR_NONE (255.255.255.255)
- * INADDR_NONE is actually a valid address, but it should never
- * be returned from any nameserver.
- * NOTE: The bit pattern for INADDR_NONE and INADDR_ANY (0.0.0.0) should be 
- * the same on all hosts so we shouldn't need to use htonl or ntohl to
- * compare or set the values.
- */ 
-#ifndef INADDR_NONE
-#define INADDR_NONE ((unsigned int) 0xffffffff)
-#endif
-
-#define MAXPACKET       1024  /* rfc sez 512 but we expand names so ... */
-#define RES_MAXALIASES  35    /* maximum aliases allowed */
-#define RES_MAXADDRS    35    /* maximum addresses allowed */
-/*
- * OSF1 doesn't have RES_NOALIASES
- */
-#ifndef RES_NOALIASES
-#define RES_NOALIASES 0
-#endif
-
-/*
- * macros used to calulate offsets into fixed query buffer
- */
-#define ALIAS_BLEN  ((RES_MAXALIASES + 1) * sizeof(char*))
-#define ADDRS_BLEN  ((RES_MAXADDRS + 1) * sizeof(struct in_addr*))
-
-#define ADDRS_OFFSET   (ALIAS_BLEN + ADDRS_BLEN)
-#define ADDRS_DLEN     (RES_MAXADDRS * sizeof(struct in_addr))
-#define NAMES_OFFSET   (ADDRS_OFFSET + ADDRS_DLEN)
-#define MAXGETHOSTLEN  (NAMES_OFFSET + MAXPACKET)
-
-#define AR_TTL          600   /* TTL in seconds for dns cache entries */
-
-/*
- * the following values should be prime
- */
-#define ARES_CACSIZE    307
-#define MAXCACHED       17
-//#define MAXCACHED       281
-
-/*
- * Building the Hostent
- * The Hostent struct is arranged like this:
- *          +-------------------------------+
- * Hostent: | struct hostent h              |
- *          |-------------------------------|
- *          | char *buf                     |
- *          +-------------------------------+
- *
- * allocated:
- *
- *          +-------------------------------+
- * buf:     | h_aliases pointer array       | Max size: ALIAS_BLEN;
- *          | NULL                          | contains `char *'s
- *          |-------------------------------|
- *          | h_addr_list pointer array     | Max size: ADDRS_BLEN;
- *          | NULL                          | contains `struct in_addr *'s
- *          |-------------------------------|
- *          | h_addr_list addresses         | Max size: ADDRS_DLEN;
- *          |                               | contains `struct in_addr's
- *          |-------------------------------|
- *          | storage for hostname strings  | Max size: ALIAS_DLEN;
- *          +-------------------------------+ contains `char's
- *
- *  For requests the size of the h_aliases, and h_addr_list pointer
- *  array sizes are set to MAXALISES and MAXADDRS respectively, and
- *  buf is a fixed size with enough space to hold the largest expected
- *  reply from a nameserver, see RFC 1034 and RFC 1035.
- *  For cached entries the sizes are dependent on the actual number
- *  of aliases and addresses. If new aliases and addresses are found
- *  for cached entries, the buffer is grown and the new entries are added.
- *  The hostent struct is filled in with the addresses of the entries in
- *  the Hostent buf as follows:
- *  h_name      - contains a pointer to the start of the hostname string area,
- *                or NULL if none is set.  The h_name is followed by the
- *                aliases, in the storage for hostname strings area.
- *  h_aliases   - contains a pointer to the start of h_aliases pointer array.
- *                This array contains pointers to the storage for hostname
- *                strings area and is terminated with a NULL.  The first alias
- *                is stored directly after the h_name.
- *  h_addr_list - contains a pointer to the start of h_addr_list pointer array.
- *                This array contains pointers to in_addr structures in the
- *                h_addr_list addresses area and is terminated with a NULL.
- *
- *  Filling the buffer this way allows for proper alignment of the h_addr_list
- *  addresses.
- *
- *  This arrangement allows us to alias a Hostent struct pointer as a
- *  real struct hostent* without lying. It also allows us to change the
- *  values contained in the cached entries and requests without changing
- *  the actual hostent pointer, which is saved in a client struct and can't
- *  be changed without blowing things up or a lot more fiddling around.
- *  It also allows for defered allocation of the fixed size buffers until
- *  they are really needed.
- *  Nov. 17, 1997 --Bleep
- */
-
-struct Hostent {
-  struct hostent h;        /* the hostent struct we are passing around */
-  char           buf[1];   /* buffer for data pointed to from hostent */
-};
-
-struct ResRequest {
-  struct ResRequest* next;
-
-  adns_rrtype        type;
-  adns_query         aq;
-
-  struct in_addr     addr;
-  char*              name;
-  struct DNSQuery    query;         /* query callback for this request */
-  struct hostent     he;
-  char*              buf;
-};
-
-int ResolverFileDescriptor    = -1;   /* GLOBAL - used in s_bsd.c */
-
-static struct Socket resSock;          /* Socket describing resolver */
-static struct Timer  resExpireDNS;     /* Timer for DNS expiration */
-static adns_state adns = NULL;
-
-/*
- * Keep a spare file descriptor open. res_init calls fopen to read the
- * resolv.conf file. If ircd is hogging all the file descriptors below 256,
- * on systems with crippled FILE structures this will cause wierd bugs.
- * This is definitely needed for Solaris which uses an unsigned char to
- * hold the file descriptor.  --Dianora
- */ 
-static int                spare_fd = -1;
-
-static struct ResRequest* requestListHead;   /* head of resolver request list */
-static struct ResRequest* requestListTail;   /* tail of resolver request list */
-
-
-static void     add_request(struct ResRequest* request);
-static void     rem_request(struct ResRequest* request);
-static struct ResRequest*   make_request(const struct DNSQuery* query);
-static time_t   timeout_query_list(time_t now);
-static void     do_query_name(const struct DNSQuery* query, 
-                              const char* name, 
-                              struct ResRequest* request);
-static void     do_query_number(const struct DNSQuery* query,
-                                const struct in_addr*, 
-                                struct ResRequest* request);
-static void res_adns_callback(adns_state state, adns_query q, void *context);
-
-static struct  resinfo {
-  int  re_errors;
-  int  re_nu_look;
-  int  re_na_look;
-  int  re_replies;
-  int  re_requests;
-  int  re_resends;
-  int  re_sent;
-  int  re_timeouts;
-  int  re_shortttl;
-  int  re_unkrep;
-} reinfo;
-
-
-/* Socket callback for resolver */
-static void res_socket_callback(struct Event* ev)
-{
-  struct timeval tv;
-
-  assert(ev_type(ev) == ET_READ || ev_type(ev) == ET_ERROR);
-
-  tv.tv_sec = CurrentTime;
-  tv.tv_usec = 0;
-  adns_processreadable(adns, ResolverFileDescriptor, &tv);
-}
-
-/*
- * start_resolver - do everything we need to read the resolv.conf file
- * and initialize the resolver file descriptor if needed
- */
-static void start_resolver(void)
-{
-  int res;
-
-  Debug((DEBUG_DNS, "Resolver: start_resolver"));
-  /*
-   * close the spare file descriptor so res_init can read resolv.conf
-   * successfully. Needed on Solaris
-   */
-  if (spare_fd > -1)
-    close(spare_fd);
-
-  /*
-   * make sure we have a valid file descriptor below 256 so we can
-   * do this again. Needed on Solaris
-   */
-  spare_fd = open("/dev/null",O_RDONLY,0);
-  if ((spare_fd < 0) || (spare_fd > 255)) {
-    char sparemsg[80];
-    ircd_snprintf(0, sparemsg, sizeof(sparemsg), "invalid spare_fd %d",
-                 spare_fd);
-    server_restart(sparemsg);
-  }
-
-  if (adns)
-    return;
-
-  if ((res = adns_init(&adns, adns_if_debug /*| adns_if_noautosys*/, NULL))) {
-    report_error("Resolver: error initializing adns for %s: %s",
-                 cli_name(&me), res);
-    errno = res;
-    return;
-  }
-  errno = 0;
-  
-  ResolverFileDescriptor = adns_get_fd(adns);
-
-  if (!socket_add(&resSock, res_socket_callback, 0, SS_DATAGRAM,
-                 SOCK_EVENT_READABLE, ResolverFileDescriptor))
-    report_error("Resolver: unable to queue resolver file descriptor for %s",
-                cli_name(&me), ENFILE);
-}
-
-/* Call the query timeout function */
-static void expire_DNS_callback(struct Event* ev)
-{
-  time_t next;
-
-  next = timeout_query_list(CurrentTime);
-
-  timer_add(&resExpireDNS, expire_DNS_callback, 0, TT_ABSOLUTE, next);
-}
-
-/*
- * init_resolver - initialize resolver and resolver library
- */
-int init_resolver(void)
-{
-  Debug((DEBUG_DNS, "Resolver: init_resolver"));
-#ifdef  LRAND48
-  srand48(CurrentTime);
-#endif
-  memset(&reinfo,   0, sizeof(reinfo));
-
-  requestListHead = requestListTail = 0;
-
-  /* initiate the resolver timers */
-  timer_add(timer_init(&resExpireDNS), expire_DNS_callback, 0,
-           TT_RELATIVE, 1);
-
-  errno = h_errno = 0;
-
-  start_resolver();
-  Debug((DEBUG_DNS, "Resolver: fd %d errno: %d h_errno: %d: %s",
-         ResolverFileDescriptor, errno, h_errno, 
-         (strerror(errno)) ? strerror(errno) : "Unknown"));
-  return ResolverFileDescriptor;
-}
-
-/*
- * restart_resolver - flush the cache, reread resolv.conf, reopen socket
- */
-void restart_resolver(void)
-{
-  start_resolver();
-}
-
-/*
- * add_request - place a new request in the request list
- */
-static void add_request(struct ResRequest* request)
-{
-  assert(0 != request);
-  if (!requestListHead)
-    requestListHead = requestListTail = request;
-  else {
-    requestListTail->next = request;
-    requestListTail = request;
-  }
-  request->next = NULL;
-  ++reinfo.re_requests;
-}
-
-/*
- * rem_request - remove a request from the list. 
- * This must also free any memory that has been allocated for 
- * temporary storage of DNS results.
- */
-static void rem_request(struct ResRequest* request)
-{
-  struct ResRequest** current;
-  struct ResRequest*  prev = NULL;
-
-  assert(0 != request);
-  for (current = &requestListHead; *current; ) {
-    if (*current == request) {
-      *current = request->next;
-      if (requestListTail == request)
-        requestListTail = prev;
-      break;
-    } 
-    prev    = *current;
-    current = &(*current)->next;
-  }
-  if (request->aq)
-    adns_cancel(request->aq);
-  MyFree(request->buf);
-  MyFree(request->name);
-  MyFree(request);
-}
-
-/*
- * make_request - Create a DNS request record for the server.
- */
-static struct ResRequest* make_request(const struct DNSQuery* query)
-{
-  struct ResRequest* request;
-  assert(0 != query);
-  request = (struct ResRequest*) MyMalloc(sizeof(struct ResRequest));
-  memset(request, 0, sizeof(struct ResRequest));
-
-  request->addr.s_addr    = INADDR_NONE;
-  request->he.h_addrtype  = AF_INET;
-  request->he.h_length    = sizeof(struct in_addr);
-  request->query.vptr     = query->vptr;
-  request->query.callback = query->callback;
-
-  add_request(request);
-  return request;
-}
-
-/*
- * timeout_query_list - Remove queries from the list which have been 
- * there too long without being resolved.
- */
-static time_t timeout_query_list(time_t now)
-{
-  struct timeval tv, tv_buf, *tv_mod = NULL;
-  time_t next;
-  
-  Debug((DEBUG_DNS, "Resolver: timeout_query_list at %s", myctime(now)));
-
-  tv.tv_sec = now;
-  tv.tv_usec = 0;
-  adns_processtimeouts(adns, &tv);
-  adns_firsttimeout(adns, &tv_mod, &tv_buf, tv);
-  next = tv_mod ? tv_mod->tv_sec : AR_TTL;
-  if (!next)
-    next = 1;
-
-  Debug((DEBUG_DNS, "Resolver: next timeout_query_list in %d seconds", next));
-  return now + next;
-}
-
-/*
- * delete_resolver_queries - cleanup outstanding queries 
- * for which there no longer exist clients or conf lines.
- */
-void delete_resolver_queries(const void* vptr)
-{
-  struct ResRequest* request;
-  struct ResRequest* next_request;
-
-  for (request = requestListHead; request; request = next_request) {
-    next_request = request->next;
-    if (vptr == request->query.vptr)
-      rem_request(request);
-  }
-}
-
-/*
- * gethost_byname - get host address from name
- */
-void gethost_byname(const char* name, const struct DNSQuery* query)
-{
-  assert(0 != name);
-
-  Debug((DEBUG_DNS, "Resolver: gethost_byname %s", name));
-  ++reinfo.re_na_look;
-  do_query_name(query, name, NULL);
-}
-
-/*
- * gethost_byaddr - get host name from address
- */
-void gethost_byaddr(const char* addr, const struct DNSQuery* query)
-{
-  assert(0 != addr);
-  Debug((DEBUG_DNS, "Resolver: gethost_byaddr %s", ircd_ntoa(addr)));
-  ++reinfo.re_nu_look;
-  do_query_number(query, (const struct in_addr*) addr, NULL);
-}
-
-/*
- * do_query_name - nameserver lookup name
- */
-static void do_query_name(const struct DNSQuery* query, 
-                          const char* name, struct ResRequest* request)
-{
-  char  hname[HOSTLEN + 1];
-  int  res;
-  assert(0 != name);
-
-  ircd_strncpy(hname, name, HOSTLEN);
-  hname[HOSTLEN] = '\0';
-
-  if (!request) {
-    request       = make_request(query);
-    request->type = adns_r_a;
-    request->name = (char*) MyMalloc(strlen(hname) + 1);
-    strcpy(request->name, hname);
-  }
-  res = adns_submit_callback(adns, hname, adns_r_a, adns_qf_owner,
-                             request, &request->aq, res_adns_callback);
-  assert(!res);
-  timer_chg(&resExpireDNS, TT_RELATIVE, 1);
-}
-
-/*
- * do_query_number - Use this to do reverse IP# lookups.
- */
-static void do_query_number(const struct DNSQuery* query, 
-                            const struct in_addr* addr,
-                            struct ResRequest* request)
-{
-  char  ipbuf[32];
-  const unsigned char* cp;
-  int  res;
-
-  assert(0 != addr);
-  cp = (const unsigned char*) &addr->s_addr;
-  ircd_snprintf(0, ipbuf, sizeof(ipbuf), "%u.%u.%u.%u.in-addr.arpa.",
-               (unsigned int)(cp[3]), (unsigned int)(cp[2]),
-               (unsigned int)(cp[1]), (unsigned int)(cp[0]));
-
-  if (!request) {
-    request              = make_request(query);
-    request->type        = adns_r_ptr;
-    request->addr.s_addr = addr->s_addr;
-  }
-  res = adns_submit_callback(adns, ipbuf, adns_r_ptr, adns_qf_owner,
-                             request, &request->aq, res_adns_callback);
-  assert(!res);
-  timer_chg(&resExpireDNS, TT_RELATIVE, 1);
-}
-
-/*
- * dup_hostent - Duplicate a hostent struct, allocate only enough memory for
- * the data we're putting in it.
- */
-static struct hostent* dup_hostent(struct hostent* hp)
-{
-  char*  p;
-  char** ap;
-  char** pp;
-  int    alias_count = 0;
-  int    addr_count = 0;
-  size_t bytes_needed = 0;
-  struct Hostent* new_hp = 0;
-
-  assert(0 != hp);
-
-  /* how much buffer do we need? */
-  bytes_needed += (strlen(hp->h_name) + 1);
-
-  pp = hp->h_aliases;
-  while (*pp) {
-    bytes_needed += (strlen(*pp++) + 1 + sizeof(char*));
-    ++alias_count;
-  }
-  pp = hp->h_addr_list;
-  while (*pp++) {
-    bytes_needed += (hp->h_length + sizeof(char*));
-    ++addr_count;
-  }
-  /* Reserve space for 2 nulls to terminate h_aliases and h_addr_list */
-  bytes_needed += (2 * sizeof(char*));
-
-  /* Allocate memory */
-  new_hp = (struct Hostent*) MyMalloc(sizeof(struct Hostent) + bytes_needed);
-
-  new_hp->h.h_addrtype = hp->h_addrtype;
-  new_hp->h.h_length = hp->h_length;
-
-  /* first write the address list */
-  pp = hp->h_addr_list;
-  ap = new_hp->h.h_addr_list =
-      (char**)(new_hp->buf + ((alias_count + 1) * sizeof(char*)));
-  p = (char*)ap + ((addr_count + 1) * sizeof(char*));
-  while (*pp)
-  {
-    *ap++ = p;
-    memcpy(p, *pp++, hp->h_length);
-    p += hp->h_length;
-  }
-  *ap = 0;
-  /* next write the name */
-  new_hp->h.h_name = p;
-  strcpy(p, hp->h_name);
-  p += (strlen(p) + 1);
-
-  /* last write the alias list */
-  pp = hp->h_aliases;
-  ap = new_hp->h.h_aliases = (char**) new_hp->buf;
-  while (*pp) {
-    *ap++ = p;
-    strcpy(p, *pp++);
-    p += (strlen(p) + 1);
-  }
-  *ap = 0;
-  return (struct hostent*) new_hp;
-}
-
-static void res_adns_callback(adns_state state, adns_query q, void *context)
-{
-  struct ResRequest *request = (struct ResRequest *) context;
-  adns_answer *answer = NULL;
-  int res, k;
-  struct hostent* hp;          /* hostent getting filled */
-  char** alias;                /* alias list */
-  char** addr;                 /* address list */
-  char** base_addr;            /* original pointer to address list */
-  char*  name;                 /* pointer to name string */
-  char*  address;              /* pointer to address */
-  char*  base_address;         /* original pointer to address */
-  char*  endp;                 /* end of our buffer */
-  int    addr_count  = 0;      /* number of addresses in hostent */
-  int    alias_count = 0;      /* number of aliases in hostent */
-  
-  assert(request);
-  assert(q);
-  assert(request->aq == q);
-  res = adns_check(adns, &q, &answer, NULL);
-  request->aq = NULL;
-
-  if (res) {
-    /* adns_check returned an error, bail */
-    Debug((DEBUG_DNS, "Resolver: adns_check result %d", res));
-
-    (*request->query.callback)(request->query.vptr, 0);
-    rem_request(request);
-    return;
-  }
-
-  Debug((DEBUG_DNS, "Resolver: adns_check status %d nrrs %d",
-        answer->status, answer->nrrs));
-  
-  /* No error, we have a valid answer structure */
-  if (answer->status != adns_s_ok || !answer->nrrs) {
-    /* Status is not 'ok', or there were no RRs found */
-    ++reinfo.re_errors;
-    (*request->query.callback)(request->query.vptr, 0);
-  } else {
-    ++reinfo.re_replies;
-    hp = &(request->he);    
-    if (!request->buf) {
-      request->buf = (char*) MyMalloc(MAXGETHOSTLEN + 1);
-      request->buf[MAXGETHOSTLEN] = '\0';
-      /*
-       * array of alias list pointers starts at beginning of buf
-       */
-      hp->h_aliases = (char**) request->buf;
-      hp->h_aliases[0] = NULL;
-      /*
-       * array of address list pointers starts after alias list pointers
-       * the actual addresses follow the the address list pointers
-       */ 
-      hp->h_addr_list = (char**)(request->buf + ALIAS_BLEN);
-      /*
-       * don't copy the host address to the beginning of h_addr_list
-       */
-      hp->h_addr_list[0] = NULL;
-    }
-
-    hp->h_addrtype = AF_INET;
-
-    endp = request->buf + MAXGETHOSTLEN;
-    /*
-     * find the end of the address list
-     */
-    addr = hp->h_addr_list;
-    while (*addr) {
-      ++addr;
-      ++addr_count;
-    }
-    base_addr = addr;
-    /*
-     * make address point to first available address slot
-     */
-    address = request->buf + ADDRS_OFFSET +
-                      (sizeof(struct in_addr) * addr_count);
-    base_address = address;
-
-    /*
-     * find the end of the alias list
-     */
-    alias = hp->h_aliases;
-    while (*alias) {
-      ++alias;
-      ++alias_count;
-    }
-    /*
-     * make name point to first available space in request->buf
-     */
-    if (alias_count > 0) {
-      name = hp->h_aliases[alias_count - 1];
-      name += (strlen(name) + 1);
-    }
-    else if (hp->h_name)
-      name = hp->h_name + strlen(hp->h_name) + 1;
-    else
-      name = request->buf + ADDRS_OFFSET + ADDRS_DLEN;
-
-    switch (request->type) {
-    case adns_r_a:
-      for (k = 0; k < answer->nrrs; k++) {
-        if (++addr_count < RES_MAXADDRS) {
-          memcpy(address, &answer->rrs.inaddr[k], sizeof(struct in_addr));
-          *addr++ = address;
-          *addr = 0;
-          address += sizeof(struct in_addr);
-       }
-        Debug((DEBUG_DNS, "Resolver: A %s for %s",
-              ircd_ntoa((char*) &answer->rrs.inaddr[k]), answer->owner));
-      }
-      if (!hp->h_name) {
-        strcpy(name, answer->owner);
-        hp->h_name = name;
-        name += strlen(name) + 1;
-      }
-      break;
-    case adns_r_ptr:
-      strcpy(name, answer->rrs.str[0]);
-      hp->h_name = name;
-      name += strlen(name) + 1;
-
-      Debug((DEBUG_DNS, "Resolver: PTR %s for %s", hp->h_name, answer->owner));
-      break;
-    default:
-      /* ignore */
-      break;
-    }
-
-    if (answer->cname) {
-      alias_count++;
-      ircd_strncpy(name, answer->cname, endp - name);
-      *alias++ = name;
-      *alias   = 0;
-      name += strlen(name) + 1;
-      Debug((DEBUG_DNS, "Resolver: CNAME %s for %s",
-            answer->cname, answer->owner));
-    }
-
-    if (request->type == adns_r_ptr) {
-
-      Debug((DEBUG_DNS, "relookup %s <-> %s",
-             request->he.h_name, ircd_ntoa((char*) &request->addr)));
-      /*
-       * Lookup the 'authoritive' name that we were given for the
-       * ip#.  By using this call rather than regenerating the
-       * type we automatically gain the use of the cache with no
-       * extra kludges.
-       */
-      gethost_byname(request->he.h_name, &request->query);
-      /*
-       * If name wasn't found, a request has been queued and it will
-       * be the last one queued.  This is rather nasty way to keep
-       * a host alias with the query. -avalon
-       */
-      MyFree(requestListTail->buf);
-      requestListTail->buf = request->buf;
-      request->buf = 0;
-      memcpy(&requestListTail->he, &request->he, sizeof(struct hostent));
-    } else {
-      /*
-       * got a name and address response, client resolved
-       * XXX - Bug found here by Dianora -
-       * make_cache() occasionally returns a NULL pointer when a
-       * PTR returned a CNAME, cp was not checked before so the
-       * callback was being called with a value of 0x2C != NULL.
-       */
-      struct hostent* he = dup_hostent(&request->he);
-      (*request->query.callback)(request->query.vptr, he);
-    }
-  }
-  
-  rem_request(request);
-  
-  /*
-   * adns doesn't use MyMalloc, so we don't use MyFree
-   */
-  free(answer);
-}
-
-/*
- * m_dns - dns status query
- */
-int m_dns(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
-{
-#if !defined(NDEBUG)
-  sendcmdto_one(&me, CMD_NOTICE, sptr,"%C :Errors %d Lookups %d/%d Replies %d Requests %d",
-               sptr, reinfo.re_errors, reinfo.re_nu_look,
-               reinfo.re_na_look, reinfo.re_replies, reinfo.re_requests);
-  sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Unknown Reply %d Short TTL(<10m) %d Sent %d Resends %d Timeouts %d", sptr,
-               reinfo.re_unkrep, reinfo.re_shortttl, reinfo.re_sent,
-               reinfo.re_resends, reinfo.re_timeouts);
-  sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :ResolverFileDescriptor = %d", 
-                sptr, ResolverFileDescriptor);
-#endif
-  return 0;
-}
-
-size_t cres_mem(struct Client* sptr)
-{
-  struct ResRequest* request;
-  size_t request_mem   = 0;
-  int    request_count = 0;
-
-  for (request = requestListHead; request; request = request->next) {
-    request_mem += sizeof(struct ResRequest);
-    if (request->name)
-      request_mem += strlen(request->name) + 1; 
-    if (request->buf)
-      request_mem += MAXGETHOSTLEN + 1;
-    ++request_count;
-  }
-
-  send_reply(sptr, SND_EXPLICIT | RPL_STATSDEBUG,
-            ":Resolver: requests %d(%d)", request_count, request_mem);
-  return request_mem;
-}
-
diff --git a/ircd/res_libresolv.c b/ircd/res_libresolv.c
deleted file mode 100644 (file)
index d964eb9..0000000
+++ /dev/null
@@ -1,1201 +0,0 @@
-/*
- * src/res.c (C)opyright 1992 Darren Reed. All rights reserved.
- * This file may not be distributed without the author's permission in any
- * shape or form. The author takes no responsibility for any damage or loss
- * of property which results from the use of this software.
- *
- * $Id$
- *
- * July 1999 - Rewrote a bunch of stuff here. Change hostent builder code,
- *     added callbacks and reference counting of returned hostents.
- *     --Bleep (Thomas Helvey <tomh@inxpress.net>)
- */
-#include "config.h"
-
-#include "res.h"
-#include "client.h"
-#include "ircd.h"
-#include "ircd_alloc.h"
-#include "ircd_events.h"
-#include "ircd_features.h"
-#include "ircd_log.h"
-#include "ircd_osdep.h"
-#include "ircd_reply.h"
-#include "ircd_snprintf.h"
-#include "ircd_string.h"
-#include "msg.h"
-#include "numeric.h"
-#include "s_bsd.h"
-#include "s_debug.h"
-#include "s_misc.h"
-#include "send.h"
-#include "struct.h"
-#include "support.h"
-#include "sys.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <regex.h>
-
-#include <arpa/nameser.h>
-#include <resolv.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-
-#include <limits.h>
-#if (CHAR_BIT != 8)
-#error this code needs to be able to address individual octets 
-#endif
-
-/*
- * Some systems do not define INADDR_NONE (255.255.255.255)
- * INADDR_NONE is actually a valid address, but it should never
- * be returned from any nameserver.
- * NOTE: The bit pattern for INADDR_NONE and INADDR_ANY (0.0.0.0) should be 
- * the same on all hosts so we shouldn't need to use htonl or ntohl to
- * compare or set the values.
- */ 
-#ifndef INADDR_NONE
-#define INADDR_NONE ((unsigned int) 0xffffffff)
-#endif
-
-#define MAXPACKET       1024  /* rfc sez 512 but we expand names so ... */
-#define RES_MAXALIASES  35    /* maximum aliases allowed */
-#define RES_MAXADDRS    35    /* maximum addresses allowed */
-/*
- * OSF1 doesn't have RES_NOALIASES
- */
-#ifndef RES_NOALIASES
-#define RES_NOALIASES 0
-#endif
-
-/*
- * macros used to calulate offsets into fixed query buffer
- */
-#define ALIAS_BLEN  ((RES_MAXALIASES + 1) * sizeof(char*))
-#define ADDRS_BLEN  ((RES_MAXADDRS + 1) * sizeof(struct in_addr*))
-
-#define ADDRS_OFFSET   (ALIAS_BLEN + ADDRS_BLEN)
-#define ADDRS_DLEN     (RES_MAXADDRS * sizeof(struct in_addr))
-#define NAMES_OFFSET   (ADDRS_OFFSET + ADDRS_DLEN)
-#define MAXGETHOSTLEN  (NAMES_OFFSET + MAXPACKET)
-
-#define AR_TTL          600   /* TTL in seconds for dns cache entries */
-
-/*
- * RFC 1104/1105 wasn't very helpful about what these fields
- * should be named, so for now, we'll just name them this way.
- * we probably should look at what named calls them or something.
- */
-#define TYPE_SIZE       2
-#define CLASS_SIZE      2
-#define TTL_SIZE        4
-#define RDLENGTH_SIZE   2
-#define ANSWER_FIXED_SIZE (TYPE_SIZE + CLASS_SIZE + TTL_SIZE + RDLENGTH_SIZE)
-
-/*
- * Building the Hostent
- * The Hostent struct is arranged like this:
- *          +-------------------------------+
- * Hostent: | struct hostent h              |
- *          |-------------------------------|
- *          | char *buf                     |
- *          +-------------------------------+
- *
- * allocated:
- *
- *          +-------------------------------+
- * buf:     | h_aliases pointer array       | Max size: ALIAS_BLEN;
- *          | NULL                          | contains `char *'s
- *          |-------------------------------|
- *          | h_addr_list pointer array     | Max size: ADDRS_BLEN;
- *          | NULL                          | contains `struct in_addr *'s
- *          |-------------------------------|
- *          | h_addr_list addresses         | Max size: ADDRS_DLEN;
- *          |                               | contains `struct in_addr's
- *          |-------------------------------|
- *          | storage for hostname strings  | Max size: ALIAS_DLEN;
- *          +-------------------------------+ contains `char's
- *
- *  For requests the size of the h_aliases, and h_addr_list pointer
- *  array sizes are set to MAXALISES and MAXADDRS respectively, and
- *  buf is a fixed size with enough space to hold the largest expected
- *  reply from a nameserver, see RFC 1034 and RFC 1035.
- *  For cached entries the sizes are dependent on the actual number
- *  of aliases and addresses. If new aliases and addresses are found
- *  for cached entries, the buffer is grown and the new entries are added.
- *  The hostent struct is filled in with the addresses of the entries in
- *  the Hostent buf as follows:
- *  h_name      - contains a pointer to the start of the hostname string area,
- *                or NULL if none is set.  The h_name is followed by the
- *                aliases, in the storage for hostname strings area.
- *  h_aliases   - contains a pointer to the start of h_aliases pointer array.
- *                This array contains pointers to the storage for hostname
- *                strings area and is terminated with a NULL.  The first alias
- *                is stored directly after the h_name.
- *  h_addr_list - contains a pointer to the start of h_addr_list pointer array.
- *                This array contains pointers to in_addr structures in the
- *                h_addr_list addresses area and is terminated with a NULL.
- *
- *  Filling the buffer this way allows for proper alignment of the h_addr_list
- *  addresses.
- *
- *  This arrangement allows us to alias a Hostent struct pointer as a
- *  real struct hostent* without lying. It also allows us to change the
- *  values contained in the cached entries and requests without changing
- *  the actual hostent pointer, which is saved in a client struct and can't
- *  be changed without blowing things up or a lot more fiddling around.
- *  It also allows for defered allocation of the fixed size buffers until
- *  they are really needed.
- *  Nov. 17, 1997 --Bleep
- */
-
-struct Hostent {
-  struct hostent h;       /* the hostent struct we are passing around */
-  char           buf[1];  /* buffer for data pointed to from hostent */
-};
-
-struct ResRequest {
-  struct ResRequest* next;
-  int                id;
-  int                sent;          /* number of requests sent */
-  time_t             ttl;
-  char               type;
-  char               retries;       /* retry counter */
-  char               sends;         /* number of sends (>1 means resent) */
-  char               resend;        /* send flag. 0 == dont resend */
-  time_t             sentat;
-  time_t             timeout;
-  struct in_addr     addr;
-  char*              name;
-  struct DNSQuery    query;         /* query callback for this request */
-  struct hostent     he;
-  char*              buf;
-};
-
-
-int ResolverFileDescriptor    = -1;   /* GLOBAL - used in s_bsd.c */
-
-static struct Socket resSock;          /* Socket describing resolver */
-static struct Timer  resExpireDNS;     /* Timer for DNS expiration */
-
-static time_t nextDNSCheck    = 0;
-
-/*
- * Keep a spare file descriptor open. res_init calls fopen to read the
- * resolv.conf file. If ircd is hogging all the file descriptors below 256,
- * on systems with crippled FILE structures this will cause wierd bugs.
- * This is definitely needed for Solaris which uses an unsigned char to
- * hold the file descriptor.  --Dianora
- */ 
-static int                spare_fd = -1;
-
-static struct ResRequest* requestListHead;   /* head of resolver request list */
-static struct ResRequest* requestListTail;   /* tail of resolver request list */
-
-
-static void     add_request(struct ResRequest* request);
-static void     rem_request(struct ResRequest* request);
-static struct ResRequest*   make_request(const struct DNSQuery* query);
-static time_t   timeout_query_list(time_t now);
-static void     do_query_name(const struct DNSQuery* query, 
-                              const char* name, 
-                              struct ResRequest* request);
-static void     do_query_number(const struct DNSQuery* query,
-                                const struct in_addr*, 
-                                struct ResRequest* request);
-static void     query_name(const char* name, 
-                           int query_class, 
-                           int query_type, 
-                           struct ResRequest* request);
-static void     resend_query(struct ResRequest* request);
-static struct ResRequest*   find_id(int);
-
-static  struct  resinfo {
-  int  re_errors;
-  int  re_nu_look;
-  int  re_na_look;
-  int  re_replies;
-  int  re_requests;
-  int  re_resends;
-  int  re_sent;
-  int  re_timeouts;
-  int  re_shortttl;
-  int  re_unkrep;
-} reinfo;
-
-
-/*
- * From bind 8.3, these aren't declared in earlier versions of bind
- */
-extern u_short  _getshort(const u_char *);
-extern u_int    _getlong(const u_char *);
-/*
- * int
- * res_isourserver(ina)
- *      looks up "ina" in _res.ns_addr_list[]
- * returns:
- *      0  : not found
- *      >0 : found
- * author:
- *      paul vixie, 29may94
- */
-static int
-res_ourserver(const struct __res_state* statp, const struct sockaddr_in* inp) 
-{
-  struct sockaddr_in ina;
-  int ns;
-
-  ina = *inp;
-  for (ns = 0;  ns < statp->nscount;  ns++) {
-    const struct sockaddr_in *srv = &statp->nsaddr_list[ns];
-
-    if (srv->sin_family == ina.sin_family &&
-         srv->sin_port == ina.sin_port &&
-         (srv->sin_addr.s_addr == INADDR_ANY ||
-          srv->sin_addr.s_addr == ina.sin_addr.s_addr))
-             return (1);
-  }
-  return (0);
-}
-
-/* Socket callback for resolver */
-static void res_callback(struct Event* ev)
-{
-  assert(ev_type(ev) == ET_READ || ev_type(ev) == ET_ERROR);
-
-  resolver_read();
-}
-
-/*
- * start_resolver - do everything we need to read the resolv.conf file
- * and initialize the resolver file descriptor if needed
- */
-static void start_resolver(void)
-{
-  Debug((DEBUG_DNS, "Resolver: start_resolver"));
-  /*
-   * close the spare file descriptor so res_init can read resolv.conf
-   * successfully. Needed on Solaris
-   */
-  if (spare_fd > -1)
-    close(spare_fd);
-
-  res_init();      /* res_init always returns 0 */
-  /*
-   * make sure we have a valid file descriptor below 256 so we can
-   * do this again. Needed on Solaris
-   */
-  spare_fd = open("/dev/null",O_RDONLY,0);
-  if ((spare_fd < 0) || (spare_fd > 255)) {
-    char sparemsg[80];
-    ircd_snprintf(0, sparemsg, sizeof(sparemsg), "invalid spare_fd %d",
-                 spare_fd);
-    server_restart(sparemsg);
-  }
-
-  if (!_res.nscount) {
-    _res.nscount = 1;
-    _res.nsaddr_list[0].sin_addr.s_addr = inet_addr("127.0.0.1");
-  }
-  _res.options |= RES_NOALIASES;
-
-  if (ResolverFileDescriptor < 0) {
-    ResolverFileDescriptor = socket(AF_INET, SOCK_DGRAM, 0);
-    if (-1 == ResolverFileDescriptor) {
-      report_error("Resolver: error creating socket for %s: %s", 
-                   cli_name(&me), errno);
-      return;
-    }
-    if (!os_set_nonblocking(ResolverFileDescriptor))
-      report_error("Resolver: error setting non-blocking for %s: %s", 
-                   cli_name(&me), errno);
-    if (!socket_add(&resSock, res_callback, 0, SS_DATAGRAM,
-                   SOCK_EVENT_READABLE, ResolverFileDescriptor))
-      report_error("Resolver: unable to queue resolver file descriptor for %s",
-                  cli_name(&me), ENFILE);
-  }
-}
-
-/* Call the query timeout function */
-static void expire_DNS_callback(struct Event* ev)
-{
-  time_t next;
-
-  next = timeout_query_list(CurrentTime);
-
-  timer_add(&resExpireDNS, expire_DNS_callback, 0, TT_ABSOLUTE, next);
-}
-
-/*
- * init_resolver - initialize resolver and resolver library
- */
-int init_resolver(void)
-{
-  Debug((DEBUG_DNS, "Resolver: init_resolver"));
-#ifdef  LRAND48
-  srand48(CurrentTime);
-#endif
-  memset(&reinfo, 0, sizeof(reinfo));
-  requestListHead = requestListTail = 0;
-
-  /* initiate the resolver timers */
-  timer_add(timer_init(&resExpireDNS), expire_DNS_callback, 0,
-           TT_RELATIVE, 1);
-
-  errno = h_errno = 0;
-
-  start_resolver();
-  Debug((DEBUG_DNS, "Resolver: fd %d errno: %d h_errno: %d: %s",
-         ResolverFileDescriptor, errno, h_errno, 
-         (strerror(errno)) ? strerror(errno) : "Unknown"));
-  return ResolverFileDescriptor;
-}
-
-/*
- * restart_resolver - flush the cache, reread resolv.conf, reopen socket
- */
-void restart_resolver(void)
-{
-  /* flush_cache();  flush the dns cache */
-  start_resolver();
-}
-
-static int validate_hostent(const struct hostent* hp)
-{
-  const char* name;
-  int  i = 0;
-  assert(0 != hp);
-  for (name = hp->h_name; name; name = hp->h_aliases[i++]) {
-    if (!string_is_hostname(name))
-      return 0;
-  }
-  return 1;
-}
-
-/*
- * add_request - place a new request in the request list
- */
-static void add_request(struct ResRequest* request)
-{
-  assert(0 != request);
-  if (!requestListHead)
-    requestListHead = requestListTail = request;
-  else {
-    requestListTail->next = request;
-    requestListTail = request;
-  }
-  request->next = NULL;
-  ++reinfo.re_requests;
-}
-
-/*
- * rem_request - remove a request from the list. 
- * This must also free any memory that has been allocated for 
- * temporary storage of DNS results.
- */
-static void rem_request(struct ResRequest* request)
-{
-  struct ResRequest** current;
-  struct ResRequest*  prev = NULL;
-
-  assert(0 != request);
-  for (current = &requestListHead; *current; ) {
-    if (*current == request) {
-      *current = request->next;
-      if (requestListTail == request)
-        requestListTail = prev;
-      break;
-    } 
-    prev    = *current;
-    current = &(*current)->next;
-  }
-  MyFree(request->buf);
-  MyFree(request->name);
-  MyFree(request);
-}
-
-/*
- * make_request - Create a DNS request record for the server.
- */
-static struct ResRequest* make_request(const struct DNSQuery* query)
-{
-  struct ResRequest* request;
-  assert(0 != query);
-  request = (struct ResRequest*) MyMalloc(sizeof(struct ResRequest));
-  memset(request, 0, sizeof(struct ResRequest));
-
-  request->sentat           = CurrentTime;
-  request->retries          = feature_int(FEAT_IRCD_RES_RETRIES);
-  request->resend           = 1;
-  request->timeout          = feature_int(FEAT_IRCD_RES_TIMEOUT);
-  request->addr.s_addr      = INADDR_NONE;
-  request->he.h_addrtype    = AF_INET;
-  request->he.h_length      = sizeof(struct in_addr);
-  request->query.vptr       = query->vptr;
-  request->query.callback   = query->callback;
-
-  add_request(request);
-  return request;
-}
-
-/*
- * timeout_query_list - Remove queries from the list which have been 
- * there too long without being resolved.
- */
-static time_t timeout_query_list(time_t now)
-{
-  struct ResRequest* request;
-  struct ResRequest* next_request = 0;
-  time_t             next_time    = 0;
-  time_t             timeout      = 0;
-
-  Debug((DEBUG_DNS, "Resolver: timeout_query_list at %s", myctime(now)));
-  for (request = requestListHead; request; request = next_request) {
-    next_request = request->next;
-    timeout = request->sentat + request->timeout;
-    if (timeout < now) {
-      if (--request->retries <= 0) {
-        ++reinfo.re_timeouts;
-        (*request->query.callback)(request->query.vptr, 0);
-        rem_request(request);
-        continue;
-      }
-      else {
-        request->sentat = now;
-        request->timeout += request->timeout;
-        resend_query(request);
-      }
-    }
-    if (!next_time || timeout < next_time) {
-      next_time = timeout;
-    }
-  }
-  return (next_time > now) ? next_time : (now + AR_TTL);
-}
-
-/*
- * timeout_resolver - check request list and cache for expired entries
- */
-time_t timeout_resolver(time_t now)
-{
-  if (nextDNSCheck < now)
-    nextDNSCheck = timeout_query_list(now);
-  return nextDNSCheck;
-}
-
-
-/*
- * delete_resolver_queries - cleanup outstanding queries 
- * for which there no longer exist clients or conf lines.
- */
-void delete_resolver_queries(const void* vptr)
-{
-  struct ResRequest* request;
-  struct ResRequest* next_request;
-
-  for (request = requestListHead; request; request = next_request) {
-    next_request = request->next;
-    if (vptr == request->query.vptr)
-      rem_request(request);
-  }
-}
-
-/*
- * send_res_msg - sends msg to all nameservers found in the "_res" structure.
- * This should reflect /etc/resolv.conf. We will get responses
- * which arent needed but is easier than checking to see if nameserver
- * isnt present. Returns number of messages successfully sent to 
- * nameservers or -1 if no successful sends.
- */
-static int send_res_msg(const u_char* msg, int len, int rcount)
-{
-  int i;
-  int sent = 0;
-  int max_queries = IRCD_MIN(_res.nscount, rcount);
-
-  assert(0 != msg);
-  /*
-   * RES_PRIMARY option is not implemented
-   * if (_res.options & RES_PRIMARY || 0 == max_queries)
-   */
-  if (0 == max_queries)
-    max_queries = 1;
-
-  Debug((DEBUG_DNS, "Resolver: sendto %d", max_queries));
-
-  for (i = 0; i < max_queries; i++) {
-    if (sendto(ResolverFileDescriptor, msg, len, 0, 
-               (struct sockaddr*) &(_res.nsaddr_list[i]),
-               sizeof(struct sockaddr_in)) == len) {
-      ++reinfo.re_sent;
-      ++sent;
-    }
-    else
-      log_write(LS_RESOLVER, L_ERROR, 0, "Resolver: send failed %m");
-  }
-  return sent;
-}
-
-/*
- * find_id - find a dns request id (id is determined by dn_mkquery)
- */
-static struct ResRequest* find_id(int id)
-{
-  struct ResRequest* request;
-
-  for (request = requestListHead; request; request = request->next) {
-    if (request->id == id)
-      return request;
-  }
-  return NULL;
-}
-
-/*
- * gethost_byname - get host address from name
- */
-void gethost_byname(const char* name, const struct DNSQuery* query)
-{
-  assert(0 != name);
-
-  Debug((DEBUG_DNS, "Resolver: gethost_byname %s", name));
-  ++reinfo.re_na_look;
-#if 0
-  if ((cp = find_cache_name(name)))
-    return &(cp->reply);
-#endif
-  do_query_name(query, name, NULL);
-  nextDNSCheck = 1;
-}
-
-/*
- * gethost_byaddr - get host name from address
- */
-void gethost_byaddr(const char* addr, const struct DNSQuery* query)
-{
-  assert(0 != addr);
-
-  Debug((DEBUG_DNS, "Resolver: gethost_byaddr %s", ircd_ntoa(addr)));
-
-  ++reinfo.re_nu_look;
-  do_query_number(query, (const struct in_addr*) addr, NULL);
-  nextDNSCheck = 1;
-}
-
-/*
- * do_query_name - nameserver lookup name
- */
-static void do_query_name(const struct DNSQuery* query, 
-                          const char* name, struct ResRequest* request)
-{
-  char  hname[HOSTLEN + 1];
-  assert(0 != name);
-
-  ircd_strncpy(hname, name, HOSTLEN);
-  hname[HOSTLEN] = '\0';
-
-  if (!request) {
-    request       = make_request(query);
-    request->type = T_A;
-    request->name = (char*) MyMalloc(strlen(hname) + 1);
-    strcpy(request->name, hname);
-  }
-  query_name(hname, C_IN, T_A, request);
-}
-
-/*
- * do_query_number - Use this to do reverse IP# lookups.
- */
-static void do_query_number(const struct DNSQuery* query, 
-                            const struct in_addr* addr,
-                            struct ResRequest* request)
-{
-  char  ipbuf[32];
-  const unsigned char* cp;
-
-  assert(0 != addr);
-  cp = (const unsigned char*) &addr->s_addr;
-  ircd_snprintf(0, ipbuf, sizeof(ipbuf), "%u.%u.%u.%u.in-addr.arpa.",
-               (unsigned int)(cp[3]), (unsigned int)(cp[2]),
-               (unsigned int)(cp[1]), (unsigned int)(cp[0]));
-
-  if (!request) {
-    request              = make_request(query);
-    request->type        = T_PTR;
-    request->addr.s_addr = addr->s_addr;
-  }
-  query_name(ipbuf, C_IN, T_PTR, request);
-}
-
-/*
- * query_name - generate a query based on class, type and name.
- */
-static void query_name(const char* name, int query_class,
-                       int type, struct ResRequest* request)
-{
-  unsigned char buf[MAXPACKET + 1];
-  int  request_len = 0;
-
-  assert(0 != name);
-  assert(0 != request);
-
-  Debug((DEBUG_DNS, "Resolver: query_name: %s %d %d", name, query_class, type));
-  memset(buf, 0, sizeof(buf));
-  if ((request_len = res_mkquery(QUERY, name, query_class, type, 
-                                 0, 0, 0,
-                                 buf, sizeof(buf) - 1)) > 0) {
-    HEADER* header = (HEADER*) buf;
-#ifndef LRAND48
-    int            k = 0;
-    struct timeval tv;
-#endif
-    /*
-     * generate a unique id
-     * NOTE: we don't have to worry about converting this to and from
-     * network byte order, the nameserver does not interpret this value
-     * and returns it unchanged
-     */
-#ifdef LRAND48
-    do {
-      header->id = (header->id + lrand48()) & 0xffff;
-    } while (find_id(header->id));
-#else
-    gettimeofday(&tv, NULL);
-    do {
-      header->id = (header->id + k + tv.tv_usec) & 0xffff;
-      ++k;
-    } while (find_id(header->id));
-#endif /* LRAND48 */
-    request->id = header->id;
-    ++request->sends;
-    Debug((DEBUG_DNS, "Resolver: query_name %d: %s %d %d", request->id, 
-          name, query_class, type));
-    request->sent += send_res_msg(buf, request_len, request->sends);
-  }
-}
-
-static void resend_query(struct ResRequest* request)
-{
-  assert(request);
-
-  if (request->resend == 0)
-    return;
-  ++reinfo.re_resends;
-  switch(request->type) {
-  case T_PTR:
-    do_query_number(NULL, &request->addr, request);
-    break;
-  case T_A:
-    do_query_name(NULL, request->name, request);
-    break;
-  default:
-    break;
-  }
-}
-
-/*
- * proc_answer - process name server reply
- * build a hostent struct in the passed request
- */
-static int proc_answer(struct ResRequest* request, HEADER* header,
-                       u_char* buf, u_char* eob)
-{
-  char   hostbuf[HOSTLEN + 1]; /* working buffer */
-  u_char* current;             /* current position in buf */
-  char** alias;                /* alias list */
-  char** addr;                 /* address list */
-  char** base_addr;            /* original pointer to address list */
-  char*  name;                 /* pointer to name string */
-  char*  address;              /* pointer to address */
-  char*  base_address;         /* original pointer to address */
-  char*  endp;                 /* end of our buffer */
-  int    query_class;          /* answer class */
-  int    type;                 /* answer type */
-  int    rd_length;            /* record data length */
-  int    answer_count = 0;     /* answer counter */
-  int    n;                    /* temp count */
-  int    addr_count  = 0;      /* number of addresses in hostent */
-  int    alias_count = 0;      /* number of aliases in hostent */
-  int    t_ptr_seen = 0;       /* Seen a T_PTR in proc_answer? */
-  struct hostent* hp;          /* hostent getting filled */
-
-  assert(request);
-  assert(header);
-  assert(buf);
-  assert(eob);
-  
-  current = buf + sizeof(HEADER);
-  hp = &(request->he);
-  /*
-   * lazy allocation of request->he.buf, we don't allocate a buffer
-   * unless there is something to put in it.
-   */
-  if (!request->buf) {
-    request->buf = (char*) MyMalloc(MAXGETHOSTLEN + 1);
-    request->buf[MAXGETHOSTLEN] = '\0';
-    /*
-     * array of alias list pointers starts at beginning of buf
-     */
-    hp->h_aliases = (char**) request->buf;
-    hp->h_aliases[0] = NULL;
-    /*
-     * array of address list pointers starts after alias list pointers
-     * the actual addresses follow the the address list pointers
-     */ 
-    hp->h_addr_list = (char**)(request->buf + ALIAS_BLEN);
-    /*
-     * don't copy the host address to the beginning of h_addr_list
-     */
-    hp->h_addr_list[0] = NULL;
-  }
-  endp = request->buf + MAXGETHOSTLEN;
-  /*
-   * find the end of the address list
-   */
-  addr = hp->h_addr_list;
-  while (*addr) {
-    ++addr;
-    ++addr_count;
-  }
-  base_addr = addr;
-  /*
-   * make address point to first available address slot
-   */
-  address = request->buf + ADDRS_OFFSET +
-                    (sizeof(struct in_addr) * addr_count);
-  base_address = address;
-
-  /*
-   * find the end of the alias list
-   */
-  alias = hp->h_aliases;
-  while (*alias) {
-    ++alias;
-    ++alias_count;
-  }
-  /*
-   * make name point to first available space in request->buf
-   */
-  if (alias_count > 0) {
-    name = hp->h_aliases[alias_count - 1];
-    name += (strlen(name) + 1);
-  }
-  else if (hp->h_name)
-    name = hp->h_name + strlen(hp->h_name) + 1;
-  else
-    name = request->buf + ADDRS_OFFSET + ADDRS_DLEN;
-  /*
-   * skip past queries
-   */ 
-  while (header->qdcount-- > 0) {
-    if ((n = dn_skipname(current, eob)) < 0)
-      break;
-    current += (n + QFIXEDSZ);
-  }
-  /*
-   * process each answer sent to us blech.
-   */
-  while (header->ancount-- > 0 && current < eob && name < endp) {
-    n = dn_expand(buf, eob, current, hostbuf, sizeof(hostbuf));
-    if (n <= 0) {
-      /*
-       * no more answers left
-       */
-      return answer_count;
-    }
-    hostbuf[HOSTLEN] = '\0';
-    /* 
-     * With Address arithmetic you have to be very anal
-     * this code was not working on alpha due to that
-     * (spotted by rodder/jailbird/dianora)
-     */
-    current += (size_t) n;
-
-    if (!((current + ANSWER_FIXED_SIZE) < eob))
-      break;
-
-    type = _getshort(current);
-    current += TYPE_SIZE;
-
-    query_class = _getshort(current);
-    current += CLASS_SIZE;
-
-    request->ttl = _getlong(current);
-    current += TTL_SIZE;
-
-    rd_length = _getshort(current);
-    current += RDLENGTH_SIZE;
-
-    /* 
-     * Wait to set request->type until we verify this structure 
-     */
-    switch(type) {
-    case T_A:
-      /*
-       * check for invalid rd_length or too many addresses
-       * ignore T_A relies if looking for a T_PTR
-       */
-      if (t_ptr_seen)
-       return answer_count;
-      if (rd_length != sizeof(struct in_addr))
-        return answer_count;
-      if (++addr_count < RES_MAXADDRS) {
-        if (answer_count == 1)
-          hp->h_addrtype = (query_class == C_IN) ?  AF_INET : AF_UNSPEC;
-
-        memcpy(address, current, sizeof(struct in_addr));
-        *addr++ = address;
-        *addr = 0;
-        address += sizeof(struct in_addr);
-
-        if (!hp->h_name) {
-          strcpy(name, hostbuf);
-          hp->h_name = name;
-          name += strlen(name) + 1;
-        }
-        Debug((DEBUG_DNS, "Resolver: A %s for %s", 
-               ircd_ntoa((char*) hp->h_addr_list[addr_count - 1]), hostbuf));
-      }
-      current += rd_length;
-      ++answer_count;
-      break;
-    case T_PTR:
-      t_ptr_seen = 1;
-      addr_count = 0;
-      addr = base_addr;
-      *addr = 0;
-      address = base_address;
-      n = dn_expand(buf, eob, current, hostbuf, sizeof(hostbuf));
-      if (n < 0) {
-        /*
-         * broken message
-         */
-        return 0;
-      }
-      else if (n == 0) {
-        /*
-         * no more answers left
-         */
-        return answer_count;
-      }
-      /*
-       * This comment is based on analysis by Shadowfax, Wohali and johan, 
-       * not me.  (Dianora) I am only commenting it.
-       *
-       * dn_expand is guaranteed to not return more than sizeof(hostbuf)
-       * but do all implementations of dn_expand also guarantee
-       * buffer is terminated with null byte? Lets not take chances.
-       *  -Dianora
-       */
-      hostbuf[HOSTLEN] = '\0';
-      current += (size_t) n;
-
-      Debug((DEBUG_DNS, "Resolver: PTR %s", hostbuf));
-      /*
-       * copy the returned hostname into the host name
-       * ignore duplicate ptr records
-       */
-      if (!hp->h_name) {
-        strcpy(name, hostbuf);
-        hp->h_name = name;
-        name += strlen(name) + 1;
-      }
-      ++answer_count;
-      break;
-    case T_CNAME:
-      Debug((DEBUG_DNS, "Resolver: CNAME %s", hostbuf));
-      if (++alias_count < RES_MAXALIASES) {
-        ircd_strncpy(name, hostbuf, endp - name);
-        *alias++ = name;
-        *alias   = 0;
-        name += strlen(name) + 1;
-      }
-      current += rd_length;
-      ++answer_count;
-      break;
-    default :
-      Debug((DEBUG_DNS,"Resolver: proc_answer type: %d for: %s", type, hostbuf));
-      break;
-    }
-  }
-  return answer_count;
-}
-
-/*
- * dup_hostent - Duplicate a hostent struct, allocate only enough memory for
- * the data we're putting in it.
- */
-static struct hostent* dup_hostent(struct hostent* hp)
-{
-  char*  p;
-  char** ap;
-  char** pp;
-  int    alias_count = 0;
-  int    addr_count = 0;
-  size_t bytes_needed = 0;
-  struct Hostent* new_hp = 0;
-
-  assert(0 != hp);
-
-  /* how much buffer do we need? */
-  bytes_needed += (strlen(hp->h_name) + 1);
-
-  pp = hp->h_aliases;
-  while (*pp) {
-    bytes_needed += (strlen(*pp++) + 1 + sizeof(char*));
-    ++alias_count;
-  }
-  pp = hp->h_addr_list;
-  while (*pp++) {
-    bytes_needed += (hp->h_length + sizeof(char*));
-    ++addr_count;
-  }
-  /* Reserve space for 2 nulls to terminate h_aliases and h_addr_list */
-  bytes_needed += (2 * sizeof(char*));
-
-  /* Allocate memory */
-  new_hp = (struct Hostent*) MyMalloc(sizeof(struct Hostent) + bytes_needed);
-
-  new_hp->h.h_addrtype = hp->h_addrtype;
-  new_hp->h.h_length = hp->h_length;
-
-  /* first write the address list */
-  pp = hp->h_addr_list;
-  ap = new_hp->h.h_addr_list =
-      (char**)(new_hp->buf + ((alias_count + 1) * sizeof(char*)));
-  p = (char*)ap + ((addr_count + 1) * sizeof(char*));
-  while (*pp)
-  {
-    *ap++ = p;
-    memcpy(p, *pp++, hp->h_length);
-    p += hp->h_length;
-  }
-  *ap = 0;
-  /* next write the name */
-  new_hp->h.h_name = p;
-  strcpy(p, hp->h_name);
-  p += (strlen(p) + 1);
-
-  /* last write the alias list */
-  pp = hp->h_aliases;
-  ap = new_hp->h.h_aliases = (char**) new_hp->buf;
-  while (*pp) {
-    *ap++ = p;
-    strcpy(p, *pp++);
-    p += (strlen(p) + 1);
-  }
-  *ap = 0;
-  return (struct hostent*) new_hp;
-}
-
-/*
- * resolver_read - read a dns reply from the nameserver and process it.
- * return 0 if nothing was read from the socket, otherwise return 1
- */
-int resolver_read(void)
-{
-  unsigned char      buf[sizeof(HEADER) + MAXPACKET];
-  HEADER*            header       = 0;
-  struct ResRequest* request      = 0;
-  unsigned int       rc           = 0;
-  int                answer_count = 0;
-  struct sockaddr_in sin;
-
-  Debug((DEBUG_DNS, "Resolver: read"));
-  if (IO_SUCCESS != os_recvfrom_nonb(ResolverFileDescriptor,
-                                     (char*) buf, sizeof(buf), &rc, &sin)) {
-    return 0;
-  }
-  if (rc < sizeof(HEADER)) {
-    Debug((DEBUG_DNS, "Resolver: short reply %d: %s", rc, 
-           (strerror(errno)) ? strerror(errno) : "Unknown"));
-    return 0;
-  }
-  /*
-   * convert DNS reply reader from Network byte order to CPU byte order.
-   */
-  header = (HEADER*) buf;
-  /* header->id = ntohs(header->id); */
-  header->ancount = ntohs(header->ancount);
-  header->qdcount = ntohs(header->qdcount);
-  header->nscount = ntohs(header->nscount);
-  header->arcount = ntohs(header->arcount);
-  ++reinfo.re_replies;
-  /*
-   * response for an id which we have already received an answer for
-   * just ignore this response.
-   */
-  if (0 == (request = find_id(header->id))) {
-    Debug((DEBUG_DNS, "Resolver: can't find request id: %d", header->id));
-    return 1;
-  }
-  /*
-   * check against possibly fake replies
-   */
-  if (!res_ourserver(&_res, &sin)) {
-    Debug((DEBUG_DNS, "Resolver: fake reply from: %s",
-           (const char*) &sin.sin_addr));
-    ++reinfo.re_unkrep;
-    return 1;
-  }
-
-  if ((header->rcode != NOERROR) || (header->ancount == 0)) {
-    ++reinfo.re_errors;
-    if (SERVFAIL == header->rcode)
-      resend_query(request);
-    else {
-      /*
-       * If a bad error was returned, we stop here and dont send
-       * send any more (no retries granted).
-       * Isomer: Perhaps we should return these error messages back to
-       *         the client?
-       */
-#ifdef DEBUGMODE
-      switch (header->rcode) {
-        case NOERROR:
-          Debug((DEBUG_DNS, "Fatal DNS error: No Error"));
-          break;
-        case FORMERR:
-          Debug((DEBUG_DNS, "Fatal DNS error: Format Error"));
-          break;
-        case SERVFAIL:
-          Debug((DEBUG_DNS, "Fatal DNS error: Server Failure"));
-          break;
-        case NXDOMAIN:
-          Debug((DEBUG_DNS, "DNS error: Non Existant Domain"));
-          break;
-        case NOTIMP:
-          Debug((DEBUG_DNS, "Fatal DNS error: Not Implemented"));
-          break;
-        case REFUSED:
-          Debug((DEBUG_DNS, "Fatal DNS error: Query Refused"));
-          break;
-        default:
-          Debug((DEBUG_DNS, "Unassigned fatal DNS error: %i", header->rcode));
-          break;
-      }
-#endif /* DEBUGMODE */
-      (*request->query.callback)(request->query.vptr, 0);
-      rem_request(request);
-    } 
-    return 1;
-  }
-  /*
-   * If this fails there was an error decoding the received packet, 
-   * try it again and hope it works the next time.
-   */
-  answer_count = proc_answer(request, header, buf, buf + rc);
-  if (answer_count) {
-    struct hostent* hp = 0;
-    if (T_PTR == request->type) {
-      if (0 == request->he.h_name) {
-        /*
-         * got a PTR response with no name, something bogus is happening
-         * don't bother trying again, the client address doesn't resolve 
-         */
-        (*request->query.callback)(request->query.vptr, hp);
-        rem_request(request); 
-        return 1;
-      }
-      Debug((DEBUG_DNS, "relookup %s <-> %s",
-             request->he.h_name, ircd_ntoa((char*) &request->addr)));
-      /*
-       * Lookup the 'authoritive' name that we were given for the
-       * ip#.  By using this call rather than regenerating the
-       * type we automatically gain the use of the cache with no
-       * extra kludges.
-       */
-      gethost_byname(request->he.h_name, &request->query);
-      /*
-       * If name wasn't found, a request has been queued and it will
-       * be the last one queued.  This is rather nasty way to keep
-       * a host alias with the query. -avalon
-       */
-      MyFree(requestListTail->buf);
-      requestListTail->buf = request->buf;
-      request->buf = 0;
-      memcpy(&requestListTail->he, &request->he, sizeof(struct hostent));
-      rem_request(request);
-    }
-    else {
-      /*
-       * got a name and address response, client resolved
-       * XXX - Bug found here by Dianora -
-       * make_cache() occasionally returns a NULL pointer when a
-       * PTR returned a CNAME, cp was not checked before so the
-       * callback was being called with a value of 0x2C != NULL.
-       */
-      if (validate_hostent(&request->he))
-        hp = dup_hostent(&request->he);
-      (*request->query.callback)(request->query.vptr, hp);
-      rem_request(request);
-    }
-  }
-  else if (!request->sent) {
-    /*
-     * XXX - we got a response for a query we didn't send with a valid id?
-     * this should never happen, bail here and leave the client unresolved
-     */
-    (*request->query.callback)(request->query.vptr, 0);
-    rem_request(request);
-  }
-  return 1;
-}
-
-/*
- * resolver_read_multiple - process up to count reads
- */
-void resolver_read_multiple(int count)
-{
-  int i = 0;
-  for ( ; i < count; ++i) {
-    if (0 == resolver_read())
-      return;
-  }
-}
-
-/*
- * m_dns - dns status query
- */
-int m_dns(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
-{
-#if !defined(NDEBUG)
-  sendcmdto_one(&me, CMD_NOTICE, sptr,"%C :Errors %d Lookups %d/%d Replies %d Requests %d",
-               sptr, reinfo.re_errors, reinfo.re_nu_look,
-               reinfo.re_na_look, reinfo.re_replies, reinfo.re_requests);
-  sendcmdto_one(&me, CMD_NOTICE, sptr,"%C :Unknown Reply %d Short TTL(<10m) %d Sent %d Resends %d Timeouts %d", sptr,
-               reinfo.re_unkrep, reinfo.re_shortttl, reinfo.re_sent,
-               reinfo.re_resends, reinfo.re_timeouts);
-  sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :ResolverFileDescriptor = %d", 
-                sptr, ResolverFileDescriptor);
-#endif
-  return 0;
-}
-
-size_t cres_mem(struct Client* sptr)
-{
-  struct ResRequest* request;
-  size_t request_mem   = 0;
-  int    request_count = 0;
-
-  for (request = requestListHead; request; request = request->next) {
-    request_mem += sizeof(struct ResRequest);
-    if (request->name)
-      request_mem += strlen(request->name) + 1; 
-    if (request->buf)
-      request_mem += MAXGETHOSTLEN + 1;
-    ++request_count;
-  }
-
-  send_reply(sptr, SND_EXPLICIT | RPL_STATSDEBUG,
-            ":Resolver: requests %d(%d)", request_count, request_mem);
-  return request_mem;
-}
-
index 64286926d9b8a073ccd6423193f55f00d0885468..552e112623c9600713b18e09f27a00f404635b8d 100644 (file)
@@ -312,7 +312,7 @@ static void release_auth_client(struct Client* client)
   Debug((DEBUG_INFO, "Auth: release_auth_client %s@%s[%s]",
          cli_username(client), cli_sockhost(client), cli_sock_ip(client)));
 }
+
 static void auth_kill_client(struct AuthRequest* auth)
 {
   assert(0 != auth);
@@ -347,17 +347,16 @@ static void auth_dns_callback(void* vptr, struct DNSReply* hp)
   ClearDNSPending(auth);
 
   if (hp) {
-    struct sockaddr_in *sin = (struct sockaddr_in*)&hp->addr;
     /*
      * Verify that the host to ip mapping is correct both ways and that
      * the ip#(s) for the socket is listed for the host.
      */
-    if (memcmp(&sin->sin_addr, &cli_ip(auth->client), sizeof(struct in_addr))) {
+    if (irc_in_addr_cmp(&hp->addr, &cli_ip(auth->client))) {
       if (IsUserPort(auth->client))
         sendheader(auth->client, REPORT_IP_MISMATCH);
       sendto_opmask_butone(0, SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%s]",
-                          cli_sock_ip(auth->client), hp->h_name, 
-                          ircd_ntoa((const char*)&sin->sin_addr));
+                          cli_sock_ip(auth->client), hp->h_name,
+                          ircd_ntoa(&hp->addr));
       if (feature_bool(FEAT_KILL_IPMISMATCH)) {
        auth_kill_client(auth);
        return;
@@ -430,55 +429,39 @@ static void auth_error(struct AuthRequest* auth, int kill)
 }
 
 /*
- * start_auth_query - Flag the client to show that an attempt to 
+ * start_auth_query - Flag the client to show that an attempt to
  * contact the ident server on the client's host.  The connect and
- * subsequently the socket are all put into 'non-blocking' mode.  
+ * subsequently the socket are all put into 'non-blocking' mode.
  * Should the connect or any later phase of the identifing process fail,
  * it is aborted and the user is given a username of "unknown".
  */
 static int start_auth_query(struct AuthRequest* auth)
 {
-  struct sockaddr_in remote_addr;
-  struct sockaddr_in local_addr;
+  struct irc_sockaddr remote_addr;
+  struct irc_sockaddr local_addr;
   int                fd;
   IOResult           result;
 
   assert(0 != auth);
   assert(0 != auth->client);
 
-  if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
-    ++ServerStats->is_abad;
-    return 0;
-  }
-  if ((MAXCONNECTIONS - 10) < fd) {
-    close(fd);
-    return 0;
-  }
-  if (!os_set_nonblocking(fd)) {
-    close(fd);
-    return 0;
-  }
-  if (IsUserPort(auth->client))
-    sendheader(auth->client, REPORT_DO_ID);
-  /* 
+  /*
    * get the local address of the client and bind to that to
    * make the auth request.  This used to be done only for
    * ifdef VIRTTUAL_HOST, but needs to be done for all clients
    * since the ident request must originate from that same address--
    * and machines with multiple IP addresses are common now
    */
-  memset(&local_addr, 0, sizeof(struct sockaddr_in));
+  memset(&local_addr, 0, sizeof(local_addr));
   os_get_sockname(cli_fd(auth->client), &local_addr);
-  local_addr.sin_port = htons(0);
-
-  if (bind(fd, (struct sockaddr*) &local_addr, sizeof(struct sockaddr_in))) {
-    close(fd);
+  local_addr.port = 0;
+  fd = os_socket(&local_addr, SOCK_STREAM, "auth query");
+  if (fd < 0)
     return 0;
-  }
-
-  remote_addr.sin_addr.s_addr = (cli_ip(auth->client)).s_addr;
-  remote_addr.sin_port = htons(113);
-  remote_addr.sin_family = AF_INET;
+  if (IsUserPort(auth->client))
+    sendheader(auth->client, REPORT_DO_ID);
+  memcpy(&remote_addr.addr, &cli_ip(auth->client), sizeof(remote_addr.addr));
+  remote_addr.port = 113;
 
   if ((result = os_connect_nonb(fd, &remote_addr)) == IO_FAILURE ||
       !socket_add(&auth->socket, auth_sock_callback, (void*) auth,
@@ -598,7 +581,7 @@ void start_auth(struct Client* client)
   Debug((DEBUG_INFO, "Beginning auth request on client %p", client));
 
   if (!feature_bool(FEAT_NODNS)) {
-    if (LOOPBACK == inet_netof(cli_ip(client)))
+    if (irc_in_addr_is_loopback(&cli_ip(client)))
       strcpy(cli_sockhost(client), cli_name(&me));
     else {
       struct DNSQuery query;
@@ -609,7 +592,7 @@ void start_auth(struct Client* client)
       if (IsUserPort(auth->client))
        sendheader(client, REPORT_DO_DNS);
 
-      gethost_byinaddr(&(cli_ip(client)), &query);
+      gethost_byaddr(&cli_ip(client), &query);
       SetDNSPending(auth);
     }
   }
@@ -639,8 +622,8 @@ void start_auth(struct Client* client)
  */
 void send_auth_query(struct AuthRequest* auth)
 {
-  struct sockaddr_in us;
-  struct sockaddr_in them;
+  struct irc_sockaddr us;
+  struct irc_sockaddr them;
   char               authbuf[32];
   unsigned int       count;
 
@@ -653,8 +636,8 @@ void send_auth_query(struct AuthRequest* auth)
     return;
   }
   ircd_snprintf(0, authbuf, sizeof(authbuf), "%u , %u\r\n",
-               (unsigned int) ntohs(them.sin_port),
-               (unsigned int) ntohs(us.sin_port));
+               (unsigned int) them.port,
+               (unsigned int) us.port);
 
   if (IO_SUCCESS == os_send_nonb(auth->fd, authbuf, strlen(authbuf), &count)) {
     ClearAuthConnect(auth);
index 0d460ba8e5fd4451cd01101cdcd69ae7891c9228..f8637137f65bf7272da25e0fb0e29f430889395c 100644 (file)
 #include <sys/poll.h>
 #endif /* USE_POLL */
 
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-
 struct Client*            LocalClientArray[MAXCONNECTIONS];
 int                       HighestFd = -1;
-struct sockaddr_in        VirtualHost;
+struct irc_sockaddr       VirtualHost;
 static char               readbuf[SERVER_TCP_WINDOW];
 
 /*
@@ -181,8 +177,7 @@ static void connect_dns_callback(void* vptr, struct DNSReply* hp)
   assert(aconf);
   aconf->dns_pending = 0;
   if (hp) {
-    struct sockaddr_in *sin = (struct sockaddr_in*)&hp->addr;
-    memcpy(&aconf->ipnum, &sin->sin_addr, sizeof(struct in_addr));
+    memcpy(&aconf->address, &hp->addr, sizeof(aconf->address));
     MyFree(hp);
     connect_server(aconf, 0);
   }
@@ -231,7 +226,6 @@ int init_connection_limits(void)
  */
 static int connect_inet(struct ConfItem* aconf, struct Client* cptr)
 {
-  static struct sockaddr_in sin;
   IOResult result;
   assert(0 != aconf);
   assert(0 != cptr);
@@ -239,53 +233,16 @@ static int connect_inet(struct ConfItem* aconf, struct Client* cptr)
    * Might as well get sockhost from here, the connection is attempted
    * with it so if it fails its useless.
    */
-  cli_fd(cptr) = socket(AF_INET, SOCK_STREAM, 0);
-  if (-1 == cli_fd(cptr)) {
-    cli_error(cptr) = errno;
-    report_error(SOCKET_ERROR_MSG, cli_name(cptr), errno);
-    return 0;
-  }
-  if (cli_fd(cptr) >= MAXCLIENTS) {
-    report_error(CONNLIMIT_ERROR_MSG, cli_name(cptr), 0);
-    close(cli_fd(cptr));
-    cli_fd(cptr) = -1;
+  cli_fd(cptr) = os_socket((feature_bool(FEAT_VIRTUAL_HOST) ? &VirtualHost : NULL), SOCK_STREAM, cli_name(cptr));
+  if (cli_fd(cptr) < 0)
     return 0;
-  }
-  /*
-   * Bind to a local IP# (with unknown port - let unix decide) so
-   * we have some chance of knowing the IP# that gets used for a host
-   * with more than one IP#.
-   *
-   * No we don't bind it, not all OS's can handle connecting with
-   * an already bound socket, different ip# might occur anyway
-   * leading to a freezing select() on this side for some time.
-   * I had this on my Linux 1.1.88 --Run
-   */
 
-  /*
-   * No, we do bind it if we have virtual host support. If we don't
-   * explicitly bind it, it will default to IN_ADDR_ANY and we lose
-   * due to the other server not allowing our base IP --smg
-   */
-  if (feature_bool(FEAT_VIRTUAL_HOST) &&
-      bind(cli_fd(cptr), (struct sockaddr*) &VirtualHost,
-          sizeof(VirtualHost))) {
-    report_error(BIND_ERROR_MSG, cli_name(cptr), errno);
-    close(cli_fd(cptr));
-    cli_fd(cptr) = -1;
-    return 0;
-  }
-
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_family      = AF_INET;
-  sin.sin_addr.s_addr = aconf->ipnum.s_addr;
-  sin.sin_port        = htons(aconf->port);
   /*
    * save connection info in client
    */
-  (cli_ip(cptr)).s_addr = aconf->ipnum.s_addr;
-  cli_port(cptr)        = aconf->port;
-  ircd_ntoa_r(cli_sock_ip(cptr), (const char*) &(cli_ip(cptr)));
+  memcpy(&cli_ip(cptr), &aconf->address.addr, sizeof(cli_ip(cptr)));
+  cli_port(cptr) = aconf->address.port;
+  ircd_ntoa_r(cli_sock_ip(cptr), &cli_ip(cptr));
   /*
    * we want a big buffer for server connections
    */
@@ -296,17 +253,7 @@ static int connect_inet(struct ConfItem* aconf, struct Client* cptr)
     cli_fd(cptr) = -1;
     return 0;
   }
-  /*
-   * ALWAYS set sockets non-blocking
-   */
-  if (!os_set_nonblocking(cli_fd(cptr))) {
-    cli_error(cptr) = errno;
-    report_error(NONB_ERROR_MSG, cli_name(cptr), errno);
-    close(cli_fd(cptr));
-    cli_fd(cptr) = -1;
-    return 0;
-  }
-  if ((result = os_connect_nonb(cli_fd(cptr), &sin)) == IO_FAILURE) {
+  if ((result = os_connect_nonb(cli_fd(cptr), &aconf->address)) == IO_FAILURE) {
     cli_error(cptr) = errno;
     report_error(CONNECT_ERROR_MSG, cli_name(cptr), errno);
     close(cli_fd(cptr));
@@ -587,7 +534,7 @@ int net_close_unregistered_connections(struct Client* source)
  * passed off to the auth handler for dns and ident queries.
  *--------------------------------------------------------------------------*/
 void add_connection(struct Listener* listener, int fd) {
-  struct sockaddr_in addr;
+  struct irc_sockaddr addr;
   struct Client      *new_client;
   time_t             next_target = 0;
 
@@ -596,14 +543,13 @@ void add_connection(struct Listener* listener, int fd) {
        /* 12345678901234567890123456789012345679012345678901234567890123456 */
   const char* const register_message =
          "ERROR :Unable to complete your registration\r\n";
-  
+
   assert(0 != listener);
 
   /*
    * Removed preliminary access check. Full check is performed in m_server and
    * m_user instead. Also connection time out help to get rid of unwanted
-   * connections.  
+   * connections.
    */
   if (!os_get_peername(fd, &addr) || !os_set_nonblocking(fd)) {
     ++ServerStats->is_ref;
@@ -626,7 +572,7 @@ void add_connection(struct Listener* listener, int fd) {
    *
    * If they're throttled, murder them, but tell them why first.
    */
-  if (!IPcheck_local_connect(addr.sin_addr, &next_target) && !listener->server)
+  if (!IPcheck_local_connect(&addr.addr, &next_target) && !listener->server)
   {
     ++ServerStats->is_ref;
     write(fd, throttle_message, strlen(throttle_message));
@@ -634,18 +580,18 @@ void add_connection(struct Listener* listener, int fd) {
     return;
   }
 
-  new_client = make_client(0, ((listener->server) ? 
+  new_client = make_client(0, ((listener->server) ?
                                STAT_UNKNOWN_SERVER : STAT_UNKNOWN_USER));
 
   /*
    * Copy ascii address to 'sockhost' just in case. Then we have something
-   * valid to put into error messages...  
+   * valid to put into error messages...
    */
   SetIPChecked(new_client);
-  ircd_ntoa_r(cli_sock_ip(new_client), (const char*) &addr.sin_addr);   
+  ircd_ntoa_r(cli_sock_ip(new_client), &addr.addr);
   strcpy(cli_sockhost(new_client), cli_sock_ip(new_client));
-  (cli_ip(new_client)).s_addr = addr.sin_addr.s_addr;
-  cli_port(new_client)        = ntohs(addr.sin_port);
+  memcpy(&cli_ip(new_client), &addr.addr, sizeof(cli_ip(new_client)));
+  cli_port(new_client) = addr.port;
 
   if (next_target)
     cli_nexttarget(new_client) = next_target;
@@ -829,7 +775,7 @@ int connect_server(struct ConfItem* aconf, struct Client* by)
     return 0;
   }
   Debug((DEBUG_NOTICE, "Connect to %s[@%s]", aconf->name,
-         ircd_ntoa((const char*) &aconf->ipnum)));
+         ircd_ntoa(&aconf->address.addr)));
 
   if ((cptr = FindClient(aconf->name))) {
     if (IsServer(cptr) || IsMe(cptr)) {
@@ -850,22 +796,21 @@ int connect_server(struct ConfItem* aconf, struct Client* by)
     }
   }
   /*
-   * If we dont know the IP# for this host and itis a hostname and
+   * If we dont know the IP# for this host and it is a hostname and
    * not a ip# string, then try and find the appropriate host record.
    */
-  if (INADDR_NONE == aconf->ipnum.s_addr) {
-    if (INADDR_NONE == (aconf->ipnum.s_addr = inet_addr(aconf->host))) {
-      char buf[HOSTLEN + 1];
-      struct DNSQuery  query;
-
-      query.vptr     = aconf;
-      query.callback = connect_dns_callback;
-      host_from_uh(buf, aconf->host, HOSTLEN);
-      buf[HOSTLEN] = '\0';
-
-      gethost_byname(buf, &query);
-      aconf->dns_pending = 1;
-    }
+  if (!irc_in_addr_valid(&aconf->address.addr)
+      && !ircd_aton(&aconf->address.addr, aconf->host)) {
+    char buf[HOSTLEN + 1];
+    struct DNSQuery  query;
+
+    query.vptr     = aconf;
+    query.callback = connect_dns_callback;
+    host_from_uh(buf, aconf->host, HOSTLEN);
+    buf[HOSTLEN] = '\0';
+
+    gethost_byname(buf, &query);
+    aconf->dns_pending = 1;
     return 0;
   }
   cptr = make_client(NULL, STAT_UNKNOWN_SERVER);
@@ -949,12 +894,11 @@ int connect_server(struct ConfItem* aconf, struct Client* by)
 /*
  * Setup local socket structure to use for binding to.
  */
-void set_virtual_host(struct in_addr addr)
+void set_virtual_host(const struct irc_in_addr *addr)
 {
   memset(&VirtualHost, 0, sizeof(VirtualHost));
-  VirtualHost.sin_family = AF_INET;
-  VirtualHost.sin_addr.s_addr = addr.s_addr;
-}  
+  memcpy(&VirtualHost.addr, addr, sizeof(VirtualHost.addr));
+}
 
 /*
  * Find the real hostname for the host running the server (or one which
index 8d6d6b299b2839565aacacd2648feef59e2e052d..6b60d7fe544472a4ceb159bf05f7d8066d42f5e9 100644 (file)
 #include <sys/stat.h>
 #include <unistd.h>
 
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-
 struct ConfItem  *GlobalConfList  = 0;
 int              GlobalConfCount = 0;
 struct s_map     *GlobalServiceMapList = 0;
@@ -130,7 +126,6 @@ struct ConfItem* make_conf(void)
 #endif
   memset(aconf, 0, sizeof(struct ConfItem));
   aconf->status       = CONF_ILLEGAL;
-  aconf->ipnum.s_addr = INADDR_NONE;
   return aconf;
 }
 
@@ -153,7 +148,7 @@ void free_conf(struct ConfItem *aconf)
   Debug((DEBUG_DEBUG, "free_conf: %s %s %d",
          aconf->host ? aconf->host : "*",
          aconf->name ? aconf->name : "*",
-         aconf->port));
+         aconf->address.port));
   if (aconf->dns_pending)
     delete_resolver_queries(aconf);
   MyFree(aconf->host);
@@ -210,8 +205,7 @@ static void conf_dns_callback(void* vptr, struct DNSReply* hp)
   assert(aconf);
   aconf->dns_pending = 0;
   if (hp) {
-    struct sockaddr_in *sin = (struct sockaddr_in*)&hp->addr;
-    memcpy(&aconf->ipnum, &sin->sin_addr, sizeof(struct in_addr));
+    memcpy(&aconf->address.addr, &hp->addr, sizeof(aconf->address.addr));
     MyFree(hp);
   }
 }
@@ -255,18 +249,13 @@ lookup_confhost(struct ConfItem *aconf)
    * Do name lookup now on hostnames given and store the
    * ip numbers in conf structure.
    */
-  if (IsDigit(*aconf->host)) {
-    /*
-     * rfc 1035 sez host names may not start with a digit
-     * XXX - this has changed code needs to be updated
-     */
-    aconf->ipnum.s_addr = inet_addr(aconf->host);
-    if (INADDR_NONE == aconf->ipnum.s_addr) {
+  if (IsIP6Char(*aconf->host)) {
+    if (!ircd_aton(&aconf->address.addr, aconf->host)) {
       Debug((DEBUG_ERROR, "Host/server name error: (%s) (%s)",
-            aconf->host, aconf->name));
+          aconf->host, aconf->name));
     }
   }
-  else 
+  else
     conf_dns_lookup(aconf);
 }
 
@@ -380,7 +369,7 @@ enum AuthorizationCheckResult attach_iline(struct Client*  cptr)
   for (aconf = GlobalConfList; aconf; aconf = aconf->next) {
     if (aconf->status != CONF_CLIENT)
       continue;
-    if (aconf->port && aconf->port != cli_listener(cptr)->port)
+    if (aconf->address.port && aconf->address.port != cli_listener(cptr)->addr.port)
       continue;
     if (!aconf->host || !aconf->name)
       continue;
@@ -609,17 +598,16 @@ struct ConfItem* find_conf_byhost(struct SLink* lp, const char* host,
  * Find a conf line using the IP# stored in it to search upon.
  * Added 1/8/92 by Avalon.
  */
-struct ConfItem* find_conf_byip(struct SLink* lp, const char* ip, 
+struct ConfItem* find_conf_byip(struct SLink* lp, const struct irc_in_addr* ip,
                                 int statmask)
 {
   struct ConfItem* tmp;
 
   for (; lp; lp = lp->next) {
     tmp = lp->value.aconf;
-    if (0 != (tmp->status & statmask)) {
-      if (0 == memcmp(&tmp->ipnum, ip, sizeof(struct in_addr)))
-        return tmp;
-    }
+    if (0 != (tmp->status & statmask)
+        && 0 == memcmp(&tmp->address.addr, ip, sizeof(*ip)))
+      return tmp;
   }
   return 0;
 }
@@ -803,106 +791,6 @@ const struct CRuleConf* conf_get_crule_list(void)
   return cruleConfList;
 }
 
-#if 0
-void conf_add_server(const char* const* fields, int count)
-{
-  struct ServerConf* server;
-  struct in_addr    addr;
-  assert(0 != fields);
-  /*
-   * missing host, password, or alias?
-   */
-  if (count < 6 || EmptyString(fields[1]) || EmptyString(fields[2]) || EmptyString(fields[3]))
-    return;
-  /*
-   * check the host
-   */
-  if (string_is_hostname(fields[1]))
-    addr.s_addr = INADDR_NONE;
-  else if (INADDR_NONE == (addr.s_addr = inet_addr(fields[1])))
-    return;
-
-  server = (struct ServerConf*) MyMalloc(sizeof(struct ServerConf));
-  assert(0 != server);
-  DupString(server->hostname, fields[1]);
-  DupString(server->passwd,   fields[2]);
-  DupString(server->alias,    fields[3]);
-  server->address.s_addr = addr.s_addr;
-  server->port           = atoi(fields[4]);
-  server->dns_pending    = 0;
-  server->connected      = 0;
-  server->hold           = 0;
-  server->conn_class      = find_class(atoi(fields[5]));
-
-  server->next = serverConfList;
-  serverConfList = server;
-
-  /* if (INADDR_NONE == server->address.s_addr) */
-    /* lookup_confhost(server); */
-}
-
-void conf_add_deny(const char* const* fields, int count, int ip_kill)
-{
-  struct DenyConf* conf;
-
-  if (count < 4 || EmptyString(fields[1]) || EmptyString(fields[3]))
-    return;
-  
-  conf = (struct DenyConf*) MyMalloc(sizeof(struct DenyConf));
-  assert(0 != conf);
-  memset(conf, 0, sizeof(struct DenyConf));
-
-  if (fields[1][0] == '$' && fields[1][1] == 'R')
-    conf->flags |= DENY_FLAGS_REALNAME;
-
-  DupString(conf->hostmask, fields[1]);
-  collapse(conf->hostmask);
-
-  if (!EmptyString(fields[2])) {
-    const char* p = fields[2];
-    if ('!' == *p) {
-      conf->flags |= DENY_FLAGS_FILE;
-      ++p;
-    }
-    DupString(conf->message, p);
-  }
-  DupString(conf->usermask, fields[3]);
-  collapse(conf->usermask);
-
-  if (ip_kill) {
-    /* 
-     * Here we use the same kludge as in listener.c to parse
-     * a.b.c.d, or a.b.c.*, or a.b.c.d/e.
-     */
-    int  c_class;
-    char ipname[16];
-    int  ad[4] = { 0 };
-    int  bits2 = 0;
-    c_class = sscanf(conf->hostmask, "%d.%d.%d.%d/%d",
-                     &ad[0], &ad[1], &ad[2], &ad[3], &bits2);
-    if (c_class != 5) {
-      conf->bits = c_class * 8;
-    }
-    else {
-      conf->bits = bits2;
-    }
-    ircd_snprintf(0, ipname, sizeof(ipname), "%d.%d.%d.%d", ad[0], ad[1],
-                 ad[2], ad[3]);
-    
-    /*
-     * This ensures endian correctness
-     */
-    conf->address = inet_addr(ipname);
-    Debug((DEBUG_DEBUG, "IPkill: %s = %08x/%i (%08x)", ipname,
-           conf->address, conf->bits, NETMASK(conf->bits)));
-    conf->flags |= DENY_FLAGS_IP;
-  }
-  conf->next = denyConfList;
-  denyConfList = conf;
-}
-#endif
-
-
 void conf_erase_deny_list(void)
 {
   struct DenyConf* next;
@@ -916,30 +804,17 @@ void conf_erase_deny_list(void)
   }
   denyConfList = 0;
 }
+
 const struct DenyConf* conf_get_deny_list(void)
 {
   return denyConfList;
 }
 
-#if 0
-void conf_add_quarantine(const char *chname, const char *reason)
-{
-  struct qline *qline;
-
-  qline = (struct qline *) MyMalloc(sizeof(struct qline));
-  DupString(qline->chname, chname);
-  DupString(qline->reason, reason);
-  qline->next = GlobalQuarantineList;
-  GlobalQuarantineList = qline;
-}
-#endif
-
 const char*
 find_quarantine(const char *chname)
 {
   struct qline *qline;
-  
+
   for (qline = GlobalQuarantineList; qline; qline = qline->next)
     if (!ircd_strcmp(qline->chname, chname))
       return qline->reason;
@@ -1192,9 +1067,12 @@ int find_kill(struct Client *cptr)
       if (0 == match(deny->hostmask + 2, realname))
        break;
     } else if (deny->flags & DENY_FLAGS_IP) { /* k: by IP */
-      Debug((DEBUG_DEBUG, "ip: %08x network: %08x/%i mask: %08x",
-             cli_ip(cptr).s_addr, deny->address, deny->bits, NETMASK(deny->bits)));
-      if ((cli_ip(cptr).s_addr & NETMASK(deny->bits)) == deny->address)
+#ifdef DEBUGMODE
+      char tbuf1[SOCKIPLEN], tbuf2[SOCKIPLEN];
+      Debug((DEBUG_DEBUG, "ip: %s network: %s/%u",
+             ircd_ntoa_r(tbuf1, &cli_ip(cptr)), ircd_ntoa_r(tbuf2, &deny->address), deny->bits));
+#endif
+      if (ipmask_check(&cli_ip(cptr), &deny->address, deny->bits))
         break;
     }
     else if (0 == match(deny->hostmask, host))
@@ -1300,7 +1178,7 @@ int conf_check_server(struct Client *cptr)
       if ((c_conf = find_conf_byhost(lp, hp->h_name, CONF_SERVER)))
         ircd_strncpy(cli_sockhost(cptr), name, HOSTLEN);
       else
-          c_conf = find_conf_byip(lp, (char*)&((struct sockaddr_in*)&hp->addr)->sin_addr, CONF_SERVER);
+        c_conf = find_conf_byip(lp, &hp->addr, CONF_SERVER);
     }
     else {
       /*
@@ -1317,7 +1195,7 @@ int conf_check_server(struct Client *cptr)
    * happen when using DNS in the way the irc server does. -avalon
    */
   if (!c_conf)
-    c_conf = find_conf_byip(lp, (const char*) &(cli_ip(cptr)), CONF_SERVER);
+    c_conf = find_conf_byip(lp, &cli_ip(cptr), CONF_SERVER);
   /*
    * detach all conf lines that got attached by attach_confs()
    */
@@ -1337,8 +1215,8 @@ int conf_check_server(struct Client *cptr)
   attach_conf(cptr, c_conf);
   attach_confs_byname(cptr, cli_name(cptr), CONF_HUB | CONF_LEAF | CONF_UWORLD);
 
-  if (INADDR_NONE == c_conf->ipnum.s_addr)
-    c_conf->ipnum.s_addr = cli_ip(cptr).s_addr;
+  if (!irc_in_addr_valid(&c_conf->address.addr))
+    memcpy(&c_conf->address.addr, &cli_ip(cptr), sizeof(c_conf->address.addr));
 
   Debug((DEBUG_DNS, "sv_cl: access ok: %s[%s]",
          cli_name(cptr), cli_sockhost(cptr)));
index e2f56ae57615d323c403461117bdbca7668ceb25..16162a6de1ec40469fc6f874aa0cb8bb1ef21a66 100644 (file)
@@ -403,7 +403,7 @@ int exit_client(struct Client *cptr,    /* Connection being handled by
                            "Client exiting: %s (%s@%s) [%s] [%s] <%s%s>",
                            cli_name(victim), cli_user(victim)->username,
                            cli_user(victim)->host, comment,
-                           ircd_ntoa((const char*) &(cli_ip(victim))),
+                           ircd_ntoa(&cli_ip(victim)),
                            NumNick(victim) /* two %s's */);
     update_load();
 
@@ -413,7 +413,7 @@ int exit_client(struct Client *cptr,    /* Connection being handled by
       log_write(LS_USER, L_TRACE, 0, "%Tu %i %s@%s %s %s %s%s %s :%s",
                cli_firsttime(victim), on_for,
                cli_user(victim)->username, cli_sockhost(victim),
-                ircd_ntoa((const char*) &(cli_ip(victim))),
+                ircd_ntoa(&cli_ip(victim)),
                 IsAccount(victim) ? cli_username(victim) : "0",
                 NumNick(victim), /* two %s's */
                 cli_name(victim), cli_info(victim));
index 29da25249a43158400107fb129071a2353c3d2c2..72d7be03e2d5b5453b67f2f95a2f628931cc3928 100644 (file)
@@ -120,7 +120,7 @@ int server_estab(struct Client *cptr, struct ConfItem *aconf)
      * XXX - if this comes from a server port, it will not have been added
      * to the IP check registry, see add_connection in s_bsd.c
      */
-    IPcheck_connect_fail(cli_ip(cptr));
+    IPcheck_connect_fail(&cli_ip(cptr));
   }
 
   det_confs_butmask(cptr, CONF_LEAF | CONF_HUB | CONF_SERVER | CONF_UWORLD);
@@ -233,14 +233,14 @@ int server_estab(struct Client *cptr, struct ConfItem *aconf)
       continue;
     if (IsUser(acptr))
     {
-      char xxx_buf[8];
+      char xxx_buf[25];
       char *s = umode_str(acptr);
       sendcmdto_one(cli_user(acptr)->server, CMD_NICK, cptr,
                    "%s %d %Tu %s %s %s%s%s%s %s%s :%s",
                    cli_name(acptr), cli_hopcount(acptr) + 1, cli_lastnick(acptr),
                    cli_user(acptr)->username, cli_user(acptr)->realhost,
                    *s ? "+" : "", s, *s ? " " : "",
-                   inttobase64(xxx_buf, ntohl(cli_ip(acptr).s_addr), 6),
+                   iptobase64(xxx_buf, &cli_ip(acptr), sizeof(xxx_buf)),
                    NumNick(acptr), cli_info(acptr));
     }
   }
index 75d3b8ae137d3053ff8215a9872240b8ec920f86..89ef883446b68bb879f4bd579d8bb7a8f5c0a21c 100644 (file)
@@ -106,7 +106,7 @@ stats_configured_links(struct Client *sptr, struct StatDesc* sd, int stat,
       host = BadPtr(tmp->host) ? null : tmp->host;
       pass = BadPtr(tmp->passwd) ? null : tmp->passwd;
       name = BadPtr(tmp->name) ? null : tmp->name;
-      port = tmp->port;
+      port = tmp->address.port;
       /*
        * On K line the passwd contents can be
        * displayed on STATS reply.    -Vesa
@@ -181,7 +181,7 @@ stats_access(struct Client *to, struct StatDesc *sd, int stat, char *param)
                    !mmatch(param, aconf->name))))
     {
       send_reply(to, RPL_STATSILINE, 'I', aconf->host, aconf->name,
-                 aconf->port, get_conf_class(aconf));
+                 aconf->address.port, get_conf_class(aconf));
       if (--count == 0)
         break;
     }
index 98f80b0e1dd9815c94f434e05cb0756c623cf9a2..02571b0fb5933c1f7eff34e7e5c9ed269438850a 100644 (file)
@@ -364,7 +364,7 @@ int register_user(struct Client *cptr, struct Client *sptr,
   short            digitgroups = 0;
   struct User*     user = cli_user(sptr);
   int              killreason;
-  char             ip_base64[8];
+  char             ip_base64[25];
 
   user->last = CurrentTime;
   parv[0] = cli_name(sptr);
@@ -401,7 +401,7 @@ int register_user(struct Client *cptr, struct Client *sptr,
                                get_client_name(sptr, SHOW_IP));
         }
         ++ServerStats->is_ref;
-        IPcheck_connect_fail(cli_ip(sptr));
+        IPcheck_connect_fail(&cli_ip(sptr));
         return exit_client(cptr, sptr, &me,
                            "Sorry, your connection class is full - try "
                            "again later or try another server");
@@ -420,7 +420,7 @@ int register_user(struct Client *cptr, struct Client *sptr,
         /* Can this ever happen? */
       case ACR_BAD_SOCKET:
         ++ServerStats->is_ref;
-        IPcheck_connect_fail(cli_ip(sptr));
+        IPcheck_connect_fail(&cli_ip(sptr));
         return exit_client(cptr, sptr, &me, "Unknown error -- Try again");
     }
     ircd_strncpy(user->host, cli_sockhost(sptr), HOSTLEN);
@@ -630,9 +630,9 @@ int register_user(struct Client *cptr, struct Client *sptr,
                        nick, cli_hopcount(sptr) + 1, cli_lastnick(sptr),
                        user->username, user->realhost,
                        *tmpstr ? "+" : "", tmpstr, *tmpstr ? " " : "",
-                       inttobase64(ip_base64, ntohl(cli_ip(sptr).s_addr), 6),
+                       iptobase64(ip_base64, &cli_ip(sptr), sizeof(ip_base64)),
                        NumNick(sptr), cli_info(sptr));
-  
+
   /* Send server notice mask to client */
   if (MyUser(sptr) && (cli_snomask(sptr) != SNO_DEFAULT) && HasFlag(sptr, FLAG_SERVNOTICE))
     send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr));
@@ -707,7 +707,7 @@ int set_nick_name(struct Client* cptr, struct Client* sptr,
     /*
      * IP# of remote client
      */
-    cli_ip(new_client).s_addr = htonl(base64toint(parv[parc - 3]));
+    base64toip(parv[parc - 3], &cli_ip(new_client));
 
     add_client_to_list(new_client);
     hAddClient(new_client);
@@ -1619,7 +1619,7 @@ int is_silenced(struct Client *sptr, struct Client *acptr)
   ircd_snprintf(0, sender, sizeof(sender), "%s!%s@%s", cli_name(sptr),
                user->username, user->host);
   ircd_snprintf(0, senderip, sizeof(senderip), "%s!%s@%s", cli_name(sptr),
-               user->username, ircd_ntoa((const char*) &(cli_ip(sptr))));
+               user->username, ircd_ntoa(&cli_ip(sptr)));
   if (HasHiddenHost(sptr))
     ircd_snprintf(0, senderh, sizeof(senderh), "%s!%s@%s", cli_name(sptr),
                  user->username, user->realhost);
index a82ed93fd784699ba11a8d29009464fd9e08f05e..cc2cc78c709c8d18482628a3ea525eb42ac42256 100644 (file)
@@ -110,6 +110,9 @@ static void makeTables(void)
   moveMacro(NTL_DIGIT, NTL_IRCIP);
   markString(NTL_IRCIP, ".");
 
+  moveMacro(NTL_DIGIT, NTL_IRCIP6);
+  markString(NTL_IRCIP6, ":.ABCDEFabcdef");
+
   moveMacro(NTL_DIGIT | NTL_ALPHA, NTL_IRCNK);
   markString(NTL_IRCNK, "-_`");
 
index 3c9ea1e1de233d34e6149ced2082733de10d98a3..f9a3759397f00dcc118e19d31ef837042ff97657 100644 (file)
 
 #define UPINGTIMEOUT 60   /* Timeout waiting for ping responses */
 
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-
 static struct UPing* pingList = 0;
 int UPingFileDescriptor       = -1; /* UDP listener socket for upings */
 
@@ -104,42 +100,15 @@ static void uping_echo_callback(struct Event* ev)
  */
 int uping_init(void)
 {
-  struct sockaddr_in from = { 0 };
+  struct irc_sockaddr from;
   int fd;
 
-  memset(&from, 0, sizeof(from));
-  from.sin_addr = VirtualHost.sin_addr;
-  from.sin_port = htons(atoi(UDP_PORT));
-  from.sin_family = AF_INET;
+  memcpy(&from, &VirtualHost, sizeof(from));
+  from.port = atoi(UDP_PORT);
 
-  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
-    Debug((DEBUG_ERROR, "UPING: UDP listener socket call failed: %s", 
-           (strerror(errno)) ? strerror(errno) : "Unknown error"));
+  fd = os_socket(&from, SOCK_DGRAM, "UDP listener socket");
+  if (fd < 0)
     return -1;
-  }
-  if (!os_set_reuseaddr(fd)) {
-    log_write(LS_SOCKET, L_ERROR, 0,
-             "UPING: set reuseaddr on UDP listener failed: %m (fd %d)", fd);
-    Debug((DEBUG_ERROR, "UPING: set reuseaddr on UDP listener failed: %s",
-           (strerror(errno)) ? strerror(errno) : "Unknown error"));
-    close(fd);
-    return -1;
-  }
-  if (bind(fd, (struct sockaddr*) &from, sizeof(from)) == -1) {
-    log_write(LS_SOCKET, L_ERROR, 0,
-             "UPING: bind on UDP listener (%d fd %d) failed: %m",
-             htons(from.sin_port), fd);
-    Debug((DEBUG_ERROR, "UPING: bind on UDP listener failed : %s",
-           (strerror(errno)) ? strerror(errno) : "Unknown error"));
-    close(fd);
-    return -1;
-  }
-  if (!os_set_nonblocking(fd)) {
-    Debug((DEBUG_ERROR, "UPING: set non-blocking: %s",
-           (strerror(errno)) ? strerror(errno) : "Unknown error"));
-    close(fd);
-    return -1;
-  }
   if (!socket_add(&upingSock, uping_echo_callback, 0, SS_DATAGRAM,
                  SOCK_EVENT_READABLE, fd)) {
     Debug((DEBUG_ERROR, "UPING: Unable to queue fd to event system"));
@@ -156,7 +125,7 @@ int uping_init(void)
  */
 void uping_echo()
 {
-  struct sockaddr_in from = { 0 };
+  struct irc_sockaddr from;
   unsigned int       len = 0;
   static time_t      last = 0;
   static int         counter = 0;
@@ -181,7 +150,7 @@ void uping_echo()
   }
   if (len < 19)
     return;
-  sendto(UPingFileDescriptor, buf, len, 0, (struct sockaddr*) &from, sizeof(from));
+  os_sendto_nonb(UPingFileDescriptor, buf, len, NULL, 0, &from);
 }
 
 
@@ -302,11 +271,10 @@ void uping_send(struct UPing* pptr)
 
   Debug((DEBUG_SEND, "send_ping: sending [%s %s] to %s.%d on %d",
          buf, &buf[12],
-          ircd_ntoa((const char*) &pptr->sin.sin_addr), ntohs(pptr->sin.sin_port),
+          ircd_ntoa(&pptr->addr.addr), pptr->addr.port,
          pptr->fd));
 
-  if (sendto(pptr->fd, buf, BUFSIZE, 0, (struct sockaddr*) &pptr->sin,
-             sizeof(struct sockaddr_in)) != BUFSIZE)
+  if (os_sendto_nonb(pptr->fd, buf, BUFSIZE, NULL, 0, &pptr->addr) != IO_SUCCESS)
   {
     const char* msg = strerror(errno);
     if (!msg)
@@ -326,7 +294,7 @@ void uping_send(struct UPing* pptr)
  */
 void uping_read(struct UPing* pptr)
 {
-  struct sockaddr_in sin;
+  struct irc_sockaddr sin;
   struct timeval     tv;
   unsigned int       len;
   unsigned int       pingtime;
@@ -349,11 +317,11 @@ void uping_read(struct UPing* pptr)
                  "%s", pptr->client, msg);
     uping_end(pptr);
     return;
-  }    
+  }
 
   if (len < 19)
     return;                    /* Broken packet */
-   
+
   ++pptr->received;
 
   buf[len] = 0;
@@ -384,7 +352,7 @@ int uping_server(struct Client* sptr, struct ConfItem* aconf, int port, int coun
   assert(0 != sptr);
   assert(0 != aconf);
 
-  if (INADDR_NONE == aconf->ipnum.s_addr) {
+  if (!irc_in_addr_valid(&aconf->address.addr)) {
     sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Host lookup failed for "
                  "%s", sptr, aconf->name);
     return 0;
@@ -393,18 +361,10 @@ int uping_server(struct Client* sptr, struct ConfItem* aconf, int port, int coun
   if (IsUPing(sptr))
     uping_cancel(sptr, sptr);  /* Cancel previous ping request */
 
-  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
-    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Unable to create udp "
-                 "ping socket", sptr);
+  fd = os_socket(NULL, SOCK_DGRAM, "UDP ping socket");
+  if (fd < 0)
     return 0;
-  }
 
-  if (!os_set_nonblocking(fd)) {
-    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Can't set fd non-"
-                 "blocking", sptr);
-    close(fd);
-    return 0;
-  }
   pptr = (struct UPing*) MyMalloc(sizeof(struct UPing));
   assert(0 != pptr);
   memset(pptr, 0, sizeof(struct UPing));
@@ -419,9 +379,8 @@ int uping_server(struct Client* sptr, struct ConfItem* aconf, int port, int coun
   }
 
   pptr->fd                  = fd;
-  pptr->sin.sin_port        = htons(port);
-  pptr->sin.sin_addr.s_addr = aconf->ipnum.s_addr;
-  pptr->sin.sin_family      = AF_INET;
+  memcpy(&pptr->addr.addr, &aconf->address.addr, sizeof(pptr->addr.addr));
+  pptr->addr.port           = port;
   pptr->count               = IRCD_MIN(20, count);
   pptr->client              = sptr;
   pptr->index               = -1;
index 8a2f963e036f18065ce30a98bcc10b80802166cb..3e40dace532f24d7b12f4f99b2ae63dbacda9cbf 100644 (file)
@@ -124,7 +124,7 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
   {
     const char* p2 = HasHiddenHost(acptr) && !IsAnOper(sptr) ?
       feature_str(FEAT_HIDDEN_IP) :
-      ircd_ntoa((const char*) &(cli_ip(acptr)));
+      ircd_ntoa(&cli_ip(acptr));
     *(p1++) = ' ';
     while ((*p2) && (*(p1++) = *(p2++)));
   }
@@ -261,7 +261,7 @@ count_users(char *mask)
     ircd_snprintf(0, namebuf, sizeof(namebuf), "%s@%s",
                  cli_user(acptr)->username, cli_user(acptr)->host);
     ircd_snprintf(0, ipbuf, sizeof(ipbuf), "%s@%s", cli_user(acptr)->username,
-                 ircd_ntoa((const char *) &(cli_ip(acptr))));
+                 ircd_ntoa(&cli_ip(acptr)));
 
     if (!match(mask, namebuf) || !match(mask, ipbuf))
       count++;