-improve UDP logging
[oweals/gnunet.git] / src / core / gnunet-service-core_neighbours.c
index 63ba8dbb6659d9b4dc869e3cc9c8728b5c5225e1..9fd9207e4c18c99cfed3e1f1bd4019766b135a36 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -103,7 +103,12 @@ struct Neighbour
   /**
    * ID of task used for re-trying plaintext scheduling.
    */
-  GNUNET_SCHEDULER_TaskIdentifier retry_plaintext_task;
+  struct GNUNET_SCHEDULER_Task * retry_plaintext_task;
+
+  /**
+   * #GNUNET_YES if this peer currently has excess bandwidth.
+   */
+  int has_excess_bandwidth;
 
 };
 
@@ -167,10 +172,10 @@ free_neighbour (struct Neighbour *n)
     GSC_KX_stop (n->kxinfo);
     n->kxinfo = NULL;
   }
-  if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK)
+  if (n->retry_plaintext_task != NULL)
   {
     GNUNET_SCHEDULER_cancel (n->retry_plaintext_task);
-    n->retry_plaintext_task = GNUNET_SCHEDULER_NO_TASK;
+    n->retry_plaintext_task = NULL;
   }
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_CONTAINER_multipeermap_remove (neighbours,
@@ -213,13 +218,13 @@ transmit_ready (void *cls, size_t size, void *buf)
 
   n->th = NULL;
   m = n->message_head;
-  if (m == NULL)
+  if (NULL == m)
   {
     GNUNET_break (0);
     return 0;
   }
   GNUNET_CONTAINER_DLL_remove (n->message_head, n->message_tail, m);
-  if (buf == NULL)
+  if (NULL == buf)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Transmission of message of type %u and size %u failed\n",
@@ -240,6 +245,7 @@ transmit_ready (void *cls, size_t size, void *buf)
               ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
               (unsigned int) ret, GNUNET_i2s (&n->peer));
   GNUNET_free (m);
+  n->has_excess_bandwidth = GNUNET_NO;
   process_queue (n);
   GNUNET_STATISTICS_update (GSC_stats,
                             gettext_noop
@@ -260,10 +266,10 @@ process_queue (struct Neighbour *n)
 {
   struct NeighbourMessageEntry *m;
 
-  if (n->th != NULL)
+  if (NULL != n->th)
     return;                     /* request already pending */
   m = n->message_head;
-  if (m == NULL)
+  if (NULL == m)
   {
     /* notify sessions that the queue is empty and more messages
      * could thus be queued now */
@@ -272,25 +278,30 @@ process_queue (struct Neighbour *n)
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Asking transport for transmission of %u bytes to `%4s' in next %s\n",
-              (unsigned int) m->size, GNUNET_i2s (&n->peer),
-              GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (m->deadline), GNUNET_NO));
-  n->th =
-      GNUNET_TRANSPORT_notify_transmit_ready (transport, &n->peer, m->size, 0,
-                                              GNUNET_TIME_absolute_get_remaining
-                                              (m->deadline), &transmit_ready,
+              (unsigned int) m->size,
+              GNUNET_i2s (&n->peer),
+              GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (m->deadline),
+                                                      GNUNET_NO));
+  n->th
+    = GNUNET_TRANSPORT_notify_transmit_ready (transport,
+                                              &n->peer,
+                                              m->size,
+                                              GNUNET_TIME_absolute_get_remaining (m->deadline),
+                                              &transmit_ready,
                                               n);
-  if (n->th != NULL)
+  if (NULL != n->th)
     return;
   /* message request too large or duplicate request */
   GNUNET_break (0);
   /* discard encrypted message */
-  GNUNET_CONTAINER_DLL_remove (n->message_head, n->message_tail, m);
+  GNUNET_CONTAINER_DLL_remove (n->message_head,
+                               n->message_tail,
+                               m);
   GNUNET_free (m);
   process_queue (n);
 }
 
 
-
 /**
  * Function called by transport to notify us that
  * a peer connected to us (on the network level).
@@ -304,7 +315,9 @@ handle_transport_notify_connect (void *cls,
 {
   struct Neighbour *n;
 
-  if (0 == memcmp (peer, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity)))
+  if (0 == memcmp (peer,
+                   &GSC_my_identity,
+                   sizeof (struct GNUNET_PeerIdentity)))
   {
     GNUNET_break (0);
     return;
@@ -350,7 +363,7 @@ handle_transport_notify_disconnect (void *cls,
               "Peer `%4s' disconnected from us; received notification from transport.\n",
               GNUNET_i2s (peer));
   n = find_neighbour (peer);
-  if (n == NULL)
+  if (NULL == n)
   {
     GNUNET_break (0);
     return;
@@ -367,7 +380,8 @@ handle_transport_notify_disconnect (void *cls,
  * @param message the message
  */
 static void
-handle_transport_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
+handle_transport_receive (void *cls,
+                          const struct GNUNET_PeerIdentity *peer,
                           const struct GNUNET_MessageHeader *message)
 {
   struct Neighbour *n;
@@ -408,9 +422,9 @@ handle_transport_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
     break;
   default:
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _
-                ("Unsupported message of type %u (%u bytes) received from peer `%s'\n"),
-                (unsigned int) type, (unsigned int) ntohs (message->size),
+                _("Unsupported message of type %u (%u bytes) received from peer `%s'\n"),
+                (unsigned int) type,
+                (unsigned int) ntohs (message->size),
                 GNUNET_i2s (peer));
     return;
   }
@@ -449,6 +463,54 @@ GSC_NEIGHBOURS_transmit (const struct GNUNET_PeerIdentity *target,
 }
 
 
+/**
+ * One of our neighbours has excess bandwidth,
+ * remember this.
+ *
+ * @param cls NULL
+ * @param pid identity of the peer with excess bandwidth
+ */
+static void
+handle_transport_notify_excess_bw (void *cls,
+                                   const struct GNUNET_PeerIdentity *pid)
+{
+  struct Neighbour *n;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Peer %s has excess bandwidth available\n",
+              GNUNET_i2s (pid));
+  n = find_neighbour (pid);
+  if (NULL == n)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  n->has_excess_bandwidth = GNUNET_YES;
+  GSC_SESSIONS_solicit (pid);
+}
+
+
+/**
+ * Check if the given neighbour has excess bandwidth available.
+ *
+ * @param target neighbour to check
+ * @return #GNUNET_YES if excess bandwidth is available, #GNUNET_NO if not
+ */
+int
+GSC_NEIGHBOURS_check_excess_bandwidth (const struct GNUNET_PeerIdentity *target)
+{
+  struct Neighbour *n;
+
+  n = find_neighbour (target);
+  if (NULL == n)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return n->has_excess_bandwidth;
+}
+
+
 /**
  * Initialize neighbours subsystem.
  */
@@ -457,10 +519,11 @@ GSC_NEIGHBOURS_init ()
 {
   neighbours = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
   transport =
-      GNUNET_TRANSPORT_connect (GSC_cfg, &GSC_my_identity, NULL,
-                                &handle_transport_receive,
-                                &handle_transport_notify_connect,
-                                &handle_transport_notify_disconnect);
+      GNUNET_TRANSPORT_connect2 (GSC_cfg, &GSC_my_identity, NULL,
+                                 &handle_transport_receive,
+                                 &handle_transport_notify_connect,
+                                 &handle_transport_notify_disconnect,
+                                 &handle_transport_notify_excess_bw);
   if (NULL == transport)
   {
     GNUNET_CONTAINER_multipeermap_destroy (neighbours);
@@ -476,8 +539,8 @@ GSC_NEIGHBOURS_init ()
  *
  * @param cls unused
  * @param key peer identity
- * @param value the 'struct Neighbour' to free
- * @return GNUNET_OK (continue to iterate)
+ * @param value the `struct Neighbour` to free
+ * @return #GNUNET_OK (continue to iterate)
  */
 static int
 free_neighbour_helper (void *cls,
@@ -506,7 +569,8 @@ GSC_NEIGHBOURS_done ()
   }
   if (NULL != neighbours)
   {
-    GNUNET_CONTAINER_multipeermap_iterate (neighbours, &free_neighbour_helper,
+    GNUNET_CONTAINER_multipeermap_iterate (neighbours,
+                                           &free_neighbour_helper,
                                           NULL);
     GNUNET_CONTAINER_multipeermap_destroy (neighbours);
     neighbours = NULL;