GSocket – Implement multicast interface selection on Windows

https://bugzilla.gnome.org/show_bug.cgi?id=697185
This commit is contained in:
Sebastian Dröge 2013-07-31 14:11:55 +02:00 committed by Dan Winship
parent c069c51db5
commit 01156b122c
4 changed files with 62 additions and 1 deletions

View File

@ -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

View File

@ -34,6 +34,7 @@
#include <windns.h>
#include <mswsock.h>
@WSPIAPI_INCLUDE@
#include <iphlpapi.h>
#else /* !G_OS_WIN32 */

View File

@ -34,6 +34,7 @@
#include <windns.h>
#include <mswsock.h>
#include <wspiapi.h>
#include <iphlpapi.h>
#else /* !G_OS_WIN32 */

View File

@ -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