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_CACHE_FLUSH)
127 if (class == FLX_DNS_CLASS_IN)
133 const gchar *flx_dns_type_to_string(guint16 type) {
135 case FLX_DNS_TYPE_CNAME:
139 case FLX_DNS_TYPE_AAAA:
141 case FLX_DNS_TYPE_PTR:
143 case FLX_DNS_TYPE_HINFO:
145 case FLX_DNS_TYPE_TXT:
147 case FLX_DNS_TYPE_SRV:
149 case FLX_DNS_TYPE_ANY:
157 gchar *flx_key_to_string(const flxKey *k) {
158 return g_strdup_printf("%s\t%s\t%s",
160 flx_dns_class_to_string(k->class),
161 flx_dns_type_to_string(k->type));
164 gchar *flx_record_to_string(const flxRecord *r) {
166 char buf[257], *t = NULL, *d = NULL;
168 switch (r->key->type) {
170 inet_ntop(AF_INET, &r->data.a.address.address, t = buf, sizeof(buf));
173 case FLX_DNS_TYPE_AAAA:
174 inet_ntop(AF_INET6, &r->data.aaaa.address.address, t = buf, sizeof(buf));
177 case FLX_DNS_TYPE_PTR:
178 case FLX_DNS_TYPE_CNAME :
180 t = r->data.ptr.name;
183 case FLX_DNS_TYPE_TXT:
184 t = d = flx_string_list_to_string(r->data.txt.string_list);
187 case FLX_DNS_TYPE_HINFO:
189 snprintf(t = buf, sizeof(buf), "\"%s\" \"%s\"", r->data.hinfo.cpu, r->data.hinfo.os);
192 case FLX_DNS_TYPE_SRV:
194 snprintf(t = buf, sizeof(buf), "%u %u %u %s",
195 r->data.srv.priority,
203 p = flx_key_to_string(r->key);
204 s = g_strdup_printf("%s %s ; ttl=%u", p, t ? t : "<unparsable>", r->ttl);
211 gboolean flx_key_equal(const flxKey *a, const flxKey *b) {
215 /* g_message("equal: %p %p", a, b); */
217 return flx_domain_equal(a->name, b->name) &&
218 a->type == b->type &&
219 a->class == b->class;
222 gboolean flx_key_pattern_match(const flxKey *pattern, const flxKey *k) {
226 /* g_message("equal: %p %p", a, b); */
228 g_assert(!flx_key_is_pattern(k));
230 return flx_domain_equal(pattern->name, k->name) &&
231 (pattern->type == k->type || pattern->type == FLX_DNS_TYPE_ANY) &&
232 pattern->class == k->class;
235 gboolean flx_key_is_pattern(const flxKey *k) {
238 return k->type == FLX_DNS_TYPE_ANY;
242 guint flx_key_hash(const flxKey *k) {
245 return flx_domain_hash(k->name) + k->type + k->class;
248 static gboolean rdata_equal(const flxRecord *a, const flxRecord *b) {
251 g_assert(a->key->type == b->key->type);
253 /* t = flx_record_to_string(a); */
254 /* g_message("comparing %s", t); */
257 /* t = flx_record_to_string(b); */
258 /* g_message("and %s", t); */
262 switch (a->key->type) {
263 case FLX_DNS_TYPE_SRV:
265 a->data.srv.priority == b->data.srv.priority &&
266 a->data.srv.weight == b->data.srv.weight &&
267 a->data.srv.port == b->data.srv.port &&
268 flx_domain_equal(a->data.srv.name, b->data.srv.name);
270 case FLX_DNS_TYPE_PTR:
271 case FLX_DNS_TYPE_CNAME:
272 return flx_domain_equal(a->data.ptr.name, b->data.ptr.name);
274 case FLX_DNS_TYPE_HINFO:
276 !strcmp(a->data.hinfo.cpu, b->data.hinfo.cpu) &&
277 !strcmp(a->data.hinfo.os, b->data.hinfo.os);
279 case FLX_DNS_TYPE_TXT:
280 return flx_string_list_equal(a->data.txt.string_list, b->data.txt.string_list);
283 return memcmp(&a->data.a.address, &b->data.a.address, sizeof(flxIPv4Address)) == 0;
285 case FLX_DNS_TYPE_AAAA:
286 return memcmp(&a->data.aaaa.address, &b->data.aaaa.address, sizeof(flxIPv6Address)) == 0;
289 return a->data.generic.size == b->data.generic.size &&
290 (a->data.generic.size == 0 || memcmp(a->data.generic.data, b->data.generic.data, a->data.generic.size) == 0);
295 gboolean flx_record_equal_no_ttl(const flxRecord *a, const flxRecord *b) {
300 flx_key_equal(a->key, b->key) &&
305 flxRecord *flx_record_copy(flxRecord *r) {
308 copy = g_new(flxRecord, 1);
310 copy->key = flx_key_ref(r->key);
313 switch (r->key->type) {
314 case FLX_DNS_TYPE_PTR:
315 case FLX_DNS_TYPE_CNAME:
316 copy->data.ptr.name = g_strdup(r->data.ptr.name);
319 case FLX_DNS_TYPE_SRV:
320 copy->data.srv.priority = r->data.srv.priority;
321 copy->data.srv.weight = r->data.srv.weight;
322 copy->data.srv.port = r->data.srv.port;
323 copy->data.srv.name = g_strdup(r->data.srv.name);
326 case FLX_DNS_TYPE_HINFO:
327 copy->data.hinfo.os = g_strdup(r->data.hinfo.os);
328 copy->data.hinfo.cpu = g_strdup(r->data.hinfo.cpu);
331 case FLX_DNS_TYPE_TXT:
332 copy->data.txt.string_list = flx_string_list_copy(r->data.txt.string_list);
336 copy->data.a.address = r->data.a.address;
339 case FLX_DNS_TYPE_AAAA:
340 copy->data.aaaa.address = r->data.aaaa.address;
344 copy->data.generic.data = g_memdup(r->data.generic.data, r->data.generic.size);
345 copy->data.generic.size = r->data.generic.size;
354 guint flx_key_get_estimate_size(flxKey *k) {
357 return strlen(k->name)+1+4;
360 guint flx_record_get_estimate_size(flxRecord *r) {
364 n = flx_key_get_estimate_size(r->key) + 4 + 2;
366 switch (r->key->type) {
367 case FLX_DNS_TYPE_PTR:
368 case FLX_DNS_TYPE_CNAME:
369 n += strlen(r->data.ptr.name) + 1;
372 case FLX_DNS_TYPE_SRV:
373 n += 6 + strlen(r->data.srv.name) + 1;
376 case FLX_DNS_TYPE_HINFO:
377 n += strlen(r->data.hinfo.os) + 1 + strlen(r->data.hinfo.cpu) + 1;
380 case FLX_DNS_TYPE_TXT:
381 n += flx_string_list_serialize(r->data.txt.string_list, NULL, 0);
385 n += sizeof(flxIPv4Address);
388 case FLX_DNS_TYPE_AAAA:
389 n += sizeof(flxIPv6Address);
393 n += r->data.generic.size;