[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [gnunet] branch master updated: more work on simple plugin
From: |
gnunet |
Subject: |
[GNUnet-SVN] [gnunet] branch master updated: more work on simple plugin |
Date: |
Mon, 10 Dec 2018 14:56:36 +0100 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository gnunet.
The following commit(s) were added to refs/heads/master by this push:
new 08e22453a more work on simple plugin
08e22453a is described below
commit 08e22453a438c8a3f6135632a6ce39239b47d9f5
Author: Christian Grothoff <address@hidden>
AuthorDate: Mon Dec 10 14:56:34 2018 +0100
more work on simple plugin
---
src/ats/plugin_ats2_simple.c | 271 +++++++++++++++++++++++++++++++++++++++----
1 file changed, 247 insertions(+), 24 deletions(-)
diff --git a/src/ats/plugin_ats2_simple.c b/src/ats/plugin_ats2_simple.c
index 689524ba4..55234f1bc 100644
--- a/src/ats/plugin_ats2_simple.c
+++ b/src/ats/plugin_ats2_simple.c
@@ -23,7 +23,7 @@
*
* TODO:
* - subscribe to PEERSTORE when short on HELLOs (given application
preferences!)
- * - keep track of HELLOs and when we tried them last => re-suggest
+ * - keep track of HELLOs and when we tried them last => re-suggest
* - sum up preferences per peer, keep totals! => PeerMap pid -> [preferences
+ sessions + addrs!]
* - sum up preferences overall, keep global sum => starting point for
"proportional"
* - store DLL of available sessions per peer
@@ -36,6 +36,12 @@
/**
+ * A handle for the proportional solver
+ */
+struct SimpleHandle;
+
+
+/**
* Entry in list of addresses we could try per peer.
*/
struct Hello
@@ -50,7 +56,7 @@ struct Hello
* Kept in a DLL.
*/
struct Hello *prev;
-
+
/**
* The address we could try.
*/
@@ -76,6 +82,13 @@ struct Hello
/**
+ * Information about preferences and sessions we track
+ * per peer.
+ */
+struct Peer;
+
+
+/**
* Internal representation of a session by the plugin.
* (If desired, plugin may just use NULL.)
*/
@@ -91,7 +104,7 @@ struct GNUNET_ATS_SessionHandle
* Kept in DLL per peer.
*/
struct GNUNET_ATS_SessionHandle *prev;
-
+
/**
* The session in the main ATS service.
*/
@@ -106,7 +119,12 @@ struct GNUNET_ATS_SessionHandle
* Hello matching this session, or NULL for none.
*/
struct Hello *hello;
-
+
+ /**
+ * Peer this session is for.
+ */
+ struct Peer *peer;
+
/**
* Address used by this session (largely for debugging).
*/
@@ -143,13 +161,28 @@ struct Peer
struct GNUNET_ATS_SessionHandle *sh_tail;
/**
+ * Kept in a DLL.
+ */
+ struct Hello *h_head;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct Hello *h_tail;
+
+ /**
+ * The handle for the proportional solver
+ */
+ struct SimpleHandle *h;
+
+ /**
* Which peer is this for?
*/
struct GNUNET_PeerIdentity pid;
/**
* Array where we sum up the bandwidth requests received indexed
- * by preference kind (see `struct GNUNET_MQ_PreferenceKind`)
+ * by preference kind (see `enum GNUNET_MQ_PreferenceKind`)
*/
uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT];
@@ -162,8 +195,8 @@ struct Peer
/**
* Task used to try again to suggest an address for this peer.
*/
- struct GNUNET_SCHEDULER_TaskHandle *task;
-
+ struct GNUNET_SCHEDULER_Task *task;
+
};
@@ -216,11 +249,147 @@ struct SimpleHandle
* Handle to the peerstore service.
*/
struct GNUNET_PEERSTORE_Handle *ps;
-
+
};
/**
+ * Lookup peer in the peers map.
+ *
+ * @param h handle to look up in
+ * @param pid peer identity to look up by
+ * @return NULL for not found
+ */
+struct Peer *
+lookup_peer (struct SimpleHandle *h,
+ const struct GNUNET_PeerIdentity *pid)
+{
+ return GNUNET_CONTAINER_multipeermap_get (h->peers,
+ pid);
+}
+
+
+/**
+ * Check if there is _any_ interesting information left we
+ * store about the peer in @a p.
+ *
+ * @param p peer to test if we can drop the data structure
+ * @return #GNUNET_YES if no information is left in @a p
+ */
+static int
+peer_test_dead (struct Peer *p)
+{
+ for (enum GNUNET_MQ_PreferenceKind pk = 0;
+ pk < GNUNET_MQ_PREFERENCE_COUNT;
+ pk++)
+ if (0 != p->bw_by_pk[pk])
+ return GNUNET_NO;
+ if (NULL != p->sh_head)
+ return GNUNET_NO;
+ return GNUNET_YES;
+}
+
+
+/**
+ * Function called by PEERSTORE for each matching record.
+ *
+ * @param cls closure with a `struct Peer`
+ * @param record peerstore record information
+ * @param emsg error message, or NULL if no errors
+ */
+static void
+watch_cb (void *cls,
+ const struct GNUNET_PEERSTORE_Record *record,
+ const char *emsg)
+{
+ struct Peer *p = cls;
+
+ // FIXME: process hello!
+ // check for expiration
+ // (add to p's doubly-linked list)
+
+ if (NULL == p->task)
+ {
+ // start suggestion task!
+ }
+}
+
+
+/**
+ * Find or add peer if necessary.
+ *
+ * @param h our plugin handle
+ * @param pid the peer identity to add/look for
+ * @return a peer handle
+ */
+static struct Peer *
+peer_add (struct SimpleHandle *h,
+ const struct GNUNET_PeerIdentity *pid)
+{
+ struct Peer *p = lookup_peer (h,
+ pid);
+
+ if (NULL != p)
+ return p;
+ p = GNUNET_new (struct Peer);
+ p->h = h;
+ p->pid = *pid;
+ p->wc = GNUNET_PEERSTORE_watch (h->ps,
+ "transport",
+ &p->pid,
+ "HELLO" /* key */,
+ &watch_cb,
+ p);
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multipeermap_put (h->peers,
+ &p->pid,
+ p,
+
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+
+ return p;
+}
+
+
+/**
+ * Free the entry (and associated tasks) of peer @a p.
+ * Note that @a p must be dead already (see #peer_test_dead()).
+ *
+ * @param p the peer to free
+ */
+static void
+peer_free (struct Peer *p)
+{
+ struct SimpleHandle *h = p->h;
+ struct Hello *hello;
+
+ GNUNET_assert (NULL == p->sh_head);
+ while (NULL != (hello = p->h_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (p->h_head,
+ p->h_tail,
+ hello);
+ GNUNET_assert (NULL == hello->sh);
+ GNUNET_free (hello);
+ }
+ if (NULL != p->task)
+ {
+ GNUNET_SCHEDULER_cancel (p->task);
+ p->task = NULL;
+ }
+ if (NULL != p->wc)
+ {
+ GNUNET_PEERSTORE_watch_cancel (p->wc);
+ p->wc = NULL;
+ }
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multipeermap_remove (h->peers,
+ &p->pid,
+ p));
+ GNUNET_free (p);
+}
+
+
+/**
* The world changed, recalculate our allocations.
*/
static void
@@ -243,9 +412,12 @@ simple_preference_add (void *cls,
const struct GNUNET_ATS_Preference *pref)
{
struct SimpleHandle *h = cls;
- // Setup peer if necessary (-> including HELLO triggers!)
- // add pref to bw_by_pk
- // trigger update
+ struct Peer *p = peer_add (h,
+ &pref->peer);
+
+ GNUNET_assert (pref->pk < GNUNET_MQ_PREFERENCE_COUNT);
+ p->bw_by_pk[pref->pk] += ntohl (pref->bw.value__);
+ update (h);
return NULL;
}
@@ -254,20 +426,26 @@ simple_preference_add (void *cls,
* The plugin should end respecting a preference.
*
* @param cls the closure
- * @param ph whatever @e preference_add returned
+ * @param ph whatever @e preference_add returned
* @param pref the preference to delete
* @return plugin's internal representation, or NULL
*/
static void
-simple_preference_del (void *cls,
+simple_preference_del (void *cls,
struct GNUNET_ATS_PreferenceHandle *ph,
const struct GNUNET_ATS_Preference *pref)
{
struct SimpleHandle *h = cls;
- // find peer
- // subtract pref from bw_by_pk
- // remove peer if otherwise dead
- // trigger update
+ struct Peer *p = lookup_peer (h,
+ &pref->peer);
+
+ GNUNET_assert (NULL != p);
+ GNUNET_assert (pref->pk < GNUNET_MQ_PREFERENCE_COUNT);
+ p->bw_by_pk[pref->pk] -= ntohl (pref->bw.value__);
+ if ( (0 == p->bw_by_pk[pref->pk]) &&
+ (GNUNET_YES == peer_test_dead (p)) )
+ peer_free (p);
+ update (h);
}
@@ -286,11 +464,47 @@ simple_session_add (void *cls,
const char *address)
{
struct SimpleHandle *h = cls;
+ struct Peer *p = peer_add (h,
+ &data->peer);
+ struct Hello *hello;
+ size_t alen;
+ struct GNUNET_ATS_SessionHandle *sh;
- // find or add peer if necessary
- // setup session
- // match HELLO
- // trigger update
+ /* setup session handle */
+ if (NULL == address)
+ alen = 0;
+ else
+ alen = strlen (address) + 1;
+ sh = GNUNET_malloc (sizeof (struct GNUNET_ATS_SessionHandle) + alen);
+ sh->peer = p;
+ sh->session = data->session;
+ sh->data = data;
+ if (NULL == address)
+ {
+ sh->address = NULL;
+ }
+ else
+ {
+ memcpy (&sh[1],
+ address,
+ alen);
+ sh->address = (const char *) &sh[1];
+ }
+ GNUNET_CONTAINER_DLL_insert (p->sh_head,
+ p->sh_tail,
+ sh);
+ /* match HELLO */
+ hello = p->h_head;
+ while ( (NULL != hello) &&
+ (0 != strcmp (address,
+ hello->address)) )
+ hello = hello->next;
+ if (NULL != hello)
+ {
+ hello->sh = sh;
+ sh->hello = hello;
+ }
+ update (h);
return NULL;
}
@@ -309,7 +523,9 @@ simple_session_update (void *cls,
const struct GNUNET_ATS_SessionData *data)
{
struct SimpleHandle *h = cls;
- // trigger update
+
+ sh->data = data; /* this statement should not really do anything... */
+ update (h);
}
@@ -326,9 +542,16 @@ simple_session_del (void *cls,
const struct GNUNET_ATS_SessionData *data)
{
struct SimpleHandle *h = cls;
- // tear down session
+ struct Peer *p = sh->peer;
+
+ // FIXME: tear down session
// del peer if otherwise dead
- // trigger update
+
+
+ if ( (NULL == p->sh_head) &&
+ (GNUNET_YES == peer_test_dead (p)) )
+ peer_free (p);
+ update (h);
}
--
To stop receiving notification emails like this one, please contact
address@hidden
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] [gnunet] branch master updated: more work on simple plugin,
gnunet <=