Fix resolver code when IPv6 is enabled (or at least make it capable of working).
authorMichael Poole <mdpoole@troilus.org>
Wed, 10 Nov 2004 03:47:36 +0000 (03:47 +0000)
committerMichael Poole <mdpoole@troilus.org>
Wed, 10 Nov 2004 03:47:36 +0000 (03:47 +0000)
git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1268 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
include/res.h
ircd/ircd.c
ircd/ircd_res.c
ircd/os_generic.c

index 6a020d1fc89ab89f48794f601b2f7e92f84408d7..471b3ee330f5b8d57ded4c3bc5a4b98bdda64ae8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2004-11-09  Michael Poole <mdpoole@troilus.org>
+
+       * include/res.h (init_resolver): Delete, and initialize lazily.
+
+       * ircd/ircd.c (main): Do not call init_resolver().
+
+       * ircd/ircd_res.c (restart_resolver): Use default VirtualHost for
+       local resolver socket address.
+       (init_resolver): Delete.
+       (make_request): Call restart_resolver() if necessary.
+       (query_name): Use ircrandom() instead of rand().
+
+       * ircd/os_generic.c (sockaddr_from_irc): Convert last argument to
+       a file descriptor that indicates the socket family to use.
+       (os_sendto_nonb,os_socket,os_connect_nonb): Update to match.
+
 2004-11-09  Michael Poole <mdpoole@troilus.org>
 
        * ircd/engine_epoll.c (engine_delete): Do not attempt to remove a
index 3b8fe57da16cd50d54d6cd3c3435333038247e73..9f5533517249205c95ba8a310a500af842630eef 100644 (file)
@@ -118,7 +118,6 @@ typedef struct
        unsigned        arcount :16;    /**< number of resource entries */
 } HEADER;
 
-extern int init_resolver(void);
 extern void restart_resolver(void);
 extern void add_local_domain(char *hname, size_t size);
 extern size_t cres_mem(struct Client* cptr);
index e55ccec2b291af1cfa4e9b7f63ecc07d8a290a8e..686e874618e8dd5dcd0c06af8b041329dba371c8 100644 (file)
@@ -674,8 +674,6 @@ int main(int argc, char **argv) {
   initmsgtree();
   initstats();
 
-  init_resolver();
-
   /* we need this for now, when we're modular this 
      should be removed -- hikari */
   ircd_crypt_init();
index 3e339d22685dc0cbeea22dde44a639619c343a05..0fd56b7c70d4e6a98fb796889720941e820f8106 100644 (file)
@@ -31,6 +31,7 @@
 #include "ircd.h"
 #include "numeric.h"
 #include "fileio.h" /* for fbopen / fbclose / fbputs */
+#include "random.h"
 #include "s_bsd.h"
 #include "s_debug.h"
 #include "s_stats.h"
@@ -53,6 +54,8 @@
 static struct Socket res_socket;
 /** Next DNS lookup timeout. */
 static struct Timer res_timeout;
+/** Check for whether the resolver has been initialized yet. */
+#define resolver_started() (request_list.next != NULL)
 
 /** Maximum DNS packet length.
  * RFC says 512, but we add extra for expanded names.
@@ -169,7 +172,7 @@ restart_resolver(void)
   if (!s_active(&res_socket))
   {
     int fd;
-    fd = os_socket(NULL, SOCK_DGRAM, "Resolver UDP socket");
+    fd = os_socket(&VirtualHost, SOCK_DGRAM, "Resolver UDP socket");
     if (fd < 0) return;
     if (!socket_add(&res_socket, res_readreply, NULL, SS_DATAGRAM,
                     SOCK_EVENT_READABLE, fd)) return;
@@ -177,19 +180,6 @@ restart_resolver(void)
   }
 }
 
-/** Initialize resolver.
- * This seends the pseudo-random number generator and calls
- * restart_resolver().
- * @return Resolver socket file descriptor.
- */
-int
-init_resolver(void)
-{
-  srand(CurrentTime);
-  restart_resolver();
-  return(s_fd(&res_socket));
-}
-
 /** Append local domain to hostname if needed.
  * If \a hname does not contain any '.'s, append #irc_domain to it.
  * @param[in,out] hname Hostname to check.
@@ -251,6 +241,9 @@ make_request(const struct DNSQuery* query)
 {
   struct reslist *request;
 
+  if (!resolver_started())
+    restart_resolver();
+
   request = (struct reslist *)MyMalloc(sizeof(struct reslist));
   memset(request, 0, sizeof(struct reslist));
 
@@ -537,7 +530,7 @@ query_name(const char *name, int query_class, int type,
      */
     do
     {
-      header->id = (header->id + rand()) & 0xffff;
+      header->id = (header->id + ircrandom()) & 0xffff;
     } while (find_id(header->id));
     request->id = header->id;
     ++request->sends;
index f9412b60fcb6f274ba79f013e374b48743a7fdc9..9191b387303639541a7925fd1c407dc296920464 100644 (file)
@@ -97,19 +97,30 @@ void sockaddr_to_irc(const struct sockaddr_in6 *v6, struct irc_sockaddr *irc)
 /** Convert IRC socket address to native format.
  * @param[out] v6 Native socket address.
  * @param[in] irc IRC socket address.
- * @param[in] persist If non-zero, and \a irc is an IPv4 address,
- * create an AF_INET size address.
+ * @param[in] compat_fd If non-negative, an FD specifying address family.
  * @return Length of address written to \a v6.
  */
-int sockaddr_from_irc(struct sockaddr_in6 *v6, const struct irc_sockaddr *irc, int persist)
+int sockaddr_from_irc(struct sockaddr_in6 *v6, const struct irc_sockaddr *irc, int compat_fd)
 {
+    struct sockaddr_in6 sin6;
+    socklen_t slen;
+    int family;
+
+    slen = sizeof(sin6);
+    if ((0 <= compat_fd) && (0 == getsockname(compat_fd, (struct sockaddr*)&sin6, &slen)))
+        family = sin6.sin6_family;
+    else if (irc_in_addr_is_ipv4(&VirtualHost.addr))
+        family = AF_INET;
+    else
+        family = AF_INET6;
+
     memset(v6, 0, sizeof(*v6));
     if (!irc) {
         memset(v6, 0, sizeof(v6));
         v6->sin6_family = AF_INET6;
         return sizeof(*v6);
     }
-    else if (persist && irc_in_addr_is_ipv4(&irc->addr)) {
+    else if ((family == AF_INET) && irc_in_addr_is_ipv4(&irc->addr)) {
         struct sockaddr_in *v4 = (struct sockaddr_in*)v6;
         v4->sin_family = AF_INET;
         memcpy(&v4->sin_addr, &irc->addr.in6_16[6], sizeof(v4->sin_addr));
@@ -136,7 +147,7 @@ void sockaddr_to_irc(const struct sockaddr_in *v4, struct irc_sockaddr *irc)
     irc->port = ntohs(v4->sin_port);
 }
 
-int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, int persist)
+int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, int compat_fd)
 {
     v4->sin_family = AF_INET;
     if (irc) {
@@ -146,7 +157,7 @@ int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, in
     } else{
         memset(&v4, 0, sizeof(v4));
     }
-    (void)persist;
+    (void)compat_fd;
     return sizeof(*v4);
 }
 
@@ -497,7 +508,7 @@ IOResult os_sendto_nonb(int fd, const char* buf, unsigned int length,
     *count_out = 0;
   errno = 0;
 
-  size = sockaddr_from_irc(&addr, peer, 1);
+  size = sockaddr_from_irc(&addr, peer, fd);
   if (-1 < (res = sendto(fd, buf, length, flags, (struct sockaddr*)&addr, size))) {
     if (count_out)
       *count_out = (unsigned) res;
@@ -599,7 +610,7 @@ int os_socket(const struct irc_sockaddr* local, int type, const char* port_name)
   struct sockaddr_native addr;
   int size, fd;
 
-  size = sockaddr_from_irc(&addr, local, 1);
+  size = sockaddr_from_irc(&addr, local, -1);
   fd = socket(addr.sn_family, type, 0);
   if (fd < 0) {
     report_error(SOCKET_ERROR_MSG, port_name, errno);
@@ -660,7 +671,7 @@ IOResult os_connect_nonb(int fd, const struct irc_sockaddr* sin)
   struct sockaddr_native addr;
   int size;
 
-  size = sockaddr_from_irc(&addr, sin, 1);
+  size = sockaddr_from_irc(&addr, sin, fd);
   if (connect(fd, (struct sockaddr*) &addr, size))
     return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
   return IO_SUCCESS;