Answer questions for .gnunet with an ipv6-address
authorPhilipp Tölke <toelke@in.tum.de>
Tue, 26 Oct 2010 13:55:56 +0000 (13:55 +0000)
committerPhilipp Tölke <toelke@in.tum.de>
Tue, 26 Oct 2010 13:55:56 +0000 (13:55 +0000)
src/vpn/gnunet-daemon-vpn.c
src/vpn/gnunet-service-dns-p.h
src/vpn/gnunet-service-dns.c
src/vpn/gnunet-vpn-packet.h

index 227bcd9ae9658e983fd082afa57250f7147562cb..a02af54a20a16a2213371761b7053e7580f8801b 100644 (file)
@@ -36,6 +36,7 @@
 #include "gnunet-service-dns-p.h"
 #include "gnunet_client_lib.h"
 #include "gnunet_container_lib.h"
+#include "block_dns.h"
 
 /**
  * Final status code.
@@ -307,8 +308,25 @@ static void
 process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) {
     struct answer_packet* pkt = cls;
 
-    if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_IP)
+    if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE)
       {
+      pkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP;
+       unsigned char ip6addr[16];
+       memcpy(ip6addr, (int[]){htons(0x1234)}, 2);
+       memcpy(ip6addr+2, &pkt->peer, 7);
+       memcpy(ip6addr+9, &pkt->service_descriptor, 7);
+
+       memcpy(((char*)pkt)+ntohs(pkt->addroffset), ip6addr, 16);
+
+         /*FIXME:
+          * -save DNS_Record into hashmap, pointed to by ip
+          * -regularily walk through hashmap, deleting old entries
+          *  when is an entry old?
+          *  have a last-used field
+          *  don't remove if last-used "recent", ask dht again if record expired
+          */
+      }
+
        struct answer_packet_list* list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*));
 
        memcpy(&list->pkt, pkt, htons(pkt->hdr.size));
@@ -318,15 +336,6 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) {
        GNUNET_SCHEDULER_add_write_file (mycls.sched, GNUNET_TIME_UNIT_FOREVER_REL, mycls.fh_to_helper, &helper_write, NULL);
 
        return;
-      }
-
-    if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE)
-      {
-       /*FIXME:
-        * -find new IP-address for this service
-        * -create a DNS-Answer
-        */
-      }
 }
 
 static void
index 1e25daa906991af7f8c5293d49691e5ce6bd0f86..690a947a6918631d087b366f05694d7502cb9957 100644 (file)
@@ -40,6 +40,12 @@ struct answer_packet {
     unsigned dst_port:16 GNUNET_PACKED;
 
     unsigned short id GNUNET_PACKED;
+    GNUNET_HashCode peer;
+    GNUNET_HashCode service_descriptor;
+    uint64_t ports;
+    uint32_t service_type;
+
+    unsigned addroffset:16 GNUNET_PACKED;
 
     unsigned char data[1];
 };
index 4849749c07d06529c8deba9b93b55f47f56d016f..9732f90c47eee284aa64a664be21d98af3b7eed8 100644 (file)
@@ -61,6 +61,8 @@ struct dns_query_id_state {
        unsigned local_ip:32;
        unsigned remote_ip:32;
        unsigned local_port:16;
+       char* name;
+       unsigned namelen:8;
 };
 static struct dns_query_id_state query_states[65536]; /* This is < 1.5MiB */
 
@@ -108,20 +110,58 @@ void receive_dht(void *cls,
   const struct GNUNET_DNS_Record* rec = data;
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got block of size %d, peer: %08x, desc: %08x\n", size, *((unsigned int*)&rec->peer), *((unsigned int*)&rec->service_descriptor));
 
-  size_t len = sizeof(struct answer_packet) + size - 1; /* 1 for the unsigned char data[1]; */
+  size_t len = sizeof(struct answer_packet) - 1 \
+              + sizeof(struct dns_static) \
+              + query_states[id].namelen \
+              + sizeof(struct dns_query_line) \
+              + 2 /* To hold the pointer to the name */ \
+              + sizeof(struct dns_record_line) - 1 \
+              + 16;
+              ;
   struct answer_packet_list* answer = GNUNET_malloc(len + 2*sizeof(struct answer_packet_list*));
+  memset(answer, 0, len + 2*sizeof(struct answer_packet_list*));
+
   answer->pkt.hdr.type = htons(GNUNET_MESSAGE_TYPE_LOCAL_RESPONSE_DNS);
   answer->pkt.hdr.size = htons(len);
   answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_SERVICE;
 
+  GNUNET_CRYPTO_hash(&rec->peer, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &answer->pkt.peer);
+  memcpy(&answer->pkt.service_descriptor, &rec->service_descriptor, sizeof(GNUNET_HashCode));
+  memcpy(&answer->pkt.service_type, &rec->service_type, sizeof(answer->pkt.service_type));
+  memcpy(&answer->pkt.ports, &rec->ports, sizeof(answer->pkt.ports));
+
   answer->pkt.from = query_states[id].remote_ip;
 
   answer->pkt.to = query_states[id].local_ip;
   answer->pkt.dst_port = query_states[id].local_port;
 
-  answer->pkt.id = id;
+  struct dns_pkt *dpkt = (struct dns_pkt*)answer->pkt.data;
+
+  dpkt->s.id = id;
+  dpkt->s.aa = 1;
+  dpkt->s.qr = 1;
+  dpkt->s.ra = 1;
+  dpkt->s.qdcount = htons(1);
+  dpkt->s.ancount = htons(1);
+
+  memcpy(dpkt->data, query_states[id].name, query_states[id].namelen);
+  GNUNET_free(query_states[id].name);
+
+
+  struct dns_query_line* dque = (struct dns_query_line*)(dpkt->data+(query_states[id].namelen));
+  dque->type = htons(28);
+  dque->class = htons(1);
+
+  char* anname = (char*)(dpkt->data+(query_states[id].namelen)+sizeof(struct dns_query_line));
+  memcpy(anname, (char[]){0xc0, 0x0c}, 2);
+
+  struct dns_record_line *drec_data = (struct dns_record_line*)(dpkt->data+(query_states[id].namelen)+sizeof(struct dns_query_line)+2);
+  drec_data->type = htons(28); /* AAAA */
+  drec_data->class = htons(1); /* IN */
+  drec_data->ttl = htonl(3600); /* FIXME: read from block */
+  drec_data->data_len = htons(16);
 
-  memcpy(answer->pkt.data, data, size);
+  answer->pkt.addroffset = htons((unsigned short)((unsigned long)(&drec_data->data)-(unsigned long)(&answer->pkt)));
 
   GNUNET_CONTAINER_DLL_insert_after(mycls.head, mycls.tail, mycls.tail, answer);
 
@@ -156,6 +196,9 @@ void receive_query(void *cls, struct GNUNET_SERVER_Client *client, const struct
        query_states[dns->s.id].local_ip = pkt->orig_from;
        query_states[dns->s.id].local_port = pkt->src_port;
        query_states[dns->s.id].remote_ip = pkt->orig_to;
+       query_states[dns->s.id].namelen = strlen((char*)dns->data) + 1;
+       query_states[dns->s.id].name = GNUNET_malloc(query_states[dns->s.id].namelen);
+       memcpy(query_states[dns->s.id].name, dns->data, query_states[dns->s.id].namelen);
 
        if (pdns->queries[0]->namelen > 9 &&
            0 == strncmp(pdns->queries[0]->name+(pdns->queries[0]->namelen - 9), ".gnunet.", 9)) {
index 3df33a3f1ed0cacf3508a40328ecca13d9b155a3..6f453d9fd187f8dd45b5af1b2e263fffc984c584 100644 (file)
@@ -98,6 +98,11 @@ struct dns_pkt_parsed {
        struct dns_record** additional;
 };
 
+struct dns_query_line {
+    unsigned short type;
+    unsigned short class;
+};
+
 struct dns_query {
        char* name;
        unsigned char namelen;
@@ -105,6 +110,14 @@ struct dns_query {
        unsigned short qclass;
 };
 
+struct dns_record_line {
+    unsigned short type;
+    unsigned short class;
+    unsigned int ttl;
+    unsigned short data_len;
+    unsigned char data;
+};
+
 struct dns_record {
        char* name;
        unsigned char namelen;