Implement System.Double runtime support
[mono.git] / mono / utils / networking-posix.c
index af9455581c44fd2c9c3b1cc7e92217d70e9ab905..6a82e68b5a60add404b2d2c00599862fee10d01a 100644 (file)
@@ -7,7 +7,7 @@
  * (C) 2015 Xamarin
  */
 
-#include <mono/utils/networking.h>
+#include <config.h>
 #include <glib.h>
 
 #ifdef HAVE_NETDB_H
@@ -19,9 +19,6 @@
 #ifdef HAVE_NET_IF_H
 #include <net/if.h>
 #endif
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 #include <ifaddrs.h>
 #endif
 
-
-static int
-get_address_size_by_family (int family)
-{
-       switch (family) {
-       case AF_INET:
-               return sizeof (struct in_addr);
-       case AF_INET6:
-               return sizeof (struct in6_addr);
-       }
-       return 0;
-}
+#include <mono/utils/networking.h>
+#include <mono/utils/mono-threads-coop.h>
 
 static void*
 get_address_from_sockaddr (struct sockaddr *sa)
@@ -63,6 +50,7 @@ mono_get_address_info (const char *hostname, int port, int flags, MonoAddressInf
        struct addrinfo hints, *res = NULL, *info;
        MonoAddressEntry *cur = NULL, *prev = NULL;
        MonoAddressInfo *addr_info;
+       int ret;
 
        memset (&hints, 0, sizeof (struct addrinfo));
        *result = NULL;
@@ -84,7 +72,12 @@ mono_get_address_info (const char *hostname, int port, int flags, MonoAddressInf
                hints.ai_flags = AI_ADDRCONFIG;
 #endif
        sprintf (service_name, "%d", port);
-    if (getaddrinfo (hostname, service_name, &hints, &info))
+
+       MONO_PREPARE_BLOCKING;
+       ret = getaddrinfo (hostname, service_name, &hints, &info);
+       MONO_FINISH_BLOCKING;
+
+       if (ret)
                return 1; /* FIXME propagate the error */
 
        res = info;
@@ -92,11 +85,6 @@ mono_get_address_info (const char *hostname, int port, int flags, MonoAddressInf
 
        while (res) {
                cur = g_new0 (MonoAddressEntry, 1);
-               if (prev)
-                       prev->next = cur;
-               else
-                       addr_info->entries = cur;
-
                cur->family = res->ai_family;
                cur->socktype = res->ai_socktype;
                cur->protocol = res->ai_protocol;
@@ -107,12 +95,20 @@ mono_get_address_info (const char *hostname, int port, int flags, MonoAddressInf
                        cur->address_len = sizeof (struct in6_addr);
                        cur->address.v6 = ((struct sockaddr_in6*)res->ai_addr)->sin6_addr;
                } else {
-                       g_error ("Cannot handle address family %d", cur->family);
+                       g_warning ("Cannot handle address family %d", cur->family);
+                       res = res->ai_next;
+                       g_free (cur);
+                       continue;
                }
 
                if (res->ai_canonname)
                        cur->canonical_name = g_strdup (res->ai_canonname);
 
+               if (prev)
+                       prev->next = cur;
+               else
+                       addr_info->entries = cur;
+                       
                prev = cur;
                res = res->ai_next;
        }
@@ -186,7 +182,7 @@ mono_get_local_interfaces (int family, int *interface_count)
 
        *interface_count = 0;
 
-       if (!get_address_size_by_family (family))
+       if (!mono_address_size_for_family (family))
                return NULL;
 
        fd = socket (family, SOCK_STREAM, 0);
@@ -195,7 +191,7 @@ mono_get_local_interfaces (int family, int *interface_count)
 
        memset (&ifc, 0, sizeof (ifc));
        ifc.ifc_len = IFCONF_BUFF_SIZE;
-       ifc.ifc_buf = g_malloc (IFCONF_BUFF_SIZE); /* We can't have such huge buffers on the stack. */
+       ifc.ifc_buf = (char *)g_malloc (IFCONF_BUFF_SIZE); /* We can't have such huge buffers on the stack. */
        if (ioctl (fd, SIOCGIFCONF, &ifc) < 0)
                goto done;
 
@@ -232,7 +228,8 @@ mono_get_local_interfaces (int family, int *interface_count)
                ++if_count;
        }
 
-       result_ptr = result = g_malloc (if_count * get_address_size_by_family (family));
+       result = (char *)g_malloc (if_count * mono_address_size_for_family (family));
+       result_ptr = (char *)result;
        FOREACH_IFR (ifr, ifc) {
                if (ifr->ifr_name [0] == '\0')
                        continue;
@@ -242,10 +239,10 @@ mono_get_local_interfaces (int family, int *interface_count)
                        continue;
                }
 
-               memcpy (result_ptr, get_address_from_sockaddr (&ifr->ifr_addr), get_address_size_by_family (family));
-               result_ptr += get_address_size_by_family (family);
+               memcpy (result_ptr, get_address_from_sockaddr (&ifr->ifr_addr), mono_address_size_for_family (family));
+               result_ptr += mono_address_size_for_family (family);
        }
-       g_assert (result_ptr <= (char*)result + if_count * get_address_size_by_family (family));
+       g_assert (result_ptr <= (char*)result + if_count * mono_address_size_for_family (family));
 
 done:
        *interface_count = if_count;
@@ -267,7 +264,7 @@ mono_get_local_interfaces (int family, int *interface_count)
 
        *interface_count = 0;
 
-       if (!get_address_size_by_family (family))
+       if (!mono_address_size_for_family (family))
                return NULL;
 
        if (getifaddrs (&ifap))
@@ -293,7 +290,7 @@ mono_get_local_interfaces (int family, int *interface_count)
                if_count++;
        }
 
-       result_ptr = result = g_malloc (if_count * get_address_size_by_family (family));
+       result_ptr = result = g_malloc (if_count * mono_address_size_for_family (family));
        for (cur = ifap; cur; cur = cur->ifa_next) {
                if (!cur->ifa_addr)
                        continue;
@@ -308,10 +305,10 @@ mono_get_local_interfaces (int family, int *interface_count)
                        continue;
                }
 
-               memcpy (result_ptr, get_address_from_sockaddr (cur->ifa_addr), get_address_size_by_family (family));
-               result_ptr += get_address_size_by_family (family);
+               memcpy (result_ptr, get_address_from_sockaddr (cur->ifa_addr), mono_address_size_for_family (family));
+               result_ptr += mono_address_size_for_family (family);
        }
-       g_assert (result_ptr <= (char*)result + if_count * get_address_size_by_family (family));
+       g_assert (result_ptr <= (char*)result + if_count * mono_address_size_for_family (family));
 
        freeifaddrs (ifap);
        *interface_count = if_count;
@@ -319,3 +316,40 @@ mono_get_local_interfaces (int family, int *interface_count)
 }
 
 #endif
+
+#ifdef HAVE_GETNAMEINFO
+
+gboolean
+mono_networking_addr_to_str (MonoAddress *address, char *buffer, socklen_t buflen)
+{
+       MonoSocketAddress saddr;
+       socklen_t len;
+       mono_socket_address_init (&saddr, &len, address->family, &address->addr, 0);
+
+       return getnameinfo (&saddr.addr, len, buffer, buflen, NULL, 0, NI_NUMERICHOST) == 0;
+}
+
+#elif HAVE_INET_NTOP
+
+gboolean
+mono_networking_addr_to_str (MonoAddress *address, char *buffer, socklen_t buflen)
+{
+       return inet_ntop (address->family, &address->addr, buffer, buflen) != NULL;
+}
+
+#endif
+
+#ifndef _WIN32
+// These are already defined in networking-windows.c for Windows
+void
+mono_networking_init (void)
+{
+       //nothing really
+}
+
+void
+mono_networking_shutdown (void)
+{
+       //nothing really
+}
+#endif