fix
[oweals/gnunet.git] / src / core / core_api.c
index 196191a3258f5faa0edb150408e8e39851142e5a..c21be318a4ffac0fd5fcee4480fd523b36340e1d 100644 (file)
@@ -1,10 +1,10 @@
 /*
      This file is part of GNUnet.
-     (C) 2009 Christian Grothoff (and other contributing authors)
+     (C) 2009, 2010 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
-     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
@@ -66,6 +66,11 @@ struct GNUNET_CORE_Handle
    */
   GNUNET_CORE_DisconnectEventHandler disconnects;
 
+  /**
+   * Function to call whenever we're notified about a peer changing status.
+   */  
+  GNUNET_CORE_PeerStatusEventHandler status_events;
+  
   /**
    * Function to call whenever we receive an inbound message.
    */
@@ -312,8 +317,10 @@ request_start (void *cls, size_t size, void *buf)
   struct GNUNET_CORE_TransmitHandle *th;
   size_t ret;
 
-  h->cth = NULL;
+  h->cth = NULL;  
   th = h->pending_head;
+  if (th == NULL)
+    return 0;
   if (buf == NULL)
     {
       timeout_request (th, NULL);
@@ -381,6 +388,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
   const struct DisconnectNotifyMessage *dnm;
   const struct NotifyTrafficMessage *ntm;
   const struct GNUNET_MessageHeader *em;
+  const struct PeerStatusNotifyMessage *psnm;
   uint16_t msize;
   uint16_t et;
   const struct GNUNET_CORE_MessageHandler *mh;
@@ -433,6 +441,26 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
       h->disconnects (h->cls,
                      &dnm->peer);
       break;
+    case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE:
+      if (NULL == h->status_events)
+        {
+          GNUNET_break (0);
+          break;
+        }
+      if (msize != sizeof (struct PeerStatusNotifyMessage))
+        {
+          GNUNET_break (0);
+          break;
+        }
+      psnm = (const struct PeerStatusNotifyMessage *) msg;
+      h->status_events (h->cls,
+                       &psnm->peer,
+                       GNUNET_TIME_relative_ntoh (psnm->latency),
+                       ntohl (psnm->distance),
+                       psnm->bandwidth_in,
+                       psnm->bandwidth_out,
+                       GNUNET_TIME_absolute_ntoh (psnm->timeout));
+      break;
     case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND:
       if (msize <
           sizeof (struct NotifyTrafficMessage) +
@@ -658,6 +686,8 @@ transmit_start (void *cls, size_t size, void *buf)
     opt |= GNUNET_CORE_OPTION_SEND_CONNECT;
   if (h->disconnects != NULL)
     opt |= GNUNET_CORE_OPTION_SEND_DISCONNECT;
+  if (h->status_events != NULL)
+    opt |= GNUNET_CORE_OPTION_SEND_STATUS_CHANGE;
   if (h->inbound_notify != NULL)
     {
       if (h->inbound_hdr_only)
@@ -697,6 +727,7 @@ transmit_start (void *cls, size_t size, void *buf)
  *        connected to the core service; note that timeout is only meaningful if init is not NULL
  * @param connects function to call on peer connect, can be NULL
  * @param disconnects function to call on peer disconnect / timeout, can be NULL
+ * @param status_events function to call on changes to peer connection status, can be NULL
  * @param inbound_notify function to call for all inbound messages, can be NULL
  * @param inbound_hdr_only set to GNUNET_YES if inbound_notify will only read the
  *                GNUNET_MessageHeader and hence we do not need to give it the full message;
@@ -717,6 +748,7 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched,
                      GNUNET_CORE_StartupCallback init,
                      GNUNET_CORE_ConnectEventHandler connects,
                      GNUNET_CORE_DisconnectEventHandler disconnects,
+                    GNUNET_CORE_PeerStatusEventHandler status_events,
                      GNUNET_CORE_MessageCallback inbound_notify,
                      int inbound_hdr_only,
                      GNUNET_CORE_MessageCallback outbound_notify,
@@ -732,6 +764,7 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched,
   h->init = init;
   h->connects = connects;
   h->disconnects = disconnects;
+  h->status_events = status_events;
   h->inbound_notify = inbound_notify;
   h->outbound_notify = outbound_notify;
   h->inbound_hdr_only = inbound_hdr_only;
@@ -781,6 +814,7 @@ GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
     GNUNET_SCHEDULER_cancel (handle->sched, handle->reconnect_task);
   if (handle->client_notifications != NULL)
     GNUNET_CLIENT_disconnect (handle->client_notifications, GNUNET_NO);
+  GNUNET_break (handle->pending_head == NULL);
   GNUNET_free_non_null (handle->solicit_buffer);
   GNUNET_free (handle);
 }