4 #include <sys/socket.h>
10 flxKey *flx_key_new(const gchar *name, guint16 class, guint16 type) {
16 k->name = flx_normalize_name(name);
20 /* g_message("%p %% ref=1", k); */
25 flxKey *flx_key_ref(flxKey *k) {
27 g_assert(k->ref >= 1);
31 /* g_message("%p ++ ref=%i", k, k->ref); */
36 void flx_key_unref(flxKey *k) {
38 g_assert(k->ref >= 1);
40 /* g_message("%p -- ref=%i", k, k->ref-1); */
42 if ((--k->ref) <= 0) {
48 flxRecord *flx_record_new(flxKey *k) {
53 r = g_new(flxRecord, 1);
55 r->key = flx_key_ref(k);
57 memset(&r->data, 0, sizeof(r->data));
59 r->ttl = FLX_DEFAULT_TTL;
64 flxRecord *flx_record_new_full(const gchar *name, guint16 class, guint16 type) {
70 k = flx_key_new(name, class, type);
71 r = flx_record_new(k);
77 flxRecord *flx_record_ref(flxRecord *r) {
79 g_assert(r->ref >= 1);
85 void flx_record_unref(flxRecord *r) {
87 g_assert(r->ref >= 1);
89 if ((--r->ref) <= 0) {
90 switch (r->key->type) {
92 case FLX_DNS_TYPE_SRV:
93 g_free(r->data.srv.name);
96 case FLX_DNS_TYPE_PTR:
97 case FLX_DNS_TYPE_CNAME:
98 g_free(r->data.ptr.name);
101 case FLX_DNS_TYPE_HINFO:
102 g_free(r->data.hinfo.cpu);
103 g_free(r->data.hinfo.os);
106 case FLX_DNS_TYPE_TXT:
107 flx_string_list_free(r->data.txt.string_list);
111 case FLX_DNS_TYPE_AAAA:
115 g_free(r->data.generic.data);
118 flx_key_unref(r->key);
123 const gchar *flx_dns_class_to_string(guint16 class) {
124 if (class == FLX_DNS_CLASS_IN)
130 const gchar *flx_dns_type_to_string(guint16 type) {
132 case FLX_DNS_TYPE_CNAME:
136 case FLX_DNS_TYPE_AAAA:
138 case FLX_DNS_TYPE_PTR:
140 case FLX_DNS_TYPE_HINFO:
142 case FLX_DNS_TYPE_TXT:
144 case FLX_DNS_TYPE_SRV:
152 gchar *flx_key_to_string(const flxKey *k) {
153 return g_strdup_printf("%s\t%s\t%s",
155 flx_dns_class_to_string(k->class),
156 flx_dns_type_to_string(k->type));
159 gchar *flx_record_to_string(const flxRecord *r) {
161 char buf[257], *t, *d = NULL;
163 switch (r->key->type) {
165 inet_ntop(AF_INET, &r->data.a.address.address, t = buf, sizeof(buf));
168 case FLX_DNS_TYPE_AAAA:
169 inet_ntop(AF_INET6, &r->data.aaaa.address.address, t = buf, sizeof(buf));
172 case FLX_DNS_TYPE_PTR:
173 case FLX_DNS_TYPE_CNAME :
175 t = r->data.ptr.name;
178 case FLX_DNS_TYPE_TXT:
179 t = d = flx_string_list_to_string(r->data.txt.string_list);
182 case FLX_DNS_TYPE_HINFO:
184 snprintf(t = buf, sizeof(buf), "\"%s\" \"%s\"", r->data.hinfo.cpu, r->data.hinfo.os);
187 case FLX_DNS_TYPE_SRV:
189 snprintf(t = buf, sizeof(buf), "%u %u %u %s",
190 r->data.srv.priority,
198 p = flx_key_to_string(r->key);
199 s = g_strdup_printf("%s %s ; ttl=%u", p, t ? t : "<unparsable>", r->ttl);
206 gboolean flx_key_equal(const flxKey *a, const flxKey *b) {
210 /* g_message("equal: %p %p", a, b); */
212 return strcmp(a->name, b->name) == 0 &&
213 a->type == b->type &&
214 a->class == b->class;
217 gboolean flx_key_pattern_match(const flxKey *pattern, const flxKey *k) {
221 /* g_message("equal: %p %p", a, b); */
223 g_assert(!flx_key_is_pattern(k));
225 return strcmp(pattern->name, k->name) == 0 &&
226 (pattern->type == k->type || pattern->type == FLX_DNS_TYPE_ANY) &&
227 pattern->class == k->class;
230 gboolean flx_key_is_pattern(const flxKey *k) {
233 return k->type == FLX_DNS_TYPE_ANY;
237 guint flx_key_hash(const flxKey *k) {
240 return g_str_hash(k->name) + k->type + k->class;
243 static gboolean rdata_equal(const flxRecord *a, const flxRecord *b) {
247 g_assert(a->key->type == b->key->type);
249 t = flx_record_to_string(a);
250 g_message("comparing %s", t);
253 t = flx_record_to_string(b);
254 g_message("and %s", t);
258 switch (a->key->type) {
259 case FLX_DNS_TYPE_SRV:
261 a->data.srv.priority == b->data.srv.priority &&
262 a->data.srv.weight == b->data.srv.weight &&
263 a->data.srv.port == b->data.srv.port &&
264 !strcmp(a->data.srv.name, b->data.srv.name);
266 case FLX_DNS_TYPE_PTR:
267 case FLX_DNS_TYPE_CNAME:
268 return !strcmp(a->data.ptr.name, b->data.ptr.name);
270 case FLX_DNS_TYPE_HINFO:
272 !strcmp(a->data.hinfo.cpu, b->data.hinfo.cpu) &&
273 !strcmp(a->data.hinfo.os, b->data.hinfo.os);
275 case FLX_DNS_TYPE_TXT:
276 return flx_string_list_equal(a->data.txt.string_list, b->data.txt.string_list);
279 return memcmp(&a->data.a.address, &b->data.a.address, sizeof(flxIPv4Address)) == 0;
281 case FLX_DNS_TYPE_AAAA:
282 return memcmp(&a->data.aaaa.address, &b->data.aaaa.address, sizeof(flxIPv6Address)) == 0;
285 return a->data.generic.size == b->data.generic.size &&
286 (a->data.generic.size == 0 || memcmp(a->data.generic.data, b->data.generic.data, a->data.generic.size) == 0);
291 gboolean flx_record_equal_no_ttl(const flxRecord *a, const flxRecord *b) {
296 flx_key_equal(a->key, b->key) &&
301 flxRecord *flx_record_copy(flxRecord *r) {
304 copy = g_new(flxRecord, 1);
306 copy->key = flx_key_ref(r->key);
309 switch (r->key->type) {
310 case FLX_DNS_TYPE_PTR:
311 case FLX_DNS_TYPE_CNAME:
312 copy->data.ptr.name = g_strdup(r->data.ptr.name);
315 case FLX_DNS_TYPE_SRV:
316 copy->data.srv.priority = r->data.srv.priority;
317 copy->data.srv.weight = r->data.srv.weight;
318 copy->data.srv.port = r->data.srv.port;
319 copy->data.srv.name = g_strdup(r->data.srv.name);
322 case FLX_DNS_TYPE_HINFO:
323 copy->data.hinfo.os = g_strdup(r->data.hinfo.os);
324 copy->data.hinfo.cpu = g_strdup(r->data.hinfo.cpu);
327 case FLX_DNS_TYPE_TXT:
328 copy->data.txt.string_list = flx_string_list_copy(r->data.txt.string_list);
332 copy->data.a.address = r->data.a.address;
335 case FLX_DNS_TYPE_AAAA:
336 copy->data.aaaa.address = r->data.aaaa.address;
340 copy->data.generic.data = g_memdup(r->data.generic.data, r->data.generic.size);
341 copy->data.generic.size = r->data.generic.size;