+
+static void handle_query_key(flxServer *s, flxKey *k, flxInterface *i, const flxAddress *a) {
+ flxServerEntry *e;
+ gchar *txt;
+
+ g_assert(s);
+ g_assert(k);
+ g_assert(i);
+ g_assert(a);
+
+ g_message("Handling query: %s", txt = flx_key_to_string(k));
+ g_free(txt);
+
+ for (e = g_hash_table_lookup(s->rrset_by_key, k); e; e = e->by_key_next)
+ if (flx_interface_match(i, e->interface, e->protocol))
+ flx_interface_post_response(i, e->record);
+}
+
+static void handle_query(flxServer *s, flxDnsPacket *p, flxInterface *i, const flxAddress *a) {
+ guint n;
+
+ g_assert(s);
+ g_assert(p);
+ g_assert(i);
+ g_assert(a);
+
+ for (n = flx_dns_packet_get_field(p, DNS_FIELD_QDCOUNT); n > 0; n --) {
+ flxKey *key;
+
+ if (!(key = flx_dns_packet_consume_key(p))) {
+ g_warning("Packet too short");
+ return;
+ }
+
+ handle_query_key(s, key, i, a);
+ flx_key_unref(key);
+ }
+}
+
+static void handle_response(flxServer *s, flxDnsPacket *p, flxInterface *i, const flxAddress *a) {
+ guint n;
+
+ g_assert(s);
+ g_assert(p);
+ g_assert(i);
+ g_assert(a);
+
+ for (n = flx_dns_packet_get_field(p, DNS_FIELD_ANCOUNT) +
+ flx_dns_packet_get_field(p, DNS_FIELD_ARCOUNT); n > 0; n--) {
+ flxRecord *record;
+ gboolean cache_flush = FALSE;
+ gchar *txt;
+
+ if (!(record = flx_dns_packet_consume_record(p, &cache_flush))) {
+ g_warning("Packet too short");
+ return;
+ }
+
+ g_message("Handling response: %s", txt = flx_record_to_string(record));
+ g_free(txt);
+
+ flx_cache_update(i->cache, record, cache_flush, a);
+ flx_packet_scheduler_drop_response(i->scheduler, record);
+ flx_record_unref(record);
+ }
+}
+