]> git.meshlink.io Git - catta/commitdiff
* correctly build probe packets
authorLennart Poettering <lennart@poettering.net>
Tue, 3 May 2005 21:22:52 +0000 (21:22 +0000)
committerLennart Poettering <lennart@poettering.net>
Tue, 3 May 2005 21:22:52 +0000 (21:22 +0000)
* fix conflict detection
* correctly handle FLUSH bit in incoming packets
* drop whole group when one record conflicts
* remove wrong TRUE/FALSE usage in flx_server_add_service_va()
* fix wrong pass-through in switch satetement in rr.c

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

announce.c
dns.c
main.c
psched.c
rr.c
server.c
server.h

index 1dae47391b3dd74cba9700ef4e10b4952148337c..613d10d99cb4589d02f0847217fd8bea4bccaf6a 100644 (file)
@@ -49,7 +49,7 @@ void flx_entry_group_check_probed(flxEntryGroup *g, gboolean immediately) {
     if (g->state != FLX_ENTRY_GROUP_REGISTERING || g->n_probing > 0) 
         return;
 
-    flx_entry_group_run_callback(g, g->state = FLX_ENTRY_GROUP_ESTABLISHED);
+    flx_entry_group_change_state(g, FLX_ENTRY_GROUP_ESTABLISHED);
 
     if (g->dead)
         return;
@@ -367,11 +367,10 @@ void flx_goodbye_interface(flxServer *s, flxInterface *i, gboolean goodbye) {
 void flx_goodbye_entry(flxServer *s, flxEntry *e, gboolean goodbye) {
     g_assert(s);
     g_assert(e);
-    g_assert(!e->dead);
     
     g_message("goodbye entry: %p", e);
     
-    if (goodbye)
+    if (goodbye && !e->dead)
         flx_interface_monitor_walk(s->monitor, 0, AF_UNSPEC, send_goodbye_callback, e);
 
     while (e->announcements)
diff --git a/dns.c b/dns.c
index a402e298815a524f8c8b3a2963e2ba2ed9ece757..3f508271672e19584fe1bbab230492d294ae8df5 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -482,9 +482,12 @@ flxRecord* flx_dns_packet_consume_record(flxDnsPacket *p, gboolean *ret_cache_fl
         goto fail;
 
 /*     g_message("name = %s, rdlength = %u", name, rdlength); */
+
+    *ret_cache_flush = !!(class & FLX_DNS_CACHE_FLUSH);
+    class &= ~ FLX_DNS_CACHE_FLUSH;
     
     start = flx_dns_packet_get_rptr(p);
-
+    
     r = flx_record_new_full(name, class, type);
     
     switch (type) {
@@ -581,9 +584,6 @@ flxRecord* flx_dns_packet_consume_record(flxDnsPacket *p, gboolean *ret_cache_fl
     if ((guint8*) flx_dns_packet_get_rptr(p) - (guint8*) start != rdlength)
         goto fail;
     
-    *ret_cache_flush = !!(class & FLX_DNS_CACHE_FLUSH);
-    class &= ~ FLX_DNS_CACHE_FLUSH;
-
     r->ttl = ttl;
 
     return r;
diff --git a/main.c b/main.c
index 82e7090528a9ade39e6040e7ac4a2e9b4694c963..987df2253758522dea68a47c7609234786589773 100644 (file)
--- a/main.c
+++ b/main.c
@@ -60,8 +60,8 @@ int main(int argc, char *argv[]) {
 
     loop = g_main_loop_new(NULL, FALSE);
     
-    g_timeout_add(1000*20, dump_timeout, flx);
-    g_timeout_add(1000*30, quit_timeout, loop);
+  /*   g_timeout_add(1000*20, dump_timeout, flx); */
+/*     g_timeout_add(1000*30, quit_timeout, loop); */
     
     g_main_loop_run(loop);
     g_main_loop_unref(loop);
index 22474f3f2692351b05d88163eaf9e0f6cbd7b156..6f148ca77ad72921ce2c419053384e225a2d6e81 100644 (file)
--- a/psched.c
+++ b/psched.c
@@ -615,7 +615,7 @@ static guint8* packet_add_probe_query(flxPacketScheduler *s, flxDnsPacket *p, fl
             continue;
 
         /* Does the record match the probe? */
-        if (k->class != pj->record->key->class || flx_domain_equal(k->name, pj->record->key->name))
+        if (k->class != pj->record->key->class || !flx_domain_equal(k->name, pj->record->key->name))
             continue;
         
         /* This job wouldn't fit in */
diff --git a/rr.c b/rr.c
index 49a60b44313e2d915768ff961e9c58182418ae94..a71e2a00a3641b694381717e8d6f45a7432998dd 100644 (file)
--- a/rr.c
+++ b/rr.c
@@ -477,7 +477,9 @@ gint flx_record_lexicographical_compare(flxRecord *a, flxRecord *b) {
             if ((r = uint16_cmp(a->data.srv.priority, b->data.srv.priority)) != 0 ||
                 (r = uint16_cmp(a->data.srv.weight, b->data.srv.weight)) != 0 ||
                 (r = uint16_cmp(a->data.srv.port, b->data.srv.port)) != 0)
-                return lexicographical_domain_cmp(a->data.srv.name, b->data.srv.name);
+                r = lexicographical_domain_cmp(a->data.srv.name, b->data.srv.name);
+            
+            return r;
         }
 
         case FLX_DNS_TYPE_HINFO: {
index 55776a09fc488029fe89a52aee56640068ab5955..f43f41491913d80e0db59c637feb303c9e0c1aa2 100644 (file)
--- a/server.c
+++ b/server.c
@@ -112,13 +112,23 @@ static void withdraw_entry(flxServer *s, flxEntry *e) {
     g_assert(s);
     g_assert(e);
 
-    e->dead = TRUE;
+    
+    if (e->group) {
+        flxEntry *k;
+        
+        for (k = e->group->entries; k; k = k->by_group_next) {
+            flx_goodbye_entry(s, k, FALSE);
+            k->dead = TRUE;
+        }
+        
+        flx_entry_group_change_state(e->group, FLX_ENTRY_GROUP_COLLISION);
+    } else {
+        flx_goodbye_entry(s, e, FALSE);
+        e->dead = TRUE;
+    }
+
     s->need_entry_cleanup = TRUE;
 
-    flx_goodbye_entry(s, e, FALSE);
-    
-    if (e->group)
-        flx_entry_group_run_callback(e->group, FLX_ENTRY_GROUP_COLLISION);
 }
 
 static void incoming_probe(flxServer *s, flxRecord *record, flxInterface *i) {
@@ -131,6 +141,9 @@ static void incoming_probe(flxServer *s, flxRecord *record, flxInterface *i) {
 
     t = flx_record_to_string(record);
 
+    g_message("PROBE! PROBE! PROBE! [%s]", t);
+    
+
     for (e = g_hash_table_lookup(s->entries_by_key, record->key); e; e = n) {
         n = e->by_key_next;
         
@@ -138,11 +151,12 @@ static void incoming_probe(flxServer *s, flxRecord *record, flxInterface *i) {
             continue;
 
         if (flx_entry_registering(s, e, i)) {
+            gint cmp;
             
-            if (flx_record_lexicographical_compare(record, e->record) > 0) {
+            if ((cmp = flx_record_lexicographical_compare(record, e->record)) > 0) {
                 withdraw_entry(s, e);
                 g_message("Recieved conflicting probe [%s]. Local host lost. Withdrawing.", t);
-            } else
+            } else if (cmp < 0)
                 g_message("Recieved conflicting probe [%s]. Local host won.", t);
         }
     }
@@ -202,7 +216,7 @@ static void handle_query(flxServer *s, flxDnsPacket *p, flxInterface *i, const f
     }
 }
 
-static gboolean handle_conflict(flxServer *s, flxInterface *i, flxRecord *record, const flxAddress *a) {
+static gboolean handle_conflict(flxServer *s, flxInterface *i, flxRecord *record, gboolean unique, const flxAddress *a) {
     gboolean valid = TRUE;
     flxEntry *e, *n;
     gchar *t;
@@ -213,6 +227,8 @@ static gboolean handle_conflict(flxServer *s, flxInterface *i, flxRecord *record
 
     t = flx_record_to_string(record);
 
+    g_message("CHECKING FOR CONFLICT: [%s]", t);
+
     for (e = g_hash_table_lookup(s->entries_by_key, record->key); e; e = n) {
         n = e->by_key_next;
 
@@ -224,17 +240,20 @@ static gboolean handle_conflict(flxServer *s, flxInterface *i, flxRecord *record
             gboolean equal = flx_record_equal_no_ttl(record, e->record);
                 
             /* Check whether there is a unique record conflict */
-            if (!equal && (e->flags & FLX_ENTRY_UNIQUE)) {
+            if (!equal && ((e->flags & FLX_ENTRY_UNIQUE) || unique)) {
+                gint cmp;
                 
                 /* The lexicographically later data wins. */
-                if (flx_record_lexicographical_compare(record, e->record) > 0) {
-                    withdraw_entry(s, e);
+                if ((cmp = flx_record_lexicographical_compare(record, e->record)) > 0) {
                     g_message("Recieved conflicting record [%s]. Local host lost. Withdrawing.", t);
-                } else {
+                    withdraw_entry(s, e);
+                } else if (cmp < 0) {
                     /* Tell the other host that our entry is lexicographically later */
+
+                    g_message("Recieved conflicting record [%s]. Local host won. Refreshing.", t);
+
                     valid = FALSE;
                     flx_interface_post_response(i, a, e->record, e->flags & FLX_ENTRY_UNIQUE, TRUE);
-                    g_message("Recieved conflicting record [%s]. Local host won. Refreshing.", t);
                 }
                 
                 /* Check wheter there is a TTL conflict */
@@ -244,6 +263,18 @@ static gboolean handle_conflict(flxServer *s, flxInterface *i, flxRecord *record
                 flx_interface_post_response(i, a, e->record, e->flags & FLX_ENTRY_UNIQUE, TRUE);
                 g_message("Recieved record with bad TTL [%s]. Refreshing.", t);
             }
+            
+        } else if (flx_entry_registering(s, e, i)) {
+
+            if (!flx_record_equal_no_ttl(record, e->record) && ((e->flags & FLX_ENTRY_UNIQUE) || unique)) {
+
+                /* We are currently registering a matching record, but
+                 * someone else already claimed it, so let's
+                 * withdraw */
+                
+                g_message("Recieved conflicting record [%s] with local record to be. Withdrawing.", t);
+                withdraw_entry(s, e);
+            }
         }
     }
 
@@ -276,7 +307,7 @@ static void handle_response(flxServer *s, flxDnsPacket *p, flxInterface *i, cons
             g_message("Handling response: %s", txt = flx_record_to_string(record));
             g_free(txt);
             
-            if (handle_conflict(s, i, record, a)) {
+            if (handle_conflict(s, i, record, cache_flush, a)) {
                 flx_cache_update(i->cache, record, cache_flush, a);
                 flx_packet_scheduler_incoming_response(i->scheduler, record);
             }
@@ -779,20 +810,20 @@ void flx_server_add_service_va(
     snprintf(ptr_name, sizeof(ptr_name), "%s.%s", type, domain);
     snprintf(svc_name, sizeof(svc_name), "%s.%s.%s", ename, type, domain);
     
-    flx_server_add_ptr(s, g, interface, protocol, FALSE, ptr_name, svc_name);
+    flx_server_add_ptr(s, g, interface, protocol, FLX_ENTRY_NULL, ptr_name, svc_name);
 
     r = flx_record_new_full(svc_name, FLX_DNS_CLASS_IN, FLX_DNS_TYPE_SRV);
     r->data.srv.priority = 0;
     r->data.srv.weight = 0;
     r->data.srv.port = port;
     r->data.srv.name = flx_normalize_name(host);
-    flx_server_add(s, g, interface, protocol, TRUE, r);
+    flx_server_add(s, g, interface, protocol, FLX_ENTRY_UNIQUE, r);
     flx_record_unref(r);
 
-    flx_server_add_text_va(s, g, interface, protocol, FALSE, svc_name, va);
+    flx_server_add_text_va(s, g, interface, protocol, FLX_ENTRY_UNIQUE, svc_name, va);
 
     snprintf(enum_ptr, sizeof(enum_ptr), "_services._dns-sd._udp.%s", domain);
-    flx_server_add_ptr(s, g, interface, protocol, FALSE, enum_ptr, ptr_name);
+    flx_server_add_ptr(s, g, interface, protocol, FLX_ENTRY_NULL, enum_ptr, ptr_name);
 }
 
 void flx_server_add_service(
@@ -862,18 +893,15 @@ void flx_server_post_response(flxServer *s, gint interface, guchar protocol, flx
     flx_interface_monitor_walk(s->monitor, interface, protocol, post_response_callback, &tmpdata);
 }
 
-void flx_entry_group_run_callback(flxEntryGroup *g, flxEntryGroupState state) {
+void flx_entry_group_change_state(flxEntryGroup *g, flxEntryGroupState state) {
     g_assert(g);
 
+    g->state = state;
+    
     if (g->callback) {
         g->callback(g->server, g, state, g->userdata);
         return;
     }
-
-    if (state == FLX_ENTRY_GROUP_COLLISION)
-        flx_entry_group_free(g);
-
-    /* Ignore the rest */
 }
 
 flxEntryGroup *flx_entry_group_new(flxServer *s, flxEntryGroupCallback callback, gpointer userdata) {
@@ -911,7 +939,7 @@ void flx_entry_group_commit(flxEntryGroup *g) {
     if (g->state != FLX_ENTRY_GROUP_UNCOMMITED)
         return;
 
-    flx_entry_group_run_callback(g, g->state = FLX_ENTRY_GROUP_REGISTERING);
+    flx_entry_group_change_state(g, FLX_ENTRY_GROUP_REGISTERING);
     flx_announce_group(g->server, g);
     flx_entry_group_check_probed(g, FALSE);
 }
index 810fd53eada3586344d6896e54ddb47c1536aa1c..3960ee5f4a1a9ee2637ec1599892121a82e7a4a2 100644 (file)
--- a/server.h
+++ b/server.h
@@ -72,7 +72,7 @@ gboolean flx_server_entry_match_interface(flxEntry *e, flxInterface *i);
 void flx_server_post_query(flxServer *s, gint interface, guchar protocol, flxKey *key);
 void flx_server_post_response(flxServer *s, gint interface, guchar protocol, flxRecord *record, gboolean flush_cache);
 
-void flx_entry_group_run_callback(flxEntryGroup *g, flxEntryGroupState state);
+void flx_entry_group_change_state(flxEntryGroup *g, flxEntryGroupState state);
 
 gboolean flx_entry_commited(flxEntry *e);