Browse Source

allow applications expressing connection preferences directly to TNG, collect HELLOs from PEERSTORE for expressed prefs

Christian Grothoff 5 years ago
parent
commit
670ebb20b9

+ 8 - 8
src/ats/gnunet-service-ats-new.c

@@ -304,7 +304,7 @@ prop_ntoh (const struct PropertiesNBO *properties,
  */
 static void
 handle_suggest (void *cls,
-		const struct ExpressPreferenceMessage *msg)
+                const struct ExpressPreferenceMessage *msg)
 {
   struct Client *c = cls;
   struct ClientPreference *cp;
@@ -344,7 +344,7 @@ handle_suggest (void *cls,
  */
 static void
 handle_suggest_cancel (void *cls,
-		       const struct ExpressPreferenceMessage *msg)
+                       const struct ExpressPreferenceMessage *msg)
 {
   struct Client *c = cls;
   struct ClientPreference *cp;
@@ -772,13 +772,13 @@ GNUNET_SERVICE_MAIN
  &client_disconnect_cb,
  NULL,
  GNUNET_MQ_hd_fixed_size (suggest,
-			  GNUNET_MESSAGE_TYPE_ATS_SUGGEST,
-			  struct ExpressPreferenceMessage,
-			  NULL),
+                          GNUNET_MESSAGE_TYPE_ATS_SUGGEST,
+                          struct ExpressPreferenceMessage,
+                          NULL),
  GNUNET_MQ_hd_fixed_size (suggest_cancel,
-			  GNUNET_MESSAGE_TYPE_ATS_SUGGEST_CANCEL,
-			  struct ExpressPreferenceMessage,
-			  NULL),
+                          GNUNET_MESSAGE_TYPE_ATS_SUGGEST_CANCEL,
+                          struct ExpressPreferenceMessage,
+                          NULL),
  GNUNET_MQ_hd_fixed_size (start,
 			  GNUNET_MESSAGE_TYPE_ATS_START,
 			  struct GNUNET_MessageHeader,

+ 3 - 3
src/include/gnunet_ats_application_service.h

@@ -83,9 +83,9 @@ struct GNUNET_ATS_ApplicationSuggestHandle;
  */
 struct GNUNET_ATS_ApplicationSuggestHandle *
 GNUNET_ATS_application_suggest (struct GNUNET_ATS_ApplicationHandle *ch,
-                                 const struct GNUNET_PeerIdentity *peer,
-                                 enum GNUNET_MQ_PreferenceKind pk,
-                                 struct GNUNET_BANDWIDTH_Value32NBO bw);
+                                const struct GNUNET_PeerIdentity *peer,
+                                enum GNUNET_MQ_PreferenceKind pk,
+                                struct GNUNET_BANDWIDTH_Value32NBO bw);
 
 
 /**

+ 2 - 2
src/include/gnunet_peerstore_service.h

@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      Copyright (C)
+      Copyright (C) GNUnet e.V. 2004--2019
 
       GNUnet is free software: you can redistribute it and/or modify it
       under the terms of the GNU Affero General Public License as published
@@ -11,7 +11,7 @@
       WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       Affero General Public License for more details.
-     
+
       You should have received a copy of the GNU Affero General Public License
       along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

+ 12 - 0
src/include/gnunet_protocols.h

@@ -3177,6 +3177,18 @@ extern "C"
  */
 #define GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_FC_LIMITS 1276
 
+/**
+ * Type of the 'struct ExpressPreferenceMessage' send by clients to TRANSPORT
+ * to establish bandwidth preference.
+ */
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST 1300
+
+/**
+ * Type of the 'struct ExpressPreferenceMessage' send by clients to TRANSPORT
+ * to abandon bandwidth preference.
+ */
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL 1301
+
 
 /* ************** NEW (NG) ATS Messages ************* */
 

+ 100 - 0
src/include/gnunet_transport_application_service.h

@@ -0,0 +1,100 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2010-2015, 2018, 2019 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ 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
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/**
+ * @file
+ * Bandwidth allocation API for applications to interact with
+ *
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ *
+ * @defgroup TRANSPORT service
+ * Bandwidth allocation
+ *
+ * @{
+ */
+#ifndef GNUNET_TRANSPORT_APPLICATION_SERVICE_H
+#define GNUNET_TRANSPORT_APPLICATION_SERVICE_H
+
+#include "gnunet_constants.h"
+#include "gnunet_util_lib.h"
+
+/**
+ * Handle to the TRANSPORT subsystem for making suggestions about
+ * connections the peer would like to have.
+ */
+struct GNUNET_TRANSPORT_ApplicationHandle;
+
+
+/**
+ * Initialize the TRANSPORT application client handle.
+ *
+ * @param cfg configuration to use
+ * @return ats application handle, NULL on error
+ */
+struct GNUNET_TRANSPORT_ApplicationHandle *
+GNUNET_TRANSPORT_application_init (const struct GNUNET_CONFIGURATION_Handle *cfg);
+
+
+/**
+ * Shutdown TRANSPORT application client.
+ *
+ * @param ch handle to destroy
+ */
+void
+GNUNET_TRANSPORT_application_done (struct GNUNET_TRANSPORT_ApplicationHandle *ch);
+
+
+/**
+ * Handle for suggestion requests.
+ */
+struct GNUNET_TRANSPORT_ApplicationSuggestHandle;
+
+
+/**
+ * An application would like to communicate with a peer.  TRANSPORT should
+ * allocate bandwith using a suitable address for requiremetns @a pk
+ * to transport.
+ *
+ * @param ch handle
+ * @param peer identity of the peer we need an address for
+ * @param pk what kind of application will the application require (can be
+ *         #GNUNET_MQ_PREFERENCE_NONE, we will still try to connect)
+ * @param bw desired bandwith, can be zero (we will still try to connect)
+ * @return suggestion handle, NULL if request is already pending
+ */
+struct GNUNET_TRANSPORT_ApplicationSuggestHandle *
+GNUNET_TRANSPORT_application_suggest (struct GNUNET_TRANSPORT_ApplicationHandle *ch,
+                                      const struct GNUNET_PeerIdentity *peer,
+                                      enum GNUNET_MQ_PreferenceKind pk,
+                                      struct GNUNET_BANDWIDTH_Value32NBO bw);
+
+
+/**
+ * We no longer care about communicating with a peer.
+ *
+ * @param sh handle
+ */
+void
+GNUNET_TRANSPORT_application_suggest_cancel (struct GNUNET_TRANSPORT_ApplicationSuggestHandle *sh);
+
+/** @} */  /* end of group */
+
+#endif
+/* end of file gnunet_ats_application_service.h */

+ 9 - 1
src/transport/Makefile.am

@@ -155,6 +155,7 @@ endif
 lib_LTLIBRARIES = \
   libgnunettransport.la \
   libgnunettransportaddress.la \
+  libgnunettransportapplication.la \
   libgnunettransportcore.la \
   libgnunettransportcommunicator.la \
   libgnunettransportmonitor.la \
@@ -196,6 +197,14 @@ libgnunettransport_la_LDFLAGS = \
   $(GN_LIB_LDFLAGS) $(WINFLAGS) \
   -version-info 4:0:2
 
+libgnunettransportapplication_la_SOURCES = \
+  transport_api2_application.c
+libgnunettransportapplication_la_LIBADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(LTLIBINTL)
+libgnunettransportapplication_la_LDFLAGS = \
+  $(GN_LIB_LDFLAGS) $(WINFLAGS) \
+  -version-info 0:0:0
 
 
 libgnunettransportaddress_la_SOURCES = \
@@ -360,7 +369,6 @@ gnunet_service_transport_CFLAGS = \
 gnunet_service_tng_SOURCES = \
  gnunet-service-tng.c
 gnunet_service_tng_LDADD = \
-  $(top_builddir)/src/ats/libgnunetatstransport.la \
   $(top_builddir)/src/peerstore/libgnunetpeerstore.la \
   $(top_builddir)/src/hello/libgnunethello.la \
   $(top_builddir)/src/statistics/libgnunetstatistics.la \

File diff suppressed because it is too large
+ 230 - 221
src/transport/gnunet-service-tng.c


+ 32 - 0
src/transport/transport.h

@@ -1107,6 +1107,38 @@ struct GNUNET_TRANSPORT_AddressToVerify
 };
 
 
+/**
+ * Application client to TRANSPORT service: we would like to have
+ * address suggestions for this peer.
+ */
+struct ExpressPreferenceMessage
+{
+  /**
+   * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST or
+   * #GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL to stop
+   * suggestions.
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * What type of performance preference does the client have?
+   * A `enum GNUNET_MQ_PreferenceKind` in NBO.
+   */
+  uint32_t pk GNUNET_PACKED;
+
+  /**
+   * Peer to get address suggestions for.
+   */
+  struct GNUNET_PeerIdentity peer;
+
+  /**
+   * How much bandwidth in bytes/second does the application expect?
+   */
+  struct GNUNET_BANDWIDTH_Value32NBO bw;
+
+};
+
+
 #endif
 
 GNUNET_NETWORK_STRUCT_END

+ 366 - 0
src/transport/transport_api2_application.c

@@ -0,0 +1,366 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2010--2019 GNUnet e.V.
+
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     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
+     Affero General Public License for more details.
+
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+*/
+/**
+ * @file transport/transport_api2_application.c
+ * @brief enable clients to ask TRANSPORT about establishing connections to peers
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_transport_application_service.h"
+#include "gnunet_transport_core_service.h"
+#include "transport.h"
+
+
+#define LOG(kind,...) GNUNET_log_from(kind, "transport-application-api", __VA_ARGS__)
+
+
+/**
+ * Handle for TRANSPORT address suggestion requests.
+ */
+struct GNUNET_TRANSPORT_ApplicationSuggestHandle
+{
+  /**
+   * ID of the peer for which address suggestion was requested.
+   */
+  struct GNUNET_PeerIdentity id;
+
+  /**
+   * Connecitivity handle this suggestion handle belongs to.
+   */
+  struct GNUNET_TRANSPORT_ApplicationHandle *ch;
+
+  /**
+   * What preference is being expressed?
+   */
+  enum GNUNET_MQ_PreferenceKind pk;
+
+  /**
+   * How much bandwidth does the client expect?
+   */
+  struct GNUNET_BANDWIDTH_Value32NBO bw;
+};
+
+
+/**
+ * Handle to the TRANSPORT subsystem for application management.
+ */
+struct GNUNET_TRANSPORT_ApplicationHandle
+{
+
+  /**
+   * Our configuration.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Map with the identities of all the peers for which we would
+   * like to have address suggestions.  The key is the PID, the
+   * value is currently the `struct GNUNET_TRANSPORT_ApplicationSuggestHandle`
+   */
+  struct GNUNET_CONTAINER_MultiPeerMap *sug_requests;
+
+  /**
+   * Message queue for sending requests to the TRANSPORT service.
+   */
+  struct GNUNET_MQ_Handle *mq;
+
+  /**
+   * Task to trigger reconnect.
+   */
+  struct GNUNET_SCHEDULER_Task *task;
+
+  /**
+   * Reconnect backoff delay.
+   */
+  struct GNUNET_TIME_Relative backoff;
+};
+
+
+/**
+ * Re-establish the connection to the TRANSPORT service.
+ *
+ * @param ch handle to use to re-connect.
+ */
+static void
+reconnect (struct GNUNET_TRANSPORT_ApplicationHandle *ch);
+
+
+/**
+ * Re-establish the connection to the TRANSPORT service.
+ *
+ * @param cls handle to use to re-connect.
+ */
+static void
+reconnect_task (void *cls)
+{
+  struct GNUNET_TRANSPORT_ApplicationHandle *ch = cls;
+
+  ch->task = NULL;
+  reconnect (ch);
+}
+
+
+/**
+ * Disconnect from TRANSPORT and then reconnect.
+ *
+ * @param ch our handle
+ */
+static void
+force_reconnect (struct GNUNET_TRANSPORT_ApplicationHandle *ch)
+{
+  if (NULL != ch->mq)
+  {
+    GNUNET_MQ_destroy (ch->mq);
+    ch->mq = NULL;
+  }
+  ch->backoff = GNUNET_TIME_STD_BACKOFF (ch->backoff);
+  ch->task = GNUNET_SCHEDULER_add_delayed (ch->backoff,
+                                           &reconnect_task,
+                                           ch);
+}
+
+
+/**
+ * We encountered an error handling the MQ to the
+ * TRANSPORT service.  Reconnect.
+ *
+ * @param cls the `struct GNUNET_TRANSPORT_ApplicationHandle`
+ * @param error details about the error
+ */
+static void
+error_handler (void *cls,
+               enum GNUNET_MQ_Error error)
+{
+  struct GNUNET_TRANSPORT_ApplicationHandle *ch = cls;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "TRANSPORT connection died (code %d), reconnecting\n",
+       (int) error);
+  force_reconnect (ch);
+}
+
+
+/**
+ * Transmit request for an address suggestion.
+ *
+ * @param cls the `struct GNUNET_TRANSPORT_ApplicationHandle`
+ * @param peer peer to ask for an address suggestion for
+ * @param value the `struct GNUNET_TRANSPORT_SuggestHandle`
+ * @return #GNUNET_OK (continue to iterate), #GNUNET_SYSERR on
+ *         failure (message queue no longer exists)
+ */
+static int
+transmit_suggestion (void *cls,
+                     const struct GNUNET_PeerIdentity *peer,
+                     void *value)
+{
+  struct GNUNET_TRANSPORT_ApplicationHandle *ch = cls;
+  struct GNUNET_TRANSPORT_ApplicationSuggestHandle *sh = value;
+  struct GNUNET_MQ_Envelope *ev;
+  struct ExpressPreferenceMessage *m;
+
+  if (NULL == ch->mq)
+    return GNUNET_SYSERR;
+  ev = GNUNET_MQ_msg (m,
+                      GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST);
+  m->pk = htonl ((uint32_t) sh->pk);
+  m->bw = sh->bw;
+  m->peer = *peer;
+  GNUNET_MQ_send (ch->mq, ev);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Re-establish the connection to the TRANSPORT service.
+ *
+ * @param ch handle to use to re-connect.
+ */
+static void
+reconnect (struct GNUNET_TRANSPORT_ApplicationHandle *ch)
+{
+  static const struct GNUNET_MQ_MessageHandler handlers[] = {
+    { NULL, 0, 0 }
+  };
+
+  GNUNET_assert (NULL == ch->mq);
+  ch->mq = GNUNET_CLIENT_connect (ch->cfg,
+                                  "transport",
+                                  handlers,
+                                  &error_handler,
+                                  ch);
+  if (NULL == ch->mq)
+  {
+    force_reconnect (ch);
+    return;
+  }
+  GNUNET_CONTAINER_multipeermap_iterate (ch->sug_requests,
+                                         &transmit_suggestion,
+                                         ch);
+}
+
+
+/**
+ * Initialize the TRANSPORT application suggestion client handle.
+ *
+ * @param cfg configuration to use
+ * @return transport application handle, NULL on error
+ */
+struct GNUNET_TRANSPORT_ApplicationHandle *
+GNUNET_TRANSPORT_application_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  struct GNUNET_TRANSPORT_ApplicationHandle *ch;
+
+  ch = GNUNET_new (struct GNUNET_TRANSPORT_ApplicationHandle);
+  ch->cfg = cfg;
+  ch->sug_requests = GNUNET_CONTAINER_multipeermap_create (32,
+                                                           GNUNET_YES);
+  reconnect (ch);
+  return ch;
+}
+
+
+/**
+ * Function called to free all `struct GNUNET_TRANSPORT_ApplicationSuggestHandle`s
+ * in the map.
+ *
+ * @param cls NULL
+ * @param key the key
+ * @param value the value to free
+ * @return #GNUNET_OK (continue to iterate)
+ */
+static int
+free_sug_handle (void *cls,
+                 const struct GNUNET_PeerIdentity *key,
+                 void *value)
+{
+  struct GNUNET_TRANSPORT_ApplicationSuggestHandle *cur = value;
+
+  GNUNET_free (cur);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Client is done with TRANSPORT application management, release resources.
+ *
+ * @param ch handle to release
+ */
+void
+GNUNET_TRANSPORT_application_done (struct GNUNET_TRANSPORT_ApplicationHandle *ch)
+{
+  if (NULL != ch->mq)
+  {
+    GNUNET_MQ_destroy (ch->mq);
+    ch->mq = NULL;
+  }
+  if (NULL != ch->task)
+  {
+    GNUNET_SCHEDULER_cancel (ch->task);
+    ch->task = NULL;
+  }
+  GNUNET_CONTAINER_multipeermap_iterate (ch->sug_requests,
+                                         &free_sug_handle,
+                                         NULL);
+  GNUNET_CONTAINER_multipeermap_destroy (ch->sug_requests);
+  GNUNET_free (ch);
+}
+
+
+/**
+ * We would like to receive address suggestions for a peer. TRANSPORT will
+ * respond with a call to the continuation immediately containing an address or
+ * no address if none is available. TRANSPORT can suggest more addresses until we call
+ * #GNUNET_TRANSPORT_application_suggest_cancel().
+ *
+ * @param ch handle
+ * @param peer identity of the peer we need an address for
+ * @param pk what kind of application will the application require (can be
+ *         #GNUNET_MQ_PREFERENCE_NONE, we will still try to connect)
+ * @param bw desired bandwith, can be zero (we will still try to connect)
+ * @return suggest handle, NULL if a request is already pending
+ */
+struct GNUNET_TRANSPORT_ApplicationSuggestHandle *
+GNUNET_TRANSPORT_application_suggest (struct GNUNET_TRANSPORT_ApplicationHandle *ch,
+                                      const struct GNUNET_PeerIdentity *peer,
+                                      enum GNUNET_MQ_PreferenceKind pk,
+                                      struct GNUNET_BANDWIDTH_Value32NBO bw)
+{
+  struct GNUNET_TRANSPORT_ApplicationSuggestHandle *s;
+
+  s = GNUNET_new (struct GNUNET_TRANSPORT_ApplicationSuggestHandle);
+  s->ch = ch;
+  s->id = *peer;
+  s->pk = pk;
+  s->bw = bw;
+  (void) GNUNET_CONTAINER_multipeermap_put (ch->sug_requests,
+                                            &s->id,
+                                            s,
+                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Requesting TRANSPORT to suggest address for `%s'\n",
+       GNUNET_i2s (peer));
+  if (NULL == ch->mq)
+    return s;
+  GNUNET_assert (GNUNET_OK ==
+                 transmit_suggestion (ch,
+                                      &s->id,
+                                      s));
+  return s;
+}
+
+
+/**
+ * We no longer care about being connected to a peer.
+ *
+ * @param sh handle to stop
+ */
+void
+GNUNET_TRANSPORT_application_suggest_cancel (struct GNUNET_TRANSPORT_ApplicationSuggestHandle *sh)
+{
+  struct GNUNET_TRANSPORT_ApplicationHandle *ch = sh->ch;
+  struct GNUNET_MQ_Envelope *ev;
+  struct ExpressPreferenceMessage *m;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Telling TRANSPORT we no longer care for an address for `%s'\n",
+       GNUNET_i2s (&sh->id));
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CONTAINER_multipeermap_remove (ch->sug_requests,
+                                                       &sh->id,
+                                                       sh));
+  if (NULL == ch->mq)
+  {
+    GNUNET_free (sh);
+    return;
+  }
+  ev = GNUNET_MQ_msg (m,
+                      GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL);
+  m->pk = htonl ((uint32_t) sh->pk);
+  m->bw = sh->bw;
+  m->peer = sh->id;
+  GNUNET_MQ_send (ch->mq,
+                  ev);
+  GNUNET_free (sh);
+}
+
+
+/* end of transport_api2_application.c */

Some files were not shown because too many files changed in this diff