gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r17761 - in gnunet: contrib src/vpn


From: gnunet
Subject: [GNUnet-SVN] r17761 - in gnunet: contrib src/vpn
Date: Wed, 26 Oct 2011 09:13:23 +0200

Author: toelke
Date: 2011-10-26 09:13:23 +0200 (Wed, 26 Oct 2011)
New Revision: 17761

Modified:
   gnunet/contrib/defaults.conf
   gnunet/src/vpn/gnunet-daemon-vpn-helper.c
   gnunet/src/vpn/gnunet-service-dns-p.h
   gnunet/src/vpn/gnunet-service-dns.c
   gnunet/src/vpn/gnunet-vpn-packet.h
Log:
handle dns over ipv6 and 6-to-4 and 4-to-6

Modified: gnunet/contrib/defaults.conf
===================================================================
--- gnunet/contrib/defaults.conf        2011-10-26 00:02:43 UTC (rev 17760)
+++ gnunet/contrib/defaults.conf        2011-10-26 07:13:23 UTC (rev 17761)
@@ -470,6 +470,7 @@
 IPV4ADDR = 10.11.10.1
 IPV4MASK = 255.255.0.0
 VIRTDNS = 10.11.10.2
+VIRTDNS6 = 1234::17
 IFNAME = vpn-gnunet
 
 [exit]

Modified: gnunet/src/vpn/gnunet-daemon-vpn-helper.c
===================================================================
--- gnunet/src/vpn/gnunet-daemon-vpn-helper.c   2011-10-26 00:02:43 UTC (rev 
17760)
+++ gnunet/src/vpn/gnunet-daemon-vpn-helper.c   2011-10-26 07:13:23 UTC (rev 
17761)
@@ -174,52 +174,114 @@
 
   GNUNET_assert (20 == sizeof (struct ip_hdr));
   GNUNET_assert (8 == sizeof (struct udp_pkt));
+
   size_t data_len = len - sizeof (struct answer_packet) + 1;
-  size_t net_len = sizeof (struct ip_hdr) + sizeof (struct udp_dns) + data_len;
-  size_t pkt_len =
-      sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + net_len;
 
-  struct ip_udp_dns *pkt = alloca (pkt_len);
+  void* buf;
+  size_t pkt_len;
 
-  GNUNET_assert (pkt != NULL);
-  memset (pkt, 0, pkt_len);
+  if (ans->pkt.addrlen == 16)
+    {
+      size_t net_len = sizeof (struct ip6_hdr) + sizeof (struct udp_dns) + 
data_len;
+      pkt_len =
+        sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + 
net_len;
 
-  /* set the gnunet-header */
-  pkt->shdr.size = htons (pkt_len);
-  pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
+      struct ip6_udp_dns *pkt = alloca (pkt_len);
 
-  /* set the tun-header (no flags and ethertype of IPv4) */
-  pkt->tun.flags = 0;
-  pkt->tun.type = htons (0x0800);
+      GNUNET_assert (pkt != NULL);
+      memset (pkt, 0, pkt_len);
 
-  /* set the ip-header */
-  pkt->ip_hdr.version = 4;
-  pkt->ip_hdr.hdr_lngth = 5;
-  pkt->ip_hdr.diff_serv = 0;
-  pkt->ip_hdr.tot_lngth = htons (net_len);
-  pkt->ip_hdr.ident = 0;
-  pkt->ip_hdr.flags = 0;
-  pkt->ip_hdr.frag_off = 0;
-  pkt->ip_hdr.ttl = 255;
-  pkt->ip_hdr.proto = IPPROTO_UDP;
-  pkt->ip_hdr.chks = 0;         /* Will be calculated later */
-  pkt->ip_hdr.sadr = ans->pkt.from;
-  pkt->ip_hdr.dadr = ans->pkt.to;
+      /* set the gnunet-header */
+      pkt->shdr.size = htons (pkt_len);
+      pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
 
-  pkt->ip_hdr.chks = calculate_ip_checksum ((uint16_t *) & pkt->ip_hdr, 5 * 4);
+      /* set the tun-header (no flags and ethertype of IPv4) */
+      pkt->tun.flags = 0;
+      pkt->tun.type = htons (0x86dd);
 
-  /* set the udp-header */
-  pkt->udp_dns.udp_hdr.spt = htons (53);
-  pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port;
-  pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip_hdr));
-  pkt->udp_dns.udp_hdr.crc = 0; /* Optional for IPv4 */
+      memcpy(&pkt->ip6_hdr.sadr, ans->pkt.from, 16);
+      memcpy(&pkt->ip6_hdr.dadr, ans->pkt.to, 16);
 
-  memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len);
+      /* set the udp-header */
+      pkt->udp_dns.udp_hdr.spt = htons (53);
+      pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port;
+      pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip6_hdr));
+      pkt->udp_dns.udp_hdr.crc = 0;
+      uint32_t sum = 0;
 
+      sum =
+        calculate_checksum_update (sum, (uint16_t *) & pkt->ip6_hdr.sadr, 16);
+      sum =
+        calculate_checksum_update (sum, (uint16_t *) & pkt->ip6_hdr.dadr, 16);
+      uint32_t tmp = (pkt->udp_dns.udp_hdr.len & 0xffff);
+
+      sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4);
+      tmp = htons (((pkt->ip6_hdr.nxthdr & 0x00ff)));
+      sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4);
+
+      sum =
+        calculate_checksum_update (sum, (uint16_t *) & pkt->udp_dns.udp_hdr,
+                                   ntohs (net_len - sizeof(struct ip6_hdr)));
+      pkt->udp_dns.udp_hdr.crc = calculate_checksum_end (sum);
+
+      pkt->ip6_hdr.version = 6;
+      pkt->ip6_hdr.paylgth = net_len - sizeof (struct ip6_hdr);
+      pkt->ip6_hdr.nxthdr = IPPROTO_UDP;
+      pkt->ip6_hdr.hoplmt = 0xff;
+
+      memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len);
+      buf = pkt;
+    }
+  else if (ans->pkt.addrlen == 4)
+    {
+      size_t net_len = sizeof (struct ip_hdr) + sizeof (struct udp_dns) + 
data_len;
+      pkt_len =
+        sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + 
net_len;
+
+      struct ip_udp_dns *pkt = alloca (pkt_len);
+
+      GNUNET_assert (pkt != NULL);
+      memset (pkt, 0, pkt_len);
+
+      /* set the gnunet-header */
+      pkt->shdr.size = htons (pkt_len);
+      pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
+
+      /* set the tun-header (no flags and ethertype of IPv4) */
+      pkt->tun.flags = 0;
+      pkt->tun.type = htons (0x0800);
+
+      /* set the ip-header */
+      pkt->ip_hdr.version = 4;
+      pkt->ip_hdr.hdr_lngth = 5;
+      pkt->ip_hdr.diff_serv = 0;
+      pkt->ip_hdr.tot_lngth = htons (net_len);
+      pkt->ip_hdr.ident = 0;
+      pkt->ip_hdr.flags = 0;
+      pkt->ip_hdr.frag_off = 0;
+      pkt->ip_hdr.ttl = 255;
+      pkt->ip_hdr.proto = IPPROTO_UDP;
+      pkt->ip_hdr.chks = 0;         /* Will be calculated later */
+
+      memcpy(&pkt->ip_hdr.sadr, ans->pkt.from, 4);
+      memcpy(&pkt->ip_hdr.dadr, ans->pkt.to, 4);
+
+      pkt->ip_hdr.chks = calculate_ip_checksum ((uint16_t *) & pkt->ip_hdr, 5 
* 4);
+
+      /* set the udp-header */
+      pkt->udp_dns.udp_hdr.spt = htons (53);
+      pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port;
+      pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip_hdr));
+      pkt->udp_dns.udp_hdr.crc = 0; /* Optional for IPv4 */
+
+      memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len);
+      buf = pkt;
+    }
+
   GNUNET_CONTAINER_DLL_remove (answer_proc_head, answer_proc_tail, ans);
   GNUNET_free (ans);
 
-  if (GNUNET_DISK_file_write (helper_handle->fh_to_helper, pkt, pkt_len) < 0)
+  if (GNUNET_DISK_file_write (helper_handle->fh_to_helper, buf, pkt_len) < 0)
   {
     cleanup_helper (helper_handle);
     GNUNET_SCHEDULER_add_now (start_helper_and_schedule, NULL);
@@ -258,11 +320,37 @@
 
     switch (pkt6->ip6_hdr.nxthdr)
     {
-    case IPPROTO_TCP:
     case IPPROTO_UDP:
-      pkt6_tcp = (struct ip6_tcp *) pkt6;
       pkt6_udp = (struct ip6_udp *) pkt6;
+      /* Send dns-packets to the service-dns */
+      if (ntohs (pkt6_udp->udp_hdr.dpt) == 53)
+        {
+          /* 9 = 8 for the udp-header + 1 for the unsigned char data[1]; */
+          size_t len = sizeof (struct query_packet) + ntohs 
(pkt6_udp->udp_hdr.len) - 9;
 
+          struct query_packet_list *query =
+            GNUNET_malloc (len + 2 * sizeof (struct query_packet_list *));
+          query->pkt.hdr.type = htons 
(GNUNET_MESSAGE_TYPE_VPN_DNS_LOCAL_QUERY_DNS);
+          query->pkt.hdr.size = htons (len);
+          memcpy(query->pkt.orig_to, &pkt6->ip6_hdr.dadr, 16);
+          memcpy(query->pkt.orig_from, &pkt6->ip6_hdr.sadr, 16);
+          query->pkt.addrlen = 16;
+          query->pkt.src_port = pkt6_udp->udp_hdr.spt;
+          memcpy (query->pkt.data, pkt6_udp->data, ntohs 
(pkt6_udp->udp_hdr.len) - 8);
+
+          GNUNET_CONTAINER_DLL_insert_after (head, tail, tail, query);
+
+          GNUNET_assert (head != NULL);
+
+          if (dns_connection != NULL && dns_transmit_handle == NULL)
+            dns_transmit_handle = GNUNET_CLIENT_notify_transmit_ready 
(dns_connection, len,
+                                                                       
GNUNET_TIME_UNIT_FOREVER_REL,
+                                                                       
GNUNET_YES, &send_query, NULL);
+          break;
+        }
+    case IPPROTO_TCP:
+      pkt6_tcp = (struct ip6_tcp *) pkt6;
+
       if ((key = address6_mapping_exists (pkt6->ip6_hdr.dadr)) != NULL)
       {
         struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, 
key);
@@ -438,8 +526,9 @@
           GNUNET_malloc (len + 2 * sizeof (struct query_packet_list *));
       query->pkt.hdr.type = htons 
(GNUNET_MESSAGE_TYPE_VPN_DNS_LOCAL_QUERY_DNS);
       query->pkt.hdr.size = htons (len);
-      query->pkt.orig_to = pkt->ip_hdr.dadr;
-      query->pkt.orig_from = pkt->ip_hdr.sadr;
+      memcpy(query->pkt.orig_to, &pkt->ip_hdr.dadr, 4);
+      memcpy(query->pkt.orig_from, &pkt->ip_hdr.sadr, 4);
+      query->pkt.addrlen = 4;
       query->pkt.src_port = udp->udp_hdr.spt;
       memcpy (query->pkt.data, udp->data, ntohs (udp->udp_hdr.len) - 8);
 

Modified: gnunet/src/vpn/gnunet-service-dns-p.h
===================================================================
--- gnunet/src/vpn/gnunet-service-dns-p.h       2011-10-26 00:02:43 UTC (rev 
17760)
+++ gnunet/src/vpn/gnunet-service-dns-p.h       2011-10-26 07:13:23 UTC (rev 
17761)
@@ -10,15 +10,16 @@
         /**
         * The IP-Address this query was originally sent to
         */
-  unsigned orig_to:32 GNUNET_PACKED;
+  char orig_to[16];
         /**
         * The IP-Address this query was originally sent from
         */
-  unsigned orig_from:32 GNUNET_PACKED;
+  char orig_from[16];
         /**
         * The UDP-Portthis query was originally sent from
         */
-  unsigned src_port:16 GNUNET_PACKED;
+  char addrlen;
+  uint16_t src_port GNUNET_PACKED;
 
   unsigned char data[1];        /* The DNS-Packet */
 };
@@ -76,8 +77,9 @@
   struct GNUNET_MessageHeader hdr;
   enum GNUNET_DNS_ANSWER_Subtype subtype GNUNET_PACKED;
 
-  unsigned from:32 GNUNET_PACKED;
-  unsigned to:32 GNUNET_PACKED;
+  char from[16];
+  char to[16];
+  char addrlen;
   unsigned dst_port:16 GNUNET_PACKED;
   /* -- */
 

Modified: gnunet/src/vpn/gnunet-service-dns.c
===================================================================
--- gnunet/src/vpn/gnunet-service-dns.c 2011-10-26 00:02:43 UTC (rev 17760)
+++ gnunet/src/vpn/gnunet-service-dns.c 2011-10-26 07:13:23 UTC (rev 17761)
@@ -50,6 +50,7 @@
  * sent through gnunet. The port of this socket will not be hijacked.
  */
 static struct GNUNET_NETWORK_Handle *dnsout;
+static struct GNUNET_NETWORK_Handle *dnsout6;
 
 /**
  * The port bound to the socket dnsout
@@ -90,8 +91,9 @@
   unsigned valid:1;
   struct GNUNET_SERVER_Client *client;
   struct GNUNET_MESH_Tunnel *tunnel;
-  uint32_t local_ip;
-  uint32_t remote_ip;
+  char local_ip[16];
+  char remote_ip[16];
+  char addrlen;
   uint16_t local_port;
   char *name;
   uint8_t namelen;
@@ -485,9 +487,9 @@
   memcpy (answer->pkt.addr, pdns->answers[0]->data,
           ntohs (pdns->answers[0]->data_len));
 
-  answer->pkt.from = query_states[dns->s.id].remote_ip;
-
-  answer->pkt.to = query_states[dns->s.id].local_ip;
+  memcpy(answer->pkt.from, query_states[dns->s.id].remote_ip, 
query_states[dns->s.id].addrlen);
+  memcpy(answer->pkt.to, query_states[dns->s.id].local_ip, 
query_states[dns->s.id].addrlen);
+  answer->pkt.addrlen = query_states[dns->s.id].addrlen;
   answer->pkt.dst_port = query_states[dns->s.id].local_port;
 
   struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data;
@@ -589,9 +591,9 @@
   answer->pkt.hdr.size = htons (len);
   answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REV;
 
-  answer->pkt.from = query_states[id].remote_ip;
+  memcpy(answer->pkt.from, query_states[id].remote_ip, 
query_states[id].addrlen);
+  memcpy(answer->pkt.to, query_states[id].local_ip, query_states[id].addrlen);
 
-  answer->pkt.to = query_states[id].local_ip;
   answer->pkt.dst_port = query_states[id].local_port;
 
   struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data;
@@ -700,9 +702,9 @@
   memcpy (&answer->pkt.service_descr.ports, &rec->ports,
           sizeof (answer->pkt.service_descr.ports));
 
-  answer->pkt.from = query_states[id].remote_ip;
+  memcpy(answer->pkt.from, query_states[id].remote_ip, 
query_states[id].addrlen);
+  memcpy(answer->pkt.to, query_states[id].local_ip, query_states[id].addrlen);
 
-  answer->pkt.to = query_states[id].local_ip;
   answer->pkt.dst_port = query_states[id].local_port;
 
   struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data;
@@ -784,9 +786,10 @@
 
   query_states[dns->s.id].valid = GNUNET_YES;
   query_states[dns->s.id].client = client;
-  query_states[dns->s.id].local_ip = pkt->orig_from;
+  memcpy(query_states[dns->s.id].local_ip, pkt->orig_from, pkt->addrlen);
+  query_states[dns->s.id].addrlen = pkt->addrlen;
   query_states[dns->s.id].local_port = pkt->src_port;
-  query_states[dns->s.id].remote_ip = pkt->orig_to;
+  memcpy(query_states[dns->s.id].remote_ip, pkt->orig_to, pkt->addrlen);
   query_states[dns->s.id].namelen = strlen ((char *) dns->data) + 1;
   if (query_states[dns->s.id].name != NULL)
     GNUNET_free (query_states[dns->s.id].name);
@@ -883,27 +886,56 @@
     }
   }
 
-  char *virt_dns;
-  unsigned int virt_dns_bytes;
+  unsigned char virt_dns_bytes[16];
 
-  if (GNUNET_SYSERR ==
-      GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "VIRTDNS", &virt_dns))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "No entry 'VIRTDNS' in configuration!\n");
-    exit (1);
-  }
+  if (pkt->addrlen == 4)
+    {
+      char *virt_dns;
 
-  if (1 != inet_pton (AF_INET, virt_dns, &virt_dns_bytes))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing 'VIRTDNS': %s; %m!\n",
-                virt_dns);
-    exit (1);
-  }
+      if (GNUNET_SYSERR ==
+          GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "VIRTDNS", 
&virt_dns))
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "No entry 'VIRTDNS' in configuration!\n");
+        exit (1);
+      }
 
-  GNUNET_free (virt_dns);
+      if (1 != inet_pton (AF_INET, virt_dns, &virt_dns_bytes))
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing 'VIRTDNS': %s; 
%m!\n",
+                    virt_dns);
+        exit (1);
+      }
 
-  if (virt_dns_bytes == pkt->orig_to)
+      GNUNET_free (virt_dns);
+    }
+  else if (pkt->addrlen == 16)
+    {
+      char *virt_dns;
+
+      if (GNUNET_SYSERR ==
+          GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "VIRTDNS6", 
&virt_dns))
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "No entry 'VIRTDNS6' in configuration!\n");
+        exit (1);
+      }
+
+      if (1 != inet_pton (AF_INET6, virt_dns, &virt_dns_bytes))
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing 'VIRTDNS6': %s; 
%m!\n",
+                    virt_dns);
+        exit (1);
+      }
+
+      GNUNET_free (virt_dns);
+    }
+  else
+    {
+      GNUNET_assert(0);
+    }
+
+  if (memcmp(virt_dns_bytes,pkt->orig_to, pkt->addrlen) == 0)
   {
     /* This is a packet that was sent directly to the virtual dns-server
      *
@@ -958,18 +990,33 @@
 
 
   /* The query should be sent to the network */
+  if (pkt->addrlen == 4)
+    {
+      struct sockaddr_in dest;
 
-  struct sockaddr_in dest;
+      memset (&dest, 0, sizeof dest);
+      dest.sin_port = htons (53);
+      memcpy(&dest.sin_addr.s_addr, pkt->orig_to, pkt->addrlen);
 
-  memset (&dest, 0, sizeof dest);
-  dest.sin_port = htons (53);
-  dest.sin_addr.s_addr = pkt->orig_to;
+      GNUNET_NETWORK_socket_sendto (dnsout, dns,
+                                    ntohs (pkt->hdr.size) -
+                                    sizeof (struct query_packet) + 1,
+                                    (struct sockaddr *) &dest, sizeof dest);
+    }
+  else if (pkt->addrlen == 16)
+    {
+      struct sockaddr_in6 dest;
 
-  GNUNET_NETWORK_socket_sendto (dnsout, dns,
-                                ntohs (pkt->hdr.size) -
-                                sizeof (struct query_packet) + 1,
-                                (struct sockaddr *) &dest, sizeof dest);
+      memset (&dest, 0, sizeof dest);
+      dest.sin6_port = htons (53);
+      memcpy(&dest.sin6_addr, pkt->orig_to, pkt->addrlen);
 
+      GNUNET_NETWORK_socket_sendto (dnsout6, dns,
+                                    ntohs (pkt->hdr.size) -
+                                    sizeof (struct query_packet) + 1,
+                                    (struct sockaddr *) &dest, sizeof dest);
+    }
+
 outfree:
   free_parsed_dns_packet (pdns);
   pdns = NULL;
@@ -980,7 +1027,40 @@
 static void
 read_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
 
+static void
+read_response6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+
 static int
+open_port6 ()
+{
+  struct sockaddr_in6 addr;
+
+  dnsout6 = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_DGRAM, 0);
+  if (dnsout6 == NULL)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not create socket: %m\n");
+      return GNUNET_SYSERR;
+    }
+  memset (&addr, 0, sizeof (struct sockaddr_in6));
+
+  addr.sin6_family = AF_INET6;
+  int err = GNUNET_NETWORK_socket_bind (dnsout6,
+                                        (struct sockaddr *) &addr,
+                                        sizeof (struct sockaddr_in6));
+
+  if (err != GNUNET_OK)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not bind a port: %m\n");
+    return GNUNET_SYSERR;
+  }
+
+  GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout6,
+                                 &read_response6, NULL);
+
+  return GNUNET_YES;
+}
+
+static int
 open_port ()
 {
   struct sockaddr_in addr;
@@ -1018,10 +1098,61 @@
   return GNUNET_YES;
 }
 
+void handle_response(struct dns_pkt* dns, struct sockaddr *addr, socklen_t 
addrlen, int r);
+
 /**
  * Read a response-packet of the UDP-Socket
  */
 static void
+read_response6 (void *cls
+                __attribute__ ((unused)),
+                const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct sockaddr_in6 addr;
+  socklen_t addrlen = sizeof (addr);
+  int r;
+  int len;
+
+  if (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)
+    return;
+
+  memset (&addr, 0, sizeof addr);
+
+#ifndef MINGW
+  if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout6), FIONREAD, &len))
+  {
+    (void)open_port6 ();
+    return;
+  }
+#else
+  /* port the code above? */
+  len = 65536;
+#endif
+
+  unsigned char buf[len];
+  struct dns_pkt *dns = (struct dns_pkt *) buf;
+
+  r = GNUNET_NETWORK_socket_recvfrom (dnsout, buf, sizeof (buf),
+                                      (struct sockaddr *) &addr, &addrlen);
+
+  if (r < 0)
+    {
+      (void)open_port6 ();
+      return;
+    }
+
+  struct sockaddr *addr_ = GNUNET_malloc(sizeof addr);
+  memcpy (addr_, &addr, sizeof addr);
+  handle_response(dns, addr_, 4, r);
+
+  GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout6,
+                                 &read_response6, NULL);
+}
+
+/**
+ * Read a response-packet of the UDP-Socket
+ */
+static void
 read_response (void *cls
                __attribute__ ((unused)),
                const struct GNUNET_SCHEDULER_TaskContext *tc)
@@ -1050,14 +1181,14 @@
   /* port the code above? */
   len = 65536;
 #endif
-  {
-    unsigned char buf[len];
-    struct dns_pkt *dns = (struct dns_pkt *) buf;
 
-    r = GNUNET_NETWORK_socket_recvfrom (dnsout, buf, sizeof (buf),
-                                        (struct sockaddr *) &addr, &addrlen);
+  unsigned char buf[len];
+  struct dns_pkt *dns = (struct dns_pkt *) buf;
 
-    if (r < 0)
+  r = GNUNET_NETWORK_socket_recvfrom (dnsout, buf, sizeof (buf),
+                                      (struct sockaddr *) &addr, &addrlen);
+
+  if (r < 0)
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
                          "recvfrom");
@@ -1067,86 +1198,112 @@
       return;
     }
 
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Answer to query %d\n",
-                ntohs (dns->s.id));
+  struct sockaddr *addr_ = GNUNET_malloc(sizeof addr);
+  memcpy (addr_, &addr, sizeof addr);
+  handle_response(dns, addr_, 4, r);
 
-    if (query_states[dns->s.id].valid == GNUNET_YES)
+  GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout,
+                                 &read_response, NULL);
+}
+
+void
+handle_response(struct dns_pkt* dns, struct sockaddr *addr, socklen_t addrlen, 
int r)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Answer to query %d\n",
+              ntohs (dns->s.id));
+
+
+  if (query_states[dns->s.id].valid == GNUNET_YES)
     {
       if (query_states[dns->s.id].tunnel != NULL)
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                    "Answer to query %d for a remote peer!\n",
-                    ntohs (dns->s.id));
-        /* This response should go through a tunnel */
-        uint32_t *c =
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                      "Answer to query %d for a remote peer!\n",
+                      ntohs (dns->s.id));
+          /* This response should go through a tunnel */
+          uint32_t *c =
             GNUNET_malloc (4 + sizeof (struct GNUNET_MESH_Tunnel *) + r);
-        *c = r;
-        struct GNUNET_MESH_Tunnel **t = (struct GNUNET_MESH_Tunnel **) (c + 1);
+          *c = r;
+          struct GNUNET_MESH_Tunnel **t = (struct GNUNET_MESH_Tunnel **) (c + 
1);
 
-        *t = query_states[dns->s.id].tunnel;
-        memcpy (t + 1, dns, r);
-        if (NULL ==
-            GNUNET_MESH_tunnel_get_data (query_states[dns->s.id].tunnel))
-        {
-          struct GNUNET_MESH_TransmitHandle *th =
-              GNUNET_MESH_notify_transmit_ready 
(query_states[dns->s.id].tunnel,
-                                                 GNUNET_YES,
-                                                 32,
-                                                 GNUNET_TIME_UNIT_MINUTES,
-                                                 NULL,
-                                                 r +
-                                                 sizeof (struct
-                                                         GNUNET_MessageHeader),
-                                                 mesh_send_response, c);
+          *t = query_states[dns->s.id].tunnel;
+          memcpy (t + 1, dns, r);
+          if (NULL ==
+              GNUNET_MESH_tunnel_get_data (query_states[dns->s.id].tunnel))
+            {
+              struct GNUNET_MESH_TransmitHandle *th =
+                GNUNET_MESH_notify_transmit_ready 
(query_states[dns->s.id].tunnel,
+                                                   GNUNET_YES,
+                                                   32,
+                                                   GNUNET_TIME_UNIT_MINUTES,
+                                                   NULL,
+                                                   r +
+                                                   sizeof (struct
+                                                           
GNUNET_MessageHeader),
+                                                   mesh_send_response, c);
 
-          GNUNET_MESH_tunnel_set_data (query_states[dns->s.id].tunnel, th);
-        }
-        else
-        {
-          struct tunnel_notify_queue *head =
-              GNUNET_MESH_tunnel_get_head (query_states[dns->s.id].tunnel);
-          struct tunnel_notify_queue *tail =
-              GNUNET_MESH_tunnel_get_tail (query_states[dns->s.id].tunnel);
+              GNUNET_MESH_tunnel_set_data (query_states[dns->s.id].tunnel, th);
+            }
+          else
+            {
+              struct tunnel_notify_queue *head =
+                GNUNET_MESH_tunnel_get_head (query_states[dns->s.id].tunnel);
+              struct tunnel_notify_queue *tail =
+                GNUNET_MESH_tunnel_get_tail (query_states[dns->s.id].tunnel);
 
-          struct tunnel_notify_queue *element =
-              GNUNET_malloc (sizeof (struct tunnel_notify_queue));
-          element->cls = c;
-          element->len = r + sizeof (struct GNUNET_MessageHeader);
-          element->cb = mesh_send_response;
+              struct tunnel_notify_queue *element =
+                GNUNET_malloc (sizeof (struct tunnel_notify_queue));
+              element->cls = c;
+              element->len = r + sizeof (struct GNUNET_MessageHeader);
+              element->cb = mesh_send_response;
 
-          GNUNET_CONTAINER_DLL_insert_tail (head, tail, element);
-          GNUNET_MESH_tunnel_set_head (query_states[dns->s.id].tunnel, head);
-          GNUNET_MESH_tunnel_set_tail (query_states[dns->s.id].tunnel, tail);
+              GNUNET_CONTAINER_DLL_insert_tail (head, tail, element);
+              GNUNET_MESH_tunnel_set_head (query_states[dns->s.id].tunnel, 
head);
+              GNUNET_MESH_tunnel_set_tail (query_states[dns->s.id].tunnel, 
tail);
+            }
         }
-      }
       else
-      {
-        query_states[dns->s.id].valid = GNUNET_NO;
+        {
+          query_states[dns->s.id].valid = GNUNET_NO;
 
-        size_t len = sizeof (struct answer_packet) + r - 1;     /* 1 for the 
unsigned char data[1]; */
-        struct answer_packet_list *answer =
+          size_t len = sizeof (struct answer_packet) + r - 1;     /* 1 for the 
unsigned char data[1]; */
+          struct answer_packet_list *answer =
             GNUNET_malloc (len + 2 * sizeof (struct answer_packet_list *));
-        answer->pkt.hdr.type =
+          answer->pkt.hdr.type =
             htons (GNUNET_MESSAGE_TYPE_VPN_DNS_LOCAL_RESPONSE_DNS);
-        answer->pkt.hdr.size = htons (len);
-        answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
-        answer->pkt.from = addr.sin_addr.s_addr;
-        answer->pkt.to = query_states[dns->s.id].local_ip;
-        answer->pkt.dst_port = query_states[dns->s.id].local_port;
-        memcpy (answer->pkt.data, buf, r);
+          answer->pkt.hdr.size = htons (len);
+          answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
+          answer->pkt.addrlen = addrlen;
+          if (addrlen == 16)
+            {
+              struct sockaddr_in6 *addr_ = (struct sockaddr_in6*)addr;
+              memcpy(answer->pkt.from, &addr_->sin6_addr, addrlen);
+              memcpy(answer->pkt.to, query_states[dns->s.id].local_ip, 
addrlen);
+            }
+          else if (addrlen == 4)
+            {
+              struct sockaddr_in *addr_ = (struct sockaddr_in*)addr;
+              memcpy(answer->pkt.from, &addr_->sin_addr.s_addr, addrlen);
+              memcpy(answer->pkt.to, query_states[dns->s.id].local_ip, 
addrlen);
+            }
+          else
+            {
+              GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "addrlen = %d\n", addrlen);
+              GNUNET_assert(0);
+            }
+          answer->pkt.dst_port = query_states[dns->s.id].local_port;
+          memcpy (answer->pkt.data, dns, r);
 
-        GNUNET_CONTAINER_DLL_insert_after (head, tail, tail, answer);
+          GNUNET_CONTAINER_DLL_insert_after (head, tail, tail, answer);
 
-        if (server_notify == NULL)
-          server_notify = GNUNET_SERVER_notify_transmit_ready 
(query_states[dns->s.id].client,
-                                                               len, 
GNUNET_TIME_UNIT_FOREVER_REL,
-                                                               &send_answer,
-                                                               
query_states[dns->s.id].client);
-      }
+          if (server_notify == NULL)
+            server_notify = GNUNET_SERVER_notify_transmit_ready 
(query_states[dns->s.id].client,
+                                                                 len, 
GNUNET_TIME_UNIT_FOREVER_REL,
+                                                                 &send_answer,
+                                                                 
query_states[dns->s.id].client);
+        }
     }
-  }
-  GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout,
-                                 &read_response, NULL);
+  GNUNET_free(addr);
 }
 
 
@@ -1422,6 +1579,11 @@
     GNUNET_APPLICATION_TYPE_END
   };
 
+  if (GNUNET_YES != open_port6 ())
+  {
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
 
   if (GNUNET_YES != open_port ())
   {

Modified: gnunet/src/vpn/gnunet-vpn-packet.h
===================================================================
--- gnunet/src/vpn/gnunet-vpn-packet.h  2011-10-26 00:02:43 UTC (rev 17760)
+++ gnunet/src/vpn/gnunet-vpn-packet.h  2011-10-26 07:13:23 UTC (rev 17761)
@@ -40,8 +40,8 @@
   unsigned proto:8 GNUNET_PACKED;
   unsigned chks:16 GNUNET_PACKED;
 
-  unsigned sadr:32 GNUNET_PACKED;
-  unsigned dadr:32 GNUNET_PACKED;
+  uint32_t sadr GNUNET_PACKED;
+  uint32_t dadr GNUNET_PACKED;
 };
 
 #define TCP_FLAG_SYN 2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]