<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40410 >

 After several patches preparing codebase for IPv6 support, this patch
actually adds it. Affected connections are server <-> client and
metaserver <-> server. LAN multicast is still completely IPv4 based.


 - ML

diff -Nurd -X.diff_ignore freeciv/utility/netintf.c freeciv/utility/netintf.c
--- freeciv/utility/netintf.c   2008-07-22 16:57:39.000000000 +0300
+++ freeciv/utility/netintf.c   2008-07-27 22:02:16.000000000 +0300
@@ -295,7 +295,7 @@
 #endif /* IPv6 support */
   {
     return FALSE;
- }
+  }
 }
 
 /***************************************************************************
@@ -304,31 +304,74 @@
 bool net_lookup_service(const char *name, int port, union my_sockaddr *addr)
 {
   struct hostent *hp;
-  struct sockaddr_in *sock = &addr->saddr_in4;
+  struct sockaddr_in *sock4;
+#ifdef IPV6_SUPPORT
+  struct sockaddr_in6 *sock6;
+#endif /* IPv6 support */
 
-  sock->sin_family = AF_INET;
-  sock->sin_port = htons(port);
+  sock4 = &addr->saddr_in4;
+
+#ifdef IPV6_SUPPORT
+  sock6 = &addr->saddr_in6;
+
+  addr->saddr.sa_family = AF_INET6;
+  sock6->sin6_port = htons(port);
 
   if (!name) {
-    sock->sin_addr.s_addr = htonl(INADDR_ANY);
+    sock6->sin6_addr = in6addr_any;
     return TRUE;
   }
+#else /* IPv6 support */
+  addr->saddr.sa_family = AF_INET;
+  sock4->sin_port = htons(port);
 
-#ifdef HAVE_INET_ATON
-  if (inet_aton(name, &sock->sin_addr) != 0) {
+  if (!name) {
+    sock4->sin_addr.s_addr = htonl(INADDR_ANY);
     return TRUE;
   }
-#else
-  if ((sock->sin_addr.s_addr = inet_addr(name)) != INADDR_NONE) {
+#endif /* IPv6 support */
+
+#ifdef IPV6_SUPPORT
+  if (inet_pton(AF_INET6, name, &sock6->sin6_addr)) {
     return TRUE;
   }
-#endif
+  /* TODO: Replace gethostbyname2() with getaddrinfo() */
+  hp = gethostbyname2(name, AF_INET6);
+  if (!hp || hp->h_addrtype != AF_INET6) {
+    /* Try to fallback to IPv4 resolution */
+    freelog(LOG_DEBUG, "Falling back to IPv4");
+    hp = gethostbyname2(name, AF_INET);
+    if (!hp || hp->h_addrtype != AF_INET) {
+      return FALSE;
+    }
+    addr->saddr.sa_family = AF_INET;
+    sock4->sin_port = htons(port);
+  }
+#else  /* IPV6 support */
+#if defined(HAVE_INET_ATON)
+  if (inet_aton(name, &sock4->sin_addr) != 0) {
+    return TRUE;
+  }
+#else  /* HAVE_INET_ATON */
+  if ((sock4->sin_addr.s_addr = inet_addr(name)) != INADDR_NONE) {
+    return TRUE;
+  }
+#endif /* HAVE_INET_ATON */
   hp = gethostbyname(name);
   if (!hp || hp->h_addrtype != AF_INET) {
     return FALSE;
   }
+#endif /* IPv6 support */
+
+#ifdef IPV6_SUPPORT
+  if (addr->saddr.sa_family == AF_INET6) {
+    memcpy(&sock6->sin6_addr, hp->h_addr, hp->h_length);
+  } else
+#endif /* IPv6 support */
+  {
+    memcpy(&sock4->sin_addr, hp->h_addr, hp->h_length);
+  }
 
-  memcpy(&sock->sin_addr, hp->h_addr, hp->h_length);
   return TRUE;
 }
 
diff -Nurd -X.diff_ignore freeciv/utility/netintf.h freeciv/utility/netintf.h
--- freeciv/utility/netintf.h   2008-07-22 16:57:39.000000000 +0300
+++ freeciv/utility/netintf.h   2008-07-27 21:07:25.000000000 +0300
@@ -79,13 +79,13 @@
 int my_select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
               struct timeval *timeout);
 int my_readsocket(int sock, void *buf, size_t size);
-int my_writesocket(int sock, const void *buf, size_t size); 
+int my_writesocket(int sock, const void *buf, size_t size);
 void my_closesocket(int sock);
-void my_init_network(void);         
+void my_init_network(void);
 void my_shutdown_network(void);
 
 void my_nonblock(int sockfd);
-bool net_lookup_service(const char *name, int port, 
+bool net_lookup_service(const char *name, int port,
                         union my_sockaddr *addr);
 fz_FILE *my_querysocket(int sock, void *buf, size_t size);
 int find_next_free_port(int starting_port);
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to