summaryrefslogtreecommitdiffstats
path: root/avahi-core/server.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2005-10-25 22:20:37 +0000
committerLennart Poettering <lennart@poettering.net>2005-10-25 22:20:37 +0000
commitc3575017e2137ef664e4735bd6f9ff1209653ef3 (patch)
tree975af5275fbba0ef9344671adf941f2a60f1968e /avahi-core/server.c
parentd2d2f82263bd1007b847324ec27236097bde1609 (diff)
* replace AF_UNSPEC by AVAHI_PROTO_UNSPEC in client-test.c
* remove some functions from the public API in avahi-common/{domain,address}.[ch] and move them into avahi-core/{domain-util,add-util}.[ch] * properly generate CNAME responses * add some more comments to server.c git-svn-id: file:///home/lennart/svn/public/avahi/trunk@871 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe
Diffstat (limited to 'avahi-core/server.c')
-rw-r--r--avahi-core/server.c103
1 files changed, 65 insertions, 38 deletions
diff --git a/avahi-core/server.c b/avahi-core/server.c
index 3edd96e..5cac056 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -45,26 +45,38 @@
#include "log.h"
#include "util.h"
#include "dns-srv-rr.h"
+#include "addr-util.h"
+#include "domain-util.h"
static void enum_aux_records(AvahiServer *s, AvahiInterface *i, const char *name, uint16_t type, void (*callback)(AvahiServer *s, AvahiRecord *r, int flush_cache, void* userdata), void* userdata) {
- AvahiKey *k;
- AvahiEntry *e;
-
assert(s);
assert(i);
assert(name);
assert(callback);
- assert(type != AVAHI_DNS_TYPE_ANY);
-
- if (!(k = avahi_key_new(name, AVAHI_DNS_CLASS_IN, type)))
- return; /** OOM */
-
- for (e = avahi_hashmap_lookup(s->entries_by_key, k); e; e = e->by_key_next)
- if (!e->dead && avahi_entry_is_registered(s, e, i))
- callback(s, e->record, e->flags & AVAHI_PUBLISH_UNIQUE, userdata);
+ if (type == AVAHI_DNS_TYPE_ANY) {
+ AvahiEntry *e;
+
+ for (e = s->entries; e; e = e->entries_next)
+ if (!e->dead &&
+ avahi_entry_is_registered(s, e, i) &&
+ e->record->key->clazz == AVAHI_DNS_CLASS_IN &&
+ avahi_domain_equal(name, e->record->key->name))
+ callback(s, e->record, e->flags & AVAHI_PUBLISH_UNIQUE, userdata);
- avahi_key_unref(k);
+ } else {
+ AvahiEntry *e;
+ AvahiKey *k;
+
+ if (!(k = avahi_key_new(name, AVAHI_DNS_CLASS_IN, type)))
+ return; /** OOM */
+
+ for (e = avahi_hashmap_lookup(s->entries_by_key, k); e; e = e->by_key_next)
+ if (!e->dead && avahi_entry_is_registered(s, e, i))
+ callback(s, e->record, e->flags & AVAHI_PUBLISH_UNIQUE, userdata);
+
+ avahi_key_unref(k);
+ }
}
void avahi_server_enumerate_aux_records(AvahiServer *s, AvahiInterface *i, AvahiRecord *r, void (*callback)(AvahiServer *s, AvahiRecord *r, int flush_cache, void* userdata), void* userdata) {
@@ -72,6 +84,8 @@ void avahi_server_enumerate_aux_records(AvahiServer *s, AvahiInterface *i, Avahi
assert(i);
assert(r);
assert(callback);
+
+ /* Call the specified callback far all records referenced by the one specified in *r */
if (r->key->clazz == AVAHI_DNS_CLASS_IN) {
if (r->key->type == AVAHI_DNS_TYPE_PTR) {
@@ -80,7 +94,8 @@ void avahi_server_enumerate_aux_records(AvahiServer *s, AvahiInterface *i, Avahi
} else if (r->key->type == AVAHI_DNS_TYPE_SRV) {
enum_aux_records(s, i, r->data.srv.name, AVAHI_DNS_TYPE_A, callback, userdata);
enum_aux_records(s, i, r->data.srv.name, AVAHI_DNS_TYPE_AAAA, callback, userdata);
- }
+ } else if (r->key->type == AVAHI_DNS_TYPE_CNAME)
+ enum_aux_records(s, i, r->data.cname.name, AVAHI_DNS_TYPE_ANY, callback, userdata);
}
}
@@ -93,17 +108,14 @@ void avahi_server_prepare_response(AvahiServer *s, AvahiInterface *i, AvahiEntry
}
void avahi_server_prepare_matching_responses(AvahiServer *s, AvahiInterface *i, AvahiKey *k, int unicast_response) {
- AvahiEntry *e;
-/* char *txt; */
-
assert(s);
assert(i);
assert(k);
-/* avahi_log_debug("Posting responses matching [%s]", txt = avahi_key_to_string(k)); */
-/* avahi_free(txt); */
+ /* Push all records that match the specified key to the record list */
if (avahi_key_is_pattern(k)) {
+ AvahiEntry *e;
/* Handle ANY query */
@@ -112,6 +124,7 @@ void avahi_server_prepare_matching_responses(AvahiServer *s, AvahiInterface *i,
avahi_server_prepare_response(s, i, e, unicast_response, 0);
} else {
+ AvahiEntry *e;
/* Handle all other queries */
@@ -119,21 +132,40 @@ void avahi_server_prepare_matching_responses(AvahiServer *s, AvahiInterface *i,
if (!e->dead && avahi_entry_is_registered(s, e, i))
avahi_server_prepare_response(s, i, e, unicast_response, 0);
}
+
+ /* Look for CNAME records */
+
+ if ((k->clazz == AVAHI_DNS_CLASS_IN || k->clazz == AVAHI_DNS_CLASS_ANY)
+ && k->type != AVAHI_DNS_TYPE_CNAME && k->type != AVAHI_DNS_TYPE_ANY) {
+
+ AvahiKey *cname_key;
+
+ if (!(cname_key = avahi_key_new(k->name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_CNAME)))
+ return;
+
+ avahi_server_prepare_matching_responses(s, i, cname_key, unicast_response);
+ avahi_key_unref(cname_key);
+ }
}
static void withdraw_entry(AvahiServer *s, AvahiEntry *e) {
assert(s);
assert(e);
+
+ /* Withdraw the specified entry, and if is part of an entry group,
+ * put that into COLLISION state */
+
+ if (e->dead)
+ return;
if (e->group) {
AvahiEntry *k;
- for (k = e->group->entries; k; k = k->by_group_next) {
+ for (k = e->group->entries; k; k = k->by_group_next)
if (!k->dead) {
avahi_goodbye_entry(s, k, 0, 1);
k->dead = 1;
}
- }
e->group->n_probing = 0;
@@ -152,24 +184,22 @@ static void withdraw_rrset(AvahiServer *s, AvahiKey *key) {
assert(s);
assert(key);
- for (e = avahi_hashmap_lookup(s->entries_by_key, key); e; e = e->by_key_next)
- if (!e->dead)
- withdraw_entry(s, e);
+ /* Withdraw an entry RRSset */
+
+ for (e = avahi_hashmap_lookup(s->entries_by_key, key); e; e = e->by_key_next)
+ withdraw_entry(s, e);
}
static void incoming_probe(AvahiServer *s, AvahiRecord *record, AvahiInterface *i) {
AvahiEntry *e, *n;
- char *t;
int ours = 0, won = 0, lost = 0;
assert(s);
assert(record);
assert(i);
- t = avahi_record_to_string(record);
-
-/* avahi_log_debug("incoming_probe()"); */
-
+ /* Handle incoming probes and check if they conflict our own probes */
+
for (e = avahi_hashmap_lookup(s->entries_by_key, record->key); e; e = n) {
int cmp;
n = e->by_key_next;
@@ -192,17 +222,17 @@ static void incoming_probe(AvahiServer *s, AvahiRecord *record, AvahiInterface *
}
if (!ours) {
-
+ char *t = avahi_record_to_string(record);
+
if (won)
avahi_log_debug("Recieved conflicting probe [%s]. Local host won.", t);
else if (lost) {
avahi_log_debug("Recieved conflicting probe [%s]. Local host lost. Withdrawing.", t);
withdraw_rrset(s, record->key);
- }/* else */
-/* avahi_log_debug("Not conflicting probe"); */
+ }
+
+ avahi_free(t);
}
-
- avahi_free(t);
}
static int handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *record, int unique, const AvahiAddress *a) {
@@ -213,9 +243,8 @@ static int handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *recor
assert(i);
assert(record);
-
-/* avahi_log_debug("CHECKING FOR CONFLICT: [%s]", t); */
-
+ /* Check whether an incoming record conflicts with one of our own */
+
for (e = avahi_hashmap_lookup(s->entries_by_key, record->key); e; e = n) {
n = e->by_key_next;
@@ -286,8 +315,6 @@ static int handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *recor
}
}
-/* avahi_log_debug("ours=%i conflict=%i", ours, conflict); */
-
if (!ours && conflict) {
char *t;