+ }
+ else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REV)
+ {
+ GNUNET_HashCode key;
+
+ memset (&key, 0, sizeof key);
+ unsigned char *k = (unsigned char *) &key;
+ unsigned char *s = pkt->data + 12;
+ int i = 0;
+
+ /* Whoever designed the reverse IPv6-lookup is batshit insane */
+ for (i = 0; i < 16; i++)
+ {
+ unsigned char c1 = s[(4 * i) + 1];
+ unsigned char c2 = s[(4 * i) + 3];
+
+ if (c1 <= '9')
+ k[i] = c1 - '0';
+ else
+ k[i] = c1 - 87; /* 87 is the difference between 'a' and 10 */
+ if (c2 <= '9')
+ k[i] += 16 * (c2 - '0');
+ else
+ k[i] += 16 * (c2 - 87);
+ }
+
+ struct map_entry *map_entry =
+ GNUNET_CONTAINER_multihashmap_get (hashmap, &key);
+ uint16_t offset = ntohs (pkt->addroffset);
+
+ if (map_entry == NULL)
+ {
+ GNUNET_free (pkt);
+ return;
+ }
+
+ GNUNET_CONTAINER_heap_update_cost (heap, map_entry->heap_node,
+ GNUNET_TIME_absolute_get ().abs_value);
+
+
+ unsigned short namelen = htons (map_entry->namelen);
+ char *name = (char *) (map_entry + 1);
+
+ list =
+ GNUNET_malloc (sizeof (struct answer_packet_list) -
+ sizeof (struct answer_packet) + offset + 2 +
+ ntohs (namelen));
+
+ struct answer_packet *rpkt = &list->pkt;
+
+ /* The offset points to the first byte belonging to the address */
+ memcpy (rpkt, pkt, offset - 1);
+
+ rpkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP;
+ rpkt->hdr.size = ntohs (offset + 2 + ntohs (namelen));
+
+ memcpy (((char *) rpkt) + offset, &namelen, 2);
+ memcpy (((char *) rpkt) + offset + 2, name, ntohs (namelen));
+
+ }
+ else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_IP)
+ {
+ list =
+ GNUNET_malloc (htons (pkt->hdr.size) +
+ sizeof (struct answer_packet_list) -
+ sizeof (struct answer_packet));
+ memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
+ }
+ else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA)
+ {
+ pkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP;
+
+ GNUNET_HashCode key;
+
+ memset (&key, 0, sizeof (GNUNET_HashCode));
+
+ unsigned char *c = ((unsigned char *) pkt) + ntohs (pkt->addroffset);
+
+ new_ip6addr_remote (c, pkt->addr, pkt->addrsize);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "New mapping to %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
+ c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9],
+ c[10], c[11], c[12], c[13], c[14], c[15]);
+ unsigned char *k = (unsigned char *) &key;
+
+ /*
+ * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
+ */
+ unsigned int i;
+
+ for (i = 0; i < 16; i++)
+ k[15 - i] = c[i];
+
+ uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
+
+ struct map_entry *value =
+ GNUNET_malloc (sizeof (struct map_entry) + namelen);
+ char *name = (char *) (value + 1);
+
+ value->namelen = namelen;
+ memcpy (name, pkt->data + 12, namelen);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n",
+ pkt->addrsize);
+ value->addrlen = pkt->addrsize;
+ memcpy (&value->addr, &pkt->addr, pkt->addrsize);
+ memset (value->additional_ports, 0, 8192);
+
+ memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
+
+ if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
+ {
+ GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ value->heap_node =
+ GNUNET_CONTAINER_heap_insert (heap, value,
+ GNUNET_TIME_absolute_get ().abs_value);
+ if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
+ GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
+ }