<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