[phodav: 3/4] avahi: advertise only on loopback



commit 62ac0a7ba30da3d720e548d051f63c761c68b116
Author: Jakub Janků <jjanku redhat com>
Date:   Wed Dec 25 17:34:32 2019 +0100

    avahi: advertise only on loopback
    
    If the service accepts connections only on loopback,
    we shouldn't advertise it on all interfaces.
    
    Fixes: https://gitlab.gnome.org/GNOME/phodav/issues/5
    
    Signed-off-by: Jakub Janků <jjanku redhat com>

 avahi-common.c        | 73 +++++++++++++++++++++++++++++++++++++++++++++++----
 avahi-common.h        |  2 +-
 libphodav/chezdav.c   |  2 +-
 spice/spice-webdavd.c |  2 +-
 4 files changed, 71 insertions(+), 8 deletions(-)
---
diff --git a/avahi-common.c b/avahi-common.c
index 9da1539..6732935 100644
--- a/avahi-common.c
+++ b/avahi-common.c
@@ -21,11 +21,68 @@
 #include <avahi-gobject/ga-client.h>
 #include <avahi-gobject/ga-entry-group.h>
 
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <errno.h>
+
 static GaClient *mdns_client;
 static GaEntryGroup *mdns_group;
 
 static const gchar *s_name;
 static guint s_port;
+static gboolean s_local;
+
+static gboolean
+ifaddr_is_loopback (struct ifaddrs *ifa)
+{
+  union {
+    struct sockaddr_in *in;
+    struct sockaddr_in6 *in6;
+  } sa;
+
+  if (!(ifa->ifa_flags & IFF_LOOPBACK))
+    return FALSE;
+
+  if (!ifa->ifa_addr)
+    return FALSE;
+
+  switch (ifa->ifa_addr->sa_family)
+    {
+      case AF_INET:
+        sa.in = (struct sockaddr_in *)(ifa->ifa_addr);
+        return sa.in->sin_addr.s_addr == g_htonl (0x7f000001); // 127.0.0.1
+      case AF_INET6:
+        sa.in6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
+        return IN6_IS_ADDR_LOOPBACK (&sa.in6->sin6_addr);
+    }
+  return FALSE;
+}
+
+static guint
+get_loopback_if_id ()
+{
+  struct ifaddrs *ifaddr, *ifa;
+  guint id = AVAHI_IF_UNSPEC;
+
+  if (getifaddrs (&ifaddr) == -1)
+    {
+      g_warning ("getifaddrs failed, using AVAHI_IF_UNSPEC: %s", g_strerror(errno));
+      return id;
+    }
+
+  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
+    {
+      if (ifaddr_is_loopback (ifa))
+        {
+          id = if_nametoindex (ifa->ifa_name);
+          break;
+        }
+    }
+
+  freeifaddrs (ifaddr);
+  return id;
+}
 
 static void
 mdns_register_service (void)
@@ -45,10 +102,15 @@ mdns_register_service (void)
         }
     }
 
-  mdns_service = ga_entry_group_add_service (mdns_group,
-                                             s_name, "_webdav._tcp",
-                                             s_port, &error,
-                                             NULL);
+  mdns_service =
+    ga_entry_group_add_service_full (mdns_group,
+                                     s_local ? get_loopback_if_id () : AVAHI_IF_UNSPEC,
+                                     AVAHI_PROTO_UNSPEC,
+                                     0,
+                                     s_name, "_webdav._tcp",
+                                     NULL, NULL,
+                                     s_port, &error,
+                                     NULL);
   if (!mdns_service)
     {
       g_warning ("Could not create service: %s", error->message);
@@ -116,13 +178,14 @@ mdns_state_changed (GaClient *client, GaClientState state, gpointer user_data)
 }
 
 gboolean
-avahi_client_start (const gchar *name, guint port, GError **error)
+avahi_client_start (const gchar *name, guint port, gboolean local, GError **error)
 {
   g_return_val_if_fail (mdns_client == NULL, FALSE);
 
   mdns_client = ga_client_new (GA_CLIENT_FLAG_NO_FLAGS);
   s_name = name;
   s_port = port;
+  s_local = local;
 
   g_signal_connect (mdns_client, "state-changed", G_CALLBACK (mdns_state_changed), NULL);
   return ga_client_start (mdns_client, error);
diff --git a/avahi-common.h b/avahi-common.h
index 4e7990b..a63c99e 100644
--- a/avahi-common.h
+++ b/avahi-common.h
@@ -17,5 +17,5 @@
 
 #include <glib-object.h>
 
-gboolean avahi_client_start (const gchar *name, guint port, GError **error);
+gboolean avahi_client_start (const gchar *name, guint port, gboolean local, GError **error);
 void avahi_client_stop ();
diff --git a/libphodav/chezdav.c b/libphodav/chezdav.c
index 9a5a98d..23e0e01 100644
--- a/libphodav/chezdav.c
+++ b/libphodav/chezdav.c
@@ -193,7 +193,7 @@ main (int argc, char *argv[])
 
 #ifdef WITH_AVAHI
   gchar *name = get_realm ();
-  if (!avahi_client_start (name, port, &error))
+  if (!avahi_client_start (name, port, local, &error))
     my_error (_ ("mDNS failed: %s\n"), error->message);
 #endif
 
diff --git a/spice/spice-webdavd.c b/spice/spice-webdavd.c
index 5830779..9868ea9 100644
--- a/spice/spice-webdavd.c
+++ b/spice/spice-webdavd.c
@@ -726,7 +726,7 @@ run_service (ServiceData *service_data)
 
 #ifdef WITH_AVAHI
   GError *error = NULL;
-  if (!avahi_client_start ("Spice client folder", port, &error))
+  if (!avahi_client_start ("Spice client folder", port, TRUE, &error))
     {
       g_printerr ("%s\n", error->message);
       exit (1);


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