gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r10218 - gnunet/src/transport


From: gnunet
Subject: [GNUnet-SVN] r10218 - gnunet/src/transport
Date: Fri, 5 Feb 2010 09:49:50 +0100

Author: grothoff
Date: 2010-02-05 09:49:50 +0100 (Fri, 05 Feb 2010)
New Revision: 10218

Modified:
   gnunet/src/transport/gnunet-nat-client.c
   gnunet/src/transport/gnunet-nat-server.c
Log:
fixed

Modified: gnunet/src/transport/gnunet-nat-client.c
===================================================================
--- gnunet/src/transport/gnunet-nat-client.c    2010-02-04 15:54:07 UTC (rev 
10217)
+++ gnunet/src/transport/gnunet-nat-client.c    2010-02-05 08:49:50 UTC (rev 
10218)
@@ -41,17 +41,24 @@
 #include <netinet/ip_icmp.h>
 #include <netinet/in.h> 
 
+#define DEBUG 0
+
 /**
- * Number of UDP ports to keep open.
+ * Number of UDP ports to keep open (typically >= 256)
  */
-#define NUM_UDP_PORTS 512
+#define NUM_UDP_PORTS 256
 
 /**
- * How often do we send our UDP messages to keep ports open?
+ * Number of ICMP replies to send per message received (typically >= 1024)
  */
-#define UDP_SEND_FREQUENCY_MS 500
+#define NUM_ICMP_REPLIES 1024
 
 /**
+ * How often do we send our UDP messages to keep ports open? (typically < 
100ms)
+ */
+#define UDP_SEND_FREQUENCY_MS 50
+
+/**
  * Port we use for the dummy target.
  */
 #define NAT_TRAV_PORT 2222
@@ -61,7 +68,6 @@
  */
 #define MAX_TRIES 10
 
-
 struct ip_packet 
 {
   uint8_t vers_ihl;
@@ -76,14 +82,6 @@
   uint32_t dst_ip;
 };
 
-struct icmp_packet 
-{
-  uint8_t type;
-  uint8_t code;
-  uint16_t checksum;
-  uint32_t reserved;
-};
-
 struct udp_packet
 {
   uint16_t source_port;
@@ -92,25 +90,17 @@
   uint16_t checksum_aka_my_magic;
 };
 
-
-/**
- * Structure of the data we tack on to the fake ICMP reply
- * (last 4 bytes of the 64 bytes).
- */
-struct extra_packet
+struct icmp_packet 
 {
-  /**
-   * if this is a reply to an icmp, what was the 'my_magic'
-   * value from the original icmp?
-   */
-  uint16_t reply_port_magic;
-
-  /**
-   * magic value of the sender of this icmp message.
-   */
-  uint16_t my_magic;
+  uint8_t type;
+  uint8_t code;
+  uint16_t checksum;
+  uint32_t reserved;
+  struct ip_packet ip;
+  struct udp_packet udp;
 };
 
+
 static int udpsocks[NUM_UDP_PORTS];
 
 static uint16_t udpports[NUM_UDP_PORTS];
@@ -217,9 +207,8 @@
 {
   struct ip_packet ip_pkt;
   struct icmp_packet icmp_pkt;
-  struct udp_packet udp_pkt;
   struct sockaddr_in dst;
-  char packet[sizeof (ip_pkt) + sizeof (icmp_pkt) + sizeof (udp_pkt)];
+  char packet[sizeof (ip_pkt) + sizeof (icmp_pkt)];
   size_t off;
   int err;
 
@@ -233,7 +222,7 @@
   ip_pkt.flags_frag_offset = 0;
   ip_pkt.ttl = IPDEFTTL;
   ip_pkt.proto = IPPROTO_ICMP;
-  ip_pkt.checksum = 0; /* maybe the kernel helps us out..? */
+  ip_pkt.checksum = 0;
   ip_pkt.src_ip = my_ip->s_addr;
   ip_pkt.dst_ip = other->s_addr;
   ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, sizeof (ip_pkt)));
@@ -243,41 +232,31 @@
   /* icmp reply: time exceeded */
   memset(&icmp_pkt, 0, sizeof(icmp_pkt));
   icmp_pkt.type = ICMP_TIME_EXCEEDED;
-  icmp_pkt.code = ICMP_NET_UNREACH;
+  icmp_pkt.code = ICMP_HOST_UNREACH;
   icmp_pkt.reserved = 0;
   icmp_pkt.checksum = 0;
-  icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&icmp_pkt, sizeof 
(icmp_pkt)));
-  memcpy (&packet[off], &icmp_pkt, sizeof (icmp_pkt));
-  off += sizeof (icmp_pkt);
 
   /* ip header of the presumably 'lost' udp packet */
-  memset(&ip_pkt, 0, sizeof (ip_pkt));
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
+  icmp_pkt.ip.vers_ihl = 0x45;
+  icmp_pkt.ip.tos = 0;
   /* no idea why i need to shift the bits here, but not on ip_pkt->pkt_len... 
*/
-  ip_pkt.pkt_len = (sizeof (ip_pkt) + sizeof (icmp_pkt)) << 8;
-  ip_pkt.id = 1; /* kernel sets proper value htons(ip_id_counter); */
-  ip_pkt.flags_frag_offset = 0;
-  ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
-  ip_pkt.proto = IPPROTO_UDP;
-  ip_pkt.src_ip = other->s_addr;
-  ip_pkt.dst_ip = dummy.s_addr;
-  ip_pkt.checksum = 0;
-  ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, sizeof (ip_pkt)));
-  memcpy (&packet[off], &ip_pkt, sizeof (ip_pkt));
-  off += sizeof (ip_pkt);
+  icmp_pkt.ip.pkt_len = (sizeof (ip_pkt) + sizeof (icmp_pkt)) << 8;
+  icmp_pkt.ip.id = 1; /* kernel sets proper value htons(ip_id_counter); */
+  icmp_pkt.ip.flags_frag_offset = 0;
+  icmp_pkt.ip.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
+  icmp_pkt.ip.proto = IPPROTO_UDP;
+  icmp_pkt.ip.src_ip = other->s_addr;
+  icmp_pkt.ip.dst_ip = dummy.s_addr;
+  icmp_pkt.ip.checksum = 0;
+  icmp_pkt.ip.checksum = htons(calc_checksum((uint16_t*)&icmp_pkt.ip, sizeof 
(icmp_pkt.ip)));
+  icmp_pkt.udp.source_port = htons (target_port_number);
+  icmp_pkt.udp.dst_port = htons (NAT_TRAV_PORT);
+  icmp_pkt.udp.mlen_aka_reply_port_magic = htons (source_port_number);
+  icmp_pkt.udp.checksum_aka_my_magic = htons (target_port_number);
+  icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&icmp_pkt, sizeof 
(icmp_pkt)));
+  memcpy (&packet[off], &icmp_pkt, sizeof (icmp_pkt));
+  off += sizeof (icmp_pkt);
   
-  memset(&udp_pkt, 0, sizeof (udp_pkt));
-  udp_pkt.source_port = htons (target_port_number);
-  udp_pkt.dst_port = htons (NAT_TRAV_PORT);
-  fprintf (stderr,
-          "** Generating ICMP with rpm %u\n",
-          target_port_number);
-  udp_pkt.mlen_aka_reply_port_magic = htons (source_port_number);
-  udp_pkt.checksum_aka_my_magic = htons (target_port_number);
-  memcpy (&packet[off], &udp_pkt, sizeof (udp_pkt));
-  off += sizeof (udp_pkt);
-  
   memset (&dst, 0, sizeof (dst));
   dst.sin_family = AF_INET;
   dst.sin_addr = *other;
@@ -309,13 +288,13 @@
 
   fprintf (stderr,
           "Sending %u ICMPs to `%s' with reply magic %u\n",
-          NUM_UDP_PORTS,
+          NUM_ICMP_REPLIES,
           inet_ntop (AF_INET,
                      other,
                      sbuf,
                      sizeof (sbuf)),
           port_magic);
-  for (i=0;i<NUM_UDP_PORTS;i++)
+  for (i=0;i<NUM_ICMP_REPLIES;i++)
     send_icmp (my_ip, other, make_port(), port_magic);
 }
 
@@ -332,7 +311,6 @@
   uint16_t local_port;
   struct ip_packet ip_pkt;
   struct icmp_packet icmp_pkt;
-  struct udp_packet udp_pkt;  
   size_t off;
   
   have = read (s, buf, sizeof (buf));
@@ -344,8 +322,7 @@
       /* What now? */
       return; 
     }
-  if (have != sizeof (struct ip_packet) *2 + sizeof (struct icmp_packet) + 
-      sizeof (struct udp_packet))
+  if (have != sizeof (struct ip_packet) + sizeof (struct icmp_packet))
     {
       fprintf (stderr,
               "Received ICMP message of unexpected size: %u bytes\n",
@@ -357,9 +334,6 @@
   off += sizeof (ip_pkt);
   memcpy (&icmp_pkt, &buf[off], sizeof (icmp_pkt));
   off += sizeof (icmp_pkt);
-  off += sizeof (ip_pkt);
-  memcpy (&udp_pkt, &buf[off], sizeof (udp_pkt));
-  off += sizeof (struct udp_packet);
 
   if ( (ip_pkt.proto == IPPROTO_ICMP) &&
        (icmp_pkt.type == ICMP_DEST_UNREACH) && 
@@ -368,31 +342,43 @@
       /* this is what is normal due to our UDP traffic */
       return;
     }
+  if ( (ip_pkt.proto == IPPROTO_ICMP) &&
+       (icmp_pkt.type == ICMP_TIME_EXCEEDED) &&
+       (icmp_pkt.code == ICMP_HOST_UNREACH) )
+    {
+      /* this is what we might see on loopback: this is the format
+        we as the client send out (the host uses 'ICMP_NET_UNREACH');
+        Ignore! */
+      return;
+    }
   if ( (ip_pkt.proto != IPPROTO_ICMP) ||
        (icmp_pkt.type != ICMP_TIME_EXCEEDED) || 
        (icmp_pkt.code != ICMP_NET_UNREACH) )
     {
       /* Note the expected client response and not the normal network response 
*/
+#if DEBUG
       fprintf (stderr,
               "Received unexpected ICMP message contents (%u, %u, %u), 
ignoring\n",
               ip_pkt.proto,
               icmp_pkt.type,
               icmp_pkt.code);
+#endif
       return;
     }
   memcpy(&sip, &ip_pkt.src_ip, sizeof (sip));
-  reply_magic = ntohs (udp_pkt.checksum_aka_my_magic);
-  my_magic = ntohs (udp_pkt.mlen_aka_reply_port_magic);
-  local_port = ntohs (udp_pkt.source_port);
+  reply_magic = ntohs (icmp_pkt.udp.checksum_aka_my_magic);
+  my_magic = ntohs (icmp_pkt.udp.mlen_aka_reply_port_magic);
+  local_port = ntohs (icmp_pkt.udp.source_port);
   if  (my_magic == 0)
     {
-#if 0
+#if DEBUG
       /* we get these a lot during loopback testing... */
       fprintf (stderr,
               "Received ICMP without hint as to which port worked, 
dropping\n");
 #endif
       return;
     }
+#if DEBUG
   fprintf (stderr,
           "Received ICMP from `%s' with outgoing port %u, listen port %u and 
incoming for other peer %u\n",
           inet_ntop (AF_INET,
@@ -402,6 +388,7 @@
           my_magic,
           local_port,
           reply_magic);
+#endif
   if (my_magic == 0)
     {
       try_connect (my_ip, &sip, reply_magic);
@@ -417,6 +404,7 @@
              my_magic,
              local_port);
       /* technically, we're done here! */      
+      exit (0);
     }
 }
 
@@ -538,10 +526,12 @@
          process_icmp_response (&external, icmpsock);
          continue;
        }
+#if DEBUG
       fprintf (stderr,
               "Sending UDP message to %s:%u\n",
               argv[3],
               NAT_TRAV_PORT);      
+#endif
       if (-1 == sendto (udpsocks[pos],
                        NULL, 0, 0,
                        (struct sockaddr*) &dst, sizeof (dst)))
@@ -553,10 +543,12 @@
          udpsocks[pos] = make_udp_socket (&udpports[pos]);
        }
       p = make_port ();
+#if DEBUG
       fprintf (stderr,
               "Sending fake ICMP message to %s:%u\n",
               argv[1],
               p);      
+#endif
       send_icmp (&external,
                 &target,
                 p,

Modified: gnunet/src/transport/gnunet-nat-server.c
===================================================================
--- gnunet/src/transport/gnunet-nat-server.c    2010-02-04 15:54:07 UTC (rev 
10217)
+++ gnunet/src/transport/gnunet-nat-server.c    2010-02-05 08:49:50 UTC (rev 
10218)
@@ -41,17 +41,24 @@
 #include <netinet/ip_icmp.h>
 #include <netinet/in.h> 
 
+#define DEBUG 0
+
 /**
- * Number of UDP ports to keep open.
+ * Number of UDP ports to keep open (typically >= 256).
  */
-#define NUM_UDP_PORTS 512
+#define NUM_UDP_PORTS 256
 
 /**
- * How often do we send our UDP messages to keep ports open?
+ * Number of ICMP replies to send per message received (typically >= 1024)
  */
-#define UDP_SEND_FREQUENCY_MS 500
+#define NUM_ICMP_REPLIES 1024
 
 /**
+ * How often do we send our UDP messages to keep ports open? (typically < 
100ms)
+ */
+#define UDP_SEND_FREQUENCY_MS 50
+
+/**
  * Port we use for the dummy target.
  */
 #define NAT_TRAV_PORT 2222
@@ -77,13 +84,6 @@
   uint32_t dst_ip;
 };
 
-struct icmp_packet 
-{
-  uint8_t type;
-  uint8_t code;
-  uint16_t checksum;
-  uint32_t reserved;
-};
 
 struct udp_packet
 {
@@ -94,6 +94,17 @@
 };
 
 
+struct icmp_packet 
+{
+  uint8_t type;
+  uint8_t code;
+  uint16_t checksum;
+  uint32_t reserved;
+  struct ip_packet ip;
+  struct udp_packet udp;
+};
+
+
 /**
  * Structure of the data we tack on to the fake ICMP reply
  * (last 4 bytes of the 64 bytes).
@@ -216,9 +227,8 @@
 {
   struct ip_packet ip_pkt;
   struct icmp_packet icmp_pkt;
-  struct udp_packet udp_pkt;
   struct sockaddr_in dst;
-  char packet[sizeof (ip_pkt) + sizeof (icmp_pkt) + sizeof (udp_pkt)];
+  char packet[sizeof (ip_pkt) + sizeof (icmp_pkt)];
   size_t off;
   int err;
 
@@ -245,35 +255,28 @@
   icmp_pkt.code = ICMP_NET_UNREACH;
   icmp_pkt.reserved = 0;
   icmp_pkt.checksum = 0;
+
+  /* ip header of the presumably 'lost' udp packet */
+  icmp_pkt.ip.vers_ihl = 0x45;
+  icmp_pkt.ip.tos = 0;
+  /* no idea why i need to shift the bits here, but not on ip_pkt->pkt_len... 
*/
+  icmp_pkt.ip.pkt_len = (sizeof (ip_pkt) + sizeof (icmp_pkt)) << 8;
+  icmp_pkt.ip.id = 1; /* kernel sets proper value htons(ip_id_counter); */
+  icmp_pkt.ip.flags_frag_offset = 0;
+  icmp_pkt.ip.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
+  icmp_pkt.ip.proto = IPPROTO_UDP;
+  icmp_pkt.ip.src_ip = other->s_addr;
+  icmp_pkt.ip.dst_ip = dummy.s_addr;
+  icmp_pkt.ip.checksum = 0;
+  icmp_pkt.ip.checksum = htons(calc_checksum((uint16_t*)&icmp_pkt.ip, sizeof 
(icmp_pkt.ip)));
+  icmp_pkt.udp.source_port = htons (target_port_number);
+  icmp_pkt.udp.dst_port = htons (NAT_TRAV_PORT);
+  icmp_pkt.udp.mlen_aka_reply_port_magic = htons (source_port_number);
+  icmp_pkt.udp.checksum_aka_my_magic = htons (target_port_number);
   icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&icmp_pkt, sizeof 
(icmp_pkt)));
   memcpy (&packet[off], &icmp_pkt, sizeof (icmp_pkt));
   off += sizeof (icmp_pkt);
-
-  /* ip header of the presumably 'lost' udp packet */
-  memset(&ip_pkt, 0, sizeof (ip_pkt));
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
-  /* no idea why i need to shift the bits here, but not on ip_pkt->pkt_len... 
*/
-  ip_pkt.pkt_len = (sizeof (ip_pkt) + sizeof (icmp_pkt)) << 8;
-  ip_pkt.id = 1; /* kernel sets proper value htons(ip_id_counter); */
-  ip_pkt.flags_frag_offset = 0;
-  ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
-  ip_pkt.proto = IPPROTO_UDP;
-  ip_pkt.src_ip = other->s_addr;
-  ip_pkt.dst_ip = dummy.s_addr;
-  ip_pkt.checksum = 0;
-  ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, sizeof (ip_pkt)));
-  memcpy (&packet[off], &ip_pkt, sizeof (ip_pkt));
-  off += sizeof (ip_pkt);
-  
-  memset(&udp_pkt, 0, sizeof (udp_pkt));
-  udp_pkt.source_port = htons (target_port_number); /* this one will be 
re-written by NAT */
-  udp_pkt.dst_port = htons (NAT_TRAV_PORT);
-  udp_pkt.mlen_aka_reply_port_magic = htons (source_port_number);
-  udp_pkt.checksum_aka_my_magic = htons (target_port_number); /* this one 
should be bounced back to me as 'reply_port_magic' */
-  memcpy (&packet[off], &udp_pkt, sizeof (udp_pkt));
-  off += sizeof (udp_pkt);
-  
+ 
   memset (&dst, 0, sizeof (dst));
   dst.sin_family = AF_INET;
   dst.sin_addr = *other;
@@ -301,17 +304,19 @@
             uint16_t port_magic)
 {
   unsigned int i;
+#if DEBUG
   char sbuf [INET_ADDRSTRLEN];
 
   fprintf (stderr,
           "Sending %u ICMPs to `%s' with reply magic %u\n",
-          NUM_UDP_PORTS,
+          NUM_ICMP_REPLIES,
           inet_ntop (AF_INET,
                      other,
                      sbuf,
                      sizeof (sbuf)),
           port_magic);  
-  for (i=0;i<NUM_UDP_PORTS;i++)
+#endif
+  for (i=0;i<NUM_ICMP_REPLIES;i++)
     send_icmp (my_ip, other, make_port(), port_magic);
 }
 
@@ -328,7 +333,6 @@
   uint16_t local_port;
   struct ip_packet ip_pkt;
   struct icmp_packet icmp_pkt;
-  struct udp_packet udp_pkt;  
   size_t off;
   
   have = read (s, buf, sizeof (buf));
@@ -340,8 +344,7 @@
       /* What now? */
       return; 
     }
-  if (have != 2 * sizeof (struct ip_packet) + sizeof (struct icmp_packet) + 
-      sizeof (struct udp_packet))
+  if (have != sizeof (struct ip_packet) + sizeof (struct icmp_packet))
     {
       fprintf (stderr,
               "Received ICMP message of unexpected size: %u bytes\n",
@@ -353,9 +356,6 @@
   off += sizeof (ip_pkt);
   memcpy (&icmp_pkt, &buf[off], sizeof (icmp_pkt));
   off += sizeof (icmp_pkt);
-  off += sizeof (ip_pkt);
-  memcpy (&udp_pkt, &buf[off], sizeof (udp_pkt));
-  off += sizeof (struct udp_packet);
 
   if ( (ip_pkt.proto == IPPROTO_ICMP) &&
        (icmp_pkt.type == ICMP_DEST_UNREACH) && 
@@ -364,9 +364,19 @@
       /* this is what is normal due to our UDP traffic */
       return;
     }
+  if ( (ip_pkt.proto == IPPROTO_ICMP) &&
+       (icmp_pkt.type == ICMP_TIME_EXCEEDED) &&
+       (icmp_pkt.code == ICMP_NET_UNREACH) )
+    {
+      /* this is what we might see on loopback: this is the format
+        we as the server send out (the client uses 'ICMP_HOST_UNREACH');
+        Ignore! */
+      return;
+    }
+
   if ( (ip_pkt.proto != IPPROTO_ICMP) ||
        (icmp_pkt.type != ICMP_TIME_EXCEEDED) || 
-       (icmp_pkt.code != ICMP_NET_UNREACH) )
+       (icmp_pkt.code != ICMP_HOST_UNREACH) )
     {
       /* Note the expected client response and not the normal network response 
*/
       fprintf (stderr,
@@ -377,9 +387,10 @@
       return;
     }
   memcpy(&sip, &ip_pkt.src_ip, sizeof (sip));
-  reply_magic = ntohs (udp_pkt.checksum_aka_my_magic);
-  my_magic = ntohs (udp_pkt.mlen_aka_reply_port_magic);
-  local_port = ntohs (udp_pkt.source_port);
+  reply_magic = ntohs (icmp_pkt.udp.checksum_aka_my_magic);
+  my_magic = ntohs (icmp_pkt.udp.mlen_aka_reply_port_magic);
+  local_port = ntohs (icmp_pkt.udp.source_port);
+#if DEBUG
   fprintf (stderr,
           "Received ICMP from `%s' with outgoing port %u, listen port %u and 
incoming port hint for other peer %u\n",
           inet_ntop (AF_INET,
@@ -389,6 +400,7 @@
           my_magic,
           local_port,
           reply_magic);
+#endif
   if (my_magic == 0)
     {
       try_connect (my_ip, &sip, reply_magic);
@@ -522,11 +534,12 @@
          process_icmp_response (&external, icmpsock);
          continue;
        }
+#if DEBUG
       fprintf (stderr,
               "Sending UDP message to %s:%u\n",
               argv[2],
               NAT_TRAV_PORT);
-              
+#endif
       if (-1 == sendto (udpsocks[pos],
                        NULL, 0, 0,
                        (struct sockaddr*) &dst, sizeof (dst)))





reply via email to

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