]> git.meshlink.io Git - catta/commitdiff
add known answer suppresion server part
authorLennart Poettering <lennart@poettering.net>
Wed, 6 Apr 2005 22:30:47 +0000 (22:30 +0000)
committerLennart Poettering <lennart@poettering.net>
Wed, 6 Apr 2005 22:30:47 +0000 (22:30 +0000)
git-svn-id: file:///home/lennart/svn/public/avahi/trunk@21 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

announce.c
iface.c
iface.h
psched.c
psched.h
server.c
todo
util.c
util.h

index 5b1e4e72afd2b920132d902d908e0e691e44ccc0..9229753d9051beb9a78153f0038ddab9740413c3 100644 (file)
@@ -23,7 +23,7 @@ static void elapse_announce(flxTimeEvent *e, void *userdata) {
     g_assert(e);
     g_assert(a);
 
-    flx_interface_post_response(a->interface, a->entry->record, FALSE);
+    flx_interface_post_response(a->interface, NULL, a->entry->record, FALSE);
 
     if (a->n_announced++ <= 8)
         a->sec_delay *= 2;
@@ -64,7 +64,7 @@ static void new_announcement(flxServer *s, flxInterface *i, flxServerEntry *e) {
     g_message("New announcement on interface %s.%i for entry [%s]", i->hardware->name, i->protocol, t = flx_record_to_string(e->record));
     g_free(t);
     
-    flx_interface_post_response(i, e->record, FALSE);
+    flx_interface_post_response(i, NULL, e->record, FALSE);
     
     a = g_new(flxAnnouncement, 1);
     a->server = s;
@@ -138,7 +138,7 @@ void flx_goodbye_interface(flxServer *s, flxInterface *i, gboolean goodbye) {
         for (e = s->entries; e; e = e->entry_next)
             if (flx_interface_match(i, e->interface, e->protocol)) {
                 flxRecord *g = make_goodbye_record(e->record);
-                flx_interface_post_response(i, g, TRUE);
+                flx_interface_post_response(i, NULL, g, TRUE);
                 flx_record_unref(g);
             }
     }
diff --git a/iface.c b/iface.c
index 24d5a375a982cfa7b48c8a0d20cd378d22aa32c9..d2daf407272509d10bf2024b632da005d4774902 100644 (file)
--- a/iface.c
+++ b/iface.c
@@ -447,12 +447,12 @@ void flx_interface_post_query(flxInterface *i, flxKey *key, gboolean immediately
 }
 
 
-void flx_interface_post_response(flxInterface *i, flxRecord *record, gboolean immediately) {
+void flx_interface_post_response(flxInterface *i, const flxAddress *a, flxRecord *record, gboolean immediately) {
     g_assert(i);
     g_assert(record);
 
     if (flx_interface_relevant(i))
-        flx_packet_scheduler_post_response(i->scheduler, record, immediately);
+        flx_packet_scheduler_post_response(i->scheduler, a, record, immediately);
 }
 
 void flx_dump_caches(flxInterfaceMonitor *m, FILE *f) {
diff --git a/iface.h b/iface.h
index 16e96508498fa58f987be3379692d58eecf5975f..4b0aef876eebedbb6be203b380440a09ec4fdb5b 100644 (file)
--- a/iface.h
+++ b/iface.h
@@ -83,7 +83,7 @@ flxHwInterface* flx_interface_monitor_get_hw_interface(flxInterfaceMonitor *m, g
 void flx_interface_send_packet(flxInterface *i, flxDnsPacket *p);
 
 void flx_interface_post_query(flxInterface *i, flxKey *k, gboolean immediately);
-void flx_interface_post_response(flxInterface *i, flxRecord *rr, gboolean immediately);
+void flx_interface_post_response(flxInterface *i, const flxAddress *a, flxRecord *rr, gboolean immediately);
 
 void flx_dump_caches(flxInterfaceMonitor *m, FILE *f);
 
index 138dd50d39a533c5857273a4c137d34ef80dcb55..1b6d26c8763d0f1b2c94be24d1bf2a89d1cfc353 100644 (file)
--- a/psched.c
+++ b/psched.c
@@ -337,7 +337,7 @@ static flxResponseJob* response_job_new(flxPacketScheduler *s, flxRecord *record
     return rj;
 }
 
-void flx_packet_scheduler_post_response(flxPacketScheduler *s, flxRecord *record, gboolean immediately) {
+void flx_packet_scheduler_post_response(flxPacketScheduler *s, const flxAddress *a, flxRecord *record, gboolean immediately) {
     flxResponseJob *rj;
     GTimeVal tv;
     gchar *t;
@@ -361,6 +361,12 @@ void flx_packet_scheduler_post_response(flxPacketScheduler *s, flxRecord *record
         if (!!record->ttl == !!rj->record->ttl &&
             d >= 0 && d <= FLX_RESPONSE_HISTORY_MSEC*1000) {
             g_message("WARNING! DUPLICATE RESPONSE SUPPRESSION ACTIVE!");
+
+            /* This job is no longer specific to a single querier, so
+             * make sure it isn't suppressed by known answer
+             * suppresion */
+            rj->address_valid = FALSE;
+            
             return;
         }
 
@@ -376,6 +382,13 @@ void flx_packet_scheduler_post_response(flxPacketScheduler *s, flxRecord *record
     rj = response_job_new(s, record);
     rj->delivery = tv;
     rj->time_event = flx_time_event_queue_add(s->server->time_event_queue, &rj->delivery, response_elapse, rj);
+
+    /* Store the address of the host this messages is intended to, so
+       that we can drop this job in case a truncated message with
+       known answer suppresion entries is recieved */
+
+    if ((rj->address_valid = !!a))
+        rj->address = *a;
 }
 
 void flx_packet_scheduler_incoming_query(flxPacketScheduler *s, flxKey *key) {
@@ -488,6 +501,27 @@ mark_done:
     g_get_current_time(&rj->delivery);
 }
 
+void flx_packet_scheduler_incoming_known_answer(flxPacketScheduler *s, flxRecord *record, const flxAddress *a) {
+    flxResponseJob *rj;
+    
+    g_assert(s);
+    g_assert(record);
+    g_assert(a);
+
+    for (rj = s->response_jobs; rj; rj = rj->jobs_next)
+        if (flx_record_equal_no_ttl(rj->record, record) &&
+            rj->address_valid &&
+            flx_address_cmp(&rj->address, a) &&
+            record->ttl >= rj->record->ttl/2) {
+
+            /* Let's suppress it */
+
+            response_job_free(s, rj);
+            break;
+        }
+    
+}
+
 void flx_packet_scheduler_flush_responses(flxPacketScheduler *s) {
     flxResponseJob *rj;
     
index 3a99ed1dddf203d5d76cc800a3d73ad41164f78a..7290265c1d957b09881f2a7beca8496524a438b3 100644 (file)
--- a/psched.h
+++ b/psched.h
@@ -24,6 +24,8 @@ struct _flxResponseJob {
     flxPacketScheduler *scheduler;
     flxTimeEvent *time_event;
     flxRecord *record;
+    flxAddress address;
+    gboolean address_valid;
     gboolean done;
     GTimeVal delivery;
     FLX_LLIST_FIELDS(flxResponseJob, jobs);
@@ -50,10 +52,11 @@ flxPacketScheduler *flx_packet_scheduler_new(flxServer *server, flxInterface *i)
 void flx_packet_scheduler_free(flxPacketScheduler *s);
 
 void flx_packet_scheduler_post_query(flxPacketScheduler *s, flxKey *key, gboolean immediately);
-void flx_packet_scheduler_post_response(flxPacketScheduler *s, flxRecord *record, gboolean immediately);
+void flx_packet_scheduler_post_response(flxPacketScheduler *s, const flxAddress *a, flxRecord *record, gboolean immediately);
 
 void flx_packet_scheduler_incoming_query(flxPacketScheduler *s, flxKey *key);
 void flx_packet_scheduler_incoming_response(flxPacketScheduler *s, flxRecord *record);
+void flx_packet_scheduler_incoming_known_answer(flxPacketScheduler *s, flxRecord *record, const flxAddress *a);
 
 void flx_packet_scheduler_flush_responses(flxPacketScheduler *s);
 
index ecf44577ce2b45861d1cdd2d68359c684b452618..04c7d10821bc8a0c4712f68b716715f5eef879cc 100644 (file)
--- a/server.c
+++ b/server.c
@@ -31,14 +31,14 @@ static void handle_query_key(flxServer *s, flxKey *k, flxInterface *i, const flx
         for (e = s->entries; e; e = e->entry_next)
             if (flx_key_pattern_match(k, e->record->key))
                 if (flx_interface_match(i, e->interface, e->protocol))
-                    flx_interface_post_response(i, e->record, FALSE);
+                    flx_interface_post_response(i, a, e->record, FALSE);
     } else {
 
         /* Handle all other queries */
         
         for (e = g_hash_table_lookup(s->rrset_by_key, k); e; e = e->by_key_next)
             if (flx_interface_match(i, e->interface, e->protocol))
-                flx_interface_post_response(i, e->record, FALSE);
+                flx_interface_post_response(i, a, e->record, FALSE);
     }
 }
 
@@ -61,6 +61,20 @@ static void handle_query(flxServer *s, flxDnsPacket *p, flxInterface *i, const f
         handle_query_key(s, key, i, a);
         flx_key_unref(key);
     }
+
+    /* Known Answer Suppresion */
+    for (n = flx_dns_packet_get_field(p, DNS_FIELD_ANCOUNT); n > 0; n --) {
+        flxRecord *record;
+        gboolean unique = FALSE;
+
+        if (!(record = flx_dns_packet_consume_record(p, &unique))) {
+            g_warning("Packet too short (2)");
+            return;
+        }
+
+        flx_packet_scheduler_incoming_known_answer(i->scheduler, record, a);
+        flx_record_unref(record);
+    }
 }
 
 static void handle_response(flxServer *s, flxDnsPacket *p, flxInterface *i, const flxAddress *a) {
@@ -583,7 +597,7 @@ static void post_response_callback(flxInterfaceMonitor *m, flxInterface *i, gpoi
     g_assert(i);
     g_assert(r);
 
-    flx_interface_post_response(i, r, FALSE);
+    flx_interface_post_response(i, NULL, r, FALSE);
 }
 
 void flx_server_post_response(flxServer *s, gint interface, guchar protocol, flxRecord *record) {
diff --git a/todo b/todo
index ab2519ba2032a1884b66fab3700f23806bdfa19b..623c0b6fbddc4cfd13d30249ad85b58faf16088b 100644 (file)
--- a/todo
+++ b/todo
@@ -1,17 +1,15 @@
 todo:
 * Probing/Conflict resolution
 * uniqueness
+
 * defend our entries on incoming goodbye
 
 * Unicast responses/queries
 * Legacy unicast
 
-* Known-Answer suppression server part
-* Truncation
-
 done:
 * really send goodbye packets
 * refresh subscribed records only
 * FLX_DNS_TYPE_ANY support
 * Known-Answer suppression client part
-
+* Known-Answer suppression server part
diff --git a/util.c b/util.c
index b8128c40c1e05de312200598d55c53e2247834ae..47642e815c8b21436a6850a244ceae824f3b2279 100644 (file)
--- a/util.c
+++ b/util.c
@@ -113,3 +113,13 @@ GTimeVal *flx_elapse_time(GTimeVal *tv, guint msec, guint jitter) {
         
     return tv;
 }
+
+gint flx_age(const GTimeVal *a) {
+    GTimeVal now;
+    
+    g_assert(a);
+
+    g_get_current_time(&now);
+
+    return flx_timeval_diff(&now, a);
+}
diff --git a/util.h b/util.h
index 517c2f1b8efa3f9712abf1afab8b278c2f45da68..36987a7d37b98e99454475c80c19d46922fd2c05 100644 (file)
--- a/util.h
+++ b/util.h
@@ -15,4 +15,6 @@ gint flx_wait_for_write(gint fd);
 
 GTimeVal *flx_elapse_time(GTimeVal *tv, guint msec, guint jitter);
 
+gint flx_age(const GTimeVal *a);
+
 #endif