[gssdp] Fix discovery regressions introduced with 177f2772.



commit fb1dcef0d5205e367b27528c2c0b49a43148e8d5
Author: Jens Georg <mail jensge org>
Date:   Sat Jul 2 15:28:30 2011 +0200

    Fix discovery regressions introduced with 177f2772.
    
     - Only M-SEARCH should be send from port different to 1900
     - GSSDP needs to listen on that socket as well since clients
       need to reply to the port M-SEARCH was sent from.

 libgssdp/gssdp-client-private.h   |    9 ++--
 libgssdp/gssdp-client.c           |   89 ++++++++++++++++++++++--------------
 libgssdp/gssdp-resource-browser.c |    3 +-
 libgssdp/gssdp-resource-group.c   |    6 ++-
 libgssdp/gssdp-socket-source.c    |    9 +++-
 libgssdp/gssdp-socket-source.h    |    3 +-
 6 files changed, 74 insertions(+), 45 deletions(-)
---
diff --git a/libgssdp/gssdp-client-private.h b/libgssdp/gssdp-client-private.h
index fc450e8..f8e26f9 100644
--- a/libgssdp/gssdp-client-private.h
+++ b/libgssdp/gssdp-client-private.h
@@ -33,10 +33,11 @@ typedef enum {
 } _GSSDPMessageType;
 
 G_GNUC_INTERNAL void
-_gssdp_client_send_message (GSSDPClient *client,
-                            const char  *dest_ip,
-                            gushort      dest_port,
-                            const char  *message);
+_gssdp_client_send_message (GSSDPClient       *client,
+                            const char        *dest_ip,
+                            gushort            dest_port,
+                            const char        *message,
+                            _GSSDPMessageType  type);
 
 G_END_DECLS
 
diff --git a/libgssdp/gssdp-client.c b/libgssdp/gssdp-client.c
index d3dce26..0854b8b 100644
--- a/libgssdp/gssdp-client.c
+++ b/libgssdp/gssdp-client.c
@@ -92,9 +92,9 @@ struct _GSSDPClientPrivate {
         char              *host_ip;
         char              *network;
 
-        GSocket           *send_socket;
         GSSDPSocketSource *request_socket;
         GSSDPSocketSource *multicast_socket;
+        GSSDPSocketSource *search_socket;
 
         gboolean           active;
 };
@@ -131,6 +131,11 @@ multicast_socket_source_cb    (GIOChannel   *source,
                                GIOCondition  condition,
                                gpointer      user_data);
 static gboolean
+search_socket_source_cb       (GIOChannel   *source,
+                               GIOCondition  condition,
+                               gpointer      user_data);
+
+static gboolean
 init_network_info             (GSSDPClient  *client,
                                GError      **error);
 
@@ -211,35 +216,26 @@ gssdp_client_initable_init (GInitable     *initable,
                         (client->priv->multicast_socket,
                          (GSourceFunc) multicast_socket_source_cb,
                          client);
+        } else {
+                goto errors;
         }
 
         /* Setup send socket. For security reasons, it is not recommended to
-         * send with source port == SSDP_PORT */
-        client->priv->send_socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
-                                                  G_SOCKET_TYPE_DATAGRAM,
-                                                  G_SOCKET_PROTOCOL_UDP,
-                                                  &internal_error);
-        if (client->priv->send_socket) {
-                GInetAddress *inet_addr;
-                GSocketAddress *sock_addr;
-
-                inet_addr = g_inet_address_new_from_string
-                                        (gssdp_client_get_host_ip (client));
-                sock_addr = g_inet_socket_address_new (inet_addr, 0);
-
-                g_socket_bind (client->priv->send_socket,
-                               sock_addr,
-                               FALSE,
-                               &internal_error);
-
-                g_object_unref (sock_addr);
-                g_object_unref (inet_addr);
+         * send M-SEARCH with source port == SSDP_PORT */
+        client->priv->search_socket = gssdp_socket_source_new
+                                        (GSSDP_SOCKET_SOURCE_TYPE_SEARCH,
+                                         gssdp_client_get_host_ip (client),
+                                         &internal_error);
+        if (client->priv->search_socket != NULL) {
+                gssdp_socket_source_set_callback
+                                        (client->priv->search_socket,
+                                         (GSourceFunc) search_socket_source_cb,
+                                         client);
         }
-
  errors:
         if (!client->priv->request_socket ||
             !client->priv->multicast_socket ||
-            !client->priv->send_socket) {
+            !client->priv->search_socket) {
                 g_propagate_error (error, internal_error);
 
                 if (client->priv->request_socket) {
@@ -254,10 +250,10 @@ gssdp_client_initable_init (GInitable     *initable,
                         client->priv->multicast_socket = NULL;
                 }
 
-                if (client->priv->send_socket) {
-                        g_object_unref (client->priv->send_socket);
+                if (client->priv->search_socket) {
+                        g_object_unref (client->priv->search_socket);
 
-                        client->priv->send_socket = NULL;
+                        client->priv->search_socket = NULL;
                 }
 
                 return FALSE;
@@ -269,6 +265,9 @@ gssdp_client_initable_init (GInitable     *initable,
         gssdp_socket_source_attach (client->priv->multicast_socket,
                                     client->priv->main_context);
 
+        gssdp_socket_source_attach (client->priv->search_socket,
+                                    client->priv->main_context);
+
         return TRUE;
 }
 
@@ -367,9 +366,9 @@ gssdp_client_dispose (GObject *object)
                 client->priv->multicast_socket = NULL;
         }
 
-        if (client->priv->send_socket) {
-                g_object_unref (client->priv->send_socket);
-                client->priv->send_socket = NULL;
+        if (client->priv->search_socket) {
+                g_object_unref (client->priv->search_socket);
+                client->priv->search_socket = NULL;
         }
 
         /* Unref the context */
@@ -736,19 +735,20 @@ gssdp_client_get_active (GSSDPClient *client)
  * Sends @message to @dest_ip.
  **/
 void
-_gssdp_client_send_message (GSSDPClient *client,
-                            const char  *dest_ip,
-                            gushort      dest_port,
-                            const char  *message)
+_gssdp_client_send_message (GSSDPClient      *client,
+                            const char       *dest_ip,
+                            gushort           dest_port,
+                            const char       *message,
+                            _GSSDPMessageType type)
 {
         gssize res;
         GError *error = NULL;
         GInetAddress *inet_address = NULL;
         GSocketAddress *address = NULL;
+        GSocket *socket;
 
         g_return_if_fail (GSSDP_IS_CLIENT (client));
         g_return_if_fail (message != NULL);
-        g_return_if_fail (client->priv->send_socket != NULL);
 
         if (!client->priv->active)
                 /* We don't send messages in passive mode */
@@ -762,10 +762,17 @@ _gssdp_client_send_message (GSSDPClient *client,
         if (dest_port == 0)
                 dest_port = SSDP_PORT;
 
+        if (type == _GSSDP_DISCOVERY_REQUEST)
+                socket = gssdp_socket_source_get_socket
+                                        (client->priv->search_socket);
+        else
+                socket = gssdp_socket_source_get_socket
+                                        (client->priv->request_socket);
+
         inet_address = g_inet_address_new_from_string (dest_ip);
         address = g_inet_socket_address_new (inet_address, dest_port);
 
-        res = g_socket_send_to (client->priv->send_socket,
+        res = g_socket_send_to (socket,
                                 address,
                                 message,
                                 strlen (message),
@@ -1058,6 +1065,18 @@ multicast_socket_source_cb (GIOChannel  *source,
         return socket_source_cb (client->priv->multicast_socket, client);
 }
 
+static gboolean
+search_socket_source_cb (GIOChannel  *source,
+                         GIOCondition condition,
+                         gpointer     user_data)
+{
+        GSSDPClient *client;
+
+        client = GSSDP_CLIENT (user_data);
+
+        return socket_source_cb (client->priv->search_socket, client);
+}
+
 #ifdef G_OS_WIN32
 static gboolean
 is_primary_adapter (PIP_ADAPTER_ADDRESSES adapter)
diff --git a/libgssdp/gssdp-resource-browser.c b/libgssdp/gssdp-resource-browser.c
index fcc9e85..c033ee1 100644
--- a/libgssdp/gssdp-resource-browser.c
+++ b/libgssdp/gssdp-resource-browser.c
@@ -932,7 +932,8 @@ send_discovery_request (GSSDPResourceBrowser *resource_browser)
         _gssdp_client_send_message (resource_browser->priv->client,
                                     NULL,
                                     0,
-                                    message);
+                                    message,
+                                    _GSSDP_DISCOVERY_REQUEST);
 
         g_free (message);
 }
diff --git a/libgssdp/gssdp-resource-group.c b/libgssdp/gssdp-resource-group.c
index ade83ba..fb5b164 100644
--- a/libgssdp/gssdp-resource-group.c
+++ b/libgssdp/gssdp-resource-group.c
@@ -922,7 +922,8 @@ discovery_response_timeout (gpointer user_data)
         _gssdp_client_send_message (client,
                                     response->dest_ip,
                                     response->dest_port,
-                                    message);
+                                    message,
+                                    _GSSDP_DISCOVERY_RESPONSE);
 
         g_free (message);
         g_free (date_str);
@@ -977,7 +978,8 @@ process_queue (gpointer data)
                 _gssdp_client_send_message (client,
                                             NULL,
                                             0,
-                                            message);
+                                            message,
+                                            _GSSDP_DISCOVERY_RESPONSE);
                 g_free (message);
 
                 return TRUE;
diff --git a/libgssdp/gssdp-socket-source.c b/libgssdp/gssdp-socket-source.c
index 830661e..14f56d3 100644
--- a/libgssdp/gssdp-socket-source.c
+++ b/libgssdp/gssdp-socket-source.c
@@ -240,8 +240,13 @@ gssdp_socket_source_do_init (GInitable     *initable,
                                                           SSDP_PORT);
 #endif
         } else {
+                guint port = SSDP_PORT;
+
+                /* Chose random port For the socket source used by M-SEARCH */
+                if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_SEARCH)
+                        port = 0;
                 bind_address = g_inet_socket_address_new (iface_address,
-                                                          SSDP_PORT);
+                                                          port);
         }
 
 #ifdef G_OS_WIN32
@@ -401,7 +406,7 @@ gssdp_socket_source_class_init (GSSDPSocketSourceClass *klass)
                          "Type",
                          "Type of socket-source (Multicast/Unicast)",
                          GSSDP_SOCKET_SOURCE_TYPE_REQUEST,
-                         GSSDP_SOCKET_SOURCE_TYPE_MULTICAST,
+                         GSSDP_SOCKET_SOURCE_TYPE_SEARCH,
                          GSSDP_SOCKET_SOURCE_TYPE_REQUEST,
                          G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
                          G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
diff --git a/libgssdp/gssdp-socket-source.h b/libgssdp/gssdp-socket-source.h
index 93a64a2..c464aeb 100644
--- a/libgssdp/gssdp-socket-source.h
+++ b/libgssdp/gssdp-socket-source.h
@@ -55,7 +55,8 @@ typedef struct _GSSDPSocketSourcePrivate GSSDPSocketSourcePrivate;
 
 typedef enum {
         GSSDP_SOCKET_SOURCE_TYPE_REQUEST,
-        GSSDP_SOCKET_SOURCE_TYPE_MULTICAST
+        GSSDP_SOCKET_SOURCE_TYPE_MULTICAST,
+        GSSDP_SOCKET_SOURCE_TYPE_SEARCH
 } GSSDPSocketSourceType;
 
 



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