begin resolving A-records
authorPhilipp Tölke <toelke@in.tum.de>
Wed, 27 Jul 2011 07:28:20 +0000 (07:28 +0000)
committerPhilipp Tölke <toelke@in.tum.de>
Wed, 27 Jul 2011 07:28:20 +0000 (07:28 +0000)
src/vpn/gnunet-daemon-exit.c
src/vpn/gnunet-daemon-vpn.c
src/vpn/gnunet-service-dns-p.h
src/vpn/gnunet-service-dns.c

index cf9f58be372b214d6cb1de3a7aec09d2c01f28b2..631873ced48d13d3eac0ef860e19a901a4f8fc78 100644 (file)
@@ -1013,7 +1013,7 @@ receive_tcp_remote (void *cls __attribute__((unused)),
                      const struct GNUNET_TRANSPORT_ATS_Information *atsi __attribute__((unused)))
 {
   GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
-  struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1);
+  struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1);
   struct remote_addr *s = (struct remote_addr *) desc;
   char *buf;
   size_t len;
@@ -1036,11 +1036,11 @@ receive_tcp_remote (void *cls __attribute__((unused)),
   switch (s->addrlen)
     {
     case 4:
-      prepare_ipv4_packet (len, ntohs (pkt->len), pkt, 0x06,    /* TCP */
+      prepare_ipv4_packet (len, pkt_len, pkt, 0x06,    /* TCP */
                            &s->addr, tunnel, state, (struct ip_pkt *) buf);
       break;
     case 16:
-      prepare_ipv6_packet (len, ntohs (pkt->len), pkt, 0x06,    /* TCP */
+      prepare_ipv6_packet (len, pkt_len, pkt, 0x06,    /* TCP */
                            &s->addr, tunnel, state, (struct ip6_pkt *) buf);
       break;
     default:
index ece7b554aee5bdda5bf034803492f256d697c1b4..257ab22b83858fcb23104e4d030a143948afb644 100644 (file)
@@ -200,7 +200,6 @@ send_pkt_to_peer_notify_callback (void *cls, size_t size, void *buf)
   GNUNET_assert (size >= ntohs (hdr->size));
   memcpy (buf, hdr, ntohs (hdr->size));
   size = ntohs(hdr->size);
-  GNUNET_free (cls);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent!\n");
 
   if (NULL != GNUNET_MESH_tunnel_get_head(*tunnel))
@@ -225,6 +224,7 @@ send_pkt_to_peer_notify_callback (void *cls, size_t size, void *buf)
       /* save the handle */
       GNUNET_MESH_tunnel_set_data(*tunnel, th);
     }
+  GNUNET_free (cls);
 
   return size;
 }
@@ -331,7 +331,60 @@ new_ip6addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
 
   int local_length = 16 - ipv6prefix;
 
-  memcpy (buf + ipv6prefix, addr, GNUNET_MAX (addrlen, local_length));
+  memcpy (buf + ipv6prefix, addr, GNUNET_MIN (addrlen, local_length));
+}
+/*}}}*/
+
+/**
+ * Create a new Address from an answer-packet
+ */
+void
+new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
+{                               /* {{{ */
+  char *ipv4addr;
+  char *ipv4mask;
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
+                                                        "IPV4ADDR",
+                                                        &ipv4addr));
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
+                                                        "IPV4MASK",
+                                                        &ipv4mask));
+  uint32_t mask;
+  inet_pton (AF_INET, ipv4addr, buf);
+  int r = inet_pton (AF_INET, ipv4mask, &mask);
+  mask = htonl(mask);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "inet_pton: %d; %m; mask: %08x\n", r, mask);
+
+  GNUNET_free (ipv4addr);
+
+  int c;
+
+  if (mask)
+    {
+      mask = (mask ^ (mask - 1)) >> 1;
+      for (c = 0; mask; c++)
+        {
+          mask >>= 1;
+        }
+    }
+  else
+    {
+      c = CHAR_BIT * sizeof(mask);
+    }
+
+  c = 32-c;
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "The mask %s has %d leading 1s.\n", ipv4mask, c);
+
+  GNUNET_free (ipv4mask);
+
+  if (c % 8 == 0)
+    c = c / 8;
+  else
+    GNUNET_assert(0);
+
+  memcpy (buf + c, addr, GNUNET_MIN (addrlen, c));
 }
 /*}}}*/
 
@@ -463,7 +516,7 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) {
        list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*));
        memcpy(&list->pkt, pkt, htons(pkt->hdr.size));
       }
-    else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE)
+    else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA)
       {
        pkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP;
 
@@ -527,6 +580,60 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) {
 
        list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*));
 
+       memcpy(&list->pkt, pkt, htons(pkt->hdr.size));
+      }
+    else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_A)
+      {
+       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_ip4addr_remote(c, pkt->addr, pkt->addrsize);
+        GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New mapping to %d.%d.%d.%d\n",
+                   c[0],
+                   c[1],
+                   c[2],
+                   c[3]);
+       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 < 4; i++)
+           k[3-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);
+          }
+        else
+          GNUNET_free(value);
+
+       list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*));
+
        memcpy(&list->pkt, pkt, htons(pkt->hdr.size));
       }
     else
index a25b7fd3fbddb29a6f4f0750f9ce4bdf62ca4fbe..6ffc2e58b1b0ead64d3398913e0e167daee51753 100644 (file)
@@ -47,10 +47,16 @@ enum GNUNET_DNS_ANSWER_Subtype {
     GNUNET_DNS_ANSWER_TYPE_REV,
 
     /**
-     * Answers of this type contains an IP-Address but traffic to this IP should
+     * Answers of this type contains an IP6-Address but traffic to this IP should
      * be routed through the GNUNet.
      */
-    GNUNET_DNS_ANSWER_TYPE_REMOTE
+    GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA,
+
+    /**
+     * Answers of this type contains an IP4-Address but traffic to this IP should
+     * be routed through the GNUNet.
+     */
+    GNUNET_DNS_ANSWER_TYPE_REMOTE_A
 };
 
 struct GNUNET_vpn_service_descriptor {
index e876940c87c73fbb338b1590df35db08bfb99dce..0c2304097a6dc0ad665ff31862059b8ba332fd0c 100644 (file)
@@ -241,7 +241,6 @@ mesh_send_response (void *cls, size_t size, void *buf)
   GNUNET_assert (size >= (*sz + sizeof (struct GNUNET_MessageHeader)));
 
   memcpy (hdr + 1, dns, *sz);
-  GNUNET_free (cls);
 
   if (NULL != GNUNET_MESH_tunnel_get_head(*tunnel))
     {
@@ -264,6 +263,9 @@ mesh_send_response (void *cls, size_t size, void *buf)
       /* save the handle */
       GNUNET_MESH_tunnel_set_data(*tunnel, th);
     }
+
+  GNUNET_free (cls);
+
   return ntohs (hdr->size);
 }
 
@@ -302,7 +304,6 @@ mesh_send (void *cls, size_t size, void *buf)
       GNUNET_MESH_tunnel_set_data(cls_->tunnel, th);
     }
 
-  GNUNET_free(cls);
   return size;
 }
 
@@ -412,7 +413,11 @@ receive_mesh_answer (void *cls __attribute__((unused)),
   /* They sent us a packet we were not waiting for */
   if (remote_pending[dns->s.id] == NULL
       || remote_pending[dns->s.id]->tunnel != tunnel)
-    return GNUNET_SYSERR;
+    return GNUNET_OK;
+
+  GNUNET_free(remote_pending[dns->s.id]);
+  remote_pending[dns->s.id] = NULL;
+
   if (query_states[dns->s.id].valid != GNUNET_YES)
     return GNUNET_SYSERR;
   query_states[dns->s.id].valid = GNUNET_NO;
@@ -428,7 +433,6 @@ receive_mesh_answer (void *cls __attribute__((unused)),
 
   answer->pkt.hdr.type = htons (GNUNET_MESSAGE_TYPE_LOCAL_RESPONSE_DNS);
   answer->pkt.hdr.size = htons (len);
-  answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE;
 
   struct dns_pkt_parsed* pdns = parse_dns_packet(dns);
 
@@ -464,7 +468,16 @@ receive_mesh_answer (void *cls __attribute__((unused)),
   struct dns_query_line *dque =
     (struct dns_query_line *) (dpkt->data +
                                (query_states[dns->s.id].namelen));
-  dque->type = htons (28);      /* AAAA */
+  if (16 == answer->pkt.addrsize)
+    {
+      answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA;
+      dque->type = htons (28);      /* AAAA */
+    }
+  else
+    {
+      answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_A;
+      dque->type = htons (1);      /* A */
+    }
   dque->class = htons (1);      /* IN */
 
   char *anname =