+ DBG("query %s (%d labels)", name, label_count);
+
+ return 0;
+}
+
+static void send_response(int sk, unsigned char *buf, int len,
+ const struct sockaddr *to, socklen_t tolen)
+{
+ struct domain_hdr *hdr = (void *) buf;
+ int err;
+
+ if (len < 12)
+ return;
+
+ DBG("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode);
+
+ hdr->qr = 1;
+ hdr->rcode = 2;
+
+ hdr->ancount = 0;
+ hdr->nscount = 0;
+ hdr->arcount = 0;
+
+ err = sendto(sk, buf, len, 0, to, tolen);
+}
+
+static int append_query(unsigned char *buf, unsigned int size,
+ const char *query, const char *domain)
+{
+ unsigned char *ptr = buf;
+ char *offset;
+
+ DBG("query %s domain %s", query, domain);
+
+ offset = (char *) query;
+ while (offset != NULL) {
+ char *tmp;
+
+ tmp = strchr(offset, '.');
+ if (tmp == NULL) {
+ if (strlen(offset) == 0)
+ break;
+ *ptr = strlen(offset);
+ memcpy(ptr + 1, offset, strlen(offset));
+ ptr += strlen(offset) + 1;
+ break;
+ }
+
+ *ptr = tmp - offset;
+ memcpy(ptr + 1, offset, tmp - offset);
+ ptr += tmp - offset + 1;
+
+ offset = tmp + 1;
+ }
+
+ offset = (char *) domain;
+ while (offset != NULL) {
+ char *tmp;
+
+ tmp = strchr(offset, '.');
+ if (tmp == NULL) {
+ if (strlen(offset) == 0)
+ break;
+ *ptr = strlen(offset);
+ memcpy(ptr + 1, offset, strlen(offset));
+ ptr += strlen(offset) + 1;
+ break;
+ }
+
+ *ptr = tmp - offset;
+ memcpy(ptr + 1, offset, tmp - offset);
+ ptr += tmp - offset + 1;
+
+ offset = tmp + 1;
+ }
+
+ *ptr++ = 0x00;
+
+ return ptr - buf;
+}
+
+static gboolean request_timeout(gpointer user_data)
+{
+ struct request_data *req = user_data;
+
+ DBG("id 0x%04x", req->srcid);
+
+ request_list = g_slist_remove(request_list, req);
+
+ if (req->resplen > 0 && req->resp != NULL) {
+ int sk, err;
+
+ sk = g_io_channel_unix_get_fd(listener_channel);
+
+ err = sendto(sk, req->resp, req->resplen, 0,
+ (struct sockaddr *) &req->sin, req->len);
+ }
+
+ g_free(req->resp);
+ g_free(req);
+
+ return FALSE;