-fixing generation of responses from exit
[oweals/gnunet.git] / src / exit / gnunet-daemon-exit.c
index b4edcad91fd0ad733c836b6b0795d5ff5f865105..d6f0dadadd25be4684f046dc7ec800fb01dc3705 100644 (file)
@@ -234,11 +234,27 @@ static struct GNUNET_HELPER_Handle *helper_handle;
  */
 static char *exit_argv[7];
 
+/**
+ * IPv6 address of our TUN interface.
+ */
+static struct in6_addr exit_ipv6addr;
+
 /**
  * IPv6 prefix (0..127) from configuration file.
  */
 static unsigned long long ipv6prefix;
 
+/**
+ * IPv4 address of our TUN interface.
+ */
+static struct in_addr exit_ipv4addr;
+
+/**
+ * IPv4 netmask of our TUN interface.
+ */
+static struct in_addr exit_ipv4mask;
+
+
 /**
  * Statistics.
  */
@@ -528,53 +544,21 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf)
  * Send the given packet via the mesh tunnel.
  *
  * @param mesh_tunnel destination
- * @param payload message to transmit
- * @param payload_length number of bytes in payload
- * @param desc descriptor to add before payload (optional)
- * @param mtype message type to use
+ * @param tnq message to queue
  */
 static void
 send_packet_to_mesh_tunnel (struct GNUNET_MESH_Tunnel *mesh_tunnel,
-                           const void *payload,
-                           size_t payload_length,
-                           const GNUNET_HashCode *desc,
-                           uint16_t mtype)
+                           struct TunnelMessageQueue *tnq)
 {
   struct TunnelState *s;
-  struct TunnelMessageQueue *tnq;
-  struct GNUNET_MessageHeader *msg;
-  size_t len;
-  GNUNET_HashCode *dp;
 
-  len = sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + payload_length;
-  if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
-  {
-    GNUNET_break (0);
-    return;
-  }
-  tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + len);
-  tnq->payload = &tnq[1];
-  tnq->len = len;
-  msg = (struct GNUNET_MessageHeader *) &tnq[1];
-  msg->size = htons ((uint16_t) len);
-  msg->type = htons (mtype);
-  if (NULL != desc)
-  {
-    dp = (GNUNET_HashCode *) &msg[1];
-    *dp = *desc;  
-    memcpy (&dp[1], payload, payload_length);
-  }
-  else
-  {
-    memcpy (&msg[1], payload, payload_length);
-  }
   s = GNUNET_MESH_tunnel_get_data (mesh_tunnel);
   GNUNET_assert (NULL != s);
   GNUNET_CONTAINER_DLL_insert_tail (s->head, s->tail, tnq);
   if (NULL == s->th)
     s->th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel, GNUNET_NO /* cork */, 0 /* priority */,
                                               GNUNET_TIME_UNIT_FOREVER_REL,
-                                              NULL, len,
+                                              NULL, tnq->len,
                                               &send_to_peer_notify_callback,
                                               s);
 }
@@ -599,6 +583,9 @@ udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp,
                 const void *source_ip)
 {
   struct TunnelState *state;
+  struct TunnelMessageQueue *tnq;
+  struct GNUNET_EXIT_UdpReplyMessage *urm;
+  size_t mlen;
 
   {
     char sbuf[INET6_ADDRSTRLEN];
@@ -638,10 +625,20 @@ udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp,
                _("Packet dropped, have no matching connection information\n"));
     return;
   }
+  mlen = sizeof (struct GNUNET_EXIT_UdpReplyMessage) + pktlen - sizeof (struct GNUNET_TUN_UdpHeader);
+  tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + mlen);  
+  tnq->payload = &tnq[1];
+  tnq->len = mlen;
+  urm = (struct GNUNET_EXIT_UdpReplyMessage *) &tnq[1];
+  urm->header.size = htons ((uint16_t) mlen);
+  urm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY);
+  urm->source_port = htons (0);
+  urm->destination_port = htons (0);
+  memcpy (&urm[1],
+         &udp[1],
+         pktlen - sizeof (struct GNUNET_TUN_UdpHeader));
   send_packet_to_mesh_tunnel (state->tunnel,
-                             &udp[1], pktlen - sizeof (struct GNUNET_TUN_UdpHeader),
-                             NULL,
-                             GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY);
+                             tnq);
 }
 
 
@@ -649,7 +646,7 @@ udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp,
  * @brief Handles a TCP packet received from the helper.
  *
  * @param tcp A pointer to the Packet
- * @param pktlen the length of the packet, including its header
+ * @param pktlen the length of the packet, including its TCP header
  * @param af address family (AFINET or AF_INET6)
  * @param destination_ip destination IP-address of the IP packet (should 
  *                       be our local address)
@@ -666,6 +663,9 @@ tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp,
   struct TunnelState *state;
   char buf[pktlen];
   struct GNUNET_TUN_TcpHeader *mtcp;
+  struct GNUNET_EXIT_TcpDataMessage *tdm;
+  struct TunnelMessageQueue *tnq;
+  size_t mlen;
 
   {
     char sbuf[INET6_ADDRSTRLEN];
@@ -707,10 +707,26 @@ tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp,
   mtcp->spt = 0;
   mtcp->dpt = 0;
   mtcp->crc = 0;
+
+  mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof (struct GNUNET_TUN_TcpHeader));
+  if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+  {
+    GNUNET_break (0);
+    return;
+  }
+
+  tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + mlen);
+  tnq->payload = &tnq[1];
+  tnq->len = mlen;
+  tdm = (struct GNUNET_EXIT_TcpDataMessage *) &tnq[1];
+  tdm->header.size = htons ((uint16_t) mlen);
+  tdm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_DATA);
+  tdm->reserved = htonl (0);
+  memcpy (&tdm->tcp_header,
+         buf, 
+         pktlen);
   send_packet_to_mesh_tunnel (state->tunnel,
-                             mtcp, pktlen,
-                             NULL,
-                             GNUNET_MESSAGE_TYPE_VPN_TCP_DATA);
+                             tnq);
 }
 
 
@@ -865,14 +881,12 @@ setup_fresh_address (int af,
   {
   case AF_INET:
     {
-      const char *ipv4addr = exit_argv[4];
-      const char *ipv4mask = exit_argv[5];
       struct in_addr addr;
       struct in_addr mask;
       struct in_addr rnd;
 
-      GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
-      GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));           
+      addr = exit_ipv4addr;
+      mask = exit_ipv4mask;
       if (0 == ~mask.s_addr)
       {
        /* only one valid IP anyway */
@@ -895,13 +909,12 @@ setup_fresh_address (int af,
     break;
   case AF_INET6:
     {
-      const char *ipv6addr = exit_argv[2];
       struct in6_addr addr;
       struct in6_addr mask;
       struct in6_addr rnd;
       int i;
-
-      GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
+      
+      addr = exit_ipv6addr;
       GNUNET_assert (ipv6prefix < 128);
       if (ipv6prefix == 127)
       {
@@ -994,6 +1007,7 @@ setup_state_record (struct TunnelState *state)
                           buf, sizeof (buf)),
                (unsigned int) state->ri.local_address.port);  
   }
+  state->state_key = key;
   GNUNET_assert (GNUNET_OK ==
                 GNUNET_CONTAINER_multihashmap_put (connections_map, 
                                                    &key, state,
@@ -2142,8 +2156,6 @@ run (void *cls, char *const *args GNUNET_UNUSED,
   char *ipv6prefix_s;
   char *ipv4addr;
   char *ipv4mask;
-  struct in_addr v4;
-  struct in6_addr v6;
 
   cfg = cfg_;
   stats = GNUNET_STATISTICS_create ("exit", cfg);
@@ -2219,7 +2231,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
     if ( (GNUNET_SYSERR ==
          GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR",
                                                 &ipv6addr) ||
-         (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
+         (1 != inet_pton (AF_INET6, ipv6addr, &exit_ipv6addr))) )
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  "No valid entry 'IPV6ADDR' in configuration!\n");
@@ -2258,7 +2270,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
     if ( (GNUNET_SYSERR ==
          GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR",
                                                 &ipv4addr) ||
-         (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
+         (1 != inet_pton (AF_INET, ipv4addr, &exit_ipv4addr))) )
       {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                    "No valid entry for 'IPV4ADDR' in configuration!\n");
@@ -2269,7 +2281,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
     if ( (GNUNET_SYSERR ==
          GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK",
                                                 &ipv4mask) ||
-         (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
+         (1 != inet_pton (AF_INET, ipv4mask, &exit_ipv4mask))) )
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  "No valid entry 'IPV4MASK' in configuration!\n");