[glib] GSocket – Implement multicast interface sele ction on Windows



commit 01156b122c1c57bb27b664c6b973a35418b1f86d
Author: Sebastian Dröge <slomo circular-chaos org>
Date:   Wed Jul 31 14:11:55 2013 +0200

    GSocket – Implement multicast interface selection on Windows
    
    https://bugzilla.gnome.org/show_bug.cgi?id=697185

 gio/Makefile.am         |    2 +-
 gio/gnetworking.h.in    |    1 +
 gio/gnetworking.h.win32 |    1 +
 gio/gsocket.c           |   59 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 62 insertions(+), 1 deletions(-)
---
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 33d5885..f861e8b 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -316,7 +316,7 @@ win32_more_sources_for_vcproj = \
 
 if OS_WIN32
 appinfo_sources += gwin32appinfo.c gwin32appinfo.h
-platform_libadd += -lshlwapi -lws2_32 -ldnsapi
+platform_libadd += -lshlwapi -lws2_32 -ldnsapi -liphlpapi
 win32_sources = $(win32_actual_sources)
 
 giowin32includedir=$(includedir)/gio-win32-2.0/gio
diff --git a/gio/gnetworking.h.in b/gio/gnetworking.h.in
index 99bdadd..a1d4716 100644
--- a/gio/gnetworking.h.in
+++ b/gio/gnetworking.h.in
@@ -34,6 +34,7 @@
 #include <windns.h>
 #include <mswsock.h>
 @WSPIAPI_INCLUDE@
+#include <iphlpapi.h>
 
 #else /* !G_OS_WIN32 */
 
diff --git a/gio/gnetworking.h.win32 b/gio/gnetworking.h.win32
index c6e11a4..c5a8980 100644
--- a/gio/gnetworking.h.win32
+++ b/gio/gnetworking.h.win32
@@ -34,6 +34,7 @@
 #include <windns.h>
 #include <mswsock.h>
 #include <wspiapi.h>
+#include <iphlpapi.h>
 
 #else /* !G_OS_WIN32 */
 
diff --git a/gio/gsocket.c b/gio/gsocket.c
index a1b00a3..b606171 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -1934,6 +1934,60 @@ g_socket_bind (GSocket         *socket,
   return TRUE;
 }
 
+#if !defined(HAVE_IF_NAMETOINDEX) && defined(G_OS_WIN32)
+static guint
+if_nametoindex (const gchar *iface)
+{
+  PIP_ADAPTER_ADDRESSES addresses = NULL, p;
+  gulong addresses_len = 0;
+  guint idx = 0;
+  DWORD res;
+
+  res = GetAdaptersAddresses (AF_UNSPEC, 0, NULL, NULL, &addresses_len);
+  if (res != NO_ERROR && res != ERROR_BUFFER_OVERFLOW)
+    {
+      if (res == ERROR_NO_DATA)
+        errno = ENXIO;
+      else
+        errno = EINVAL;
+      return 0;
+    }
+
+  addresses = g_malloc (addresses_len);
+  res = GetAdaptersAddresses (AF_UNSPEC, 0, NULL, addresses, &addresses_len);
+
+  if (res != NO_ERROR)
+    {
+      g_free (addresses);
+      if (res == ERROR_NO_DATA)
+        errno = ENXIO;
+      else
+        errno = EINVAL;
+      return 0;
+    }
+
+  p = addresses;
+  while (p)
+    {
+      if (strcmp (p->AdapterName, iface) == 0)
+        {
+          idx = p->IfIndex;
+          break;
+        }
+      p = p->Next;
+    }
+
+  if (p == NULL)
+    errno = ENXIO;
+
+  g_free (addresses);
+
+  return idx;
+}
+
+#define HAVE_IF_NAMETOINDEX 1
+#endif
+
 static gboolean
 g_socket_multicast_group_operation (GSocket       *socket,
                                    GInetAddress  *group,
@@ -1969,6 +2023,11 @@ g_socket_multicast_group_operation (GSocket       *socket,
         mc_req.imr_ifindex = if_nametoindex (iface);
       else
         mc_req.imr_ifindex = 0;  /* Pick any.  */
+#elif defined(G_OS_WIN32)
+      if (iface)
+        mc_req.imr_interface.s_addr = g_htonl (if_nametoindex (iface));
+      else
+        mc_req.imr_interface.s_addr = g_htonl (INADDR_ANY);
 #else
       mc_req.imr_interface.s_addr = g_htonl (INADDR_ANY);
 #endif


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]