gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r17306 - in gnunet/src: ats include
Date: Mon, 10 Oct 2011 12:59:00 +0200

Author: grothoff
Date: 2011-10-10 12:59:00 +0200 (Mon, 10 Oct 2011)
New Revision: 17306

Added:
   gnunet/src/ats/ats_api.h
   gnunet/src/ats/ats_api_peer_change_preference.c
Modified:
   gnunet/src/ats/Makefile.am
   gnunet/src/ats/ats_api.c
   gnunet/src/include/gnunet_ats_service.h
Log:
adding change preference API to ATS

Modified: gnunet/src/ats/Makefile.am
===================================================================
--- gnunet/src/ats/Makefile.am  2011-10-10 10:50:08 UTC (rev 17305)
+++ gnunet/src/ats/Makefile.am  2011-10-10 10:59:00 UTC (rev 17306)
@@ -11,7 +11,8 @@
 lib_LTLIBRARIES = libgnunetats.la
 
 libgnunetats_la_SOURCES = \
-  ats_api.c
+  ats_api.c ats_api.h \
+  ats_api_peer_change_preference.c
 
 libgnunetats_la_LIBADD = \
  $(top_builddir)/src/util/libgnunetutil.la

Modified: gnunet/src/ats/ats_api.c
===================================================================
--- gnunet/src/ats/ats_api.c    2011-10-10 10:50:08 UTC (rev 17305)
+++ gnunet/src/ats/ats_api.c    2011-10-10 10:59:00 UTC (rev 17306)
@@ -32,68 +32,23 @@
  */
 #include "platform.h"
 #include "gnunet_ats_service.h"
+#include "ats_api.h"
 
 #define DEBUG_ATS GNUNET_EXTRA_LOGGING
 
+/**
+ * Receive and send buffer windows grow over time.  For
+ * how long can 'unused' bandwidth accumulate before we
+ * need to cap it?  (specified in seconds).
+ */
+#define MAX_WINDOW_TIME_S (5 * 60)
+
 // NOTE: this implementation is simply supposed
 // to implement a simplistic strategy in-process;
 // in the future, we plan to replace it with a real
 // service implementation
 
-/**
- * Allocation record for a peer's address.
- */
-struct AllocationRecord
-{
 
-  /**
-   * Performance information associated with this address (array).
-   */
-  struct GNUNET_TRANSPORT_ATS_Information *ats;
-
-  /**
-   * Name of the plugin
-   */
-  char *plugin_name;
-
-  /**
-   * Address this record represents, allocated at the end of this struct.
-   */
-  const void *plugin_addr;
-
-  /**
-   * Session associated with this record.
-   */
-  struct Session *session;
-
-  /**
-   * Number of bytes in plugin_addr.
-   */
-  size_t plugin_addr_len;
-
-  /**
-   * Number of entries in 'ats'.
-   */
-  uint32_t ats_count;
-
-  /**
-   * Inbound bandwidth assigned to this address right now, 0 for none.
-   */
-  struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
-
-  /**
-   * Outbound bandwidth assigned to this address right now, 0 for none.
-   */
-  struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out;
-
-  /**
-   * Set to GNUNET_YES if this is the connected address of a connected peer.
-   */
-  int connected;
-
-};
-
-
 /**
  * Opaque handle to obtain address suggestions.
  */
@@ -124,55 +79,6 @@
 
 
 /**
- * Handle to the ATS subsystem.
- */
-struct GNUNET_ATS_Handle
-{
-  /**
-   * Configuration.
-   */
-  const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-  /**
-   * Function to call when the allocation changes.
-   */
-  GNUNET_TRANSPORT_ATS_AllocationNotification alloc_cb;
-
-  /**
-   * Closure for 'alloc_cb'.
-   */
-  void *alloc_cb_cls;
-
-  /**
-   * Information about all connected peers.  Maps peer identities
-   * to one or more 'struct AllocationRecord' values.
-   */
-  struct GNUNET_CONTAINER_MultiHashMap *peers;
-
-  /**
-   * Map of PeerIdentities to 'struct GNUNET_ATS_SuggestionContext's.
-   */
-  struct GNUNET_CONTAINER_MultiHashMap *notify_map;
-
-
-  /**
-   * Task scheduled to update our bandwidth assignment.
-   */
-  GNUNET_SCHEDULER_TaskIdentifier ba_task;
-
-  /**
-   * Total inbound bandwidth per configuration.
-   */
-  unsigned long long total_bps_in;
-
-  /**
-   * Total outbound bandwidth per configuration.
-   */
-  unsigned long long total_bps_out;
-};
-
-
-/**
  * Count number of connected records.
  *
  * @param cls pointer to counter
@@ -232,6 +138,8 @@
   {
     ar->bandwidth_in = sbc->bw_in;
     ar->bandwidth_out = sbc->bw_out;
+    GNUNET_BANDWIDTH_tracker_update_quota (&ar->available_recv_window,
+                                          ar->bandwidth_in);
     sbc->atc->alloc_cb (sbc->atc->alloc_cb_cls,
                         (const struct GNUNET_PeerIdentity *) key,
                         ar->plugin_name, ar->session, ar->plugin_addr,
@@ -609,6 +517,9 @@
   memcpy (&ar[1], plugin_addr, plugin_addr_len);
   ar->session = session;
   ar->plugin_addr_len = plugin_addr_len;  
+  GNUNET_BANDWIDTH_tracker_init (&ar->available_recv_window, 
+                                ar->bandwidth_in,
+                                 MAX_WINDOW_TIME_S);
   GNUNET_assert (ats_count > 0);
   GNUNET_array_grow (ar->ats, ar->ats_count, ats_count);
   memcpy (ar->ats, ats,

Added: gnunet/src/ats/ats_api.h
===================================================================
--- gnunet/src/ats/ats_api.h                            (rev 0)
+++ gnunet/src/ats/ats_api.h    2011-10-10 10:59:00 UTC (rev 17306)
@@ -0,0 +1,138 @@
+/*
+     This file is part of GNUnet.
+     (C) 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
+     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
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file ats/ats_api.h
+ * @brief automatic transport selection API common includes
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#ifndef ATS_API_H
+#define ATS_API_H
+
+#include "gnunet_util_lib.h"
+
+/**
+ * Allocation record for a peer's address.
+ */
+struct AllocationRecord
+{
+
+  /**
+   * Performance information associated with this address (array).
+   */
+  struct GNUNET_TRANSPORT_ATS_Information *ats;
+
+  /**
+   * Name of the plugin
+   */
+  char *plugin_name;
+
+  /**
+   * Address this record represents, allocated at the end of this struct.
+   */
+  const void *plugin_addr;
+
+  /**
+   * Session associated with this record.
+   */
+  struct Session *session;
+
+  /**
+   * Number of bytes in plugin_addr.
+   */
+  size_t plugin_addr_len;
+
+  /**
+   * Number of entries in 'ats'.
+   */
+  uint32_t ats_count;
+
+  /**
+   * Inbound bandwidth assigned to this address right now, 0 for none.
+   */
+  struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
+
+  /**
+   * Outbound bandwidth assigned to this address right now, 0 for none.
+   */
+  struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out;
+
+  /**
+   * Tracking bandwidth for receiving from this peer.  Used for
+   * applications that want to 'reserve' bandwidth for replies.
+   */
+  struct GNUNET_BANDWIDTH_Tracker available_recv_window;
+
+  /**
+   * Set to GNUNET_YES if this is the connected address of a connected peer.
+   */
+  int connected;
+
+};
+
+
+/**
+ * Handle to the ATS subsystem.
+ */
+struct GNUNET_ATS_Handle
+{
+  /**
+   * Configuration.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Function to call when the allocation changes.
+   */
+  GNUNET_TRANSPORT_ATS_AllocationNotification alloc_cb;
+
+  /**
+   * Closure for 'alloc_cb'.
+   */
+  void *alloc_cb_cls;
+
+  /**
+   * Information about all connected peers.  Maps peer identities
+   * to one or more 'struct AllocationRecord' values.
+   */
+  struct GNUNET_CONTAINER_MultiHashMap *peers;
+
+  /**
+   * Map of PeerIdentities to 'struct GNUNET_ATS_SuggestionContext's.
+   */
+  struct GNUNET_CONTAINER_MultiHashMap *notify_map;
+
+  /**
+   * Task scheduled to update our bandwidth assignment.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier ba_task;
+
+  /**
+   * Total inbound bandwidth per configuration.
+   */
+  unsigned long long total_bps_in;
+
+  /**
+   * Total outbound bandwidth per configuration.
+   */
+  unsigned long long total_bps_out;
+};
+
+#endif

Added: gnunet/src/ats/ats_api_peer_change_preference.c
===================================================================
--- gnunet/src/ats/ats_api_peer_change_preference.c                             
(rev 0)
+++ gnunet/src/ats/ats_api_peer_change_preference.c     2011-10-10 10:59:00 UTC 
(rev 17306)
@@ -0,0 +1,310 @@
+/*
+     This file is part of GNUnet.
+     (C) 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
+     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
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file ats/ats_api_peer_change_preference.c
+ * @brief automatic transport selection API, preference management
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ *
+ * TODO:
+ * - write test case
+ * - extend API to get performance data
+ * - implement simplistic strategy based on say 'lowest latency' or strict 
ordering
+ * - extend API to get peer preferences, implement proportional bandwidth 
assignment
+ * - re-implement API against a real ATS service (!)
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "ats_api.h"
+
+struct GNUNET_ATS_InformationRequestContext
+{
+
+  /**
+   * Our connection to the service.
+   */
+  struct GNUNET_ATS_Handle *h;
+
+  /**
+   * Link to peer record.
+   */
+  struct AllocationRecord *ar;
+
+  int32_t amount;
+
+  uint64_t preference;
+
+  GNUNET_ATS_PeerConfigurationInfoCallback info;
+
+  void *info_cls;
+  
+  struct GNUNET_PeerIdentity peer;
+  
+  GNUNET_SCHEDULER_TaskIdentifier task;
+
+};
+
+
+static void
+exec_pcp (void *cls,
+         const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_ATS_InformationRequestContext *irc = cls;
+  int32_t want_reserv;
+  int32_t got_reserv;
+  struct GNUNET_TIME_Relative rdelay;
+
+  rdelay = GNUNET_TIME_UNIT_ZERO;
+  want_reserv = irc->amount;
+  if (want_reserv < 0)
+  {
+    got_reserv = want_reserv;
+  }
+  else if (want_reserv > 0)
+  {
+    rdelay =
+      GNUNET_BANDWIDTH_tracker_get_delay (&irc->ar->available_recv_window,
+                                         want_reserv);
+    if (rdelay.rel_value == 0)
+      got_reserv = want_reserv;
+    else
+      got_reserv = 0;         /* all or nothing */
+  }
+  else
+    got_reserv = 0;
+  GNUNET_BANDWIDTH_tracker_consume (&irc->ar->available_recv_window, 
got_reserv);
+
+  irc->info (irc->info_cls,
+            &irc->peer,
+            got_reserv,
+            rdelay);
+  GNUNET_free (irc);
+}
+
+
+/**
+ * Obtain statistics and/or change preferences for the given peer.
+ *
+ * @param h core handle
+ * @param peer identifies the peer
+ * @param amount reserve N bytes for receiving, negative
+ *                amounts can be used to undo a (recent) reservation;
+ * @param preference increase incoming traffic share preference by this amount;
+ *                in the absence of "amount" reservations, we use this
+ *                preference value to assign proportional bandwidth shares
+ *                to all connected peers
+ * @param info function to call with the resulting configuration information
+ * @param info_cls closure for info
+ * @return NULL on error
+ */
+struct GNUNET_ATS_InformationRequestContext *
+GNUNET_ATS_peer_change_preference (struct GNUNET_ATS_Handle *h,
+                                  const struct GNUNET_PeerIdentity *peer,
+                                    int32_t amount, uint64_t preference,
+                                    GNUNET_ATS_PeerConfigurationInfoCallback
+                                    info, void *info_cls)
+{
+  struct GNUNET_ATS_InformationRequestContext *irc;
+  struct AllocationRecord *ar;
+
+  ar = GNUNET_CONTAINER_multihashmap_get (h->peers, &peer->hashPubKey);
+  if (NULL == ar)
+  {
+    /* attempt to change preference on peer that is not connected */
+    GNUNET_assert (0);
+    return NULL;
+  }
+  irc = GNUNET_malloc (sizeof (struct GNUNET_ATS_InformationRequestContext));
+  irc->h = h;
+  irc->peer = *peer;
+  irc->ar = ar;
+  irc->amount = amount;
+  irc->preference = preference;
+  irc->info = info;
+  irc->info_cls = info_cls;
+  irc->task = GNUNET_SCHEDULER_add_now (&exec_pcp, irc);
+  return irc;
+}
+
+
+/**
+ * Cancel request for getting information about a peer.
+ * Note that an eventual change in preference, trust or bandwidth
+ * assignment MAY have already been committed at the time,
+ * so cancelling a request is NOT sure to undo the original
+ * request.  The original request may or may not still commit.
+ * The only thing cancellation ensures is that the callback
+ * from the original request will no longer be called.
+ *
+ * @param irc context returned by the original GNUNET_ATS_peer_get_info call
+ */
+void
+GNUNET_ATS_peer_change_preference_cancel (struct
+                                           GNUNET_ATS_InformationRequestContext
+                                           *irc)
+{
+  GNUNET_SCHEDULER_cancel (irc->task);
+  GNUNET_free (irc);
+}
+
+
+#if 0
+/* old CORE API implementation follows for future reference */
+struct GNUNET_ATS_InformationRequestContext
+{
+
+  /**
+   * Our connection to the service.
+   */
+  struct GNUNET_ATS_Handle *h;
+
+  /**
+   * Link to control message, NULL if CM was sent.
+   */
+  struct ControlMessage *cm;
+
+  /**
+   * Link to peer record.
+   */
+  struct PeerRecord *pr;
+};
+
+
+/**
+ * CM was sent, remove link so we don't double-free.
+ *
+ * @param cls the 'struct GNUNET_ATS_InformationRequestContext'
+ * @param success were we successful?
+ */
+static void
+change_preference_send_continuation (void *cls, int success)
+{
+  struct GNUNET_ATS_InformationRequestContext *irc = cls;
+
+  irc->cm = NULL;
+}
+
+
+/**
+ * Obtain statistics and/or change preferences for the given peer.
+ *
+ * @param h core handle
+ * @param peer identifies the peer
+ * @param amount reserve N bytes for receiving, negative
+ *                amounts can be used to undo a (recent) reservation;
+ * @param preference increase incoming traffic share preference by this amount;
+ *                in the absence of "amount" reservations, we use this
+ *                preference value to assign proportional bandwidth shares
+ *                to all connected peers
+ * @param info function to call with the resulting configuration information
+ * @param info_cls closure for info
+ * @return NULL on error
+ */
+struct GNUNET_ATS_InformationRequestContext *
+GNUNET_ATS_peer_change_preference (struct GNUNET_ATS_Handle *h,
+                                    const struct GNUNET_PeerIdentity *peer,
+                                    int32_t amount, uint64_t preference,
+                                    GNUNET_ATS_PeerConfigurationInfoCallback
+                                    info, void *info_cls)
+{
+  struct GNUNET_ATS_InformationRequestContext *irc;
+  struct PeerRecord *pr;
+  struct RequestInfoMessage *rim;
+  struct ControlMessage *cm;
+
+  pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &peer->hashPubKey);
+  if (NULL == pr)
+  {
+    /* attempt to change preference on peer that is not connected */
+    GNUNET_assert (0);
+    return NULL;
+  }
+  if (pr->pcic != NULL)
+  {
+    /* second change before first one is done */
+    GNUNET_break (0);
+    return NULL;
+  }
+  irc = GNUNET_malloc (sizeof (struct GNUNET_ATS_InformationRequestContext));
+  irc->h = h;
+  irc->pr = pr;
+  cm = GNUNET_malloc (sizeof (struct ControlMessage) +
+                      sizeof (struct RequestInfoMessage));
+  cm->cont = &change_preference_send_continuation;
+  cm->cont_cls = irc;
+  irc->cm = cm;
+  rim = (struct RequestInfoMessage *) &cm[1];
+  rim->header.size = htons (sizeof (struct RequestInfoMessage));
+  rim->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_REQUEST_INFO);
+  rim->rim_id = htonl (pr->rim_id = h->rim_id_gen++);
+  rim->reserved = htonl (0);
+  rim->reserve_inbound = htonl (amount);
+  rim->preference_change = GNUNET_htonll (preference);
+  rim->peer = *peer;
+#if DEBUG_ATS
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Queueing CHANGE PREFERENCE request for peer `%s' with RIM %u\n",
+              GNUNET_i2s (peer), (unsigned int) pr->rim_id);
+#endif
+  GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head,
+                                    h->control_pending_tail, cm);
+  pr->pcic = info;
+  pr->pcic_cls = info_cls;
+  pr->pcic_ptr = irc;           /* for free'ing irc */
+  if (NULL != h->client)
+    trigger_next_request (h, GNUNET_NO);
+  return irc;
+}
+
+
+/**
+ * Cancel request for getting information about a peer.
+ * Note that an eventual change in preference, trust or bandwidth
+ * assignment MAY have already been committed at the time,
+ * so cancelling a request is NOT sure to undo the original
+ * request.  The original request may or may not still commit.
+ * The only thing cancellation ensures is that the callback
+ * from the original request will no longer be called.
+ *
+ * @param irc context returned by the original GNUNET_ATS_peer_get_info call
+ */
+void
+GNUNET_ATS_peer_change_preference_cancel (struct
+                                           GNUNET_ATS_InformationRequestContext
+                                           *irc)
+{
+  struct GNUNET_ATS_Handle *h = irc->h;
+  struct PeerRecord *pr = irc->pr;
+
+  GNUNET_assert (pr->pcic_ptr == irc);
+  if (irc->cm != NULL)
+  {
+    GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
+                                 h->control_pending_tail, irc->cm);
+    GNUNET_free (irc->cm);
+  }
+  pr->pcic = NULL;
+  pr->pcic_cls = NULL;
+  pr->pcic_ptr = NULL;
+  GNUNET_free (irc);
+}
+#endif
+
+/* end of ats_api_peer_change_preference.c */

Modified: gnunet/src/include/gnunet_ats_service.h
===================================================================
--- gnunet/src/include/gnunet_ats_service.h     2011-10-10 10:50:08 UTC (rev 
17305)
+++ gnunet/src/include/gnunet_ats_service.h     2011-10-10 10:59:00 UTC (rev 
17306)
@@ -243,5 +243,77 @@
                            uint32_t ats_count);
 
 
+
+/**
+ * Function called with perference change information about the given peer.
+ *
+ * @param cls closure
+ * @param peer identifies the peer
+ * @param amount set to the amount that was actually reserved or unreserved;
+ *               either the full requested amount or zero (no partial 
reservations)
+ * @param res_delay if the reservation could not be satisfied (amount was 0), 
how
+ *        long should the client wait until re-trying?
+ */
+typedef void (*GNUNET_ATS_PeerConfigurationInfoCallback) (void *cls,
+                                                         const struct
+                                                         GNUNET_PeerIdentity *
+                                                         peer,
+                                                         int32_t amount,
+                                                         struct
+                                                         GNUNET_TIME_Relative
+                                                         res_delay);
+
+
+
+/**
+ * Context that can be used to cancel a peer information request.
+ */
+struct GNUNET_ATS_InformationRequestContext;
+
+
+/**
+ * Obtain statistics and/or change preferences for the given peer.
+ * You can only have one such pending request per peer.
+ *
+ * @param h core handle
+ * @param peer identifies the peer
+ * @param amount reserve N bytes for receiving, negative
+ *                amounts can be used to undo a (recent) reservation;
+ * @param preference increase incoming traffic share preference by this amount;
+ *                in the absence of "amount" reservations, we use this
+ *                preference value to assign proportional bandwidth shares
+ *                to all connected peers
+ * @param info function to call with the resulting configuration information
+ * @param info_cls closure for info
+ * @return NULL on error
+ * @deprecated will be replaced soon
+ */
+struct GNUNET_ATS_InformationRequestContext *
+GNUNET_ATS_peer_change_preference (struct GNUNET_ATS_Handle *h,
+                                  const struct GNUNET_PeerIdentity *peer,
+                                  int32_t amount, uint64_t preference,
+                                  GNUNET_ATS_PeerConfigurationInfoCallback
+                                  info, void *info_cls);
+
+
+/**
+ * Cancel request for getting information about a peer.
+ * Note that an eventual change in preference, trust or bandwidth
+ * assignment MAY have already been committed at the time,
+ * so cancelling a request is NOT sure to undo the original
+ * request.  The original request may or may not still commit.
+ * The only thing cancellation ensures is that the callback
+ * from the original request will no longer be called.
+ *
+ * @param irc context returned by the original GNUNET_ATS_peer_get_info call
+ * @deprecated will be replaced soon
+ */
+void
+GNUNET_ATS_peer_change_preference_cancel (struct
+                                         GNUNET_ATS_InformationRequestContext
+                                         *irc);
+
+
+
 #endif
 /* end of file gnunet-service-transport_ats.h */




reply via email to

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