Browse Source

Merge branch 'fix-ipv4-ipv6-choosing'

* fix-ipv4-ipv6-choosing:
  * If wanting ipv6, only lookup AAAA, otherwise lookup A
  * Bot no longer connects to IRC over IPv6 if it was specifically given an IPv4 IP.
Bryan Drewery 16 years ago
parent
commit
778afaab1c
4 changed files with 36 additions and 17 deletions
  1. 1 0
      doc/UPDATES
  2. 9 0
      src/adns.c
  3. 1 0
      src/adns.h
  4. 25 17
      src/mod/server.mod/servmsg.c

+ 1 - 0
doc/UPDATES

@@ -22,6 +22,7 @@
   * Add Google DNS servers as backups: 8.8.8.8, 8.8.4.4 (http://code.google.com/speed/public-dns/)
   * Add Google DNS servers as backups: 8.8.8.8, 8.8.4.4 (http://code.google.com/speed/public-dns/)
   * If a .resolv.conf exists, only use the nameservers listed in it.
   * If a .resolv.conf exists, only use the nameservers listed in it.
   * Fix problem of bots never reconnecting to hub after being up for long periods. (Was a DNS issue)
   * Fix problem of bots never reconnecting to hub after being up for long periods. (Was a DNS issue)
+  * Bot no longer connects to IRC over IPv6 if it was specifically given an IPv4 IP.
 * Botlink
 * Botlink
   * Bots now link to the first bot in their binary (the localhub) over a UNIX domain socket. Only the localhub connects to the main hubs.
   * Bots now link to the first bot in their binary (the localhub) over a UNIX domain socket. Only the localhub connects to the main hubs.
   * Bots must have a matching host to be able to link now.
   * Bots must have a matching host to be able to link now.

+ 9 - 0
src/adns.c

@@ -1176,4 +1176,13 @@ bool valid_dns_id(int idx, int id)
   sdprintf("dns_id: %d is not associated with dead idx: %d", id, idx);
   sdprintf("dns_id: %d is not associated with dead idx: %d", id, idx);
   return 0;
   return 0;
 }
 }
+
+bd::String dns_find_ip(bd::Array<bd::String> ips, int af_type) {
+    for (size_t i = 0; i < ips.size(); ++i) {
+      if (is_dotted_ip(bd::String(ips[i]).c_str()) == af_type) {
+        return ips[i];
+      }
+    }
+	return bd::String();
+}
 /* vim: set sts=4 sw=4 ts=4 noet: */
 /* vim: set sts=4 sw=4 ts=4 noet: */

+ 1 - 0
src/adns.h

@@ -56,6 +56,7 @@ void tell_dnsdebug(int);
 void dns_cache_flush();
 void dns_cache_flush();
 bool valid_dns_id(int, int);
 bool valid_dns_id(int, int);
 int reverse_ip(const char *host, char *reverse);
 int reverse_ip(const char *host, char *reverse);
+bd::String dns_find_ip(bd::Array<bd::String> ips, int af_type);
 
 
 extern int		dns_sock, dns_idx;
 extern int		dns_sock, dns_idx;
 extern const char	*dns_ip;
 extern const char	*dns_ip;

+ 25 - 17
src/mod/server.mod/servmsg.c

@@ -1776,7 +1776,7 @@ static void connect_server(void)
     /* I'm resolving... don't start another server connect request */
     /* I'm resolving... don't start another server connect request */
     resolvserv = 1;
     resolvserv = 1;
     /* Resolve the hostname. */
     /* Resolve the hostname. */
-    int dns_id = egg_dns_lookup(botserver, 20, server_dns_callback, (void *) (long) newidx);
+    int dns_id = egg_dns_lookup(botserver, 20, server_dns_callback, (void *) (long) newidx, conf.bot->net.v6 ? DNS_LOOKUP_AAAA : DNS_LOOKUP_A);
     if (dns_id >= 0)
     if (dns_id >= 0)
       dcc[newidx].dns_id = dns_id;
       dcc[newidx].dns_id = dns_id;
     /* wait for async reply */
     /* wait for async reply */
@@ -1803,28 +1803,28 @@ static void server_dns_callback(int id, void *client_data, const char *host, bd:
 
 
   my_addr_t addr;
   my_addr_t addr;
   char *ip = NULL;
   char *ip = NULL;
+  const char* dns_type = NULL;
+  bd::String ip_from_dns;
 
 
-  /* FIXME: this is a temporary hack to stop bots from connecting over ipv4 when they should be on ipv6
-   * eventually will handle this in open_telnet(ips);
-   */
 #ifdef USE_IPV6
 #ifdef USE_IPV6
+  /* If IPv6 is wanted, ensure we are connecting to an IPv6 server, otherwise skip it */
   if (conf.bot->net.v6) {
   if (conf.bot->net.v6) {
-    size_t i = 0;
-    for (i = 0; i < ips.size(); ++i) {
-      if (is_dotted_ip(bd::String(ips[i]).c_str()) == AF_INET6) {
-        ip = strdup(bd::String(ips[i]).c_str());
-        break;
-      }
-    }
-    if (!ip) {
-      putlog(LOG_SERV, "*", "Failed connect to %s (Could not DNS as IPV6)", host);
-      trying_server = 0;
-      lostdcc(idx);
-      return;
+    ip_from_dns = dns_find_ip(ips, AF_INET6);
+    if (!ip_from_dns.length()) {
+      dns_type = "IPv6";
+      goto fatal_dns;
     }
     }
   } else
   } else
 #endif /* USE_IPV6 */
 #endif /* USE_IPV6 */
-    ip = strdup(bd::String(ips[0]).c_str());
+  {
+    /* If IPv4 is wanted, don't connect to IPv6! */
+    ip_from_dns = dns_find_ip(ips, AF_INET);
+    if (!ip_from_dns.length()) {
+      dns_type = "IPv4";
+      goto fatal_dns;
+    }
+  }
+  ip = strdup(ip_from_dns.c_str());
 
 
   get_addr(ip, &addr);
   get_addr(ip, &addr);
  
  
@@ -1870,5 +1870,13 @@ static void server_dns_callback(int id, void *client_data, const char *host, bd:
     dprintf(DP_MODE, "USER %s localhost %s :%s\n", botuser, dcc[idx].host, replace_vars(botrealname));
     dprintf(DP_MODE, "USER %s localhost %s :%s\n", botuser, dcc[idx].host, replace_vars(botrealname));
     /* Wait for async result now */
     /* Wait for async result now */
   }
   }
+
   free(ip);
   free(ip);
+  return;
+
+fatal_dns:
+  putlog(LOG_SERV, "*", "Failed connect to %s (Could not DNS as %s)", host, dns_type);
+  trying_server = 0;
+  lostdcc(idx);
+  return;
 }
 }