]> git.meshlink.io Git - catta/commitdiff
add support for RR modification in service data
authorLennart Poettering <lennart@poettering.net>
Sun, 21 Aug 2005 20:03:50 +0000 (20:03 +0000)
committerLennart Poettering <lennart@poettering.net>
Sun, 21 Aug 2005 20:03:50 +0000 (20:03 +0000)
git-svn-id: file:///home/lennart/svn/public/avahi/trunk@386 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

avahi-core/browse.c
avahi-core/browse.h
avahi-core/resolve-service.c
avahi-core/response-sched.c

index 5b873264468b0474a86d72244e1c1e2c901e31a8..fa97c351b89d04072fb7aa91fb9b42c86c9fb007 100644 (file)
@@ -126,6 +126,17 @@ static void scan_callback(AvahiTimeEvent *e, void *userdata) {
     }
 }
 
+void avahi_s_record_browser_restart(AvahiSRecordBrowser *b) {
+    assert(b);
+
+    if (!b->scan_time_event) {
+        b->scan_time_event = avahi_time_event_new(b->server->time_event_queue, NULL, scan_callback, b);
+        assert(b->scan_time_event);
+    }
+
+    avahi_server_post_query(b->server, b->interface, b->protocol, b->key);
+}
+
 AvahiSRecordBrowser *avahi_s_record_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, AvahiKey *key, AvahiSRecordBrowserCallback callback, void* userdata) {
     AvahiSRecordBrowser *b, *t;
     struct timeval tv;
index a38075eb36ddb235c48e87b91185bcf577438168..0d1cdb881e9123b058c5828c481464ed8c8563cc 100644 (file)
@@ -34,6 +34,8 @@ int avahi_is_subscribed(AvahiServer *s, AvahiInterface *i, AvahiKey *k);
 
 void avahi_s_record_browser_destroy(AvahiSRecordBrowser *b);
 
+void avahi_s_record_browser_restart(AvahiSRecordBrowser *b);
+
 void avahi_browser_new_interface(AvahiServer*s, AvahiInterface *i);
 
 #endif
index 141df9e11364a1b2221b2125a59dac5f86d496f5..347de777bc9280c6138fef2296532005c03e50b2 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #include <avahi-common/domain.h>
 #include <avahi-common/timeval.h>
@@ -33,6 +34,8 @@
 
 #include "browse.h"
 
+#define TIMEOUT_MSEC 1000
+
 struct AvahiSServiceResolver {
     AvahiServer *server;
     char *service_name;
@@ -61,26 +64,6 @@ struct AvahiSServiceResolver {
 static void finish(AvahiSServiceResolver *r, AvahiResolverEvent event) {
     assert(r);
 
-    if (r->record_browser_a) {
-        avahi_s_record_browser_free(r->record_browser_a);
-        r->record_browser_a = NULL;
-    }
-
-    if (r->record_browser_aaaa) {
-        avahi_s_record_browser_free(r->record_browser_aaaa);
-        r->record_browser_aaaa = NULL;
-    }
-
-    if (r->record_browser_srv) {
-        avahi_s_record_browser_free(r->record_browser_srv);
-        r->record_browser_srv = NULL;
-    }
-
-    if (r->record_browser_txt) {
-        avahi_s_record_browser_free(r->record_browser_txt);
-        r->record_browser_txt = NULL;
-    }
-
     if (r->time_event) {
         avahi_time_event_free(r->time_event);
         r->time_event = NULL;
@@ -125,6 +108,26 @@ static void finish(AvahiSServiceResolver *r, AvahiResolverEvent event) {
     }
 }
 
+static void time_event_callback(AvahiTimeEvent *e, void *userdata) {
+    AvahiSServiceResolver *r = userdata;
+    
+    assert(e);
+    assert(r);
+
+    finish(r, AVAHI_RESOLVER_TIMEOUT);
+}
+
+static void start_timeout(AvahiSServiceResolver *r) {
+    struct timeval tv;
+    assert(r);
+
+    if (r->time_event)
+        return;
+    
+    avahi_elapse_time(&tv, TIMEOUT_MSEC, 0);
+    r->time_event = avahi_time_event_new(r->server->time_event_queue, &tv, time_event_callback, r);
+}
+
 static void record_browser_callback(AvahiSRecordBrowser*rr, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, AvahiRecord *record, void* userdata) {
     AvahiSServiceResolver *r = userdata;
 
@@ -132,74 +135,120 @@ static void record_browser_callback(AvahiSRecordBrowser*rr, AvahiIfIndex interfa
     assert(record);
     assert(r);
 
-    if (!(event == AVAHI_BROWSER_NEW))
-        return;
+    if (event == AVAHI_BROWSER_NEW) {
+        int changed = 0;
 
-    if (r->interface > 0 && interface != r->interface)
-        return;
+        if (r->interface > 0 && interface != r->interface)
+            return;
+        
+        if (r->protocol != AVAHI_PROTO_UNSPEC && protocol != r->protocol)
+            return;
+        
+        if (r->interface <= 0)
+            r->interface = interface;
+        
+        if (r->protocol == AVAHI_PROTO_UNSPEC)
+            r->protocol = protocol;
+        
+        switch (record->key->type) {
+            case AVAHI_DNS_TYPE_SRV:
+                if (!r->srv_record) {
+                    r->srv_record = avahi_record_ref(record);
+                    changed = 1;
+                    
+                    assert(!r->record_browser_a && !r->record_browser_aaaa);
+                    
+                    if (r->address_protocol == AVAHI_PROTO_INET || r->address_protocol == AVAHI_PROTO_UNSPEC) {
+                        AvahiKey *k = avahi_key_new(r->srv_record->data.srv.name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A);
+                        r->record_browser_a = avahi_s_record_browser_new(r->server, r->interface, r->protocol, k, record_browser_callback, r);
+                        avahi_key_unref(k);
+                    } 
+                    
+                    if (r->address_protocol == AVAHI_PROTO_INET6 || r->address_protocol == AVAHI_PROTO_UNSPEC) {
+                        AvahiKey *k = avahi_key_new(r->srv_record->data.srv.name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA);
+                        r->record_browser_aaaa = avahi_s_record_browser_new(r->server, r->interface, r->protocol, k, record_browser_callback, r);
+                        avahi_key_unref(k);
+                    }
+                }
+                break;
+                
+            case AVAHI_DNS_TYPE_TXT:
+                if (!r->txt_record) {
+                    r->txt_record = avahi_record_ref(record);
+                    changed = 1;
+                }
+                break;
+                
+            case AVAHI_DNS_TYPE_A:
+            case AVAHI_DNS_TYPE_AAAA:
+                if (!r->address_record) {
+                    r->address_record = avahi_record_ref(record);
+                    changed = 1;
+                }
+                break;
+                
+            default:
+                abort();
+        }
 
-    if (r->protocol != AVAHI_PROTO_UNSPEC && protocol != r->protocol)
-        return;
-    
-    if (r->interface <= 0)
-        r->interface = interface;
 
-    if (r->protocol == AVAHI_PROTO_UNSPEC)
-        r->protocol = protocol;
-    
-    switch (record->key->type) {
-        case AVAHI_DNS_TYPE_SRV:
-            if (!r->srv_record) {
-                r->srv_record = avahi_record_ref(record);
+        if (changed && r->txt_record && r->srv_record && r->address_record)
+            finish(r, AVAHI_RESOLVER_FOUND);
 
-                assert(!r->record_browser_a && !r->record_browser_aaaa);
-                
-                if (r->address_protocol == AVAHI_PROTO_INET || r->address_protocol == AVAHI_PROTO_UNSPEC) {
-                    AvahiKey *k = avahi_key_new(r->srv_record->data.srv.name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A);
-                    r->record_browser_a = avahi_s_record_browser_new(r->server, r->interface, r->protocol, k, record_browser_callback, r);
-                    avahi_key_unref(k);
-                } 
+    } else {
+        assert(event == AVAHI_BROWSER_REMOVE);
+
+        switch (record->key->type) {
+            case AVAHI_DNS_TYPE_SRV:
+
+                if (avahi_record_equal_no_ttl(record, r->srv_record)) {
+                    avahi_record_unref(r->srv_record);
+                    r->srv_record = NULL;
+
+                    /** Look for a replacement */
+                    avahi_s_record_browser_restart(r->record_browser_srv);
+                    start_timeout(r);
+                }
                 
-                if (r->address_protocol == AVAHI_PROTO_INET6 || r->address_protocol == AVAHI_PROTO_UNSPEC) {
-                    AvahiKey *k = avahi_key_new(r->srv_record->data.srv.name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA);
-                    r->record_browser_aaaa = avahi_s_record_browser_new(r->server, r->interface, r->protocol, k, record_browser_callback, r);
-                    avahi_key_unref(k);
+                break;
+
+            case AVAHI_DNS_TYPE_TXT:
+
+                if (avahi_record_equal_no_ttl(record, r->txt_record)) {
+                    avahi_record_unref(r->txt_record);
+                    r->txt_record = NULL;
+
+                    /** Look for a replacement */
+                    avahi_s_record_browser_restart(r->record_browser_txt);
+                    start_timeout(r);
                 }
-            }
-            break;
-            
-        case AVAHI_DNS_TYPE_TXT:
-            if (!r->txt_record)
-                r->txt_record = avahi_record_ref(record);
-            break;
-
-        case AVAHI_DNS_TYPE_A:
-        case AVAHI_DNS_TYPE_AAAA:
-            if (!r->address_record)
-                r->address_record = avahi_record_ref(record);
-            break;
-            
-        default:
-            assert(0);
-    }
+                break;
 
-    if (r->txt_record && r->srv_record && r->address_record)
-        finish(r, AVAHI_RESOLVER_FOUND);
-}
+            case AVAHI_DNS_TYPE_A:
+            case AVAHI_DNS_TYPE_AAAA:
 
-static void time_event_callback(AvahiTimeEvent *e, void *userdata) {
-    AvahiSServiceResolver *r = userdata;
-    
-    assert(e);
-    assert(r);
+                if (avahi_record_equal_no_ttl(record, r->address_record)) {
+                    avahi_record_unref(r->address_record);
+                    r->address_record = NULL;
 
-    finish(r, AVAHI_RESOLVER_TIMEOUT);
+                    /** Look for a replacement */
+                    if (r->record_browser_aaaa)
+                        avahi_s_record_browser_restart(r->record_browser_aaaa);
+                    if (r->record_browser_a)
+                        avahi_s_record_browser_restart(r->record_browser_a);
+                    start_timeout(r);
+                }
+                break;
+
+            default:
+                abort();
+        }
+    }
 }
 
 AvahiSServiceResolver *avahi_s_service_resolver_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char *domain, AvahiProtocol aprotocol, AvahiSServiceResolverCallback callback, void* userdata) {
     AvahiSServiceResolver *r;
     AvahiKey *k;
-    struct timeval tv;
     char t[256], *n;
     size_t l;
     
@@ -246,8 +295,8 @@ AvahiSServiceResolver *avahi_s_service_resolver_new(AvahiServer *server, AvahiIf
     avahi_escape_label((const uint8_t*) name, strlen(name), &n, &l);
     snprintf(n, l, ".%s.%s", r->service_type, r->domain_name);
 
-    avahi_elapse_time(&tv, 1000, 0);
-    r->time_event = avahi_time_event_new(server->time_event_queue, &tv, time_event_callback, r);
+    r->time_event = NULL;
+    start_timeout(r);
     
     AVAHI_LLIST_PREPEND(AvahiSServiceResolver, resolver, server->service_resolvers, r);
 
index 08598fc983f0707197945b781e5f4ada8bd711c4..6bc48cad55d80d3b518bafa7d5c682c624b0b99a 100644 (file)
 #include "response-sched.h"
 #include "log.h"
 
+/* Local packets are supressed this long after sending them */
 #define AVAHI_RESPONSE_HISTORY_MSEC 500
+
+/* Local packets are deferred this long before sending them */
 #define AVAHI_RESPONSE_DEFER_MSEC 20
+
+/* Additional jitter for deferred packets */
 #define AVAHI_RESPONSE_JITTER_MSEC 100
+
+/* Remote packets can suppress local traffic as long as this value */
 #define AVAHI_RESPONSE_SUPPRESS_MSEC 700
 
 typedef struct AvahiResponseJob AvahiResponseJob;