+
+ addr = net_client_lookup("localhost", buf, AF_UNSPEC, SOCK_STREAM);
+ if (!addr)
+ return addr;
+
+ /* If we only got one, we need to fake up the other one. */
+ if (addr->ai_next) {
+ addr2 = addr->ai_next;
+ *fake_double = false;
+ } else {
+ /* OK, IPv4 only? */
+ if (addr->ai_family == AF_INET) {
+ /* These are the names I found on my Ubuntu system. */
+ addr2 = net_client_lookup("ip6-localhost", buf,
+ AF_UNSPEC, SOCK_STREAM);
+ if (!addr2)
+ addr2 = net_client_lookup("localhost6", buf,
+ AF_UNSPEC,
+ SOCK_STREAM);
+ if (!addr2)
+ addr2 = net_client_lookup("::1", buf,
+ AF_UNSPEC,
+ SOCK_STREAM);
+ } else if (addr->ai_family == AF_INET6)
+ /* IPv6 only? This is a guess... */
+ addr2 = net_client_lookup("ip4-localhost", buf,
+ AF_UNSPEC, SOCK_STREAM);
+
+ /* Perhaps no support on this system? Go ahead with one. */
+ if (!addr2) {
+ *fake_double = false;
+ return addr;
+ }
+
+ *fake_double = true;
+ addr->ai_next = addr2;
+ }
+
+ /* More than two? */
+ if (addr2->ai_next)
+ return NULL;
+ /* One IPv4 and one IPv6? */
+ if (addr->ai_family == AF_INET && addr2->ai_family == AF_INET6)
+ return addr;
+ if (addr->ai_family == AF_INET6 && addr2->ai_family == AF_INET)
+ return addr;
+ return NULL;
+}
+
+static void double_addr_free(struct addrinfo* addr, bool fake_double)
+{
+ if (fake_double) {
+ freeaddrinfo(addr->ai_next);
+ addr->ai_next = NULL;
+ }
+ freeaddrinfo(addr);
+}
+
+int main(void)
+{
+ struct addrinfo *addr;