tolerate additional IPv4 address now available for gnunet.org
[oweals/gnunet.git] / src / util / network.c
index 0cb1529a665d8426676bae353354af657fbc3349..90f8c8640ad5f70ff9f7a59090ea6a6649c9344c 100644 (file)
@@ -2,20 +2,20 @@
      This file is part of GNUnet.
      Copyright (C) 2009-2013 GNUnet e.V.
 
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
+     Affero General Public License for more details.
 
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
 */
 
 /**
@@ -83,24 +83,64 @@ struct GNUNET_NETWORK_Handle
 int
 GNUNET_NETWORK_test_pf (int pf)
 {
+  static int cache_v4 = -1;
+  static int cache_v6 = -1;
+  static int cache_un = -1;
   int s;
+  int ret;
 
+  switch (pf)
+  {
+  case PF_INET:
+    if (-1 != cache_v4)
+      return cache_v4;
+    break;
+  case PF_INET6:
+    if (-1 != cache_v6)
+      return cache_v6;
+    break;
+#ifdef PF_UNIX
+  case PF_UNIX:
+    if (-1 != cache_un)
+      return cache_un;
+    break;
+#endif
+  }
   s = socket (pf, SOCK_STREAM, 0);
   if (-1 == s)
   {
-    if (EAFNOSUPPORT == errno)
-      return GNUNET_NO;
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Failed to create test socket: %s\n",
-                STRERROR (errno));
-    return GNUNET_SYSERR;
+    if (EAFNOSUPPORT != errno)
+    {
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                          "socket");
+      return GNUNET_SYSERR;
+    }
+    ret = GNUNET_NO;
   }
+  else
+  {
 #if WINDOWS
-  closesocket (s);
+    closesocket (s);
 #else
-  close (s);
+    close (s);
 #endif
-  return GNUNET_OK;
+    ret = GNUNET_OK;
+  }
+  switch (pf)
+  {
+  case PF_INET:
+    cache_v4 = ret;
+    break;
+  case PF_INET6:
+    cache_v6 = ret;
+    break;
+#ifdef PF_UNIX
+  case PF_UNIX:
+    cache_un = ret;
+    break;
+#endif
+  }
+  return ret;
 }
 
 
@@ -141,7 +181,8 @@ GNUNET_NETWORK_shorten_unixpath (char *unixpath)
     *end = '\0';
   }
   GNUNET_CRYPTO_hash_to_enc (&sh, &ae);
-  strncat (unixpath, (char *) ae.encoding, 16);
+  ae.encoding[16] = '\0';
+  strcat (unixpath, (char *) ae.encoding);
   return unixpath;
 }
 
@@ -463,7 +504,6 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc,
                                  (NULL != address) ? address->sa_family : desc->af,
                                  SOCK_STREAM))
   {
-
     return NULL;
   }
   return ret;