]> git.meshlink.io Git - catta/commitdiff
* add new tool avahi-publish-address
authorLennart Poettering <lennart@poettering.net>
Sat, 30 Jul 2005 01:13:56 +0000 (01:13 +0000)
committerLennart Poettering <lennart@poettering.net>
Sat, 30 Jul 2005 01:13:56 +0000 (01:13 +0000)
* avahi-publish-service: fail after 12 collisions
* avahi-daemon: dump record data on SIGUSR1 to syslog
* avahi-core:
* improve dumping API
* shorten response history time to 500ms, infriniging the RFC but fixing ping-pong behaviour on RR registration
* remove gcc warning

git-svn-id: file:///home/lennart/svn/public/avahi/trunk@195 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

15 files changed:
avahi-core/announce.c
avahi-core/avahi-test.c
avahi-core/browse-domain.c
avahi-core/cache.c
avahi-core/cache.h
avahi-core/conformance-test.c
avahi-core/core.h
avahi-core/iface.c
avahi-core/iface.h
avahi-core/probe-sched.c
avahi-core/response-sched.c
avahi-core/server.c
avahi-daemon/main.c
avahi-utils/avahi-publish-address [new file with mode: 0755]
avahi-utils/avahi-publish-service

index 0b7af8dd083f6d7300384382a9e6e4ddb6e6701b..fe461de60804a4ca9fc7e9e32cb3ab23f6031d0d 100644 (file)
@@ -208,7 +208,7 @@ static void go_to_initial_state(AvahiAnnouncement *a, gboolean immediately) {
         
     g_assert(a);
     e = a->entry;
-    
+
     if ((e->flags & AVAHI_ENTRY_UNIQUE) && !(e->flags & AVAHI_ENTRY_NOPROBE))
         a->state = AVAHI_PROBING;
     else if (!(e->flags & AVAHI_ENTRY_NOANNOUNCE)) {
@@ -342,6 +342,8 @@ gboolean avahi_entry_probing(AvahiServer *s, AvahiEntry *e, AvahiInterface *i) {
 
     if (!(a = avahi_get_announcement(s, e, i)))
         return FALSE;
+
+/*     avahi_log_debug("state: %i", a->state); */
     
     return
         a->state == AVAHI_PROBING ||
index 669ca5b52157aa7138c88bd1921e0a5eca9be682..595393717c8f78879dc1a2e3c06770cac299f4c4 100644 (file)
@@ -40,9 +40,13 @@ static gboolean quit_timeout(gpointer data) {
     return FALSE;
 }
 
+static void dump_line(const gchar *text, gpointer userdata) {
+    printf("%s\n", text);
+}
+
 static gboolean dump_timeout(gpointer data) {
     AvahiServer *Avahi = data;
-    avahi_server_dump(Avahi, stdout);
+    avahi_server_dump(Avahi, dump_line, NULL);
     return TRUE;
 }
 
index 7a9561148504fcb5f789c5be589ca526e676415b..30745f62ea4709a76c1ee5ffcb510c86b74ff61b 100644 (file)
@@ -83,6 +83,10 @@ AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, gint interface
         case AVAHI_DOMAIN_BROWSER_BROWSE_LEGACY:
             n = g_strdup_printf("lb._dns-sd._udp.%s", b->domain_name);
             break;
+
+        case AVAHI_DOMAIN_BROWSER_MAX:
+            g_assert(FALSE);
+            break;
     }
 
     g_assert(n);
index 0a39194c7ae45e91474af523b7779acb61498dd3..7060433526548a087f43a93f238aa8f8a34207a0 100644 (file)
@@ -342,26 +342,39 @@ void avahi_cache_update(AvahiCache *c, AvahiRecord *r, gboolean cache_flush, con
 /*     g_free(txt);  */
 }
 
+struct dump_data {
+    AvahiDumpCallback callback;
+    gpointer userdata;
+};
+
 static void dump_callback(gpointer key, gpointer data, gpointer userdata) {
     AvahiCacheEntry *e = data;
     AvahiKey *k = key;
+    struct dump_data *dump_data = userdata;
 
     g_assert(k);
     g_assert(e);
+    g_assert(data);
 
     for (; e; e = e->by_key_next) {
         gchar *t = avahi_record_to_string(e->record);
-        fprintf((FILE*) userdata, "%s\n", t);
+        dump_data->callback(t, dump_data->userdata);
         g_free(t);
     }
 }
 
-void avahi_cache_dump(AvahiCache *c, FILE *f) {
+void avahi_cache_dump(AvahiCache *c, AvahiDumpCallback callback, gpointer userdata) {
+    struct dump_data data;
+
     g_assert(c);
-    g_assert(f);
+    g_assert(callback);
+
+    callback(";;; CACHE DUMP FOLLOWS ;;;", userdata);
+
+    data.callback = callback;
+    data.userdata = userdata;
 
-    fprintf(f, ";;; CACHE DUMP FOLLOWS ;;;\n");
-    g_hash_table_foreach(c->hash_table, dump_callback, f);
+    g_hash_table_foreach(c->hash_table, dump_callback, &data);
 }
 
 gboolean avahi_cache_entry_half_ttl(AvahiCache *c, AvahiCacheEntry *e) {
index e4bdbc4f83f2b506e8d9b37ed10361e0ec1f756a..b6e3e8addf70cb7829e61f09475f4f15bfa6711b 100644 (file)
@@ -77,7 +77,7 @@ AvahiCacheEntry *avahi_cache_lookup_record(AvahiCache *c, AvahiRecord *r);
 
 void avahi_cache_update(AvahiCache *c, AvahiRecord *r, gboolean cache_flush, const AvahiAddress *a);
 
-void avahi_cache_dump(AvahiCache *c, FILE *f);
+void avahi_cache_dump(AvahiCache *c, AvahiDumpCallback callback, gpointer userdata);
 
 typedef gpointer AvahiCacheWalkCallback(AvahiCache *c, AvahiKey *pattern, AvahiCacheEntry *e, gpointer userdata);
 gpointer avahi_cache_walk(AvahiCache *c, AvahiKey *pattern, AvahiCacheWalkCallback cb, gpointer userdata);
index e8309825bbe1294f59e222e42199701d90074816..f7eba12a06bd1b94097db5eb94f1fb6d16b81ae4 100644 (file)
@@ -39,8 +39,12 @@ static AvahiEntryGroup *group = NULL;
 static int try = 0;
 static AvahiServer *avahi = NULL;
 
+static void dump_line(const gchar *text, gpointer userdata) {
+    printf("%s\n", text);
+}
+
 static gboolean dump_timeout(gpointer data) {
-    avahi_server_dump(avahi, stdout);
+    avahi_server_dump(avahi, dump_line, NULL);
     return TRUE;
 }
 
@@ -96,7 +100,7 @@ int main(int argc, char *argv[]) {
 
     avahi = avahi_server_new(NULL, NULL, server_callback, NULL);
     create_service("gurke");
-    avahi_server_dump(avahi, stdout);
+    avahi_server_dump(avahi, dump_line, NULL);
     
     loop = g_main_loop_new(NULL, FALSE);
     g_timeout_add(1000*5, dump_timeout, avahi);
index 39a1db6d7f4cede07d8abfb02502059866cc610f..dbbd55572e33d840c66505078a562c710e86c2da 100644 (file)
@@ -171,8 +171,11 @@ AvahiServerState avahi_server_get_state(AvahiServer *s);
  * has been read, NULL is returned. */
 const AvahiRecord *avahi_server_iterate(AvahiServer *s, AvahiEntryGroup *g, void **state);
 
-/** Dump the current server status to the specified FILE object */
-void avahi_server_dump(AvahiServer *s, FILE *f);
+/** Callback prototype for avahi_server_dump() */
+typedef void (*AvahiDumpCallback)(const gchar *text, gpointer userdata);
+
+/** Dump the current server status by calling "callback" for each line.  */
+void avahi_server_dump(AvahiServer *s, AvahiDumpCallback callback, gpointer userdata);
 
 /** Create a new entry group. The specified callback function is
  * called whenever the state of the group changes. Use entry group
index 070ef6a33620366f585349b36e5cd2798e0d213a..d068f28fce0ca253286bd39c98e56a88ff94bfee 100644 (file)
@@ -600,17 +600,18 @@ gboolean avahi_interface_post_probe(AvahiInterface *i, AvahiRecord *record, gboo
     return FALSE;
 }
 
-void avahi_dump_caches(AvahiInterfaceMonitor *m, FILE *f) {
+void avahi_dump_caches(AvahiInterfaceMonitor *m, AvahiDumpCallback callback, gpointer userdata) {
     AvahiInterface *i;
     g_assert(m);
 
     for (i = m->interfaces; i; i = i->interface_next) {
         if (avahi_interface_relevant(i)) {
-            fprintf(f, "\n;;; INTERFACE %s.%i ;;;\n", i->hardware->name, i->protocol);
-            avahi_cache_dump(i->cache, f);
+            char ln[256];
+            snprintf(ln, sizeof(ln), ";;; INTERFACE %s.%i ;;;", i->hardware->name, i->protocol);
+            callback(ln, userdata);
+            avahi_cache_dump(i->cache, callback, userdata);
         }
     }
-    fprintf(f, "\n");
 }
 
 gboolean avahi_interface_relevant(AvahiInterface *i) {
index 486207e0c4e275e1973b51fba118e21dce39d84a..33d20f05d6f575984905139f5d908b1ece49928c 100644 (file)
@@ -122,7 +122,7 @@ gboolean avahi_interface_post_query(AvahiInterface *i, AvahiKey *k, gboolean imm
 gboolean avahi_interface_post_response(AvahiInterface *i, AvahiRecord *record, gboolean flush_cache, const AvahiAddress *querier, gboolean immediately);
 gboolean avahi_interface_post_probe(AvahiInterface *i, AvahiRecord *p, gboolean immediately);
 
-void avahi_dump_caches(AvahiInterfaceMonitor *m, FILE *f);
+void avahi_dump_caches(AvahiInterfaceMonitor *m, AvahiDumpCallback callback, gpointer userdata);
 
 gboolean avahi_interface_relevant(AvahiInterface *i);
 gboolean avahi_interface_address_relevant(AvahiInterfaceAddress *a);
index 0e36bb4fc305944c39442e7f2f0f71caedfdf5d6..d9c659964af4e8d2ff15a44952fff1f4454528a1 100644 (file)
@@ -352,7 +352,7 @@ gboolean avahi_probe_scheduler_post(AvahiProbeScheduler *s, AvahiRecord *record,
 
     if ((pj = find_history_job(s, record)))
         return FALSE;
-    
+
     avahi_elapse_time(&tv, immediately ? 0 : AVAHI_PROBE_DEFER_MSEC, 0);
 
     if ((pj = find_scheduled_job(s, record))) {
index 1e763e6366cb4beeae9455b60e21e7cad858e810..6d1269e2e97c57299c215d4919ae07cf0e3b1b47 100644 (file)
@@ -27,7 +27,7 @@
 #include "util.h"
 #include "log.h"
 
-#define AVAHI_RESPONSE_HISTORY_MSEC 700
+#define AVAHI_RESPONSE_HISTORY_MSEC 500
 #define AVAHI_RESPONSE_DEFER_MSEC 20
 #define AVAHI_RESPONSE_JITTER_MSEC 100
 #define AVAHI_RESPONSE_SUPPRESS_MSEC 700
@@ -284,7 +284,9 @@ static AvahiResponseJob* find_history_job(AvahiResponseScheduler *s, AvahiRecord
         if (avahi_record_equal_no_ttl(rj->record, record)) {
             /* Check whether this entry is outdated */
 
-            if (avahi_age(&rj->delivery) > AVAHI_RESPONSE_HISTORY_MSEC*1000) {
+/*             avahi_log_debug("history age: %u", (unsigned) (avahi_age(&rj->delivery)/1000)); */
+            
+            if (avahi_age(&rj->delivery)/1000 > AVAHI_RESPONSE_HISTORY_MSEC) {
                 /* it is outdated, so let's remove it */
                 job_free(s, rj);
                 return NULL;
@@ -328,19 +330,24 @@ static AvahiResponseJob* find_suppressed_job(AvahiResponseScheduler *s, AvahiRec
 gboolean avahi_response_scheduler_post(AvahiResponseScheduler *s, AvahiRecord *record, gboolean flush_cache, const AvahiAddress *querier, gboolean immediately) {
     AvahiResponseJob *rj;
     GTimeVal tv;
+/*     gchar *t; */
     
     g_assert(s);
     g_assert(record);
 
     g_assert(!avahi_key_is_pattern(record->key));
 
+/*     t = avahi_record_to_string(record); */
+/*     avahi_log_debug("post %i %s", immediately, t); */
+/*     g_free(t); */
+
     /* Check whether this response is suppressed */
     if (querier &&
         (rj = find_suppressed_job(s, record, querier)) &&
         avahi_record_is_goodbye(record) == avahi_record_is_goodbye(rj->record) &&
         rj->record->ttl >= record->ttl/2) {
 
-/*         avahi_log_debug("Response suppressed by known answer suppression."); */
+/*         avahi_log_debug("Response suppressed by known answer suppression.");  */
         return FALSE;
     }
 
@@ -350,7 +357,7 @@ gboolean avahi_response_scheduler_post(AvahiResponseScheduler *s, AvahiRecord *r
         if (avahi_record_is_goodbye(record) == avahi_record_is_goodbye(rj->record) &&
             rj->record->ttl >= record->ttl/2 &&
             (rj->flush_cache || !flush_cache)) {
-/*             avahi_log_debug("Response suppressed by local duplicate suppression (history)"); */
+/*             avahi_log_debug("Response suppressed by local duplicate suppression (history)");  */
             return FALSE;
         }
 
@@ -361,7 +368,7 @@ gboolean avahi_response_scheduler_post(AvahiResponseScheduler *s, AvahiRecord *r
     avahi_elapse_time(&tv, immediately ? 0 : AVAHI_RESPONSE_DEFER_MSEC, immediately ? 0 : AVAHI_RESPONSE_JITTER_MSEC);
          
     if ((rj = find_scheduled_job(s, record))) {
-/*         avahi_log_debug("Response suppressed by local duplicate suppression (scheduled)"); */
+/*          avahi_log_debug("Response suppressed by local duplicate suppression (scheduled)"); */
 
         /* Update a little ... */
 
@@ -385,7 +392,7 @@ gboolean avahi_response_scheduler_post(AvahiResponseScheduler *s, AvahiRecord *r
 
         return TRUE;
     } else {
-/*         avahi_log_debug("Accepted new response job."); */
+/*         avahi_log_debug("Accepted new response job.");  */
 
         /* Create a new job and schedule it */
         rj = job_new(s, record, AVAHI_SCHEDULED);
index b3ab0090fc176a0ec7e7ad6909e02443ff5b98d4..d63f5eca557a13d0c7b85e20f4657fbac856f2c8 100644 (file)
@@ -223,6 +223,10 @@ static void incoming_probe(AvahiServer *s, AvahiRecord *record, AvahiInterface *
     g_assert(record);
     g_assert(i);
 
+    t = avahi_record_to_string(record);
+
+/*     avahi_log_debug("incoming_probe()");  */
+
     for (e = g_hash_table_lookup(s->entries_by_key, record->key); e; e = n) {
         gint cmp;
         n = e->by_key_next;
@@ -244,8 +248,6 @@ static void incoming_probe(AvahiServer *s, AvahiRecord *record, AvahiInterface *
         }
     }
 
-    t = avahi_record_to_string(record);
-
     if (!ours) {
 
         if (won)
@@ -253,7 +255,8 @@ static void incoming_probe(AvahiServer *s, AvahiRecord *record, AvahiInterface *
         else if (lost) {
             avahi_log_debug("Recieved conflicting probe [%s]. Local host lost. Withdrawing.", t);
             withdraw_rrset(s, record->key);
-        }
+        }/*  else */
+/*             avahi_log_debug("Not conflicting probe"); */
     }
 
     g_free(t);
@@ -334,7 +337,7 @@ static gboolean handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *
             avahi_log_debug("Recieved conflicting record [%s]. Resetting our record.", t);
             avahi_entry_return_to_initial_state(s, conflicting_entry, i);
 
-            /* Local unique records are returned to probin
+            /* Local unique records are returned to probing
              * state. Local shared records are reannounced. */
         }
 
@@ -1527,25 +1530,29 @@ const AvahiRecord *avahi_server_iterate(AvahiServer *s, AvahiEntryGroup *g, void
     return avahi_record_ref((*e)->record);
 }
 
-void avahi_server_dump(AvahiServer *s, FILE *f) {
+void avahi_server_dump(AvahiServer *s, AvahiDumpCallback callback, gpointer userdata) {
     AvahiEntry *e;
+    
     g_assert(s);
-    g_assert(f);
+    g_assert(callback);
 
-    fprintf(f, "\n;;; ZONE DUMP FOLLOWS ;;;\n");
+    callback(";;; ZONE DUMP FOLLOWS ;;;", userdata);
 
     for (e = s->entries; e; e = e->entries_next) {
         gchar *t;
+        gchar ln[256];
 
         if (e->dead)
             continue;
         
         t = avahi_record_to_string(e->record);
-        fprintf(f, "%s ; iface=%i proto=%i\n", t, e->interface, e->protocol);
+        snprintf(ln, sizeof(ln), "%s ; iface=%i proto=%i", t, e->interface, e->protocol);
         g_free(t);
+
+        callback(ln, userdata);
     }
 
-    avahi_dump_caches(s->monitor, f);
+    avahi_dump_caches(s->monitor, callback, userdata);
 }
 
 gint avahi_server_add_ptr(
index bc99926818ce432052d47d78787ed60227c9c9fa..059ebe5e44fa5bcaa6fe8bfcc8998760d4b022f8 100644 (file)
@@ -443,6 +443,10 @@ static void log_function(AvahiLogLevel level, const gchar *txt) {
     daemon_log(log_level_map[level], "%s", txt);
 }
 
+static void dump(const gchar *text, gpointer userdata) {
+    avahi_log_info("%s", text);
+}
+
 static gboolean signal_callback(GIOChannel *source, GIOCondition condition, gpointer data) {
     gint sig;
     GMainLoop *loop = data;
@@ -483,6 +487,11 @@ static gboolean signal_callback(GIOChannel *source, GIOCondition condition, gpoi
 
             break;
 
+        case SIGUSR1:
+            avahi_log_info("Got SIGUSR1, dumping record data.");
+            avahi_server_dump(avahi_server, dump, NULL);
+            break;
+
         default:
             avahi_log_warn("Got spurious signal, ignoring.");
             break;
@@ -501,7 +510,7 @@ static gint run_server(DaemonConfig *config) {
     
     loop = g_main_loop_new(NULL, FALSE);
 
-    if (daemon_signal_init(SIGINT, SIGQUIT, SIGHUP, SIGTERM, 0) < 0) {
+    if (daemon_signal_init(SIGINT, SIGQUIT, SIGHUP, SIGTERM, SIGUSR1, 0) < 0) {
         avahi_log_error("Could not register signal handlers (%s).", strerror(errno));
         goto finish;
     }
diff --git a/avahi-utils/avahi-publish-address b/avahi-utils/avahi-publish-address
new file mode 100755 (executable)
index 0000000..dce00bd
--- /dev/null
@@ -0,0 +1,73 @@
+#!/usr/bin/python2.4
+# -*-python-*-
+# $Id$
+
+import avahi, dbus, gobject, sys, getopt, string
+
+try:
+    import dbus.glib
+except ImportError, e:
+    pass
+
+def usage(retval = 0):
+    print "%s <name> <address>" % sys.argv[0]
+    sys.exit(retval)
+
+if len(sys.argv) != 3:
+    usage(2)
+
+name = sys.argv[1]
+address = sys.argv[2]
+
+group = None
+n_rename = 0
+
+def remove_address():
+    global group
+    
+    if not (group is None):
+        group.Free()
+        group = None
+
+def add_address():
+    global server, group, name, address
+    assert group is None
+
+    print "Adding address '%s' for '%s' ..." % (name, address)
+    group = dbus.Interface(bus.get_object("org.freedesktop.Avahi", server.EntryGroupNew()), 'org.freedesktop.Avahi.EntryGroup')
+    group.connect_to_signal('StateChanged', entry_group_state_changed)
+    group.AddAddress(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, name, address)
+    group.Commit()
+
+def entry_group_state_changed(state):
+    global name, server, n_rename, main_loop
+    
+    if state == avahi.ENTRY_GROUP_ESTABLISHED:
+        print "Address established."
+    elif state == avahi.ENTRY_GROUP_COLLISION:
+
+        n_rename = n_rename + 1
+        if n_rename >= 12:
+            print "ERROR: No suitable name found after %i retries, exiting." % n_rename
+            main_loop.quit()
+        else:
+            hn = name.split('.')
+            hn[0] = server.GetAlternativeHostName(hn[0])
+            name = string.join(hn, '.')
+            print "WARNING: Address/host name collision, changing name to '%s' ..." % name
+            remove_address()
+            add_address()
+
+main_loop = gobject.MainLoop()
+
+bus = dbus.SystemBus()
+server = dbus.Interface(bus.get_object("org.freedesktop.Avahi", '/org/freedesktop/Avahi/Server'), 'org.freedesktop.Avahi.Server')
+
+add_address()
+
+try:
+    main_loop.run()
+except KeyboardInterrupt, k:
+    pass
+
+remove_address()
index 4375d1a3dcc4f8c477a9eece1efeafc3cd471535..376df346c717eb3ba2ee457e543cba8d85dcd333 100755 (executable)
@@ -48,6 +48,7 @@ if len(txt) == 0:
     txt.append("python-dbus=brain-damage")
 
 group = None
+n_rename = 0
 
 def remove_service():
     global group
@@ -57,27 +58,31 @@ def remove_service():
         group = None
 
 def add_service():
-    global group, name, stype, domain, host, port, txt
-
+    global server, group, name, stype, domain, host, port, txt
     assert group is None
 
-    print "Adding service '%s' of type '%s' ..." % (name, args[1])
-    
+    print "Adding service '%s' of type '%s' ..." % (name, stype)
     group = dbus.Interface(bus.get_object("org.freedesktop.Avahi", server.EntryGroupNew()), 'org.freedesktop.Avahi.EntryGroup')
     group.connect_to_signal('StateChanged', entry_group_state_changed)
     group.AddService(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, name, stype, domain, host, dbus.UInt16(port), txt)
     group.Commit()
 
 def entry_group_state_changed(state):
-    global name, server
+    global name, server, n_rename
     
     if state == avahi.ENTRY_GROUP_ESTABLISHED:
         print "Service established."
     elif state == avahi.ENTRY_GROUP_COLLISION:
-        name = server.GetAlternativeServiceName(name)
-        print "WARNING: Service name collision, changing name to '%s' ..." % name
-        remove_service()
-        add_service()
+
+        n_rename = n_rename + 1
+        if n_rename >= 12:
+            print "ERROR: No suitable service name found after %i retries, exiting." % n_rename
+            main_loop.quit()
+        else:
+            name = server.GetAlternativeServiceName(name)
+            print "WARNING: Service name collision, changing name to '%s' ..." % name
+            remove_service()
+            add_service()
 
 def server_state_changed(state):
     if state == avahi.SERVER_COLLISION:
@@ -86,13 +91,15 @@ def server_state_changed(state):
     elif state == avahi.SERVER_RUNNING:
         add_service()
 
+main_loop = gobject.MainLoop()
+
 bus = dbus.SystemBus()
 server = dbus.Interface(bus.get_object("org.freedesktop.Avahi", '/org/freedesktop/Avahi/Server'), 'org.freedesktop.Avahi.Server')
 server.connect_to_signal("StateChanged", server_state_changed)
 server_state_changed(server.GetState())
 
 try:
-    gobject.MainLoop().run()
+    main_loop.run()
 except KeyboardInterrupt, k:
     pass