gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r18961 - in gnunet/src: dns util


From: gnunet
Subject: [GNUnet-SVN] r18961 - in gnunet/src: dns util
Date: Tue, 3 Jan 2012 23:51:14 +0100

Author: grothoff
Date: 2012-01-03 23:51:14 +0100 (Tue, 03 Jan 2012)
New Revision: 18961

Modified:
   gnunet/src/dns/Makefile.am
   gnunet/src/dns/dns.conf
   gnunet/src/dns/gnunet-helper-dns.c
   gnunet/src/dns/gnunet-service-dns_new.c
   gnunet/src/util/crypto_crc.c
   gnunet/src/util/helper.c
Log:
-misc DNS related bugfixes

Modified: gnunet/src/dns/Makefile.am
===================================================================
--- gnunet/src/dns/Makefile.am  2012-01-03 21:29:22 UTC (rev 18960)
+++ gnunet/src/dns/Makefile.am  2012-01-03 22:51:14 UTC (rev 18961)
@@ -60,7 +60,6 @@
 gnunet_service_dns_new_LDADD = \
   $(top_builddir)/src/statistics/libgnunetstatistics.la \
   $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/dns/libgnunetdnsparser.la \
   $(GN_LIBINTL)
 
 libgnunetdnsparser_la_SOURCES = \

Modified: gnunet/src/dns/dns.conf
===================================================================
--- gnunet/src/dns/dns.conf     2012-01-03 21:29:22 UTC (rev 18960)
+++ gnunet/src/dns/dns.conf     2012-01-03 22:51:14 UTC (rev 18961)
@@ -8,4 +8,15 @@
 ACCEPT_FROM = 127.0.0.1;
 ACCEPT_FROM6 = ::1;
 UNIXPATH = /tmp/gnunet-service-dns.sock
-PROVIDE_EXIT = NO
+
+PROVIDE_EXIT = YES
+IFNAME = gnunet-dns
+
+# Use RFC 3849-style documentation IPv6 address (RFC 4773 might provide an 
alternative in the future)
+IPV6ADDR = 2001:DB8::1
+IPV6PREFIX = 126
+
+# Use RFC 3927-style link-local address
+IPV4ADDR = 169.254.1.1
+IPV4MASK = 255.255.0.0
+

Modified: gnunet/src/dns/gnunet-helper-dns.c
===================================================================
--- gnunet/src/dns/gnunet-helper-dns.c  2012-01-03 21:29:22 UTC (rev 18960)
+++ gnunet/src/dns/gnunet-helper-dns.c  2012-01-03 22:51:14 UTC (rev 18961)
@@ -760,7 +760,9 @@
       return 6;
     }
   }
-  if (SIG_ERR == signal (SIGTERM, &signal_handler))
+  if ( (SIG_ERR == signal (SIGTERM, &signal_handler)) ||
+       (SIG_ERR == signal (SIGINT, &signal_handler)) ||
+       (SIG_ERR == signal (SIGHUP, &signal_handler)) )       
   { 
     fprintf (stderr, 
             "Fatal: could not initialize signal handler: %s\n",
@@ -779,7 +781,9 @@
   if (-1 == (fd_tun = init_tun (dev)))
   {
     fprintf (stderr, "Fatal: could not initialize tun-interface\n");
+    (void) signal (SIGTERM, SIG_IGN);
     (void) signal (SIGINT, SIG_IGN);
+    (void) signal (SIGHUP, SIG_IGN);
     (void) close (cpipe[0]);
     (void) close (cpipe[1]);
     return 5;
@@ -793,7 +797,9 @@
     if ((prefix_len < 1) || (prefix_len > 127))
     {
       fprintf (stderr, "Fatal: prefix_len out of range\n");
+      (void) signal (SIGTERM, SIG_IGN);
       (void) signal (SIGINT, SIG_IGN);
+      (void) signal (SIGHUP, SIG_IGN);
       (void) close (cpipe[0]);
       (void) close (cpipe[1]);
       return 2;
@@ -941,8 +947,10 @@
  cleanup_rest:
   /* close virtual interface */
   (void) close (fd_tun);
-  /* remove SIGINT handler so we can close the pipes */
+  /* remove signal handler so we can close the pipes */
+  (void) signal (SIGTERM, SIG_IGN);
   (void) signal (SIGINT, SIG_IGN);
+  (void) signal (SIGHUP, SIG_IGN);
   (void) close (cpipe[0]);
   (void) close (cpipe[1]);
   return r;

Modified: gnunet/src/dns/gnunet-service-dns_new.c
===================================================================
--- gnunet/src/dns/gnunet-service-dns_new.c     2012-01-03 21:29:22 UTC (rev 
18960)
+++ gnunet/src/dns/gnunet-service-dns_new.c     2012-01-03 22:51:14 UTC (rev 
18961)
@@ -30,7 +30,35 @@
 #include "dns_new.h"
 #include "gnunet_dns_service-new.h"
 
+/* see http://www.iana.org/assignments/ethernet-numbers */
+#ifndef ETH_P_IPV4
+#define ETH_P_IPV4 0x0800
+#endif
+
+#ifndef ETH_P_IPV6
+#define ETH_P_IPV6 0x86DD
+#endif
+
 GNUNET_NETWORK_STRUCT_BEGIN
+/**
+ * Header from Linux TUN interface.
+ */ 
+struct tun_header
+{
+  /**
+   * Some flags (unused).
+   */ 
+  uint16_t flags;
+
+  /**
+   * Here we get an ETH_P_-number.
+   */
+  uint16_t proto;
+};
+
+/**
+ * Standard IPv4 header.
+ */
 struct ip4_header
 {
   unsigned header_length:4 GNUNET_PACKED;
@@ -47,6 +75,9 @@
   struct in_addr destination_address GNUNET_PACKED;
 };
 
+/**
+ * Standard IPv6 header.
+ */
 struct ip6_header
 {
   unsigned traffic_class_h:4 GNUNET_PACKED;
@@ -60,6 +91,9 @@
   struct in6_addr destination_address GNUNET_PACKED;
 };
 
+/**
+ * UDP packet header.
+ */
 struct udp_packet
 {
   uint16_t spt GNUNET_PACKED;
@@ -68,6 +102,9 @@
   uint16_t crc GNUNET_PACKED;
 };
 
+/**
+ * DNS header.
+ */
 struct dns_header
 {
   uint16_t id GNUNET_PACKED;
@@ -263,7 +300,7 @@
 /**
  * Array of all open requests.
  */
-static struct RequestRecord requests[UINT16_MAX];
+static struct RequestRecord requests[UINT16_MAX + 1];
 
 /**
  * Generator for unique request IDs.
@@ -279,7 +316,7 @@
 static void
 cleanup_rr (struct RequestRecord *rr)
 {
-  GNUNET_free (rr->payload);
+  GNUNET_free_non_null (rr->payload);
   rr->payload = NULL;
   rr->payload_length = 0;
   GNUNET_array_grow (rr->client_wait_list,
@@ -356,6 +393,7 @@
   
   /* send response via hijacker */
   reply_len = sizeof (struct GNUNET_MessageHeader);
+  reply_len += sizeof (struct tun_header);
   switch (rr->src_addr.ss_family)
   {
   case AF_INET:
@@ -381,6 +419,9 @@
   {
     char buf[reply_len];
     size_t off;
+    uint16_t *udp_crcp;
+    char *udp_crc_start;
+    uint16_t udp_crc_length;
 
     /* first, GNUnet message header */
     hdr = (struct GNUNET_MessageHeader*) buf;
@@ -388,7 +429,22 @@
     hdr->size = htons ((uint16_t) reply_len);
     off = sizeof (struct GNUNET_MessageHeader);
 
+    /* first, TUN header */
+    {
+      struct tun_header tun;
+
+      tun.flags = htons (0);
+      if (rr->src_addr.ss_family == AF_INET)
+       tun.proto = htons (ETH_P_IPV4); 
+      else
+       tun.proto = htons (ETH_P_IPV6);
+      memcpy (&buf[off], &tun, sizeof (struct tun_header));
+      off += sizeof (struct tun_header);
+    }
+
     /* now IP header */
+    udp_crc_start = &buf[off];
+    udp_crc_length = reply_len - off;
     switch (rr->src_addr.ss_family)
     {
     case AF_INET:
@@ -412,6 +468,8 @@
        ip.checksum = 0; /* checksum is optional */
        ip.source_address = dst->sin_addr;
        ip.destination_address = src->sin_addr;
+
+       ip.checksum = GNUNET_CRYPTO_crc16_n ((uint16_t*) &ip, sizeof (ip));
        memcpy (&buf[off], &ip, sizeof (ip));
        off += sizeof (ip);
        break;
@@ -448,16 +506,23 @@
       udp.spt = spt;
       udp.dpt = dpt;
       udp.len = htons (reply_len - off);
-      udp.crc = 0; /* checksum is optional */
+      udp.crc = 0; /* checksum will be set later */
+
       memcpy (&buf[off], &udp, sizeof (udp));
+      udp_crcp = (uint16_t*) &buf[off + offsetof (struct udp_packet, crc)];
       off += sizeof (udp);
     }
         /* now DNS header */
     {
       memcpy (&buf[off], rr->payload, rr->payload_length);
       off += rr->payload_length;
+
+      fprintf (stderr,
+              "Sending %u bytes UDP packet to TUN\n",
+              (unsigned int) rr->payload_length);
     }
     
+    *udp_crcp = GNUNET_CRYPTO_crc16_n ((uint16_t *)udp_crc_start, 
udp_crc_length);
     /* final checks & sending */
     GNUNET_assert (off == reply_len);
     GNUNET_HELPER_send (hijacker,
@@ -579,6 +644,12 @@
       cleanup_rr (rr);
       return;   
     }
+    if (NULL == dnsout)
+    {
+      /* fail, FIXME: case for statistics! */
+      cleanup_rr (rr);
+      return;
+    }
     GNUNET_NETWORK_socket_sendto (dnsout,
                                  rr->payload,
                                  rr->payload_length,
@@ -735,6 +806,10 @@
     GNUNET_free_non_null (rr->payload);
     rr->payload = GNUNET_malloc (len);
     memcpy (rr->payload, buf, len);
+    rr->payload_length = len;
+    fprintf (stderr,
+            "Received %u bytes UDP packet from DNS server\n",
+            (unsigned int) len);
     next_phase (rr);
   }  
 }
@@ -976,6 +1051,7 @@
                         const struct GNUNET_MessageHeader *message)
 {
   uint16_t msize;
+  const struct tun_header *tun;
   const struct ip4_header *ip4;
   const struct ip6_header *ip6;
   const struct udp_packet *udp;
@@ -987,29 +1063,52 @@
   struct sockaddr_in6 *dsta6;
 
   msize = ntohs (message->size);
-  if (msize < sizeof (struct GNUNET_MessageHeader) + sizeof (struct 
ip4_header))
+  if (msize < sizeof (struct GNUNET_MessageHeader) + sizeof (struct 
tun_header) + sizeof (struct ip4_header))
   {
     /* non-IP packet received on TUN!? */
     GNUNET_break (0);
     return;
   }
   msize -= sizeof (struct GNUNET_MessageHeader);
-  ip4 = (const struct ip4_header *) &message[1];
-  ip6 = (const struct ip6_header *) &message[1];
-  if (ip4->version == IPVERSION)
+  tun = (const struct tun_header *) &message[1];
+  msize -= sizeof (struct tun_header);
+  switch (ntohs (tun->proto))
   {
+  case ETH_P_IPV4:
+    ip4 = (const struct ip4_header *) &tun[1];
+    if ( (msize < sizeof (struct ip4_header)) ||
+        (ip4->version != IPVERSION) ||
+        (ip4->header_length != sizeof (struct ip4_header) / 4) ||
+        (ntohs(ip4->total_length) != msize) ||
+        (ip4->protocol != IPPROTO_UDP) )
+    {
+      /* non-IP/UDP packet received on TUN (or with options) */
+      GNUNET_break (0);
+      return;
+    }
     udp = (const struct udp_packet*) &ip4[1];
     msize -= sizeof (struct ip4_header);
-  }
-  else if ( (ip6->version == 6) &&
-           (msize >= sizeof (struct ip6_header)) )
-  {
+    break;
+  case ETH_P_IPV6:
+    ip6 = (const struct ip6_header *) &tun[1];
+    if ( (msize < sizeof (struct ip6_header)) ||
+        (ip6->version != 6) ||
+        (ntohs (ip6->payload_length) != msize) ||
+        (ip6->next_header != IPPROTO_UDP) )
+    {
+      /* non-IP/UDP packet received on TUN (or with extensions) */
+      GNUNET_break (0);
+      return;
+    }
     udp = (const struct udp_packet*) &ip6[1];
     msize -= sizeof (struct ip6_header);
-  }
-  else
-  {
+    break;
+  default:
     /* non-IP packet received on TUN!? */
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               _("Got packet with %u bytes and protocol %u from TUN\n"),
+               (unsigned int) msize,
+               ntohs (tun->proto));
     GNUNET_break (0);
     return;
   }

Modified: gnunet/src/util/crypto_crc.c
===================================================================
--- gnunet/src/util/crypto_crc.c        2012-01-03 21:29:22 UTC (rev 18960)
+++ gnunet/src/util/crypto_crc.c        2012-01-03 22:51:14 UTC (rev 18961)
@@ -114,7 +114,6 @@
 }
 
 
-
 /**
  * Perform an incremental step in a CRC16 (for TCP/IP) calculation.
  *
@@ -126,7 +125,6 @@
 uint32_t
 GNUNET_CRYPTO_crc16_step (uint32_t sum, uint16_t * hdr, size_t len)
 {
-  GNUNET_assert (0 == (len & 1));
   for (; len >= 2; len -= 2)
     sum += *(hdr++);
   if (len == 1)

Modified: gnunet/src/util/helper.c
===================================================================
--- gnunet/src/util/helper.c    2012-01-03 21:29:22 UTC (rev 18960)
+++ gnunet/src/util/helper.c    2012-01-03 22:51:14 UTC (rev 18961)
@@ -152,7 +152,7 @@
 
   if (NULL != h->helper_proc)
   {
-    GNUNET_OS_process_kill (h->helper_proc, SIGKILL);
+    GNUNET_OS_process_kill (h->helper_proc, SIGTERM);
     GNUNET_OS_process_wait (h->helper_proc);
     GNUNET_OS_process_close (h->helper_proc);
     h->helper_proc = NULL;
@@ -247,16 +247,16 @@
   }
   if (0 == t)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 
+    /* this happens if the helper is shut down via a 
+       signal, so it is not a "hard" error */
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
                _("Got 0 bytes from helper `%s' (EOF)\n"),
                h->binary_name);
-#if 0
     stop_helper (h);
     /* Restart the helper */
     h->restart_task =
       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
                                    &restart_task, h);
-#endif
     return;
   }
   if (GNUNET_SYSERR ==




reply via email to

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