gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r14639 - gnunet/src/vpn


From: gnunet
Subject: [GNUnet-SVN] r14639 - gnunet/src/vpn
Date: Mon, 14 Mar 2011 16:16:31 +0100

Author: toelke
Date: 2011-03-14 16:16:31 +0100 (Mon, 14 Mar 2011)
New Revision: 14639

Modified:
   gnunet/src/vpn/gnunet-daemon-exit.c
   gnunet/src/vpn/gnunet-daemon-vpn-helper.c
   gnunet/src/vpn/gnunet-daemon-vpn.c
Log:
Send TCP in both directions:

address@hidden ~$ time scp philipptoelke.gnunet:tmp/file tmp/d/
file 100%  100MB   4.8MB/s   00:21
real    0m30.588s
user    0m1.484s
sys 0m0.386s

Modified: gnunet/src/vpn/gnunet-daemon-exit.c
===================================================================
--- gnunet/src/vpn/gnunet-daemon-exit.c 2011-03-14 15:16:31 UTC (rev 14638)
+++ gnunet/src/vpn/gnunet-daemon-exit.c 2011-03-14 15:16:31 UTC (rev 14639)
@@ -174,102 +174,190 @@
 }
 
 /**
- * Receive packets from the helper-process
+ * @brief Handles an UDP-Packet received from the helper.
+ *
+ * @param udp A pointer to the Packet
+ * @param dadr The IP-Destination-address
+ * @param addrlen The length of the address
+ * @param version 4 or 6
  */
 static void
-message_token (void *cls,
-               void *client, const struct GNUNET_MessageHeader *message)
+udp_from_helper (struct udp_pkt *udp, unsigned char *dadr, size_t addrlen,
+                 unsigned int version)
 {
-  GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER);
-
-  struct tun_pkt *pkt_tun = (struct tun_pkt *) message;
-
-  struct GNUNET_MessageHeader *msg;
+  struct redirect_info u_i;
   struct GNUNET_MESH_Tunnel *tunnel;
   uint32_t len;
+  struct GNUNET_MessageHeader *msg;
 
-  struct udp_pkt *udp;
-  struct redirect_info u_i;
-  memset(&u_i, 0, sizeof(struct redirect_info));
+  memset (&u_i, 0, sizeof (struct redirect_info));
 
-  unsigned int version;
+  memcpy (&u_i.addr, dadr, addrlen);
 
-  /* ethertype is ipv6 */
-  if (ntohs (pkt_tun->tun.type) == 0x86dd)
-    {
-      struct ip6_udp *pkt6 = (struct ip6_udp*)pkt_tun;
-      if (pkt6->ip6_hdr.nxthdr != 0x11) return;
-      /* lookup in udp_connections for dpt/dadr*/
-      memcpy(&u_i.addr, pkt6->ip6_hdr.dadr, 16);
-      udp = &pkt6->udp_hdr;
-      version = 6;
-    }
-  else if (ntohs(pkt_tun->tun.type) == 0x0800)
-    {
-      struct ip_udp *pkt4 = (struct ip_udp*)pkt_tun;
-      if (pkt4->ip_hdr.proto != 0x11) return;
-      uint32_t tmp = pkt4->ip_hdr.dadr;
-      memcpy(&u_i.addr, &tmp, 4);
-      udp = &pkt4->udp_hdr;
-      version = 4;
-    }
-  else
-    {
-      return;
-    }
-
   u_i.pt = udp->dpt;
 
-  /* get tunnel and service-descriptor from this*/
+  /* get tunnel and service-descriptor from this */
   GNUNET_HashCode hash;
-  GNUNET_CRYPTO_hash(&u_i, sizeof(struct redirect_info), &hash);
-  struct redirect_state *state = 
GNUNET_CONTAINER_multihashmap_get(udp_connections, &hash);
+  GNUNET_CRYPTO_hash (&u_i, sizeof (struct redirect_info), &hash);
+  struct redirect_state *state =
+    GNUNET_CONTAINER_multihashmap_get (udp_connections, &hash);
 
   tunnel = state->tunnel;
 
-  /* check if spt == serv.remote if yes: set spt = serv.myport*/
-  if (ntohs(udp->spt) == state->serv->remote_port)
+  /* check if spt == serv.remote if yes: set spt = serv.myport ("nat") */
+  if (ntohs (udp->spt) == state->serv->remote_port)
     {
-      udp->spt = htons(state->serv->my_port);
+      udp->spt = htons (state->serv->my_port);
     }
   else
     {
-      struct redirect_service *serv = GNUNET_malloc(sizeof(struct 
redirect_service));
-      memcpy(serv, state->serv, sizeof(struct redirect_service));
-      serv->my_port = ntohs(udp->spt);
-      serv->remote_port = ntohs(udp->spt);
+      struct redirect_service *serv =
+        GNUNET_malloc (sizeof (struct redirect_service));
+      memcpy (serv, state->serv, sizeof (struct redirect_service));
+      serv->my_port = ntohs (udp->spt);
+      serv->remote_port = ntohs (udp->spt);
       uint16_t *desc = alloca (sizeof (GNUNET_HashCode) + 2);
-      memcpy((GNUNET_HashCode *) (desc + 1), &state->desc, 
sizeof(GNUNET_HashCode));
-      *desc = ntohs(udp->spt);
+      memcpy ((GNUNET_HashCode *) (desc + 1), &state->desc,
+              sizeof (GNUNET_HashCode));
+      *desc = ntohs (udp->spt);
       GNUNET_HashCode hash;
       GNUNET_CRYPTO_hash (desc, sizeof (GNUNET_HashCode) + 2, &hash);
       GNUNET_assert (GNUNET_OK ==
-                    GNUNET_CONTAINER_multihashmap_put (udp_services,
-                                                       &hash, serv,
-                                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+                     GNUNET_CONTAINER_multihashmap_put (udp_services,
+                                                        &hash, serv,
+                                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
       state->serv = serv;
     }
-  /* send udp-packet back */ 
-  len = sizeof(struct GNUNET_MessageHeader) + sizeof(GNUNET_HashCode) + 
ntohs(udp->len);
-  msg = GNUNET_malloc(len);
-  msg->size = htons(len);
-  msg->type = htons(GNUNET_MESSAGE_TYPE_SERVICE_UDP_BACK);
-  GNUNET_HashCode *desc = (GNUNET_HashCode*)(msg+1);
-  memcpy(desc, &state->desc, sizeof(GNUNET_HashCode));
-  void* _udp = desc+1;
-  memcpy(_udp, udp, ntohs(udp->len));
+  /* send udp-packet back */
+  len =
+    sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) +
+    ntohs (udp->len);
+  msg = GNUNET_malloc (len);
+  msg->size = htons (len);
+  msg->type = htons (GNUNET_MESSAGE_TYPE_SERVICE_UDP_BACK);
+  GNUNET_HashCode *desc = (GNUNET_HashCode *) (msg + 1);
+  memcpy (desc, &state->desc, sizeof (GNUNET_HashCode));
+  void *_udp = desc + 1;
+  memcpy (_udp, udp, ntohs (udp->len));
 
   GNUNET_MESH_notify_transmit_ready (tunnel,
-                                    GNUNET_NO,
-                                    42,
-                                    
GNUNET_TIME_relative_divide(GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
-                                    len,
-                                    send_udp_to_peer_notify_callback,
-                                    msg);
+                                     GNUNET_NO,
+                                     42,
+                                     GNUNET_TIME_relative_divide
+                                     (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
+                                     len, send_udp_to_peer_notify_callback,
+                                     msg);
 }
 
+/**
+ * @brief Handles a TCP-Packet received from the helper.
+ *
+ * @param tcp A pointer to the Packet
+ * @param dadr The IP-Destination-address
+ * @param addrlen The length of the address
+ * @param version 4 or 6
+ */
+static void
+tcp_from_helper (struct tcp_pkt *tcp, unsigned char *dadr, size_t addrlen,
+                 unsigned int version, size_t pktlen)
+{
+  struct redirect_info u_i;
+  struct GNUNET_MESH_Tunnel *tunnel;
+  uint32_t len;
+  struct GNUNET_MessageHeader *msg;
 
+  memset (&u_i, 0, sizeof (struct redirect_info));
+
+  memcpy (&u_i.addr, dadr, addrlen);
+  u_i.pt = tcp->dpt;
+
+  /* get tunnel and service-descriptor from this */
+  GNUNET_HashCode hash;
+  GNUNET_CRYPTO_hash (&u_i, sizeof (struct redirect_info), &hash);
+  struct redirect_state *state =
+    GNUNET_CONTAINER_multihashmap_get (tcp_connections, &hash);
+
+  tunnel = state->tunnel;
+
+  /* check if spt == serv.remote if yes: set spt = serv.myport ("nat") */
+  if (ntohs (tcp->spt) == state->serv->remote_port)
+    {
+      tcp->spt = htons (state->serv->my_port);
+    }
+  else
+    {
+      // This is an illegal packet.
+      GNUNET_assert (0);
+    }
+  /* send udp-packet back */
+  len =
+    sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + pktlen;
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "len: %d\n", pktlen);
+  msg = GNUNET_malloc (len);
+  msg->size = htons (len);
+  msg->type = htons (GNUNET_MESSAGE_TYPE_SERVICE_TCP_BACK);
+  GNUNET_HashCode *desc = (GNUNET_HashCode *) (msg + 1);
+  memcpy (desc, &state->desc, sizeof (GNUNET_HashCode));
+  void *_tcp = desc + 1;
+  memcpy (_tcp, tcp, pktlen);
+
+  GNUNET_MESH_notify_transmit_ready (tunnel,
+                                     GNUNET_NO,
+                                     42,
+                                     GNUNET_TIME_relative_divide
+                                     (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
+                                     len, send_udp_to_peer_notify_callback,
+                                     msg);
+}
+
+
 /**
+ * Receive packets from the helper-process
+ */
+static void
+message_token (void *cls,
+               void *client, const struct GNUNET_MessageHeader *message)
+{
+  GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER);
+
+  struct tun_pkt *pkt_tun = (struct tun_pkt *) message;
+
+  /* ethertype is ipv6 */
+  if (ntohs (pkt_tun->tun.type) == 0x86dd)
+    {
+      struct ip6_pkt *pkt6 = (struct ip6_pkt *) pkt_tun;
+      if (0x11 == pkt6->ip6_hdr.nxthdr)
+        udp_from_helper (&((struct ip6_udp *) pkt6)->udp_hdr,
+                         (unsigned char *) &pkt6->ip6_hdr.dadr, 16, 6);
+      else if (0x06 == pkt6->ip6_hdr.nxthdr)
+        tcp_from_helper (&((struct ip6_tcp *) pkt6)->tcp_hdr,
+                         (unsigned char *) &pkt6->ip6_hdr.dadr, 16, 6,
+                         ntohs (pkt6->ip6_hdr.paylgth));
+    }
+  else if (ntohs (pkt_tun->tun.type) == 0x0800)
+    {
+      struct ip_pkt *pkt4 = (struct ip_pkt *) pkt_tun;
+      uint32_t tmp = pkt4->ip_hdr.dadr;
+      if (0x11 == pkt4->ip_hdr.proto)
+        udp_from_helper (&((struct ip_udp *) pkt4)->udp_hdr,
+                         (unsigned char *) &tmp, 4, 4);
+      else if (0x06 == pkt4->ip_hdr.proto)
+        {
+          size_t pktlen = ntohs(pkt4->ip_hdr.tot_lngth);
+          GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "tot: %d\n", pktlen);
+          pktlen -= 4*pkt4->ip_hdr.hdr_lngth;
+          GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "-hdr: %d\n", pktlen);
+          tcp_from_helper (&((struct ip_tcp *) pkt4)->tcp_hdr,
+                           (unsigned char *) &tmp, 4, 4, pktlen);
+        }
+    }
+  else
+    {
+      return;
+    }
+}
+
+/**
  * Reads the configuration servicecfg and populates udp_services
  *
  * @param cls unused

Modified: gnunet/src/vpn/gnunet-daemon-vpn-helper.c
===================================================================
--- gnunet/src/vpn/gnunet-daemon-vpn-helper.c   2011-03-14 15:16:31 UTC (rev 
14638)
+++ gnunet/src/vpn/gnunet-daemon-vpn-helper.c   2011-03-14 15:16:31 UTC (rev 
14639)
@@ -274,6 +274,9 @@
                 }
               else
                 {
+                  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Dropping packet. 
nxthdr=%d, type=%d, dpt=%x, flg=%d, ports=%x\n",
+                             pkt6->ip6_hdr.nxthdr, 
ntohl(me->desc.service_type),
+                             ntohs(pkt6_tcp->tcp_hdr.dpt), 
pkt6_tcp->tcp_hdr.flg, me->desc.ports);
                   GNUNET_free (cls);
                   cls = NULL;
                 }

Modified: gnunet/src/vpn/gnunet-daemon-vpn.c
===================================================================
--- gnunet/src/vpn/gnunet-daemon-vpn.c  2011-03-14 15:16:31 UTC (rev 14638)
+++ gnunet/src/vpn/gnunet-daemon-vpn.c  2011-03-14 15:16:31 UTC (rev 14639)
@@ -479,6 +479,80 @@
   return GNUNET_OK;
 }
 
+static int
+receive_tcp_back (void *cls, struct GNUNET_MESH_Tunnel* tunnel,
+                 void **tunnel_ctx,
+                 const struct GNUNET_PeerIdentity *sender,
+                 const struct GNUNET_MessageHeader *message,
+                 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
+{
+  GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
+  struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1);
+  const struct GNUNET_PeerIdentity* other = GNUNET_MESH_get_peer(tunnel);
+
+  size_t pktlen = ntohs(message->size) - sizeof(struct GNUNET_MessageHeader) - 
sizeof(GNUNET_HashCode);
+  size_t size = pktlen + sizeof(struct ip6_tcp) - 1;
+
+  struct ip6_tcp* pkt6 = alloca(size);
+
+  GNUNET_assert(pkt6 != NULL);
+
+  new_ip6addr(pkt6->ip6_hdr.sadr, &other->hashPubKey, desc);
+
+  pkt6->shdr.type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
+  pkt6->shdr.size = htons(size);
+
+  pkt6->tun.flags = 0;
+  pkt6->tun.type = htons(0x86dd);
+
+  pkt6->ip6_hdr.version = 6;
+  pkt6->ip6_hdr.tclass_h = 0;
+  pkt6->ip6_hdr.tclass_l = 0;
+  pkt6->ip6_hdr.flowlbl = 0;
+  pkt6->ip6_hdr.paylgth = htons(pktlen);
+  pkt6->ip6_hdr.nxthdr = 0x06;
+  pkt6->ip6_hdr.hoplmt = 0xff;
+
+  {
+    char* ipv6addr;
+    GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, 
"vpn", "IPV6ADDR", &ipv6addr));
+    inet_pton (AF_INET6, ipv6addr, pkt6->ip6_hdr.dadr);
+    GNUNET_free(ipv6addr);
+  }
+  memcpy(&pkt6->tcp_hdr, pkt, pktlen);
+
+  GNUNET_HashCode* key = address_mapping_exists(pkt6->ip6_hdr.sadr);
+  GNUNET_assert (key != NULL);
+
+  struct map_entry *me = GNUNET_CONTAINER_multihashmap_get(hashmap, key);
+
+  GNUNET_free(key);
+
+  GNUNET_assert (me != NULL);
+  GNUNET_assert (me->desc.service_type & htonl(GNUNET_DNS_SERVICE_TYPE_TCP));
+
+  pkt6->tcp_hdr.crc = 0;
+  uint32_t sum = 0;
+  uint32_t tmp;
+  sum =
+    calculate_checksum_update (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
+  sum =
+    calculate_checksum_update (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16);
+  tmp = htonl(pktlen);
+  sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4);
+  tmp = htonl (((pkt6->ip6_hdr.nxthdr & 0x000000ff)));
+  sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4);
+
+  sum =
+    calculate_checksum_update (sum, (uint16_t *) & pkt6->tcp_hdr,
+                               ntohs (pkt6->ip6_hdr.paylgth));
+  pkt6->tcp_hdr.crc = calculate_checksum_end (sum);
+
+  write_to_helper(pkt6, size);
+
+  return GNUNET_OK;
+}
+
 void init_mesh (void* cls, struct GNUNET_MESH_Handle* server, const struct 
GNUNET_PeerIdentity* my_identity, const struct 
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey) {
   GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected to MESH, I am %x\n", 
*((unsigned long*)my_identity));
 }
@@ -503,6 +577,7 @@
 {
     const static struct GNUNET_MESH_MessageHandler handlers[] = {
          {receive_udp_back, GNUNET_MESSAGE_TYPE_SERVICE_UDP_BACK, 0},
+         {receive_tcp_back, GNUNET_MESSAGE_TYPE_SERVICE_TCP_BACK, 0},
          {NULL, 0, 0}
     };
     mesh_handle = GNUNET_MESH_connect(cfg_,




reply via email to

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