[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;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r26447 - gnunet/src/dv,
gnunet <=