gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r19219 - in gnunet/src: dns exit include tun vpn


From: gnunet
Subject: [GNUnet-SVN] r19219 - in gnunet/src: dns exit include tun vpn
Date: Tue, 17 Jan 2012 21:19:03 +0100

Author: grothoff
Date: 2012-01-17 21:19:03 +0100 (Tue, 17 Jan 2012)
New Revision: 19219

Modified:
   gnunet/src/dns/gnunet-service-dns.c
   gnunet/src/exit/gnunet-daemon-exit.c
   gnunet/src/include/gnunet_tun_lib.h
   gnunet/src/tun/tun.c
   gnunet/src/vpn/gnunet-service-vpn.c
Log:
-moving remaining checksum calculations to tun library, fixing #2066

Modified: gnunet/src/dns/gnunet-service-dns.c
===================================================================
--- gnunet/src/dns/gnunet-service-dns.c 2012-01-17 20:14:38 UTC (rev 19218)
+++ gnunet/src/dns/gnunet-service-dns.c 2012-01-17 20:19:03 UTC (rev 19219)
@@ -20,6 +20,7 @@
 
 /**
  * @file dns/gnunet-service-dns.c
+ * @brief service to intercept and modify DNS queries (and replies) of this 
system
  * @author Christian Grothoff
  */
 #include "platform.h"
@@ -351,7 +352,8 @@
   {
     char buf[reply_len];
     size_t off;
-    uint32_t udp_crc_sum;
+    struct GNUNET_TUN_IPv4Header ip4;
+    struct GNUNET_TUN_IPv6Header ip6;
 
     /* first, GNUnet message header */
     hdr = (struct GNUNET_MessageHeader*) buf;
@@ -373,71 +375,38 @@
     }
 
     /* now IP header */
-    udp_crc_sum = 0;    
     switch (rr->src_addr.ss_family)
     {
     case AF_INET:
       {
        struct sockaddr_in *src = (struct sockaddr_in *) &rr->src_addr;
        struct sockaddr_in *dst = (struct sockaddr_in *) &rr->dst_addr;
-       struct GNUNET_TUN_IPv4Header ip;
        
        spt = dst->sin_port;
        dpt = src->sin_port;
-       GNUNET_TUN_initialize_ipv4_header (&ip,
+       GNUNET_TUN_initialize_ipv4_header (&ip4,
                                           IPPROTO_UDP,
                                           reply_len - off - sizeof (struct 
GNUNET_TUN_IPv4Header),
                                           &dst->sin_addr,
                                           &src->sin_addr);
-
-
-
-       udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, 
-                                               &ip.source_address,
-                                               sizeof (struct in_addr) * 2);
-       {
-         uint16_t tmp;
-         
-         tmp = htons (IPPROTO_UDP);
-         udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, 
-                                                 &tmp, 
-                                                 sizeof (uint16_t));
-         tmp = htons (rr->payload_length + sizeof (struct 
GNUNET_TUN_UdpHeader));
-         udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, 
-                                                 &tmp, 
-                                                 sizeof (uint16_t));
-       }
-       memcpy (&buf[off], &ip, sizeof (ip));
-       off += sizeof (ip);
+       memcpy (&buf[off], &ip4, sizeof (ip4));
+       off += sizeof (ip4);
       }
       break;
     case AF_INET6:
       {
        struct sockaddr_in6 *src = (struct sockaddr_in6 *) &rr->src_addr;
        struct sockaddr_in6 *dst = (struct sockaddr_in6 *) &rr->dst_addr;
-       struct GNUNET_TUN_IPv6Header ip;
 
        spt = dst->sin6_port;
        dpt = src->sin6_port;
-       GNUNET_TUN_initialize_ipv6_header (&ip,
+       GNUNET_TUN_initialize_ipv6_header (&ip6,
                                           IPPROTO_UDP,
                                           reply_len - sizeof (struct 
GNUNET_TUN_IPv6Header),
                                           &dst->sin6_addr,
                                           &src->sin6_addr);
-       {
-         uint32_t tmp;
-         
-         tmp = htons (rr->payload_length + sizeof (struct 
GNUNET_TUN_UdpHeader));
-         udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, 
-                                                 &tmp, 
-                                                 sizeof (uint32_t));
-         tmp = htons (IPPROTO_UDP);
-         udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, 
-                                                 &tmp, 
-                                                 sizeof (uint32_t));
-       }
-       memcpy (&buf[off], &ip, sizeof (ip));
-       off += sizeof (ip);
+       memcpy (&buf[off], &ip6, sizeof (ip6));
+       off += sizeof (ip6);
       }
       break;
     default:
@@ -451,17 +420,20 @@
       udp.spt = spt;
       udp.dpt = dpt;
       udp.len = htons (reply_len - off);
-      udp.crc = 0; 
-      udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, 
-                                             &udp, 
-                                             sizeof (udp));
-      udp_crc_sum = GNUNET_CRYPTO_crc16_step (udp_crc_sum, 
-                                             rr->payload,
-                                             rr->payload_length);
-      udp.crc = GNUNET_CRYPTO_crc16_finish (udp_crc_sum);
+      if (AF_INET == rr->src_addr.ss_family)
+       GNUNET_TUN_calculate_udp4_checksum (&ip4,
+                                           &udp,
+                                           rr->payload,
+                                           rr->payload_length);
+      else
+       GNUNET_TUN_calculate_udp6_checksum (&ip6,
+                                           &udp,
+                                           rr->payload,
+                                           rr->payload_length);
       memcpy (&buf[off], &udp, sizeof (udp));
       off += sizeof (udp);
     }
+
     /* now DNS payload */
     {
       memcpy (&buf[off], rr->payload, rr->payload_length);
@@ -1273,4 +1245,4 @@
 }
 
 
-/* end of gnunet-service-dns_new.c */
+/* end of gnunet-service-dns.c */

Modified: gnunet/src/exit/gnunet-daemon-exit.c
===================================================================
--- gnunet/src/exit/gnunet-daemon-exit.c        2012-01-17 20:14:38 UTC (rev 
19218)
+++ gnunet/src/exit/gnunet-daemon-exit.c        2012-01-17 20:19:03 UTC (rev 
19219)
@@ -27,9 +27,6 @@
  * TODO:
  * - test
  *
- * Code cleanup:
- * - factor out crc computations from DNS/EXIT/VPN into shared library?
- *
  * Design:
  * - which code should advertise services? the service model is right
  *   now a bit odd, especially as this code DOES the exit and knows
@@ -1078,8 +1075,10 @@
 
       pkt4_udp->spt = htons (src_address->port);
       pkt4_udp->dpt = htons (dst_address->port);
-      pkt4_udp->crc = 0;  /* Optional for IPv4 */
       pkt4_udp->len = htons ((uint16_t) payload_length);
+      GNUNET_TUN_calculate_udp4_checksum (pkt4,
+                                         pkt4_udp,
+                                         payload, payload_length);
       memcpy (&pkt4_udp[1], payload, payload_length);
     }
     break;
@@ -1088,19 +1087,13 @@
       struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *) 
&pkt4[1];
       
       memcpy (pkt4_tcp, tcp_header, sizeof (struct GNUNET_TUN_TcpHeader));
-      memcpy (&pkt4_tcp[1], payload, payload_length);
       pkt4_tcp->spt = htons (src_address->port);
       pkt4_tcp->dpt = htons (dst_address->port);
-      
-      pkt4_tcp->crc = 0;
-      uint32_t sum = 0;
-      sum = GNUNET_CRYPTO_crc16_step (sum, 
-                                     &pkt4->source_address,
-                                     sizeof (struct in_addr) * 2);
-      uint32_t tmp = htonl ((protocol << 16) | (0xffff & len));
-      sum = GNUNET_CRYPTO_crc16_step (sum, & tmp, sizeof (uint32_t));
-      sum = GNUNET_CRYPTO_crc16_step (sum, & pkt4_tcp, len);
-      pkt4_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
+      GNUNET_TUN_calculate_tcp4_checksum (pkt4,
+                                         pkt4_tcp,
+                                         payload,
+                                         payload_length);
+      memcpy (&pkt4_tcp[1], payload, payload_length);
     }
     break;
   default:
@@ -1172,28 +1165,22 @@
     {
       struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *) 
&pkt6[1];
 
-      memcpy (&pkt6[1], payload, payload_length);
-      pkt6_udp->crc = 0;
       pkt6_udp->spt = htons (src_address->port);
       pkt6_udp->dpt = htons (dst_address->port);
       pkt6_udp->len = htons ((uint16_t) payload_length);
-
-      uint32_t sum = 0;
-      sum = GNUNET_CRYPTO_crc16_step (sum,
-                                     &pkt6->source_address,
-                                     sizeof (struct in6_addr) * 2);
-      uint32_t tmp = htons (len);
-      sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
-      tmp = htonl (pkt6->next_header);
-      sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
-      sum = GNUNET_CRYPTO_crc16_step (sum, pkt6_udp, len);
-      pkt6_udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
+      pkt6_udp->crc = 0;
+      GNUNET_TUN_calculate_udp6_checksum (pkt6,
+                                         pkt6_udp,
+                                         payload,
+                                         payload_length);
+      memcpy (&pkt6[1], payload, payload_length);
     }
     break;
   case IPPROTO_TCP:
     {
       struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *) 
pkt6;
-      
+
+      /* memcpy first here as some TCP header fields are initialized this way! 
*/
       memcpy (pkt6_tcp, payload, payload_length);
       pkt6_tcp->spt = htons (src_address->port);
       pkt6_tcp->dpt = htons (dst_address->port);

Modified: gnunet/src/include/gnunet_tun_lib.h
===================================================================
--- gnunet/src/include/gnunet_tun_lib.h 2012-01-17 20:14:38 UTC (rev 19218)
+++ gnunet/src/include/gnunet_tun_lib.h 2012-01-17 20:19:03 UTC (rev 19219)
@@ -182,10 +182,24 @@
                                   const struct in6_addr *dst);
 
 /**
+ * Calculate IPv4 TCP checksum.
+ *
+ * @param ipv4 header fully initialized
+ * @param tcp TCP header (initialized except for CRC)
+ * @param payload the TCP payload
+ * @param payload_length number of bytes of TCP payload
+ */
+void
+GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
+                                   struct GNUNET_TUN_TcpHeader *tcp,
+                                   const void *payload,
+                                   uint16_t payload_length);
+
+/**
  * Calculate IPv6 TCP checksum.
  *
  * @param ipv6 header fully initialized
- * @param tcp header (initialized except for CRC)
+ * @param tcp TCP header (initialized except for CRC)
  * @param payload the TCP payload
  * @param payload_length number of bytes of TCP payload
  */
@@ -195,5 +209,34 @@
                                    const void *payload,
                                    uint16_t payload_length);
 
+/**
+ * Calculate IPv4 UDP checksum.
+ *
+ * @param ipv4 header fully initialized
+ * @param udp UDP header (initialized except for CRC)
+ * @param payload the UDP payload
+ * @param payload_length number of bytes of UDP payload
+ */
+void
+GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
+                                   struct GNUNET_TUN_UdpHeader *udp,
+                                   const void *payload,
+                                   uint16_t payload_length);
 
+
+/**
+ * Calculate IPv6 UDP checksum.
+ *
+ * @param ipv6 header fully initialized
+ * @param udp UDP header (initialized except for CRC)
+ * @param payload the UDP payload
+ * @param payload_length number of bytes of UDP payload
+ */
+void
+GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
+                                   struct GNUNET_TUN_UdpHeader *udp,
+                                   const void *payload,
+                                   uint16_t payload_length);
+
+
 #endif

Modified: gnunet/src/tun/tun.c
===================================================================
--- gnunet/src/tun/tun.c        2012-01-17 20:14:38 UTC (rev 19218)
+++ gnunet/src/tun/tun.c        2012-01-17 20:19:03 UTC (rev 19219)
@@ -19,7 +19,7 @@
 */
 
 /**
- * @file tun/tun.
+ * @file tun/tun.c
  * @brief standard IP calculations for TUN interaction
  * @author Philipp Toelke
  * @author Christian Grothoff
@@ -32,6 +32,7 @@
  */
 #define FRESH_TTL 255
 
+
 /**
  * Initialize an IPv4 header.
  *
@@ -96,6 +97,39 @@
 
 
 /**
+ * Calculate IPv4 TCP checksum.
+ *
+ * @param ipv4 header fully initialized
+ * @param tcp TCP header (initialized except for CRC)
+ * @param payload the TCP payload
+ * @param payload_length number of bytes of TCP payload
+ */
+void
+GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
+                                   struct GNUNET_TUN_TcpHeader *tcp,
+                                   const void *payload,
+                                   uint16_t payload_length)
+{
+  uint32_t sum;
+  uint32_t tmp;
+
+  GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + 
sizeof (struct GNUNET_TUN_TcpHeader) ==
+                ntohs (ip->total_length));
+  GNUNET_assert (IPPROTO_TCP == ip->protocol);
+
+  tcp->crc = 0;
+  sum = GNUNET_CRYPTO_crc16_step (0, 
+                                 &ip->source_address,
+                                 sizeof (struct in_addr) * 2);
+  tmp = htonl ((IPPROTO_TCP << 16) | (payload_length + sizeof (struct 
GNUNET_TUN_TcpHeader)));
+  sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
+  sum = GNUNET_CRYPTO_crc16_step (sum, tcp, sizeof (struct 
GNUNET_TUN_TcpHeader));
+  sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
+  tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
+}
+
+
+/**
  * Calculate IPv6 TCP checksum.
  *
  * @param ipv6 header fully initialized
@@ -114,6 +148,7 @@
 
   GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv6Header) + 
sizeof (struct GNUNET_TUN_TcpHeader) ==
                 ntohs (ip->payload_length));
+  GNUNET_assert (IPPROTO_TCP == ip->next_header);
   tcp->crc = 0;
   sum = GNUNET_CRYPTO_crc16_step (0, &ip->source_address, 2 * sizeof (struct 
in6_addr));
   tmp = htonl (sizeof (struct GNUNET_TUN_TcpHeader) + payload_length);
@@ -127,5 +162,84 @@
 }
 
 
+/**
+ * Calculate IPv4 UDP checksum.
+ *
+ * @param ipv4 header fully initialized
+ * @param udp UDP header (initialized except for CRC)
+ * @param payload the UDP payload
+ * @param payload_length number of bytes of UDP payload
+ */
+void
+GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip,
+                                   struct GNUNET_TUN_UdpHeader *udp,
+                                   const void *payload,
+                                   uint16_t payload_length)
+{
+  uint32_t sum;
+  uint16_t tmp;
 
+  GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv4Header) + 
sizeof (struct GNUNET_TUN_UdpHeader) ==
+                ntohs (ip->total_length));
+  GNUNET_assert (IPPROTO_UDP == ip->protocol);
+
+  udp->crc = 0; /* technically optional, but we calculate it anyway, just to 
be sure */
+  sum = GNUNET_CRYPTO_crc16_step (0, 
+                                 &ip->source_address,
+                                 sizeof (struct in_addr) * 2);
+  tmp = htons (IPPROTO_UDP);
+  sum = GNUNET_CRYPTO_crc16_step (sum, 
+                                 &tmp, 
+                                 sizeof (uint16_t));
+  tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length);
+  sum = GNUNET_CRYPTO_crc16_step (sum, 
+                                 &tmp, 
+                                 sizeof (uint16_t));
+  sum = GNUNET_CRYPTO_crc16_step (sum, 
+                                 udp, 
+                                 sizeof (struct GNUNET_TUN_UdpHeader));
+  sum = GNUNET_CRYPTO_crc16_step (sum, 
+                                 payload,
+                                 payload_length);
+  udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
+}
+
+
+/**
+ * Calculate IPv6 UDP checksum.
+ *
+ * @param ipv6 header fully initialized
+ * @param udp UDP header (initialized except for CRC)
+ * @param payload the UDP payload
+ * @param payload_length number of bytes of UDP payload
+ */
+void
+GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip,
+                                   struct GNUNET_TUN_UdpHeader *udp,
+                                   const void *payload,
+                                   uint16_t payload_length)
+{
+  uint32_t sum;
+  uint32_t tmp;
+
+  GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_IPv6Header) + 
sizeof (struct GNUNET_TUN_UdpHeader) ==
+                ntohs (ip->payload_length));
+  GNUNET_assert (payload_length + sizeof (struct GNUNET_TUN_UdpHeader) ==
+                ntohs (udp->len));
+  GNUNET_assert (IPPROTO_UDP == ip->next_header);
+
+  udp->crc = 0;
+  sum = GNUNET_CRYPTO_crc16_step (0,
+                                 &ip->source_address,
+                                 sizeof (struct in6_addr) * 2);
+  tmp = htons (sizeof (struct GNUNET_TUN_UdpHeader) + payload_length); /* aka 
udp->len */
+  sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
+  tmp = htons (ip->next_header);
+  sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
+  sum = GNUNET_CRYPTO_crc16_step (sum, udp, sizeof (struct 
GNUNET_TUN_UdpHeader));
+  sum = GNUNET_CRYPTO_crc16_step (sum, payload, payload_length);
+  udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
+}
+
+
 /* end of tun.c */

Modified: gnunet/src/vpn/gnunet-service-vpn.c
===================================================================
--- gnunet/src/vpn/gnunet-service-vpn.c 2012-01-17 20:14:38 UTC (rev 19218)
+++ gnunet/src/vpn/gnunet-service-vpn.c 2012-01-17 20:19:03 UTC (rev 19219)
@@ -32,10 +32,6 @@
  *
  * Features:
  * - add back ICMP support (especially needed for IPv6)
- *
- * Code cleanup:
- * - consider moving IP-header building / checksumming code into shared library
- *   with dns/exit/vpn (libgnunettun_tcpip?)
  */
 #include "platform.h"
 #include "gnunet_util_lib.h"
@@ -1436,7 +1432,10 @@
        else
          udp->dpt = reply->destination_port;
        udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader));
-       udp->crc = 0; // FIXME: optional, but we might want to calculate this 
one anyway
+       GNUNET_TUN_calculate_udp4_checksum (ipv4,
+                                           udp,
+                                           &reply[1],
+                                           mlen);
        memcpy (&udp[1],
                &reply[1],
                mlen);
@@ -1464,15 +1463,11 @@
        msg->size = htons (size);
        tun->flags = htons (0);
        tun->proto = htons (ETH_P_IPV6);
-       ipv6->traffic_class_h = 0;
-       ipv6->version = 6;
-       ipv6->traffic_class_l = 0;
-       ipv6->flow_label = 0;
-       ipv6->payload_length = htons (sizeof (struct GNUNET_TUN_UdpHeader) + 
sizeof (struct GNUNET_TUN_IPv6Header) + mlen);
-       ipv6->next_header = IPPROTO_UDP;
-       ipv6->hop_limit = 255;
-       ipv6->source_address = ts->destination_ip.v6;
-       ipv6->destination_address = ts->source_ip.v6;
+       GNUNET_TUN_initialize_ipv6_header (ipv6,
+                                          IPPROTO_UDP,
+                                          sizeof (struct GNUNET_TUN_UdpHeader) 
+ mlen,
+                                          &ts->destination_ip.v6,
+                                          &ts->source_ip.v6);
        if (0 == ntohs (reply->source_port))
          udp->spt = htons (ts->destination_port);
        else
@@ -1482,24 +1477,12 @@
        else
          udp->dpt = reply->destination_port;
        udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader));
-       udp->crc = 0;
+       GNUNET_TUN_calculate_udp6_checksum (ipv6,
+                                           udp,
+                                           &reply[1], mlen);
        memcpy (&udp[1],
                &reply[1],
                mlen);
-       {
-         uint32_t sum = 0;
-         sum =
-           GNUNET_CRYPTO_crc16_step (sum, &ipv6->source_address, 
-                                     sizeof (struct in6_addr) * 2);
-         uint32_t tmp = udp->len;
-         sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
-         tmp = htons (IPPROTO_UDP);
-         sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
-         sum = GNUNET_CRYPTO_crc16_step (sum, 
-                                         udp,
-                                         ntohs (udp->len));
-         udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
-       }
        (void) GNUNET_HELPER_send (helper_handle,
                                   msg,
                                   GNUNET_YES,
@@ -1596,22 +1579,13 @@
        *tcp = data->tcp_header;
        tcp->spt = htons (ts->destination_port);
        tcp->dpt = htons (ts->source_port);
-       tcp->crc = 0;
+       GNUNET_TUN_calculate_tcp4_checksum (ipv4,
+                                           tcp,
+                                           &data[1],
+                                           mlen);
        memcpy (&tcp[1],
                &data[1],
                mlen);
-       {
-         uint32_t sum = 0;
-         uint32_t tmp;
-         
-         sum = GNUNET_CRYPTO_crc16_step (sum, 
-                                         &ipv4->source_address,
-                                         2 * sizeof (struct in_addr));   
-         tmp = htonl ((IPPROTO_TCP << 16) | (mlen + sizeof (struct 
GNUNET_TUN_TcpHeader)));
-         sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
-         sum = GNUNET_CRYPTO_crc16_step (sum, tcp, mlen + sizeof (struct 
GNUNET_TUN_TcpHeader));
-         tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
-       }
        (void) GNUNET_HELPER_send (helper_handle,
                                   msg,
                                   GNUNET_YES,




reply via email to

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