(no commit message)
[oweals/gnunet.git] / src / transport / gnunet-service-transport.c
index 3a6fcf9251bf7b2747a44803eaf56b5c8387c5dd..12db541acf802efe8ba075a88deddc0962133af8 100644 (file)
@@ -4,7 +4,7 @@
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
@@ -57,7 +57,7 @@
  * How many messages can we have pending for a given client process
  * before we start to drop incoming messages?  We typically should
  * have only one client and so this would be the primary buffer for
- * messages, so the number should be chosen rather generously.
 * messages, so the number should be chosen rather generously.
  *
  * The expectation here is that most of the time the queue is large
  * enough so that a drop is virtually never required.  Note that
@@ -1108,7 +1108,10 @@ read_blacklist_file (const struct GNUNET_CONFIGURATION_Handle *cfg)
           GNUNET_free (data);
           return;
         }
-      tsize = tsize;
+
+      if (tsize < 1)
+        continue;
+
       transport_name = GNUNET_malloc(tsize + 1);
       memcpy(transport_name, &data[pos], tsize);
       pos = colon_pos + 1;
@@ -1772,6 +1775,7 @@ transmit_to_peer (struct TransportClient *client,
   mq = GNUNET_malloc (sizeof (struct MessageQueue) + message_buf_size);
   mq->specific_address = peer_address;
   mq->client = client;
+  /* FIXME: this memcpy can be up to 7% of our total runtime! */
   memcpy (&mq[1], message_buf, message_buf_size);
   mq->message_buf = (const char*) &mq[1];
   mq->message_buf_size = message_buf_size;
@@ -2608,13 +2612,11 @@ add_to_foreign_address_list (void *cls,
  * @param cls closure ('struct NeighbourList*')
  * @param peer id of the peer, NULL for last call
  * @param h hello message for the peer (can be NULL)
- * @param trust amount of trust we have in the peer (not used)
  */
 static void
 add_hello_for_peer (void *cls,
                    const struct GNUNET_PeerIdentity *peer,
-                   const struct GNUNET_HELLO_Message *h, 
-                   uint32_t trust)
+                   const struct GNUNET_HELLO_Message *h)
 {
   struct NeighbourList *n = cls;
 
@@ -2702,7 +2704,7 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer,
   if (do_hello)
     {
       n->piter = GNUNET_PEERINFO_iterate (peerinfo, peer,
-                                         0, GNUNET_TIME_UNIT_FOREVER_REL,
+                                         GNUNET_TIME_UNIT_FOREVER_REL,
                                          &add_hello_for_peer, n);
       transmit_to_peer (NULL, NULL, 0,
                        HELLO_ADDRESS_EXPIRATION,
@@ -3172,6 +3174,10 @@ send_periodic_ping (void *cls,
       slen = strlen (tp->short_name) + 1;
       tsize += slen + peer_address->addrlen;
     }
+  else
+    {
+      slen = 0; /* make gcc happy */
+    }
   message_buf = GNUNET_malloc(tsize);
   ping.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
   ping.challenge = htonl(va->challenge);
@@ -3401,10 +3407,9 @@ check_pending_validation (void *cls,
                         ve->addr,
                         ve->addrlen)) )
        return GNUNET_YES; /* different entry, keep trying! */
-      if ( (0 != memcmp (&pong->pid,
-                        key,
-                        sizeof (struct GNUNET_PeerIdentity))) ||
-          (ve->addrlen == 0) )
+      if (0 != memcmp (&pong->pid,
+                      key,
+                      sizeof (struct GNUNET_PeerIdentity))) 
        {
          GNUNET_break_op (0);
          return GNUNET_NO;
@@ -3863,13 +3868,11 @@ run_validation (void *cls,
  * @param cls closure
  * @param peer id of the peer, NULL for last call
  * @param h hello message for the peer (can be NULL)
- * @param trust amount of trust we have in the peer (not used)
  */
 static void
 check_hello_validated (void *cls,
                        const struct GNUNET_PeerIdentity *peer,
-                       const struct GNUNET_HELLO_Message *h, 
-                      uint32_t trust)
+                       const struct GNUNET_HELLO_Message *h)
 {
   struct CheckHelloValidatedContext *chvc = cls;
   struct GNUNET_HELLO_Message *plain_hello;
@@ -3992,6 +3995,7 @@ process_hello (struct TransportPlugin *plugin,
                            gettext_noop ("# HELLOs received for validation"),
                            1,
                            GNUNET_NO);      
+
   /* first, check if load is too high */
   if (GNUNET_SCHEDULER_get_load (sched,
                                 GNUNET_SCHEDULER_PRIORITY_BACKGROUND) > MAX_HELLO_LOAD)
@@ -4020,9 +4024,11 @@ process_hello (struct TransportPlugin *plugin,
       GNUNET_break_op (0);
       return GNUNET_SYSERR;
     }
+
   GNUNET_CRYPTO_hash (&publicKey,
                       sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                       &target.hashPubKey);
+
   if (0 == memcmp (&my_identity,
                   &target,
                   sizeof (struct GNUNET_PeerIdentity)))
@@ -4078,7 +4084,6 @@ process_hello (struct TransportPlugin *plugin,
      (continuation will then schedule actual validation) */
   chvc->piter = GNUNET_PEERINFO_iterate (peerinfo,
                                          &target,
-                                         0,
                                          HELLO_VERIFICATION_TIMEOUT,
                                          &check_hello_validated, chvc);
   return GNUNET_OK;
@@ -4335,6 +4340,18 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
       /* peer wants to confirm that this is one of our addresses */
       addr += slen;
       alen -= slen;
+      if (GNUNET_OK !=
+         plugin->api->check_address (plugin->api->cls,
+                                     addr,
+                                     alen))
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                     _("Not confirming PING with address `%s' since I cannot confirm having this address.\n"),
+                     a2s (plugin->short_name,
+                          addr,
+                          alen));
+         return GNUNET_NO;
+       }
       oal = plugin->addresses;
       while (NULL != oal)
        {
@@ -4345,15 +4362,6 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
            break;
          oal = oal->next;
        }
-      if (oal == NULL)
-       {
-         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                     _("Not confirming PING with address `%s' since I cannot confirm having this address.\n"),
-                     a2s (plugin->short_name,
-                          addr,
-                          alen));
-         return GNUNET_NO;
-       }
       pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + alen + slen);
       pong->header.size = htons (sizeof (struct TransportPongMessage) + alen + slen);
       pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
@@ -4369,8 +4377,9 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
             &my_identity, 
             sizeof(struct GNUNET_PeerIdentity));
       memcpy (&pong[1], plugin->short_name, slen);
-      memcpy (&((char*)&pong[1])[slen], &oal[1], alen);
-      if (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).value < PONG_SIGNATURE_LIFETIME.value / 4)
+      memcpy (&((char*)&pong[1])[slen], addr, alen);
+      if ( (oal != NULL) &&
+          (GNUNET_TIME_absolute_get_remaining (oal->pong_sig_expires).value < PONG_SIGNATURE_LIFETIME.value / 4) )
        {
          /* create / update cached sig */
 #if DEBUG_TRANSPORT
@@ -4383,15 +4392,28 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
          GNUNET_assert (GNUNET_OK ==
                         GNUNET_CRYPTO_rsa_sign (my_private_key,
                                                 &pong->purpose,
-                                                &oal->pong_signature));
+                                                &oal->pong_signature));            
+         memcpy (&pong->signature,
+                 &oal->pong_signature,
+                 sizeof (struct GNUNET_CRYPTO_RsaSignature));    
+       }
+      else if (oal == NULL)
+       {
+         /* not using cache (typically DV-only) */
+         pong->expiration = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME));
+         GNUNET_assert (GNUNET_OK ==
+                        GNUNET_CRYPTO_rsa_sign (my_private_key,
+                                                &pong->purpose,
+                                                &pong->signature));        
        }
       else
        {
+         /* can used cached version */
          pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires);
+         memcpy (&pong->signature,
+                 &oal->pong_signature,
+                 sizeof (struct GNUNET_CRYPTO_RsaSignature));    
        }
-      memcpy (&pong->signature,
-             &oal->pong_signature,
-             sizeof (struct GNUNET_CRYPTO_RsaSignature));    
     }
   n = find_neighbour(peer);
   GNUNET_assert (n != NULL);
@@ -4782,6 +4804,7 @@ handle_send (void *cls,
   tcmc->priority = ntohl (obm->priority);
   tcmc->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_ntoh (obm->timeout));
   tcmc->msize = msize;
+  /* FIXME: this memcpy can be up to 7% of our total runtime */
   memcpy (&tcmc[1], obmm, msize);
   GNUNET_SERVER_client_keep (client);
   setup_peer_check_blacklist (&obm->peer, GNUNET_YES,