gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r26447 - gnunet/src/dv


From: gnunet
Subject: [GNUnet-SVN] r26447 - gnunet/src/dv
Date: Fri, 15 Mar 2013 11:35:14 +0100

Author: grothoff
Date: 2013-03-15 11:35:13 +0100 (Fri, 15 Mar 2013)
New Revision: 26447

Modified:
   gnunet/src/dv/gnunet_dv_service.h
   gnunet/src/dv/plugin_transport_dv.c
Log:
-dv work

Modified: gnunet/src/dv/gnunet_dv_service.h
===================================================================
--- gnunet/src/dv/gnunet_dv_service.h   2013-03-15 10:35:00 UTC (rev 26446)
+++ gnunet/src/dv/gnunet_dv_service.h   2013-03-15 10:35:13 UTC (rev 26447)
@@ -32,6 +32,10 @@
 /**
  * Signature of a function to be called if DV
  * starts to be able to talk to a peer.
+ *
+ * @param cls closure
+ * @param peer newly connected peer
+ * @param distance distance to the peer
  */
 typedef void (*GNUNET_DV_ConnectCallback)(void *cls,
                                          const struct GNUNET_PeerIdentity 
*peer,
@@ -41,6 +45,10 @@
 /**
  * Signature of a function to be called if DV
  * distance to a peer is changed.
+ *
+ * @param cls closure
+ * @param peer connected peer
+ * @param distance new distance to the peer
  */
 typedef void (*GNUNET_DV_DistanceChangedCallback)(void *cls,
                                                  const struct 
GNUNET_PeerIdentity *peer,
@@ -50,6 +58,9 @@
 /**
  * Signature of a function to be called if DV
  * is no longer able to talk to a peer.
+ *
+ * @param cls closure
+ * @param peer peer that disconnected
  */
 typedef void (*GNUNET_DV_DisconnectCallback)(void *cls,
                                             const struct GNUNET_PeerIdentity 
*peer);

Modified: gnunet/src/dv/plugin_transport_dv.c
===================================================================
--- gnunet/src/dv/plugin_transport_dv.c 2013-03-15 10:35:00 UTC (rev 26446)
+++ gnunet/src/dv/plugin_transport_dv.c 2013-03-15 10:35:13 UTC (rev 26447)
@@ -37,7 +37,6 @@
 #include "gnunet_transport_plugin.h"
 #include "dv.h"
 
-#define DEBUG_TEMPLATE GNUNET_EXTRA_LOGGING
 
 /**
  * Encapsulation of all of the state of the plugin.
@@ -52,9 +51,9 @@
 {
 
   /**
-   * Stored in a linked list.
+   * Mandatory session header.
    */
-  struct Session *next;
+  struct SessionHeader header;
 
   /**
    * Pointer to the global plugin struct.
@@ -62,11 +61,6 @@
   struct Plugin *plugin;
 
   /**
-   * The client (used to identify this connection)
-   */
-  /* void *client; */
-
-  /**
    * Continuation function to call once the transmission buffer
    * has again space available.  NULL if there is no
    * continuation to call.
@@ -79,30 +73,24 @@
   void *transmit_cont_cls;
 
   /**
-   * To whom are we talking to (set to our identity
-   * if we are still waiting for the welcome message)
+   * To whom are we talking to.
    */
   struct GNUNET_PeerIdentity sender;
 
   /**
-   * At what time did we reset last_received last?
+   * Current distance to the given peer.
    */
-  struct GNUNET_TIME_Absolute last_quota_update;
+  uint32_t distance;
 
   /**
-   * How many bytes have we received since the "last_quota_update"
-   * timestamp?
+   * Does the transport service know about this session (and we thus
+   * need to call 'session_end' when it is released?)
    */
-  uint64_t last_received;
+  int active;
 
-  /**
-   * Number of bytes per ms that this peer is allowed
-   * to send to us.
-   */
-  uint32_t quota;
-
 };
 
+
 /**
  * Encapsulation of all of the state of the plugin.
  */
@@ -114,9 +102,9 @@
   struct GNUNET_TRANSPORT_PluginEnvironment *env;
 
   /**
-   * List of open sessions.  FIXME: use hash map!
+   * Hash map of sessions (active and inactive).
    */
-  struct Session *sessions;
+  struct GNUNET_CONTAINER_MultiHashMap *sessions;
 
   /**
    * Copy of the handler array where the closures are
@@ -148,23 +136,112 @@
 {
   struct Plugin *plugin = cls;
   struct GNUNET_ATS_Information ats;
+  struct Session *session;
 
+  session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions,
+                                              &sender->hashPubKey);
+  if (NULL == session)    
+  {
+    GNUNET_break (0);
+    return;
+  }
   ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
   ats.value = htonl (distance);
-
+  session->active = GNUNET_YES;
   plugin->env->receive (plugin->env->cls, sender,
                         msg,
                         &ats, 1,
-                       NULL, NULL, 0);
+                       session, "", 0);
 }
 
 
-/* Question: how does the transport service learn of a newly connected 
(gossipped about)
- * DV peer?  Should the plugin (here) create a HELLO for that peer and send it 
along,
- * or should the DV service create a HELLO and send it to us via the other 
part?
+/**
+ * Function called if DV starts to be able to talk to a peer.
+ *
+ * @param cls closure with 'struct Plugin'
+ * @param peer newly connected peer
+ * @param distance distance to the peer
  */
+static void 
+handle_dv_connect (void *cls,
+                  const struct GNUNET_PeerIdentity *peer,
+                  uint32_t distance)
+{
+  struct Plugin *plugin = cls;
+  struct Session *session;
 
+  session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions,
+                                              &peer->hashPubKey);
+  if (NULL != session)    
+  {
+    GNUNET_break (0);
+    session->distance = distance;
+    if (GNUNET_YES == session->active)
+      GNUNET_break (0); // FIXME: notify transport about distance change
+    return; /* nothing to do */  
+  }
+  session = GNUNET_malloc (sizeof (struct Session));
+  session->sender = *peer;
+  session->distance = distance;
+  GNUNET_assert (GNUNET_YES ==
+                GNUNET_CONTAINER_multihashmap_put (plugin->sessions,
+                                                   &session->sender.hashPubKey,
+                                                   session,
+                                                   
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+}
+
+
 /**
+ * Function called if DV distance to a peer is changed.
+ *
+ * @param cls closure with 'struct Plugin'
+ * @param peer connected peer
+ * @param distance new distance to the peer
+ */
+static void 
+handle_dv_distance_changed (void *cls,
+                           const struct GNUNET_PeerIdentity *peer,
+                           uint32_t distance)
+{
+  struct Plugin *plugin = cls;
+  struct Session *session;
+
+  session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions,
+                                              &peer->hashPubKey);
+  if (NULL == session)    
+  {
+    GNUNET_break (0);
+    handle_dv_connect (plugin, peer, distance);
+    return;
+  }
+  session->distance = distance;
+  if (GNUNET_YES == session->active)
+    GNUNET_break (0); // FIXME: notify transport about distance change
+}
+
+
+/**
+ * Function called if DV is no longer able to talk to a peer.
+ *
+ * @param cls closure with 'struct Plugin'
+ * @param peer peer that disconnected
+ */
+static void 
+handle_dv_disconnect (void *cls,
+                     const struct GNUNET_PeerIdentity *peer)
+{
+  struct Plugin *plugin = cls;
+  struct Session *session;
+
+  session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions,
+                                              &peer->hashPubKey);
+  if (NULL == session)    
+    return; /* nothing to do */  
+  GNUNET_break (0); // FIXME!
+}
+
+
+/**
  * Function that can be used by the transport service to transmit
  * a message using the plugin.
  *
@@ -192,11 +269,11 @@
 {
   int ret = -1;
 
+  GNUNET_break (0); // FIXME!
   return ret;
 }
 
 
-
 /**
  * Function that can be used to force the plugin to disconnect
  * from the given peer and cancel all previous transmissions
@@ -208,8 +285,16 @@
 static void
 dv_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
 {
-  // struct Plugin *plugin = cls;
-  // TODO: Add message type to send to dv service to "disconnect" a peer
+  struct Plugin *plugin = cls;
+  struct Session *session;
+
+  session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions,
+                                              &target->hashPubKey);
+  if (NULL == session)    
+    return; /* nothing to do */  
+  session->transmit_cont = NULL;
+  session->transmit_cont_cls = NULL;
+  session->active = GNUNET_NO;
 }
 
 
@@ -234,6 +319,9 @@
                                   GNUNET_TRANSPORT_AddressStringCallback asc,
                                   void *asc_cls)
 {
+  if ( (0 == addrlen) &&
+       (0 == strcmp (type, "dv")) )
+    asc (asc_cls, "dv");
   asc (asc_cls, NULL);
 }
 
@@ -248,9 +336,14 @@
  * @return string representing the DV address
  */
 static const char *
-address_to_string (void *cls, const void *addr, size_t addrlen)
+dv_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
 {
-  return "<not implemented>";
+  if (0 != addrlen)
+  {
+    GNUNET_break (0); /* malformed */
+    return NULL; 
+  }
+  return "dv";
 }
 
 
@@ -273,11 +366,12 @@
 static int
 dv_plugin_check_address (void *cls, const void *addr, size_t addrlen)
 {
-  return GNUNET_SYSERR;
+  if (0 != addrlen)
+    return GNUNET_SYSERR;
+  return GNUNET_OK;
 }
 
 
-
 /**
  * Create a new session to transmit data to the target
  * This session will used to send data to this peer and the plugin will
@@ -291,11 +385,50 @@
 dv_get_session (void *cls,
                const struct GNUNET_HELLO_Address *address)
 {
-  return NULL;
+  struct Plugin *plugin = cls;
+  struct Session *session;
+
+  if (0 != address->address_length)
+    return NULL;
+  session = GNUNET_CONTAINER_multihashmap_get (plugin->sessions,
+                                              &address->peer.hashPubKey);
+  if (NULL == session)
+    return NULL; /* not valid right now */
+  session->active = GNUNET_YES;
+  return session;
 }
 
 
 /**
+ * Function called to convert a string address to
+ * a binary address.
+ *
+ * @param cls closure ('struct Plugin*')
+ * @param addr string address
+ * @param addrlen length of the address including \0 termination
+ * @param buf location to store the buffer
+ *        If the function returns GNUNET_SYSERR, its contents are undefined.
+ * @param added length of created address
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+static int 
+dv_plugin_string_to_address (void *cls,
+                            const char *addr,
+                            uint16_t addrlen,
+                            void **buf,
+                            size_t *added)
+{
+  if ( (addrlen == 3) &&
+       (0 == strcmp ("dv", addr)) )
+  {
+    *added = 0;
+    return GNUNET_OK;
+  }
+  return GNUNET_SYSERR;
+}
+
+
+/**
  * Entry point for the plugin.
  */
 void *
@@ -307,24 +440,54 @@
 
   plugin = GNUNET_malloc (sizeof (struct Plugin));
   plugin->env = env;
+  plugin->sessions = GNUNET_CONTAINER_multihashmap_create (1024 * 8, 
GNUNET_YES);
   plugin->dvh = GNUNET_DV_service_connect (env->cfg,
                                           plugin,
-                                          NULL, NULL, NULL, /*FIXME! */
+                                          &handle_dv_connect,
+                                          &handle_dv_distance_changed,
+                                          &handle_dv_disconnect,
                                           &handle_dv_message_received);
+  if (NULL == plugin->dvh)
+  {
+    GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions);
+    GNUNET_free (plugin);
+    return NULL;
+  }
   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
   api->cls = plugin;
   api->send = &dv_plugin_send;
   api->disconnect = &dv_plugin_disconnect;
   api->address_pretty_printer = &dv_plugin_address_pretty_printer;
   api->check_address = &dv_plugin_check_address;
-  api->address_to_string = &address_to_string;
-  api->string_to_address = NULL; /* FIXME */
+  api->address_to_string = &dv_plugin_address_to_string;
+  api->string_to_address = &dv_plugin_string_to_address;
   api->get_session = dv_get_session;
   return api;
 }
 
 
 /**
+ * Function called to free a session.
+ *
+ * @param cls NULL
+ * @param key unused
+ * @param value session to free
+ * @return GNUNET_OK (continue to iterate)
+ */
+static int
+free_session_iterator (void *cls,
+                      const struct GNUNET_HashCode *key,
+                      void *value)
+{
+  struct Session *session = value;
+
+  // FIXME: still call transmit_cont's here!?
+  GNUNET_free (session);
+  return GNUNET_OK;
+}
+
+
+/**
  * Exit point from the plugin.
  */
 void *
@@ -334,6 +497,10 @@
   struct Plugin *plugin = api->cls;
 
   GNUNET_DV_service_disconnect (plugin->dvh);
+  GNUNET_CONTAINER_multihashmap_iterate (plugin->sessions,
+                                        &free_session_iterator,
+                                        NULL);
+  GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions);
   GNUNET_free (plugin);
   GNUNET_free (api);
   return NULL;




reply via email to

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