diff options
author | Riko Yamada <rik0yamada@yahoo.co.jp> | 2012-08-19 14:56:02 +0900 |
---|---|---|
committer | Jens Georg <mail@jensge.org> | 2014-03-15 10:01:23 +0100 |
commit | 3030bf4cb97db33fcdfe7e69706fdb0f19b0f446 (patch) | |
tree | ecd53bc8a5de8de0e03688ffaa2e7357e1a9b0d1 | |
parent | 3a257bafe5f5eb4b488ee30213d47221b81c60fa (diff) | |
download | gssdp-3030bf4cb97db33fcdfe7e69706fdb0f19b0f446.tar.gz |
Port to glib multicast socket functions
https://bugzilla.gnome.org/show_bug.cgi?id=678660
Signed-off-by: Jens Georg <mail@jensge.org>
-rw-r--r-- | libgssdp/gssdp-client.c | 3 | ||||
-rw-r--r-- | libgssdp/gssdp-socket-functions.c | 138 | ||||
-rw-r--r-- | libgssdp/gssdp-socket-functions.h | 17 | ||||
-rw-r--r-- | libgssdp/gssdp-socket-source.c | 69 | ||||
-rw-r--r-- | libgssdp/gssdp-socket-source.h | 1 |
5 files changed, 42 insertions, 186 deletions
diff --git a/libgssdp/gssdp-client.c b/libgssdp/gssdp-client.c index c4d745b..f24e57a 100644 --- a/libgssdp/gssdp-client.c +++ b/libgssdp/gssdp-client.c @@ -220,6 +220,7 @@ gssdp_client_initable_init (GInitable *initable, gssdp_socket_source_new (GSSDP_SOCKET_SOURCE_TYPE_REQUEST, gssdp_client_get_host_ip (client), client->priv->socket_ttl, + client->priv->device.iface_name, &internal_error); if (client->priv->request_socket != NULL) { gssdp_socket_source_set_callback @@ -234,6 +235,7 @@ gssdp_client_initable_init (GInitable *initable, gssdp_socket_source_new (GSSDP_SOCKET_SOURCE_TYPE_MULTICAST, gssdp_client_get_host_ip (client), client->priv->socket_ttl, + client->priv->device.iface_name, &internal_error); if (client->priv->multicast_socket != NULL) { gssdp_socket_source_set_callback @@ -254,6 +256,7 @@ gssdp_client_initable_init (GInitable *initable, "host-ip", gssdp_client_get_host_ip (client), "ttl", client->priv->socket_ttl, "port", client->priv->msearch_port, + "device-name", client->priv->device.iface_name, NULL)); if (client->priv->search_socket != NULL) { diff --git a/libgssdp/gssdp-socket-functions.c b/libgssdp/gssdp-socket-functions.c index 5919e2b..e1ffaaa 100644 --- a/libgssdp/gssdp-socket-functions.c +++ b/libgssdp/gssdp-socket-functions.c @@ -89,52 +89,6 @@ gssdp_socket_option_set (GSocket *socket, } gboolean -gssdp_socket_enable_loop (GSocket *socket, - gboolean _enable, - GError **error) { -#if defined(__OpenBSD__) - guint8 enable = (guint8) _enable; -#else - gboolean enable = _enable; -#endif - return gssdp_socket_option_set (socket, - IPPROTO_IP, - IP_MULTICAST_LOOP, - (char *) &enable, - sizeof (enable), - error); -} - -gboolean -gssdp_socket_set_ttl (GSocket *socket, - int _ttl, - GError **error) { -#if defined(__OpenBSD__) - guint8 ttl = (guint8) _ttl; -#else - int ttl = _ttl; -#endif - return gssdp_socket_option_set (socket, - IPPROTO_IP, - IP_MULTICAST_TTL, - (char *) &ttl, - sizeof (ttl), - error); -} - -gboolean -gssdp_socket_enable_broadcast (GSocket *socket, - gboolean enable, - GError **error) { - return gssdp_socket_option_set (socket, - SOL_SOCKET, - SO_BROADCAST, - (char *) &enable, - sizeof (enable), - error); -} - -gboolean gssdp_socket_mcast_interface_set (GSocket *socket, GInetAddress *iface_address, GError **error) { @@ -178,95 +132,3 @@ gssdp_socket_reuse_address (GSocket *socket, #endif return TRUE; } - - -/* - * Iface may be NULL if no special interface is wanted - */ -gboolean -gssdp_socket_mcast_group_join (GSocket *socket, - GInetAddress *group, - GInetAddress *iface, - GError **error) { - struct ip_mreq mreq; - GError *inner_error = NULL; - gboolean result; -#ifdef G_OS_WIN32 - GSocketAddress *local_address; -#endif - if (group == NULL || ! G_IS_INET_ADDRESS (group)) { - g_set_error_literal (error, - GSSDP_ERROR, - GSSDP_ERROR_NO_IP_ADDRESS, - "Address is not a valid address"); - - return FALSE; - } - - if (!g_inet_address_get_is_multicast (group)) { - char *address; - - address = g_inet_address_to_string (group); - g_set_error (error, - GSSDP_ERROR, - GSSDP_ERROR_FAILED, - "Address '%s' is not a multicast address", - address); - g_free (address); - - return FALSE; - } - - if (g_inet_address_get_family (group) != G_SOCKET_FAMILY_IPV4) { - g_set_error_literal (error, - GSSDP_ERROR, - GSSDP_ERROR_FAILED, - "IPv6 not supported"); - - return FALSE; - } -#ifdef G_OS_WIN32 - /* On Window, it is only possible to join multicast groups on a bound - * socket - * Note: This test is valid on Windows only. On linux, local_addres - * will be the ANY address (0.0.0.0 for IPv4) - */ - local_address = g_socket_get_local_address (socket, &inner_error); - if (local_address == NULL) { - g_set_error_literal (error, - GSSDP_ERROR, - GSSDP_ERROR_FAILED, - "Cannot join multicast group;" - "socket is not bound"); - - return FALSE; - } - g_object_unref (local_address); -#endif - - memset (&mreq, 0, sizeof (struct ip_mreq)); - memcpy (&(mreq.imr_multiaddr), - g_inet_address_to_bytes (group), - g_inet_address_get_native_size (group)); - - /* if omitted, join will fail if there isn't an explicit multicast - * route or a default route - */ - if (iface != NULL) - memcpy (&(mreq.imr_interface), - g_inet_address_to_bytes (iface), - g_inet_address_get_native_size (iface)); - - result = gssdp_socket_option_set (socket, - IPPROTO_IP, - IP_ADD_MEMBERSHIP, - (char *) &mreq, - sizeof (mreq), - &inner_error); - if (!result) - g_propagate_error (error, inner_error); - - return result; -} - - diff --git a/libgssdp/gssdp-socket-functions.h b/libgssdp/gssdp-socket-functions.h index 47b1095..14f0650 100644 --- a/libgssdp/gssdp-socket-functions.h +++ b/libgssdp/gssdp-socket-functions.h @@ -25,27 +25,10 @@ #include <gio/gio.h> G_GNUC_INTERNAL gboolean -gssdp_socket_enable_loop (GSocket *socket, - gboolean enable, - GError **error); -G_GNUC_INTERNAL gboolean -gssdp_socket_set_ttl (GSocket *socket, - int ttl, - GError **error); -G_GNUC_INTERNAL gboolean -gssdp_socket_enable_broadcast (GSocket *socket, - gboolean enable, - GError **error); -G_GNUC_INTERNAL gboolean gssdp_socket_mcast_interface_set (GSocket *socket, GInetAddress *iface_address, GError **error); G_GNUC_INTERNAL gboolean -gssdp_socket_mcast_group_join (GSocket *socket, - GInetAddress *group, - GInetAddress *iface, - GError **error); -G_GNUC_INTERNAL gboolean gssdp_socket_reuse_address (GSocket *socket, gboolean enable, GError **error); diff --git a/libgssdp/gssdp-socket-source.c b/libgssdp/gssdp-socket-source.c index c7e9585..a51b1a7 100644 --- a/libgssdp/gssdp-socket-source.c +++ b/libgssdp/gssdp-socket-source.c @@ -27,11 +27,19 @@ #include <config.h> #include <glib.h> +#ifndef G_OS_WIN32 +#include <arpa/inet.h> +#include <net/if.h> +#include <ifaddrs.h> +#endif #include "gssdp-socket-functions.h" #include "gssdp-socket-source.h" #include "gssdp-protocol.h" #include "gssdp-error.h" +#include <string.h> +#include <stdio.h> + static void gssdp_socket_source_initable_init (gpointer g_iface, gpointer iface_data); @@ -49,6 +57,7 @@ struct _GSSDPSocketSourcePrivate { GSSDPSocketSourceType type; char *host_ip; + char *device_name; guint ttl; guint port; }; @@ -58,7 +67,8 @@ enum { PROP_TYPE, PROP_HOST_IP, PROP_TTL, - PROP_PORT + PROP_PORT, + PROP_IFA_NAME }; static void @@ -113,6 +123,9 @@ gssdp_socket_source_set_property (GObject *object, case PROP_HOST_IP: self->priv->host_ip = g_value_dup_string (value); break; + case PROP_IFA_NAME: + self->priv->device_name = g_value_dup_string (value); + break; case PROP_TTL: self->priv->ttl = g_value_get_uint (value); break; @@ -134,6 +147,7 @@ GSSDPSocketSource * gssdp_socket_source_new (GSSDPSocketSourceType type, const char *host_ip, guint ttl, + const char *device_name, GError **error) { return g_initable_new (GSSDP_TYPE_SOCKET_SOURCE, @@ -145,6 +159,8 @@ gssdp_socket_source_new (GSSDPSocketSourceType type, host_ip, "ttl", ttl, + "device-name", + device_name, NULL); } @@ -202,43 +218,20 @@ gssdp_socket_source_do_init (GInitable *initable, } /* Enable broadcasting */ - if (!gssdp_socket_enable_broadcast (self->priv->socket, - TRUE, - &inner_error)) { - g_propagate_prefixed_error (error, - inner_error, - "Failed to enable broadcast"); - goto error; - } + g_socket_set_broadcast (self->priv->socket, TRUE); /* TTL */ if (!self->priv->ttl) /* UDA/1.0 says 4, UDA/1.1 says 2 */ self->priv->ttl = 4; - if (!gssdp_socket_set_ttl (self->priv->socket, - self->priv->ttl, - &inner_error)) { - g_propagate_prefixed_error (error, - inner_error, - "Failed to set TTL to %u", self->priv->ttl); + g_socket_set_multicast_ttl (self->priv->socket, 4); - goto error; - } /* Set up additional things according to the type of socket desired */ if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) { /* Enable multicast loopback */ - if (!gssdp_socket_enable_loop (self->priv->socket, - TRUE, - &inner_error)) { - g_propagate_prefixed_error ( - error, - inner_error, - "Failed to enable loop-back"); - - goto error; - } + g_socket_set_multicast_loopback (self->priv->socket, TRUE); if (!gssdp_socket_mcast_interface_set (self->priv->socket, iface_address, @@ -299,11 +292,13 @@ gssdp_socket_source_do_init (GInitable *initable, } if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) { - - /* Subscribe to multicast channel */ - if (!gssdp_socket_mcast_group_join (self->priv->socket, + /* The 4th argument 'iface_name' can't be NULL even though Glib API doc says you + * can. 'NULL' will fail the test. + */ + if (!g_socket_join_multicast_group (self->priv->socket, group, - iface_address, + FALSE, + self->priv->device_name, /* e.g. 'lo' */ &inner_error)) { char *address = g_inet_address_to_string (group); g_propagate_prefixed_error (error, @@ -446,6 +441,18 @@ gssdp_socket_source_class_init (GSSDPSocketSourceClass *klass) g_object_class_install_property (object_class, + PROP_IFA_NAME, + g_param_spec_string + ("device-name", + "Interface name", + "Name of associated network interface", + NULL, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_object_class_install_property + (object_class, PROP_TTL, g_param_spec_uint ("ttl", diff --git a/libgssdp/gssdp-socket-source.h b/libgssdp/gssdp-socket-source.h index ed9ef42..d2e9611 100644 --- a/libgssdp/gssdp-socket-source.h +++ b/libgssdp/gssdp-socket-source.h @@ -76,6 +76,7 @@ G_GNUC_INTERNAL GSSDPSocketSource * gssdp_socket_source_new (GSSDPSocketSourceType type, const char *host_ip, guint ttl, + const char *device_name, GError **error); G_GNUC_INTERNAL GSocket* |