still not really working... sending and receiving of messages a bit hinky
[oweals/gnunet.git] / src / transport / gnunet-service-transport.c
index ca1d376da494b234a28799016c5ad7fd45727256..28fd381261fe506399f9d37ea33dcde9405b0fad 100644 (file)
@@ -73,7 +73,7 @@
  * Besides, if a single request to an address takes a long time,
  * then the peer is unlikely worthwhile anyway.
  */
-#define HELLO_VERIFICATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
+#define HELLO_VERIFICATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
 
 /**
  * How long will we allow sending of a ping to be delayed?
@@ -988,7 +988,12 @@ transmit_send_continuation (void *cls,
       rl->connected = GNUNET_NO;
     }
   if (!mq->internal_msg)
-    rl->transmit_ready = GNUNET_YES;
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Setting transmit_ready on transport!\n");
+      rl->transmit_ready = GNUNET_YES;
+    }
+
   if (mq->client != NULL)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1025,6 +1030,16 @@ try_transmission_to_peer (struct NeighborList *neighbor)
   struct MessageQueue *mq;
   struct GNUNET_TIME_Absolute now;
 
+  if (neighbor->addr != NULL)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+          _("try_transmission_to_peer entry: at this point neighbor->addr is NOT NULL\n"));
+    }
+  else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("try_transmission_to_peer entry: at this point neighbor->addr is NULL\n"));
+    }
+
   if (neighbor->messages == NULL)
     return;                     /* nothing to do */
   try_alternative_plugins (neighbor);
@@ -1045,6 +1060,13 @@ try_transmission_to_peer (struct NeighborList *neighbor)
 #endif
           pos->connected = GNUNET_NO;
         }
+      if (GNUNET_YES == pos->transmit_ready)
+        {
+#if DEBUG_TRANSPORT
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                      "Found transmit_ready flag...\n");
+#endif
+        }
       if (((GNUNET_YES == pos->transmit_ready) ||
            (mq->internal_msg)) &&
           (pos->connect_attempts < MAX_CONNECT_RETRY) &&
@@ -1084,9 +1106,15 @@ try_transmission_to_peer (struct NeighborList *neighbor)
               GNUNET_i2s (&neighbor->id), rl->plugin->short_name);
 #endif
 
+  if (rl->neighbor->addr != NULL)
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("try_transmission_to_peer pre-send: at this point rl->neighbor->addr is NOT NULL, addrlen is %d\n"), rl->neighbor->addr_len);
+  else
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("try_transmission_to_peer pre-send: at this point rl->neighbor->addr is NULL\n"));
+  /* FIXME: Change MessageQueue to hold message buffer and size? */
   rl->plugin->api->send (rl->plugin->api->cls,
                          &neighbor->id,
-                         mq->message,
+                         (char *)mq->message,
+                         ntohs(mq->message->size),
                          mq->priority,
                          GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
                          rl->neighbor->addr,
@@ -1119,6 +1147,8 @@ transmit_to_peer (struct TransportClient *client,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               _("Sending message of type %u to peer `%4s'\n"),
               ntohs (msg->type), GNUNET_i2s (&neighbor->id));
+  if (neighbor->addr != NULL)
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("transmit_to_peer: at this point neighbor->addr is NOT NULL\n"));
 #endif
   if (client != NULL)
     {
@@ -1190,7 +1220,17 @@ address_generator (void *cls, size_t max, void *buf)
       gc->addr_pos = (gc->plug_pos != NULL) ? gc->plug_pos->addresses : NULL;
     }
   if (NULL == gc->plug_pos)
-    return 0;
+    {
+#if DEBUG_TRANSPORT
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "In address_generator, gc->plug_pos is NULL!\n");
+#endif
+      return 0;
+    }
+#if DEBUG_TRANSPORT
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Should be adding an address...\n");
+#endif
   ret = GNUNET_HELLO_add_address (gc->plug_pos->short_name,
                                   gc->expiration,
                                   gc->addr_pos->addr,
@@ -1220,6 +1260,10 @@ refresh_hello ()
   gc.addr_pos = plugins != NULL ? plugins->addresses : NULL;
   gc.expiration = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
   hello = GNUNET_HELLO_create (&my_public_key, &address_generator, &gc);
+#if DEBUG_TRANSPORT
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
+              "Refreshed my `%s', new size is %d\n", "HELLO", GNUNET_HELLO_size(hello));
+#endif
   cpos = clients;
   while (cpos != NULL)
     {
@@ -1514,7 +1558,9 @@ cleanup_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
           GNUNET_PEERINFO_add_peer (cfg, sched, &pid, hello);
           n = find_neighbor (&pid, NULL, 0);
           if (NULL != n)
-            try_transmission_to_peer (n);
+            {
+              try_transmission_to_peer (n);
+            }
           GNUNET_free (hello);
           while (NULL != (va = pos->addresses))
             {
@@ -1551,21 +1597,6 @@ cleanup_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 }
 
 
-static struct GNUNET_MessageHeader *
-createPingMessage (struct GNUNET_PeerIdentity * target, struct ValidationAddress *va)
-{
-
-  struct TransportPingMessage *ping;
-  ping = GNUNET_malloc(sizeof(struct TransportPingMessage));
-
-  ping->challenge = htonl(va->challenge);
-  ping->header.size = sizeof(struct TransportPingMessage);
-  ping->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
-  memcpy(&ping->target, target, sizeof(struct GNUNET_PeerIdentity));
-
-  return &ping->header;
-}
-
 /**
  * Function that will be called if we receive a validation
  * of an address challenge that we transmitted to another
@@ -1593,7 +1624,7 @@ handle_pong (void *cls, const struct GNUNET_MessageHeader *message,
   struct ValidationAddress *va;
   struct GNUNET_PeerIdentity id;
   struct TransportPongMessage *pong = (struct TransportPongMessage *)message;
-
+  int count = 0;
   unsigned int challenge = ntohl(pong->challenge);
   pos = pending_validations;
   while (pos != NULL)
@@ -1605,14 +1636,15 @@ handle_pong (void *cls, const struct GNUNET_MessageHeader *message,
       if (0 == memcmp (peer, &id, sizeof (struct GNUNET_PeerIdentity)))
         break;
       pos = pos->next;
+      count++;
     }
   if (pos == NULL)
     {
       /* TODO: call statistics (unmatched PONG) */
       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                   _
-                  ("Received validation response but have no record of any validation request for `%4s'. Ignoring.\n"),
-                  GNUNET_i2s (peer));
+                  ("Received validation response but have no record of any validation request for `%4s' (out of %d). Ignoring.\n"),
+                  GNUNET_i2s (peer), count);
       return;
     }
   not_done = 0;
@@ -1714,8 +1746,12 @@ run_validation (void *cls,
   struct TransportPlugin *tp;
   struct ValidationAddress *va;
   struct GNUNET_PeerIdentity id;
-  struct GNUNET_MessageHeader *pingMessage;
   int sent;
+  struct TransportPingMessage *ping;
+  char * message_buf;
+  int hello_size;
+  int tsize;
+
   tp = find_transport (tname);
   if (tp == NULL)
     {
@@ -1743,19 +1779,35 @@ run_validation (void *cls,
                                             (unsigned int) -1);
   memcpy (&va[1], addr, addrlen);
 
-  pingMessage = createPingMessage(&id, va);
+  hello_size = GNUNET_HELLO_size(our_hello);
+  tsize = sizeof(struct TransportPingMessage) + hello_size;
+
+  message_buf = GNUNET_malloc(tsize);
+
+  ping = GNUNET_malloc(sizeof(struct TransportPingMessage));
+  ping->challenge = htonl(va->challenge);
+  ping->header.size = htons(sizeof(struct TransportPingMessage));
+  ping->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
+  memcpy(&ping->target, &id, sizeof(struct GNUNET_PeerIdentity));
+
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "hello size is %d, ping size is %d, total size is %d", hello_size, sizeof(struct TransportPingMessage), tsize);
+
+  memcpy(message_buf, our_hello, hello_size);
+  memcpy(&message_buf[hello_size], ping, sizeof(struct TransportPingMessage));
+
+
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ping message to address `%s' via `%s' for `%4s'\n",
                 GNUNET_a2s (addr, addrlen), tname, GNUNET_i2s (&id));
 
 
-  sent = tp->api->send(tp->api->cls, &id, pingMessage, GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+  sent = tp->api->send(tp->api->cls, &id, message_buf, tsize, GNUNET_SCHEDULER_PRIORITY_DEFAULT,
                 TRANSPORT_DEFAULT_TIMEOUT, addr, addrlen, GNUNET_YES, NULL, NULL);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transport returned %d from send!\n", sent);
 
-  GNUNET_free(pingMessage);
-
+  GNUNET_free(ping);
+  GNUNET_free(message_buf);
   return GNUNET_OK;
 }
 
@@ -1771,6 +1823,8 @@ run_validation (void *cls,
  * the address via the transport plugin.  If not validated, then
  * do not count this as a good peer/address...
  *
+ * Currently this function is not used, ping/pongs get sent from the
+ * run_validation function.  Haven't decided yet how to do this.
  */
 static void
 validate_address (void *cls, struct ValidationAddress *va,
@@ -1800,6 +1854,7 @@ check_hello_validated (void *cls,
   struct ValidationAddress *va;
   struct TransportPlugin *tp;
   int first_call;
+  int count;
   struct GNUNET_PeerIdentity apeer;
 
   first_call = GNUNET_NO;
@@ -1816,6 +1871,10 @@ check_hello_validated (void *cls,
       chvc->e->next = pending_validations;
       pending_validations = chvc->e;
     }
+  /* no existing HELLO, all addresses are new */
+  GNUNET_HELLO_iterate_addresses (chvc->hello,
+                                  GNUNET_NO, &run_validation, chvc->e);
+#if 0
   if (h != NULL)
     {
       GNUNET_HELLO_iterate_new_addresses (chvc->hello,
@@ -1829,6 +1888,7 @@ check_hello_validated (void *cls,
       GNUNET_HELLO_iterate_addresses (chvc->hello,
                                       GNUNET_NO, &run_validation, chvc->e);
     }
+#endif
   if (h != NULL)
     return;                     /* wait for next call */
   /* finally, transmit validation attempts */
@@ -1839,6 +1899,7 @@ check_hello_validated (void *cls,
               "HELLO", GNUNET_i2s (&apeer));
 #endif
   va = chvc->e->addresses;
+  count = 0;
   while (va != NULL)
     {
 #if DEBUG_TRANSPORT
@@ -1857,7 +1918,13 @@ check_hello_validated (void *cls,
                         &va[1], va->addr_len);
       /* va->ok = GNUNET_SYSERR; will be set by validate_address! */
       va = va->next;
+      count++;
     }
+
+#if DEBUG_TRANSPORT
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Found %d addresses in hello of size %d\n", count, GNUNET_HELLO_size(chvc->hello));
+#endif
   GNUNET_SCHEDULER_add_delayed (sched,
                                 GNUNET_TIME_absolute_get_remaining (chvc->
                                                                     e->timeout),
@@ -1908,8 +1975,8 @@ process_hello (struct TransportPlugin *plugin,
                       &target.hashPubKey);
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Processing `%s' message for `%4s'\n",
-              "HELLO", GNUNET_i2s (&target));
+              "Processing `%s' message for `%4s' of size %d (hsize is %d)\n",
+              "HELLO", GNUNET_i2s (&target), GNUNET_HELLO_size(hello), hsize);
 #endif
   /* check if a HELLO for this peer is already on the validation list */
   e = pending_validations;
@@ -2124,7 +2191,7 @@ static int handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
   struct TransportPingMessage *ping;
   struct TransportPongMessage *pong;
   uint16_t msize;
-
+  struct NeighborList *n;
   pong = GNUNET_malloc(sizeof(struct TransportPongMessage));
 
 #if DEBUG_TRANSPORT
@@ -2180,11 +2247,37 @@ static int handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_CRYPTO_rsa_sign (my_private_key,
                                          &pong->purpose, &pong->signature));
+  /* Will this nonsense work, even for UDP?
+   * The idea is that we need an address to send to for UDP, but we may not know
+   * this peer yet.  So in that case, we need to create a new neighbor with the
+   * current address, but is this address going to be correct, or will it have a
+   * random high port or something? Another question is, why didn't we get a WELCOME
+   * from this peer with its advertised addresses already?  We don't want to
+   * differentiate based on transport... */
+  n = find_neighbor(peer, NULL, 0);
+  if (n == NULL)
+    {
+#if DEBUG_TRANSPORT
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Didn't find peer in list, adding...\n");
+#endif
+      setup_new_neighbor(peer, sender_address, sender_address_len);
+      n = find_neighbor(peer, sender_address, sender_address_len);
+      GNUNET_assert(n != NULL);
+    }
+  else if (n->addr == NULL)
+    {
+#if DEBUG_TRANSPORT
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Found peer in list, but without address, adding!\n");
+#endif
+      n->addr = GNUNET_malloc(sender_address_len);
+      memcpy(n->addr, sender_address, sender_address_len);
+      n->addr_len = sender_address_len;
+    }
+
+  transmit_to_peer(NULL, TRANSPORT_DEFAULT_PRIORITY, &pong->header, GNUNET_NO, n);
 
-  transmit_to_peer(NULL, TRANSPORT_DEFAULT_PRIORITY, &pong->header, GNUNET_NO, find_neighbor(peer, NULL, 0));
-  /* plugin->api->send(); */ /* We can't directly send back along received address, because
-                          the port we saw for the peer (for TCP especially) will not
-                          likely be the open port on the other side! */
   GNUNET_free(pong);
   return GNUNET_OK;
 }
@@ -2757,7 +2850,7 @@ client_disconnect_notification (void *cls,
   struct TransportClient *prev;
   struct ClientMessageQueueEntry *mqe;
 
-  if (client == NULL) 
+  if (client == NULL)
     return;
 #if DEBUG_TRANSPORT
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,