1 #include <sys/socket.h>
8 flxServer *flx_server_new(GMainContext *c) {
9 flxServer *s = g_new(flxServer, 1);
12 g_main_context_ref(c);
15 s->context = g_main_context_default();
18 s->rrset_by_id = g_hash_table_new(g_int_hash, g_int_equal);
19 s->rrset_by_name = g_hash_table_new(g_str_hash, g_str_equal);
22 s->monitor = flx_interface_monitor_new(s->context);
27 void flx_server_free(flxServer* s) {
30 flx_interface_monitor_free(s->monitor);
32 flx_server_remove(s, 0);
34 g_hash_table_destroy(s->rrset_by_id);
35 g_hash_table_destroy(s->rrset_by_name);
36 g_main_context_unref(s->context);
40 gint flx_server_get_next_id(flxServer *s) {
43 return s->current_id++;
46 void flx_server_add_rr(flxServer *s, gint id, gint interface, const flxRecord *rr) {
54 e = g_new(flxEntry, 1);
55 flx_record_copy_normalize(&e->rr, rr);
57 e->interface = interface;
59 /* Insert into linked list */
61 if ((e->next = s->entries))
65 /* Insert into hash table indexed by id */
67 if ((e->next_by_id = g_hash_table_lookup(s->rrset_by_id, &id)))
68 e->next_by_id->prev = e;
69 g_hash_table_replace(s->rrset_by_id, &e->id, e);
71 /* Insert into hash table indexed by name */
72 e->prev_by_name = NULL;
73 if ((e->next_by_name = g_hash_table_lookup(s->rrset_by_name, e->rr.name)))
74 e->next_by_name->prev = e;
75 g_hash_table_replace(s->rrset_by_name, e->rr.name, e);
78 void flx_server_add(flxServer *s, gint id, const gchar *name, gint interface, guint16 type, gconstpointer data, guint size) {
85 rr.name = (gchar*) name;
87 rr.class = FLX_DNS_CLASS_IN;
88 rr.data = (gpointer) data;
90 rr.interface = interface;
91 rr.ttl = FLX_DEFAULT_TTL;
92 flx_server_add_rr(s, id, 0, &rr);
95 const flxRecord *flx_server_iterate(flxServer *s, gint id, void **state) {
96 flxEntry **e = (flxEntry**) state;
101 *e = id > 0 ? (*e)->next_by_id : (*e)->next;
103 *e = id > 0 ? g_hash_table_lookup(s->rrset_by_id, &id) : s->entries;
111 static void free_entry(flxServer*s, flxEntry *e) {
114 /* Remove from linked list */
116 e->prev->next = e->next;
118 s->entries = e->next;
121 e->next->prev = e->prev;
123 /* Remove from hash table indexed by id */
125 e->prev_by_id = e->next_by_id;
128 g_hash_table_replace(s->rrset_by_id, &e->next_by_id->id, e->next_by_id);
130 g_hash_table_remove(s->rrset_by_id, &e->id);
134 e->next_by_id->prev_by_id = e->prev_by_id;
136 /* Remove from hash table indexed by name */
138 e->prev_by_name = e->next_by_name;
141 g_hash_table_replace(s->rrset_by_name, &e->next_by_name->rr.name, e->next_by_name);
143 g_hash_table_remove(s->rrset_by_name, &e->rr.name);
147 e->next_by_name->prev_by_name = e->prev_by_name;
150 void flx_server_remove(flxServer *s, gint id) {
155 free_entry(s, s->entries);
159 while ((e = g_hash_table_lookup(s->rrset_by_id, &id)))
164 flxRecord *flx_record_copy_normalize(flxRecord *ret_dest, const flxRecord*src) {
169 ret_dest->name = flx_normalize_name(src->name);
170 ret_dest->data = g_memdup(src->data, src->size);
175 static const gchar *dns_class_to_string(guint16 class) {
176 if (class == FLX_DNS_CLASS_IN)
182 static const gchar *dns_type_to_string(guint16 type) {
186 case FLX_DNS_TYPE_AAAA:
188 case FLX_DNS_TYPE_PTR:
190 case FLX_DNS_TYPE_HINFO:
192 case FLX_DNS_TYPE_TXT:
199 void flx_server_dump(flxServer *s, FILE *f) {
204 for (e = s->entries; e; e = e->next) {
206 fprintf(f, "%-40s %-8s %-8s ", e->rr.name, dns_class_to_string(e->rr.class), dns_type_to_string(e->rr.type));
210 if (e->rr.class == FLX_DNS_CLASS_IN) {
211 if (e->rr.type == FLX_DNS_TYPE_A)
212 inet_ntop(AF_INET, e->rr.data, t, sizeof(t));
213 else if (e->rr.type == FLX_DNS_TYPE_AAAA)
214 inet_ntop(AF_INET6, e->rr.data, t, sizeof(t));
215 else if (e->rr.type == FLX_DNS_TYPE_PTR)
216 g_strlcpy(t, e->rr.data, sizeof(t));
217 else if (e->rr.type == FLX_DNS_TYPE_HINFO) {
220 if ((s2 = memchr(e->rr.data, 0, e->rr.size))) {
222 if (memchr(s2, 0, e->rr.size - ((char*) s2 - (char*) e->rr.data)))
223 snprintf(t, sizeof(t), "'%s' '%s'", (char*) e->rr.data, s2);
229 fprintf(f, "%s\n", t);