summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2005-04-06 22:30:47 +0000
committerLennart Poettering <lennart@poettering.net>2005-04-06 22:30:47 +0000
commitcfc653d0fd2f58ef3f4b5ecb285d5beb5bfaacfb (patch)
tree5f6d15b20c60111d8b8bba1cea289f14cb63931e
parentd553a1c2d1cd3fcdd65ade64940b5bd3efc70675 (diff)
add known answer suppresion server part
git-svn-id: file:///home/lennart/svn/public/avahi/trunk@21 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe
-rw-r--r--announce.c6
-rw-r--r--iface.c4
-rw-r--r--iface.h2
-rw-r--r--psched.c36
-rw-r--r--psched.h5
-rw-r--r--server.c20
-rw-r--r--todo6
-rw-r--r--util.c10
-rw-r--r--util.h2
9 files changed, 76 insertions, 15 deletions
diff --git a/announce.c b/announce.c
index 5b1e4e7..9229753 100644
--- a/announce.c
+++ b/announce.c
@@ -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 24d5a37..d2daf40 100644
--- 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 16e9650..4b0aef8 100644
--- 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);
diff --git a/psched.c b/psched.c
index 138dd50..1b6d26c 100644
--- 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;
diff --git a/psched.h b/psched.h
index 3a99ed1..7290265 100644
--- 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);
diff --git a/server.c b/server.c
index ecf4457..04c7d10 100644
--- 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 ab2519b..623c0b6 100644
--- 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 b8128c4..47642e8 100644
--- 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 517c2f1..36987a7 100644
--- 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