[glib] GSocket: Add possibility to join a multicast group only on a specific interface
- From: Sebastian DrÃge <sdroege src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GSocket: Add possibility to join a multicast group only on a specific interface
- Date: Mon, 16 Jan 2012 17:42:21 +0000 (UTC)
commit 97f25892ea38e227fe802d0cc50fd88be12cdb17
Author: Sebastian DrÃge <sebastian droege collabora co uk>
Date: Fri Jan 13 12:37:31 2012 +0100
GSocket: Add possibility to join a multicast group only on a specific interface
configure.ac | 4 ++++
gio/gnetworkingprivate.h | 1 +
gio/gsocket.c | 28 +++++++++++++++++++++++++---
gio/gsocket.h | 2 ++
4 files changed, 32 insertions(+), 3 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index d3628e5..630656b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1109,6 +1109,10 @@ AC_CHECK_HEADER([linux/netlink.h],
[#include <sys/socket.h>])
AM_CONDITIONAL(HAVE_NETLINK, [test "$ac_cv_header_linux_netlink_h" = "yes"])
+AC_CHECK_TYPE([struct ip_mreqn], [
+ AC_DEFINE(HAVE_IP_MREQN,, [Define if we have struct ip_mreqn])],,
+ [#include <netinet/in.h>])
+
case $host in
*-*-solaris* )
AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, Needed to get declarations for msg_control and msg_controllen on Solaris)
diff --git a/gio/gnetworkingprivate.h b/gio/gnetworkingprivate.h
index 5ca7c17..ce31b1e 100644
--- a/gio/gnetworkingprivate.h
+++ b/gio/gnetworkingprivate.h
@@ -53,6 +53,7 @@
#if defined(HAVE_ARPA_NAMESER_COMPAT_H) && !defined(GETSHORT)
#include <arpa/nameser_compat.h>
#endif
+#include <net/if.h>
#ifndef T_SRV
#define T_SRV 33
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 416ac77..e2e4e39 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -47,6 +47,8 @@
#include <sys/uio.h>
#endif
+#include <net/if.h>
+
#include "gcancellable.h"
#include "gioenumtypes.h"
#include "ginetaddress.h"
@@ -1688,6 +1690,7 @@ g_socket_bind (GSocket *socket,
static gboolean
g_socket_multicast_group_operation (GSocket *socket,
GInetAddress *group,
+ const gchar *interface,
gboolean join_group,
GError **error)
{
@@ -1705,10 +1708,22 @@ g_socket_multicast_group_operation (GSocket *socket,
native_addr = g_inet_address_to_bytes (group);
if (socket->priv->family == G_SOCKET_FAMILY_IPV4)
{
+#ifdef HAVE_IP_MREQN
+ struct ip_mreqn mc_req;
+#else
struct ip_mreq mc_req;
+#endif
memcpy (&mc_req.imr_multiaddr, native_addr, sizeof (struct in_addr));
+
+#ifdef HAVE_IP_MREQN
+ if (interface)
+ mc_req.imr_ifindex = if_nametoindex (interface);
+ else
+ mc_req.imr_ifindex = 0; /* Pick any. */
+#else
mc_req.imr_interface.s_addr = g_htonl (INADDR_ANY);
+#endif
optname = join_group ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
result = setsockopt (socket->priv->fd, IPPROTO_IP, optname,
@@ -1719,7 +1734,10 @@ g_socket_multicast_group_operation (GSocket *socket,
struct ipv6_mreq mc_req_ipv6;
memcpy (&mc_req_ipv6.ipv6mr_multiaddr, native_addr, sizeof (struct in6_addr));
- mc_req_ipv6.ipv6mr_interface = 0;
+ if (interface)
+ mc_req_ipv6.ipv6mr_interface = if_nametoindex (interface);
+ else
+ mc_req_ipv6.ipv6mr_interface = 0;
optname = join_group ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP;
result = setsockopt (socket->priv->fd, IPPROTO_IPV6, optname,
@@ -1747,6 +1765,7 @@ g_socket_multicast_group_operation (GSocket *socket,
* g_socket_join_multicast_group:
* @socket: a #GSocket.
* @group: a #GInetAddress specifying the group address to join.
+ * @interface: Interface to use
* @error: #GError for error reporting, or %NULL to ignore.
*
* Registers @socket to receive multicast messages sent to @group.
@@ -1761,15 +1780,17 @@ g_socket_multicast_group_operation (GSocket *socket,
gboolean
g_socket_join_multicast_group (GSocket *socket,
GInetAddress *group,
+ const gchar *interface,
GError **error)
{
- return g_socket_multicast_group_operation (socket, group, TRUE, error);
+ return g_socket_multicast_group_operation (socket, group, interface, TRUE, error);
}
/**
* g_socket_leave_multicast_group:
* @socket: a #GSocket.
* @group: a #GInetAddress specifying the group address to leave.
+ * @interface: Interface to use
* @error: #GError for error reporting, or %NULL to ignore.
*
* Removes @socket from the multicast group @group (while still
@@ -1782,9 +1803,10 @@ g_socket_join_multicast_group (GSocket *socket,
gboolean
g_socket_leave_multicast_group (GSocket *socket,
GInetAddress *group,
+ const gchar *interface,
GError **error)
{
- return g_socket_multicast_group_operation (socket, group, FALSE, error);
+ return g_socket_multicast_group_operation (socket, group, interface, FALSE, error);
}
/**
diff --git a/gio/gsocket.h b/gio/gsocket.h
index d833875..5cfec2f 100644
--- a/gio/gsocket.h
+++ b/gio/gsocket.h
@@ -113,9 +113,11 @@ gboolean g_socket_bind (GSocket
GError **error);
gboolean g_socket_join_multicast_group (GSocket *socket,
GInetAddress *group,
+ const gchar *interface,
GError **error);
gboolean g_socket_leave_multicast_group (GSocket *socket,
GInetAddress *group,
+ const gchar *interface,
GError **error);
gboolean g_socket_connect (GSocket *socket,
GSocketAddress *address,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]