]> git.meshlink.io Git - catta/blob - rr.c
massive work
[catta] / rr.c
1 #include <string.h>
2 #include <stdio.h>
3 #include <sys/types.h>
4 #include <sys/socket.h>
5 #include <arpa/inet.h>
6
7 #include "util.h"
8 #include "rr.h"
9
10 flxKey *flx_key_new(const gchar *name, guint16 class, guint16 type) {
11     flxKey *k;
12     g_assert(name);
13
14     k = g_new(flxKey, 1);
15     k->ref = 1;
16     k->name = flx_normalize_name(name);    
17     k->class = class;
18     k->type = type;
19
20     return k;
21 }
22
23 flxKey *flx_key_ref(flxKey *k) {
24     g_assert(k);
25     g_assert(k->ref >= 1);
26
27     k->ref++;
28     return k;
29 }
30
31 void flx_key_unref(flxKey *k) {
32     g_assert(k);
33     g_assert(k->ref >= 1);
34
35     if ((--k->ref) <= 0) {
36         g_free(k->name);
37         g_free(k);
38     }
39 }
40
41 flxRecord *flx_record_new(flxKey *k, gconstpointer data, guint16 size, guint32 ttl) {
42     flxRecord *r;
43     
44     g_assert(k);
45     g_assert(data);
46     g_assert(size > 0);
47     g_assert(ttl > 0);
48
49     r = g_new(flxRecord, 1);
50     r->ref = 1;
51     r->key = flx_key_ref(k);
52     r->data = g_memdup(data, size);
53     r->size = size;
54     r->ttl = ttl;
55
56     return r;
57 }
58
59 flxRecord *flx_record_new_full(const gchar *name, guint16 class, guint16 type, gconstpointer data, guint16 size, guint32 ttl) {
60     flxRecord *r;
61     flxKey *k;
62     
63     k = flx_key_new(name, class, type);
64     r = flx_record_new(k, data, size, ttl);
65     flx_key_unref(k);
66
67     return r;
68 }
69
70 flxRecord *flx_record_ref(flxRecord *r) {
71     g_assert(r);
72     g_assert(r->ref >= 1);
73
74     r->ref++;
75     return r;
76 }
77
78 void flx_record_unref(flxRecord *r) {
79     g_assert(r);
80     g_assert(r->ref >= 1);
81
82     if ((--r->ref) <= 0) {
83         flx_key_unref(r->key);
84         g_free(r->data);
85         g_free(r);
86     }
87 }
88
89 const gchar *flx_dns_class_to_string(guint16 class) {
90     if (class == FLX_DNS_CLASS_IN)
91         return "IN";
92
93     return NULL;
94 }
95
96 const gchar *flx_dns_type_to_string(guint16 type) {
97     switch (type) {
98         case FLX_DNS_TYPE_A:
99             return "A";
100         case FLX_DNS_TYPE_AAAA:
101             return "AAAA";
102         case FLX_DNS_TYPE_PTR:
103             return "PTR";
104         case FLX_DNS_TYPE_HINFO:
105             return "HINFO";
106         case FLX_DNS_TYPE_TXT:
107             return "TXT";
108         default:
109             return NULL;
110     }
111 }
112
113
114 gchar *flx_key_to_string(flxKey *k) {
115     return g_strdup_printf("%s\t%s\t%s",
116                            k->name,
117                            flx_dns_class_to_string(k->class),
118                            flx_dns_type_to_string(k->type));
119 }
120
121 gchar *flx_record_to_string(flxRecord *r) {
122     gchar *p, *s;
123     char t[256] = "<unparsable>";
124
125     if (r->key->type == FLX_DNS_TYPE_A)
126         inet_ntop(AF_INET, r->data, t, sizeof(t));
127     else if (r->key->type == FLX_DNS_TYPE_AAAA)
128         inet_ntop(AF_INET6, r->data, t, sizeof(t));
129     else if (r->key->type == FLX_DNS_TYPE_PTR || r->key->type == FLX_DNS_TYPE_TXT) {
130         size_t l;
131         
132         l = r->size;
133         if (l > sizeof(t)-1)
134             l = sizeof(t)-1;
135         
136         memcpy(t, r->data, l);
137         t[l] = 0;
138     } else if (r->key->type == FLX_DNS_TYPE_HINFO) {
139         char *s2;
140         
141         if ((s2 = memchr(r->data, 0, r->size))) {
142             s2++;
143             if (memchr(s2, 0, r->size - ((char*) s2 - (char*) r->data)))
144                 snprintf(t, sizeof(t), "'%s' '%s'", (char*) r->data, s2);
145         }
146     }
147
148     p = flx_key_to_string(r->key);
149     s = g_strdup_printf("%s %s", p, t);
150     g_free(p);
151     
152     return s;
153 }
154
155 gboolean flx_key_equal(const flxKey *a, const flxKey *b) {
156     g_assert(a);
157     g_assert(b);
158     
159     return strcmp(a->name, b->name) == 0 && a->type == b->type && a->class == b->class;
160 }
161
162 guint flx_key_hash(const flxKey *k) {
163     g_assert(k);
164
165     return g_str_hash(k->name) + k->type + k->class;
166 }