From a73689c4c313917619709e6e40b85fc7194105cf Mon Sep 17 00:00:00 2001 From: gnupnp Date: Wed, 20 Feb 2013 13:13:23 +0100 Subject: [PATCH] Allow custom TTL value for GSSDPClient. Add 'ttl' property to GSSDPSocketSource. Add ttl parameter to gssdp_socket_source_new(). Add 'socket-ttl' property to GSSPDClient. https://bugzilla.gnome.org/show_bug.cgi?id=656406 --- libgssdp/gssdp-client.c | 33 ++++++++++++++++++++++++++++++++- libgssdp/gssdp-socket-source.c | 33 ++++++++++++++++++++++++++++++--- libgssdp/gssdp-socket-source.h | 1 + 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/libgssdp/gssdp-client.c b/libgssdp/gssdp-client.c index 8e20a7a..206c3ac 100644 --- a/libgssdp/gssdp-client.c +++ b/libgssdp/gssdp-client.c @@ -95,6 +95,7 @@ typedef struct _GSSDPNetworkDevice GSSDPNetworkDevice; struct _GSSDPClientPrivate { char *server_id; + guint socket_ttl; GSSDPNetworkDevice device; GSSDPSocketSource *request_socket; @@ -112,7 +113,8 @@ enum { PROP_IFACE, PROP_NETWORK, PROP_HOST_IP, - PROP_ACTIVE + PROP_ACTIVE, + PROP_SOCKET_TTL, }; enum { @@ -203,6 +205,7 @@ gssdp_client_initable_init (GInitable *initable, client->priv->request_socket = gssdp_socket_source_new (GSSDP_SOCKET_SOURCE_TYPE_REQUEST, gssdp_client_get_host_ip (client), + client->priv->socket_ttl, &internal_error); if (client->priv->request_socket != NULL) { gssdp_socket_source_set_callback @@ -216,6 +219,7 @@ gssdp_client_initable_init (GInitable *initable, client->priv->multicast_socket = gssdp_socket_source_new (GSSDP_SOCKET_SOURCE_TYPE_MULTICAST, gssdp_client_get_host_ip (client), + client->priv->socket_ttl, &internal_error); if (client->priv->multicast_socket != NULL) { gssdp_socket_source_set_callback @@ -231,6 +235,7 @@ gssdp_client_initable_init (GInitable *initable, client->priv->search_socket = gssdp_socket_source_new (GSSDP_SOCKET_SOURCE_TYPE_SEARCH, gssdp_client_get_host_ip (client), + client->priv->socket_ttl, &internal_error); if (client->priv->search_socket != NULL) { gssdp_socket_source_set_callback @@ -313,6 +318,9 @@ gssdp_client_get_property (GObject *object, case PROP_ACTIVE: g_value_set_boolean (value, client->priv->active); break; + case PROP_SOCKET_TTL: + g_value_set_uint (value, client->priv->socket_ttl); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -348,6 +356,9 @@ gssdp_client_set_property (GObject *object, case PROP_ACTIVE: client->priv->active = g_value_get_boolean (value); break; + case PROP_SOCKET_TTL: + client->priv->socket_ttl = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -530,6 +541,26 @@ gssdp_client_class_init (GSSDPClientClass *klass) G_PARAM_STATIC_BLURB)); /** + * GSSDPClient:socket-ttl: + * + * Time-to-live value to use for all sockets created by this client. + * If not set (or set to 0) the value recommended by UPnP will be used. + * This property can only be set during object construction. + */ + g_object_class_install_property + (object_class, + PROP_SOCKET_TTL, + g_param_spec_uint + ("socket-ttl", + "Socket TTL", + "Time To Live for client's sockets", + 0, 255, + 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** * GSSDPClient::message-received: (skip) * * Internal signal. diff --git a/libgssdp/gssdp-socket-source.c b/libgssdp/gssdp-socket-source.c index e51b1fe..aa32c63 100644 --- a/libgssdp/gssdp-socket-source.c +++ b/libgssdp/gssdp-socket-source.c @@ -47,13 +47,16 @@ struct _GSSDPSocketSourcePrivate { GSource *source; GSocket *socket; GSSDPSocketSourceType type; + char *host_ip; + guint ttl; }; enum { PROP_0, PROP_TYPE, - PROP_HOST_IP + PROP_HOST_IP, + PROP_TTL, }; static void @@ -108,6 +111,9 @@ gssdp_socket_source_set_property (GObject *object, case PROP_HOST_IP: self->priv->host_ip = g_value_dup_string (value); break; + case PROP_TTL: + self->priv->ttl = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -122,6 +128,7 @@ gssdp_socket_source_set_property (GObject *object, GSSDPSocketSource * gssdp_socket_source_new (GSSDPSocketSourceType type, const char *host_ip, + guint ttl, GError **error) { return g_initable_new (GSSDP_TYPE_SOCKET_SOURCE, @@ -131,6 +138,8 @@ gssdp_socket_source_new (GSSDPSocketSourceType type, type, "host-ip", host_ip, + "ttl", + ttl, NULL); } @@ -198,15 +207,20 @@ gssdp_socket_source_do_init (GInitable *initable, } /* 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, - 4, + self->priv->ttl, &inner_error)) { g_propagate_prefixed_error (error, inner_error, - "Failed to set TTL"); + "Failed to set TTL to %u", self->priv->ttl); 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 */ @@ -422,4 +436,17 @@ gssdp_socket_source_class_init (GSSDPSocketSourceClass *klass) 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", + "TTL", + "Time To Live for the socket", + 0, 255, + 0, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); } diff --git a/libgssdp/gssdp-socket-source.h b/libgssdp/gssdp-socket-source.h index d40af3e..c3bba90 100644 --- a/libgssdp/gssdp-socket-source.h +++ b/libgssdp/gssdp-socket-source.h @@ -74,6 +74,7 @@ typedef struct _GSSDPSocketSourceClass { G_GNUC_INTERNAL GSSDPSocketSource * gssdp_socket_source_new (GSSDPSocketSourceType type, const char *host_ip, + guint ttl, GError **error); G_GNUC_INTERNAL GSocket* gssdp_socket_source_get_socket (GSSDPSocketSource *socket_source); -- 2.7.4