From 8d8c0255f0f0242a067b577747740bab1b1021ea Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 10 May 2005 23:15:51 +0000 Subject: check MUSTs of RFC: * always set AA bit on response * handle conflict in known answer suppresion git-svn-id: file:///home/lennart/svn/public/avahi/trunk@67 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-core/cache.c | 6 +-- avahi-core/dns.c | 9 ++-- avahi-core/dns.h | 2 +- avahi-core/psched.c | 2 +- avahi-core/server.c | 128 ++++++++++++++++++++++++++++------------------------ todo | 13 ++++++ 6 files changed, 92 insertions(+), 68 deletions(-) diff --git a/avahi-core/cache.c b/avahi-core/cache.c index 0307b8e..5b9c881 100644 --- a/avahi-core/cache.c +++ b/avahi-core/cache.c @@ -181,11 +181,11 @@ static void elapse_func(AvahiTimeEvent *t, void *userdata) { g_assert(percent > 0); - g_message("Requesting cache entry update at %i%%.", percent); - /* Request a cache update, if we are subscribed to this entry */ - if (avahi_is_subscribed(e->cache->server, e->record->key)) + if (avahi_is_subscribed(e->cache->server, e->record->key)) { + g_message("Requesting cache entry update at %i%%.", percent); avahi_interface_post_query(e->cache->interface, e->record->key, TRUE); + } /* Check again later */ next_expiry(e->cache, e, percent); diff --git a/avahi-core/dns.c b/avahi-core/dns.c index 3435a0d..7a99192 100644 --- a/avahi-core/dns.c +++ b/avahi-core/dns.c @@ -63,11 +63,11 @@ AvahiDnsPacket* avahi_dns_packet_new_query(guint mtu) { return p; } -AvahiDnsPacket* avahi_dns_packet_new_response(guint mtu) { +AvahiDnsPacket* avahi_dns_packet_new_response(guint mtu, gboolean aa) { AvahiDnsPacket *p; p = avahi_dns_packet_new(mtu); - avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_FLAGS, AVAHI_DNS_FLAGS(1, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_FLAGS, AVAHI_DNS_FLAGS(1, 0, aa, 0, 0, 0, 0, 0, 0, 0)); return p; } @@ -75,7 +75,7 @@ AvahiDnsPacket* avahi_dns_packet_new_reply(AvahiDnsPacket* p, guint mtu, gboolea AvahiDnsPacket *r; g_assert(p); - r = avahi_dns_packet_new_response(mtu); + r = avahi_dns_packet_new_response(mtu, aa); if (copy_queries) { guint n, saved_rindex; @@ -102,8 +102,7 @@ AvahiDnsPacket* avahi_dns_packet_new_reply(AvahiDnsPacket* p, guint mtu, gboolea avahi_dns_packet_set_field(r, AVAHI_DNS_FIELD_FLAGS, (avahi_dns_packet_get_field(r, AVAHI_DNS_FIELD_FLAGS) & ~AVAHI_DNS_FLAG_OPCODE) | - (avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_OPCODE) | - (aa ? AVAHI_DNS_FLAG_AA : 0)); + (avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_OPCODE)); return r; } diff --git a/avahi-core/dns.h b/avahi-core/dns.h index c7d858f..373b9a6 100644 --- a/avahi-core/dns.h +++ b/avahi-core/dns.h @@ -39,7 +39,7 @@ typedef struct AvahiDnsPacket { AvahiDnsPacket* avahi_dns_packet_new(guint mtu); AvahiDnsPacket* avahi_dns_packet_new_query(guint mtu); -AvahiDnsPacket* avahi_dns_packet_new_response(guint mtu); +AvahiDnsPacket* avahi_dns_packet_new_response(guint mtu, gboolean aa); AvahiDnsPacket* avahi_dns_packet_new_reply(AvahiDnsPacket* p, guint mtu, gboolean copy_queries, gboolean aa); diff --git a/avahi-core/psched.c b/avahi-core/psched.c index 5af4a07..a1ab1bf 100644 --- a/avahi-core/psched.c +++ b/avahi-core/psched.c @@ -307,7 +307,7 @@ static void send_response_packet(AvahiPacketScheduler *s, AvahiResponseJob *rj) g_assert(s); - p = avahi_dns_packet_new_response(s->interface->hardware->mtu); + p = avahi_dns_packet_new_response(s->interface->hardware->mtu, TRUE); n = 0; /* If a job was specified, put it in the packet. */ diff --git a/avahi-core/server.c b/avahi-core/server.c index 3f37e1f..e9289da 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -265,64 +265,6 @@ static void incoming_probe(AvahiServer *s, AvahiRecord *record, AvahiInterface * g_free(t); } -static void handle_query(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a, guint16 port, gboolean legacy_unicast) { - guint n; - - g_assert(s); - g_assert(p); - g_assert(i); - g_assert(a); - - g_assert(!s->unicast_packet); - - /* Handle the questions */ - for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT); n > 0; n --) { - AvahiKey *key; - gboolean unicast_response = FALSE; - - if (!(key = avahi_dns_packet_consume_key(p, &unicast_response))) { - g_warning("Packet too short (1)"); - return; - } - - handle_query_key(s, p, key, i, a, port, legacy_unicast, unicast_response); - avahi_key_unref(key); - } - - /* Known Answer Suppression */ - for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ANCOUNT); n > 0; n --) { - AvahiRecord *record; - gboolean unique = FALSE; - - if (!(record = avahi_dns_packet_consume_record(p, &unique))) { - g_warning("Packet too short (2)"); - return; - } - - avahi_packet_scheduler_incoming_known_answer(i->scheduler, record, a); - avahi_record_unref(record); - } - - /* Probe record */ - for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_NSCOUNT); n > 0; n --) { - AvahiRecord *record; - gboolean unique = FALSE; - - if (!(record = avahi_dns_packet_consume_record(p, &unique))) { - g_warning("Packet too short (3)"); - return; - } - - if (record->key->type != AVAHI_DNS_TYPE_ANY) - incoming_probe(s, record, i); - - avahi_record_unref(record); - } - - if (s->unicast_packet) - send_unicast_response_packet(s, i, a, port); -} - static gboolean handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *record, gboolean unique, const AvahiAddress *a) { gboolean valid = TRUE; AvahiEntry *e, *n; @@ -390,6 +332,76 @@ static gboolean handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord * return valid; } +static void incoming_known_answer(AvahiServer *s, AvahiInterface *i, AvahiRecord *r, gboolean legacy_unicast, gboolean unique, const AvahiAddress *a) { + g_assert(s); + g_assert(i); + g_assert(r); + + if (legacy_unicast) + return; + + if (handle_conflict(s, i, r, unique, a)) + avahi_packet_scheduler_incoming_known_answer(i->scheduler, r, a); +} + +static void handle_query(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a, guint16 port, gboolean legacy_unicast) { + guint n; + + g_assert(s); + g_assert(p); + g_assert(i); + g_assert(a); + + g_assert(!s->unicast_packet); + + /* Handle the questions */ + for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT); n > 0; n --) { + AvahiKey *key; + gboolean unicast_response = FALSE; + + if (!(key = avahi_dns_packet_consume_key(p, &unicast_response))) { + g_warning("Packet too short (1)"); + return; + } + + handle_query_key(s, p, key, i, a, port, legacy_unicast, unicast_response); + avahi_key_unref(key); + } + + /* Known Answer Suppression */ + for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ANCOUNT); n > 0; n --) { + AvahiRecord *record; + gboolean unique = FALSE; + + if (!(record = avahi_dns_packet_consume_record(p, &unique))) { + g_warning("Packet too short (2)"); + return; + } + + incoming_known_answer(s, i, record, legacy_unicast, unique, a); + avahi_record_unref(record); + } + + /* Probe record */ + for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_NSCOUNT); n > 0; n --) { + AvahiRecord *record; + gboolean unique = FALSE; + + if (!(record = avahi_dns_packet_consume_record(p, &unique))) { + g_warning("Packet too short (3)"); + return; + } + + if (record->key->type != AVAHI_DNS_TYPE_ANY) + incoming_probe(s, record, i); + + avahi_record_unref(record); + } + + if (s->unicast_packet) + send_unicast_response_packet(s, i, a, port); +} + static void handle_response(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a) { guint n; diff --git a/todo b/todo index b0a9fef..a4da15e 100644 --- a/todo +++ b/todo @@ -4,6 +4,16 @@ todo: * Add some APIs to get the clean service name from RR for browsing +RFC MUSTs: + * Return to probing state on conflict + * fix flush bit when working on RRsets + * one RR too large for single packet + +* check wether RRsets are supported correctly (i.e. that all records of an + RRset are really sent if it is requested) (rfc 2181) + +* test against apple test suite + * release! done: @@ -24,3 +34,6 @@ done: * change flx_* to avahi_* * Unicast responses/queries * Legacy unicast +* no flush bit in known answer +* always set AA +* check: TC bit is valid for queries ONLY -- cgit