gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r17445 - in gnunet/src: ats include


From: gnunet
Subject: [GNUnet-SVN] r17445 - in gnunet/src: ats include
Date: Thu, 13 Oct 2011 16:06:14 +0200

Author: grothoff
Date: 2011-10-13 16:06:14 +0200 (Thu, 13 Oct 2011)
New Revision: 17445

Modified:
   gnunet/src/ats/ats.h
   gnunet/src/ats/ats_api_performance.c
   gnunet/src/include/gnunet_ats_service.h
Log:
API change to make mwachs happy

Modified: gnunet/src/ats/ats.h
===================================================================
--- gnunet/src/ats/ats.h        2011-10-13 13:59:20 UTC (rev 17444)
+++ gnunet/src/ats/ats.h        2011-10-13 14:06:14 UTC (rev 17445)
@@ -111,7 +111,7 @@
 {
   struct GNUNET_MessageHeader header;
 
-  uint32_t reserved GNUNET_PACKED;
+  uint32_t ats_count GNUNET_PACKED;
 
   struct GNUNET_PeerIdentity peer;
 
@@ -126,6 +126,7 @@
   struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
 
   /* followed by:
+     - struct GNUNET_TRANSPORT_ATS_Information [ats_count];
      - char address[address_length]
      - char plugin_name[plugin_name_length] (including '\0'-termination).
   */

Modified: gnunet/src/ats/ats_api_performance.c
===================================================================
--- gnunet/src/ats/ats_api_performance.c        2011-10-13 13:59:20 UTC (rev 
17444)
+++ gnunet/src/ats/ats_api_performance.c        2011-10-13 14:06:14 UTC (rev 
17445)
@@ -18,25 +18,301 @@
      Boston, MA 02111-1307, USA.
 */
 /**
- * @file include/gnunet_ats_service.h
+ * @file ats/ats_api_performance.c
  * @brief automatic transport selection and outbound bandwidth determination
  * @author Christian Grothoff
  * @author Matthias Wachs
   */
 #include "platform.h"
 #include "gnunet_ats_service.h"
+#include "ats.h"
 
-/* ******************************** Performance API 
***************************** */
 
 /**
+ * Message in linked list we should send to the ATS service.  The
+ * actual binary message follows this struct.
+ */
+struct PendingMessage
+{
+
+  /**
+   * Kept in a DLL.
+   */ 
+  struct PendingMessage *next;
+
+  /**
+   * Kept in a DLL.
+   */ 
+  struct PendingMessage *prev;
+
+  /**
+   * Size of the message.
+   */
+  size_t size;
+
+  /**
+   * Is this the 'ATS_START' message?
+   */ 
+  int is_init;
+};
+
+
+/**
+ * Linked list of pending reservations.
+ */
+struct GNUNET_ATS_ReservationContext
+{
+
+  /**
+   * Kept in a DLL.
+   */ 
+  struct GNUNET_ATS_ReservationContext *next;
+
+  /**
+   * Kept in a DLL.
+   */ 
+  struct GNUNET_ATS_ReservationContext *prev;
+
+  /**
+   * Target peer.
+   */
+  struct GNUNET_PeerIdentity peer;
+                           
+  /**
+   * Desired reservation
+   */
+  int32_t size;
+
+  /**
+   * Function to call on result.
+   */
+  GNUNET_ATS_ReservationCallback info;
+
+  /**
+   * Closure for 'info'
+   */
+  void *info_cls;
+
+  /**
+   * Do we need to undo this reservation if it succeeded?  Set to
+   * GNUNET_YES if a reservation is cancelled.  (at that point, 'info'
+   * is also set to NULL; however, info will ALSO be NULL for the
+   * reservation context that is created to undo the original request,
+   * so 'info' being NULL cannot be used to check if undo is
+   * required).
+   */
+  int undo;
+};
+
+
+/**
  * ATS Handle to obtain and/or modify performance information.
  */
 struct GNUNET_ATS_PerformanceHandle
 {
+ 
+  /**
+   * Our configuration.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Callback to invoke on performance changes.
+   */
+  GNUNET_ATS_PeerInformationCallback infocb;
+  
+  /**
+   * Closure for 'infocb'.
+   */
+  void *infocb_cls;
+
+  /**
+   * Connection to ATS service.
+   */
+  struct GNUNET_CLIENT_Connection *client;
+
+  /**
+   * Head of list of messages for the ATS service.
+   */
+  struct PendingMessage *pending_head;
+
+  /**
+   * Tail of list of messages for the ATS service
+   */
+  struct PendingMessage *pending_tail;
+
+  /**
+   * Head of linked list of pending reservation requests.
+   */
+  struct GNUNET_ATS_ReservationContext *reservation_head;
+
+  /**
+   * Tail of linked list of pending reservation requests.
+   */
+  struct GNUNET_ATS_ReservationContext *reservation_tail;
+
+  /**
+   * Current request for transmission to ATS.
+   */
+  struct GNUNET_CLIENT_TransmitHandle *th;
+
 };
 
 
 /**
+ * Re-establish the connection to the ATS service.
+ *
+ * @param sh handle to use to re-connect.
+ */
+static void
+reconnect (struct GNUNET_ATS_PerformanceHandle *ph);
+
+
+/**
+ * Transmit messages from the message queue to the service
+ * (if there are any, and if we are not already trying).
+ *
+ * @param sh handle to use
+ */
+static void
+do_transmit (struct GNUNET_ATS_PerformanceHandle *ph);
+
+
+/**
+ * We can now transmit a message to ATS. Do it.
+ *
+ * @param cls the 'struct GNUNET_ATS_SchedulingHandle'
+ * @param size number of bytes we can transmit to ATS
+ * @param buf where to copy the messages
+ * @return number of bytes copied into buf
+ */
+static size_t
+transmit_message_to_ats (void *cls,
+                        size_t size,
+                        void *buf)
+{
+  struct GNUNET_ATS_PerformanceHandle *ph = cls;
+  struct PendingMessage *p;
+  size_t ret;
+  char *cbuf;
+
+  ph->th = NULL;
+  ret = 0;
+  cbuf = buf;
+  while ( (NULL != (p = ph->pending_head)) &&
+         (p->size <= size) )
+  {
+    memcpy (&cbuf[ret], &p[1], p->size);    
+    ret += p->size;
+    GNUNET_CONTAINER_DLL_remove (ph->pending_head,
+                                ph->pending_tail,
+                                p);
+    GNUNET_free (p);
+  }
+  do_transmit (ph);
+  return ret;
+}
+
+
+/**
+ * Transmit messages from the message queue to the service
+ * (if there are any, and if we are not already trying).
+ *
+ * @param ph handle to use
+ */
+static void
+do_transmit (struct GNUNET_ATS_PerformanceHandle *ph)
+{
+  struct PendingMessage *p;
+
+  if (NULL != ph->th)
+    return;
+  if (NULL == (p = ph->pending_head))
+    return;
+  ph->th = GNUNET_CLIENT_notify_transmit_ready (ph->client,
+                                               p->size,
+                                               GNUNET_TIME_UNIT_FOREVER_REL,
+                                               GNUNET_YES,
+                                               &transmit_message_to_ats, ph);
+}
+
+
+/**
+ * Type of a function to call when we receive a message
+ * from the service.
+ *
+ * @param cls the 'struct GNUNET_ATS_SchedulingHandle'
+ * @param msg message received, NULL on timeout or fatal error
+ */
+static void
+process_ats_message (void *cls,
+                    const struct GNUNET_MessageHeader *msg)
+{
+  struct GNUNET_ATS_PerformanceHandle *ph = cls;
+
+  if (NULL == msg) 
+  {
+    GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO);
+    ph->client = NULL;
+    reconnect (ph);
+    return;
+  }
+  switch (ntohs (msg->type))
+  {
+    // FIXME
+  default:
+    GNUNET_break (0);
+    GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO);
+    ph->client = NULL;
+    reconnect (ph);
+    return;
+  }
+  GNUNET_CLIENT_receive (ph->client,
+                        &process_ats_message, ph,
+                        GNUNET_TIME_UNIT_FOREVER_REL);
+}
+
+
+/**
+ * Re-establish the connection to the ATS service.
+ *
+ * @param ph handle to use to re-connect.
+ */
+static void
+reconnect (struct GNUNET_ATS_PerformanceHandle *ph)
+{
+  struct PendingMessage *p;
+  struct ClientStartMessage *init;
+
+  GNUNET_assert (NULL == ph->client);
+  ph->client = GNUNET_CLIENT_connect ("ats", ph->cfg);
+  GNUNET_assert (NULL != ph->client);
+  GNUNET_CLIENT_receive (ph->client,
+                        &process_ats_message, ph,
+                        GNUNET_TIME_UNIT_FOREVER_REL);
+  if ( (NULL == (p = ph->pending_head)) ||
+       (GNUNET_YES != p->is_init) )
+  {
+    p = GNUNET_malloc (sizeof (struct PendingMessage) +
+                      sizeof (struct ClientStartMessage));
+    p->size = sizeof (struct ClientStartMessage);
+    p->is_init = GNUNET_YES;
+    init = (struct ClientStartMessage *) &p[1];
+    init->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_START);
+    init->header.size = htons (sizeof (struct ClientStartMessage));
+    init->start_flag = htonl ((ph->infocb == NULL) 
+                             ? START_FLAG_PERFORMANCE_NO_PIC 
+                             : START_FLAG_PERFORMANCE_WITH_PIC);
+    GNUNET_CONTAINER_DLL_insert (ph->pending_head,
+                                ph->pending_tail,
+                                p);
+  }
+  do_transmit (ph);
+}
+
+
+
+/**
  * Get handle to access performance API of the ATS subsystem.
  *
  * @param cfg configuration to use
@@ -49,7 +325,14 @@
                             GNUNET_ATS_PeerInformationCallback infocb,
                             void *infocb_cls)
 {
-  return NULL;
+  struct GNUNET_ATS_PerformanceHandle *ph;
+
+  ph = GNUNET_malloc (sizeof (struct GNUNET_ATS_PerformanceHandle));
+  ph->cfg = cfg;
+  ph->infocb = infocb;
+  ph->infocb_cls = infocb_cls;
+  reconnect (ph);
+  return ph;
 }
 
 
@@ -61,18 +344,30 @@
 void
 GNUNET_ATS_performance_done (struct GNUNET_ATS_SchedulingHandle *ph)
 {
+  struct PendingMessage *p;
+  struct GNUNET_ATS_ReservationContext *rc;
+  
+  while (NULL != (p = ph->pending_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (ph->pending_head,
+                                ph->pending_tail,
+                                p);
+    GNUNET_free (p);
+  }
+  while (NULL != (rc = ph->reservation_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (ph->reservation_head,
+                                ph->reservation_tail,
+                                rc);
+    GNUNET_break (NULL == rc->info);
+    GNUNET_free (p);
+  }  
+  GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO);
+  GNUNET_free (ph);
 }
 
 
 /**
- * Context that can be used to cancel a peer information request.
- */
-struct GNUNET_ATS_ReservationContext
-{
-};
-
-
-/**
  * Reserve inbound bandwidth from the given peer.  ATS will look at
  * the current amount of traffic we receive from the peer and ensure
  * that the peer could add 'amount' of data to its stream.
@@ -93,7 +388,32 @@
                              GNUNET_ATS_ReservationCallback info, 
                              void *info_cls)
 {
-  return NULL;
+  struct GNUNET_ATS_ReservationContext *rc;
+  struct PendingMessage *p;
+  struct ReservationRequestMessage *m;
+
+  rc = GNUNET_malloc (sizeof (struct GNUNET_ATS_ReservationContext));
+  rc->size = amount;
+  rc->peer = *peer;
+  rc->info = info;
+  rc->info_cls = info_cls;
+  GNUNET_CONTAINER_DLL_insert_tail (ph->reservation_head,
+                                   ph->reservation_tail,
+                                   rc);
+  
+  p = GNUNET_malloc (sizeof (struct PendingMessage) + 
+                    sizeof (struct ReservationRequestMessage));
+  p->size = sizeof (struct ReservationRequestMessage);
+  p->is_init = GNUNET_NO;
+  m = (struct ReservationRequestMessage*) &p[1];
+  m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE);
+  m->header.size = htons (sizeof (struct ReservationRequestMessage));
+  m->amount = htonl (amount);
+  m->peer = *peer;
+  GNUNET_CONTAINER_DLL_insert_tail (ph->pending_head,
+                                   ph->pending_tail,
+                                   p);
+  return rc;
 }
 
 
@@ -106,6 +426,7 @@
 GNUNET_ATS_reserve_bandwidth_cancel (struct
                                     GNUNET_ATS_ReservationContext *rc)
 {
+  rc->info = NULL;
 }
 
 
@@ -122,6 +443,29 @@
                              const struct GNUNET_PeerIdentity *peer,
                              ...)
 {
+  struct PendingMessage *p;
+  struct ChangePreferenceMessage *m;
+  size_t msize;
+  uint32_t count;
+  struct PreferenceInformation *pi;
+
+  // FIXME: set 'count'
+  p = GNUNET_malloc (sizeof (struct PendingMessage) + 
+                    sizeof (struct ChangePreferenceMessage) + 
+                    count * sizeof (struct PreferenceInformation));
+  p->size = msize;
+  p->is_init = GNUNET_NO;
+  m = (struct ReservationRequestMessage*) &p[1];
+  m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE);
+  m->header.size = htons (msize);
+  m->num_preferences = htonl (count);
+  m->peer = *peer;
+  pi = (struct PreferenceInformation*) &m[1];
+  // FIXME: fill in 'pi'
+
+  GNUNET_CONTAINER_DLL_insert_tail (ph->pending_head,
+                                   ph->pending_tail,
+                                   p);
 }
 
 /* end of ats_api_performance.c */

Modified: gnunet/src/include/gnunet_ats_service.h
===================================================================
--- gnunet/src/include/gnunet_ats_service.h     2011-10-13 13:59:20 UTC (rev 
17444)
+++ gnunet/src/include/gnunet_ats_service.h     2011-10-13 14:06:14 UTC (rev 
17445)
@@ -61,6 +61,8 @@
  * @param session session to use
  * @param bandwidth_out assigned outbound bandwidth for the connection
  * @param bandwidth_in assigned inbound bandwidth for the connection
+ * @param ats performance data for the address (as far as known)
+ * @param ats_count number of performance records in 'ats'
  */
 typedef void (*GNUNET_ATS_AddressSuggestionCallback) (void *cls,
                                                       const struct
@@ -75,7 +77,11 @@
                                                       bandwidth_out,
                                                       struct
                                                       
GNUNET_BANDWIDTH_Value32NBO
-                                                      bandwidth_in);
+                                                      bandwidth_in,
+                                                     const struct
+                                                     
GNUNET_TRANSPORT_ATS_Information
+                                                     * ats,
+                                                     uint32_t ats_count);
 
 
 /**




reply via email to

[Prev in Thread] Current Thread [Next in Thread]