#include "util.h"
#include "rr.h"
-#include "dns.h"
AvahiKey *avahi_key_new(const gchar *name, guint16 class, guint16 type) {
AvahiKey *k;
k = g_new(AvahiKey, 1);
k->ref = 1;
k->name = avahi_normalize_name(name);
- k->class = class;
+ k->clazz = class;
k->type = type;
/* g_message("%p %% ref=1", k); */
}
}
-AvahiRecord *avahi_record_new(AvahiKey *k) {
+AvahiRecord *avahi_record_new(AvahiKey *k, guint32 ttl) {
AvahiRecord *r;
g_assert(k);
memset(&r->data, 0, sizeof(r->data));
- r->ttl = AVAHI_DEFAULT_TTL;
+ r->ttl = ttl != (guint32) -1 ? ttl : AVAHI_DEFAULT_TTL;
return r;
}
-AvahiRecord *avahi_record_new_full(const gchar *name, guint16 class, guint16 type) {
+AvahiRecord *avahi_record_new_full(const gchar *name, guint16 class, guint16 type, guint32 ttl) {
AvahiRecord *r;
AvahiKey *k;
g_assert(name);
k = avahi_key_new(name, class, type);
- r = avahi_record_new(k);
+ r = avahi_record_new(k, ttl);
avahi_key_unref(k);
return r;
const gchar *avahi_dns_class_to_string(guint16 class) {
if (class & AVAHI_DNS_CACHE_FLUSH)
return "FLUSH";
-
- if (class == AVAHI_DNS_CLASS_IN)
- return "IN";
- return NULL;
+ switch (class) {
+ case AVAHI_DNS_CLASS_IN:
+ return "IN";
+ case AVAHI_DNS_CLASS_ANY:
+ return "ANY";
+ default:
+ return NULL;
+ }
}
const gchar *avahi_dns_type_to_string(guint16 type) {
}
}
-
gchar *avahi_key_to_string(const AvahiKey *k) {
+ g_assert(k);
+ g_assert(k->ref >= 1);
+
return g_strdup_printf("%s\t%s\t%s",
k->name,
- avahi_dns_class_to_string(k->class),
+ avahi_dns_class_to_string(k->clazz),
avahi_dns_type_to_string(k->type));
}
gchar *p, *s;
char buf[257], *t = NULL, *d = NULL;
+ g_assert(r);
+ g_assert(r->ref >= 1);
+
switch (r->key->type) {
case AVAHI_DNS_TYPE_A:
inet_ntop(AF_INET, &r->data.a.address.address, t = buf, sizeof(buf));
return avahi_domain_equal(a->name, b->name) &&
a->type == b->type &&
- a->class == b->class;
+ a->clazz == b->clazz;
}
gboolean avahi_key_pattern_match(const AvahiKey *pattern, const AvahiKey *k) {
return avahi_domain_equal(pattern->name, k->name) &&
(pattern->type == k->type || pattern->type == AVAHI_DNS_TYPE_ANY) &&
- pattern->class == k->class;
+ (pattern->clazz == k->clazz || pattern->clazz == AVAHI_DNS_CLASS_ANY);
}
gboolean avahi_key_is_pattern(const AvahiKey *k) {
g_assert(k);
- return k->type == AVAHI_DNS_TYPE_ANY;
+ return
+ k->type == AVAHI_DNS_TYPE_ANY ||
+ k->clazz == AVAHI_DNS_CLASS_ANY;
}
-
guint avahi_key_hash(const AvahiKey *k) {
g_assert(k);
- return avahi_domain_hash(k->name) + k->type + k->class;
+ return
+ avahi_domain_hash(k->name) +
+ k->type +
+ k->clazz;
}
static gboolean rdata_equal(const AvahiRecord *a, const AvahiRecord *b) {
g_assert(b);
c = al < bl ? al : bl;
- if ((ret = memcmp(a, b, c)) != 0)
+ if ((ret = memcmp(a, b, c)))
return ret;
if (al == bl)
}
static gint uint16_cmp(guint16 a, guint16 b) {
- return a == b ? 0 : (a < b ? a : b);
-}
-
-static gint lexicographical_domain_cmp(const gchar *a, const gchar *b) {
- g_assert(a);
- g_assert(b);
-
-
- for (;;) {
- gchar t1[64];
- gchar t2[64];
- size_t al, bl;
- gint r;
-
- if (!a && !b)
- return 0;
-
- if (a && !b)
- return 1;
-
- if (b && !a)
- return -1;
-
- avahi_unescape_label(t1, sizeof(t1), &a);
- avahi_unescape_label(t2, sizeof(t2), &b);
-
- al = strlen(t1);
- bl = strlen(t2);
-
- if (al != bl)
- return al < bl ? -1 : 1;
-
- if ((r = strcmp(t1, t2)) != 0)
- return r;
- }
+ return a == b ? 0 : (a < b ? -1 : 1);
}
gint avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b) {
+ gint r;
+/* gchar *t1, *t2; */
+
g_assert(a);
g_assert(b);
+/* t1 = avahi_record_to_string(a); */
+/* t2 = avahi_record_to_string(b); */
+/* g_message("lexicocmp: %s %s", t1, t2); */
+/* g_free(t1); */
+/* g_free(t2); */
+
if (a == b)
return 0;
-
-/* gchar *t; */
-
-/* g_message("comparing [%s]", t = avahi_record_to_string(a)); */
-/* g_free(t); */
-
-/* g_message("and [%s]", t = avahi_record_to_string(b)); */
-/* g_free(t); */
- if (a->key->class < b->key->class)
- return -1;
- else if (a->key->class > b->key->class)
- return 1;
-
- if (a->key->type < b->key->type)
- return -1;
- else if (a->key->type > b->key->type)
- return 1;
+ if ((r = uint16_cmp(a->key->clazz, b->key->clazz)) ||
+ (r = uint16_cmp(a->key->type, b->key->type)))
+ return r;
switch (a->key->type) {
case AVAHI_DNS_TYPE_PTR:
case AVAHI_DNS_TYPE_CNAME:
- return lexicographical_domain_cmp(a->data.ptr.name, b->data.ptr.name);
+ return avahi_binary_domain_cmp(a->data.ptr.name, b->data.ptr.name);
case AVAHI_DNS_TYPE_SRV: {
- gint r;
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)
- r = lexicographical_domain_cmp(a->data.srv.name, b->data.srv.name);
+ r = avahi_binary_domain_cmp(a->data.srv.name, b->data.srv.name);
return r;
}
case AVAHI_DNS_TYPE_HINFO: {
- size_t al = strlen(a->data.hinfo.cpu), bl = strlen(b->data.hinfo.cpu);
- gint r;
-
- if (al != bl)
- return al < bl ? -1 : 1;
- if ((r = strcmp(a->data.hinfo.cpu, b->data.hinfo.cpu)) != 0)
- return r;
-
- al = strlen(a->data.hinfo.os), bl = strlen(b->data.hinfo.os);
-
- if (al != bl)
- return al < bl ? -1 : 1;
-
- if ((r = strcmp(a->data.hinfo.os, b->data.hinfo.os)) != 0)
+ if ((r = strcmp(a->data.hinfo.cpu, b->data.hinfo.cpu)) ||
+ (r = strcmp(a->data.hinfo.os, b->data.hinfo.os)))
return r;
return 0;
guint8 *ma, *mb;
guint asize, bsize;
- gint r;
ma = g_new(guint8, asize = avahi_string_list_serialize(a->data.txt.string_list, NULL, 0));
mb = g_new(guint8, bsize = avahi_string_list_serialize(b->data.txt.string_list, NULL, 0));
avahi_string_list_serialize(a->data.txt.string_list, ma, asize);
- avahi_string_list_serialize(a->data.txt.string_list, mb, bsize);
-
- r = lexicographical_memcmp(ma, asize, mb, bsize);
+ avahi_string_list_serialize(b->data.txt.string_list, mb, bsize);
+
+ if (asize && bsize)
+ r = lexicographical_memcmp(ma, asize, mb, bsize);
+ else if (asize && !bsize)
+ r = 1;
+ else if (!asize && bsize)
+ r = -1;
+ else
+ r = 0;
+
g_free(ma);
g_free(mb);
}
}
+
+gboolean avahi_record_is_goodbye(AvahiRecord *r) {
+ g_assert(r);
+
+ return r->ttl == 0;
+}
+
+gboolean avahi_key_valid(AvahiKey *k) {
+ g_assert(k);
+
+ if (!avahi_valid_domain_name(k->name))
+ return FALSE;
+
+ return TRUE;
+}
+
+gboolean avahi_record_valid(AvahiRecord *r) {
+ g_assert(r);
+
+ if (!avahi_key_valid(r->key))
+ return FALSE;
+
+ switch (r->key->type) {
+
+ case AVAHI_DNS_TYPE_PTR:
+ case AVAHI_DNS_TYPE_CNAME:
+ return avahi_valid_domain_name(r->data.ptr.name);
+
+ case AVAHI_DNS_TYPE_SRV:
+ return avahi_valid_domain_name(r->data.srv.name);
+
+ case AVAHI_DNS_TYPE_HINFO:
+ return
+ strlen(r->data.hinfo.os) <= 255 &&
+ strlen(r->data.hinfo.cpu) <= 255;
+
+
+ case AVAHI_DNS_TYPE_TXT: {
+
+ AvahiStringList *strlst;
+
+ for (strlst = r->data.txt.string_list; strlst; strlst = strlst->next)
+ if (strlst->size > 255)
+ return FALSE;
+
+ return TRUE;
+ }
+ }
+
+
+ return TRUE;
+}