summaryrefslogtreecommitdiff
path: root/src/ats
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-12-06 18:38:43 +0100
committerChristian Grothoff <christian@grothoff.org>2018-12-06 18:38:43 +0100
commit5a1d7b406639cb12640c9906ca38c3c08f912a85 (patch)
tree2f41b3ef348f2525e8560406106647af6823b1a1 /src/ats
parentaa6e0a1941f98ed90947aa5e3671438cb381995c (diff)
downloadgnunet-5a1d7b406639cb12640c9906ca38c3c08f912a85.tar.gz
gnunet-5a1d7b406639cb12640c9906ca38c3c08f912a85.zip
skeleton for 'simple' ATS2 plugin
Diffstat (limited to 'src/ats')
-rw-r--r--src/ats/Makefile.am15
-rw-r--r--src/ats/plugin_ats2_common.c96
-rw-r--r--src/ats/plugin_ats2_simple.c408
3 files changed, 517 insertions, 2 deletions
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am
index 52a1e7d11..97497c94e 100644
--- a/src/ats/Makefile.am
+++ b/src/ats/Makefile.am
@@ -24,7 +24,8 @@ lib_LTLIBRARIES = \
24 libgnunetatstransport.la 24 libgnunetatstransport.la
25 25
26plugin_LTLIBRARIES = \ 26plugin_LTLIBRARIES = \
27 libgnunet_plugin_ats_proportional.la 27 libgnunet_plugin_ats_proportional.la \
28 libgnunet_plugin_ats2_simple.la
28 29
29if HAVE_EXPERIMENTAL 30if HAVE_EXPERIMENTAL
30plugin_LTLIBRARIES += \ 31plugin_LTLIBRARIES += \
@@ -77,6 +78,15 @@ libgnunet_plugin_ats_proportional_la_LIBADD = \
77libgnunet_plugin_ats_proportional_la_LDFLAGS = \ 78libgnunet_plugin_ats_proportional_la_LDFLAGS = \
78 $(GN_PLUGIN_LDFLAGS) 79 $(GN_PLUGIN_LDFLAGS)
79 80
81libgnunet_plugin_ats2_simple_la_SOURCES = \
82 plugin_ats2_simple.c
83libgnunet_plugin_ats2_simple_la_LIBADD = \
84 $(top_builddir)/src/statistics/libgnunetstatistics.la \
85 $(top_builddir)/src/util/libgnunetutil.la \
86 $(LTLIBINTL)
87libgnunet_plugin_ats2_simple_la_LDFLAGS = \
88 $(GN_PLUGIN_LDFLAGS)
89
80 90
81libgnunet_plugin_ats_mlp_la_SOURCES = \ 91libgnunet_plugin_ats_mlp_la_SOURCES = \
82 plugin_ats_mlp.c 92 plugin_ats_mlp.c
@@ -186,7 +196,8 @@ test_ats_api_mlp_LDADD = \
186 libgnunetats.la 196 libgnunetats.la
187 197
188EXTRA_DIST = \ 198EXTRA_DIST = \
189 ats.h \ 199 ats.h ats2.h \
200 plugin_ats2_common.c \
190 test_delay \ 201 test_delay \
191 test_ats_api_mlp.conf \ 202 test_ats_api_mlp.conf \
192 test_ats_api_ril.conf \ 203 test_ats_api_ril.conf \
diff --git a/src/ats/plugin_ats2_common.c b/src/ats/plugin_ats2_common.c
new file mode 100644
index 000000000..6911ba44d
--- /dev/null
+++ b/src/ats/plugin_ats2_common.c
@@ -0,0 +1,96 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011-2015, 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18/**
19 * @file ats/plugin_ats2_common.c
20 * @brief ATS solver helper functions to be inlined
21 * @author Matthias Wachs
22 * @author Christian Grothoff
23 */
24
25/**
26 * Default bandwidth assigned to a network: 64 KB/s
27 */
28#define DEFAULT_BANDWIDTH 65536
29
30
31/**
32 * Parse @a cfg for @a quota as specified for @a direction of
33 * network type @a nts.
34 *
35 * @param cfg configuration to parse
36 * @param nts network type string to get quota for
37 * @param direction direction to get quota for ("IN" or "OUT")
38 * @param quota[out] set to quota, #DEFAULT_BANDWIDTH if @a cfg does not say anything useful
39 */
40static void
41get_quota (const struct GNUNET_CONFIGURATION_Handle *cfg,
42 const char *nts,
43 const char *direction,
44 unsigned long long *quota)
45{
46 char *quota_str;
47 char *quota_s;
48 int res;
49
50 GNUNET_asprintf (&quota_s,
51 "%s_QUOTA_%s",
52 nts,
53 direction);
54 if (GNUNET_OK !=
55 GNUNET_CONFIGURATION_get_value_string (cfg,
56 "ATS",
57 quota_s,
58 &quota_str))
59 {
60 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
61 "ATS",
62 quota_s);
63 GNUNET_free (quota_s);
64 return;
65 }
66 GNUNET_free (quota_s);
67 res = GNUNET_NO;
68 if (0 == strcmp (quota_str,
69 "unlimited"))
70 {
71 *quota = ULONG_MAX;
72 res = GNUNET_YES;
73 }
74 if ( (GNUNET_NO == res) &&
75 (GNUNET_OK ==
76 GNUNET_STRINGS_fancy_size_to_bytes (quota_str,
77 quota)) )
78 res = GNUNET_YES;
79 if ( (GNUNET_NO == res) &&
80 (1 ==
81 sscanf (quota_str,
82 "%llu",
83 quota)) )
84 res = GNUNET_YES;
85 if (GNUNET_NO == res)
86 {
87 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
88 _("Could not load %s quota for network `%s': `%s', assigning default bandwidth %llu\n"),
89 direction,
90 nts,
91 quota_str,
92 (unsigned long long) DEFAULT_BANDWIDTH);
93 *quota = DEFAULT_BANDWIDTH;
94 }
95 GNUNET_free (quota_str);
96}
diff --git a/src/ats/plugin_ats2_simple.c b/src/ats/plugin_ats2_simple.c
new file mode 100644
index 000000000..689524ba4
--- /dev/null
+++ b/src/ats/plugin_ats2_simple.c
@@ -0,0 +1,408 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011-2015, 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18/**
19 * @file ats/plugin_ats2_simple.c
20 * @brief ATS simple solver
21 * @author Matthias Wachs
22 * @author Christian Grothoff
23 *
24 * TODO:
25 * - subscribe to PEERSTORE when short on HELLOs (given application preferences!)
26 * - keep track of HELLOs and when we tried them last => re-suggest
27 * - sum up preferences per peer, keep totals! => PeerMap pid -> [preferences + sessions + addrs!]
28 * - sum up preferences overall, keep global sum => starting point for "proportional"
29 * - store DLL of available sessions per peer
30 */
31#include "platform.h"
32#include "gnunet_ats_plugin_new.h"
33#include "gnunet_peerstore_service.h"
34
35#define LOG(kind,...) GNUNET_log_from (kind, "ats-simple",__VA_ARGS__)
36
37
38/**
39 * Entry in list of addresses we could try per peer.
40 */
41struct Hello
42{
43
44 /**
45 * Kept in a DLL.
46 */
47 struct Hello *next;
48
49 /**
50 * Kept in a DLL.
51 */
52 struct Hello *prev;
53
54 /**
55 * The address we could try.
56 */
57 const char *address;
58
59 /**
60 * When did we try it last?
61 */
62 struct GNUNET_TIME_Absolute last_attempt;
63
64 /**
65 * Current exponential backoff value.
66 */
67 struct GNUNET_TIME_Relative backoff;
68
69 /**
70 * Is a session with this address already up?
71 * If not, set to NULL.
72 */
73 struct GNUNET_ATS_SessionHandle *sh;
74
75};
76
77
78/**
79 * Internal representation of a session by the plugin.
80 * (If desired, plugin may just use NULL.)
81 */
82struct GNUNET_ATS_SessionHandle
83{
84
85 /**
86 * Kept in DLL per peer.
87 */
88 struct GNUNET_ATS_SessionHandle *next;
89
90 /**
91 * Kept in DLL per peer.
92 */
93 struct GNUNET_ATS_SessionHandle *prev;
94
95 /**
96 * The session in the main ATS service.
97 */
98 struct GNUNET_ATS_Session *session;
99
100 /**
101 * Current performance data for this @e session
102 */
103 const struct GNUNET_ATS_SessionData *data;
104
105 /**
106 * Hello matching this session, or NULL for none.
107 */
108 struct Hello *hello;
109
110 /**
111 * Address used by this session (largely for debugging).
112 */
113 const char *address;
114
115 /**
116 * Last BW-in allocation given to the transport service.
117 */
118 struct GNUNET_BANDWIDTH_Value32NBO bw_in;
119
120 /**
121 * Last BW-out allocation given to the transport service.
122 */
123 struct GNUNET_BANDWIDTH_Value32NBO bw_out;
124
125};
126
127
128/**
129 * Information about preferences and sessions we track
130 * per peer.
131 */
132struct Peer
133{
134
135 /**
136 * Kept in DLL per peer.
137 */
138 struct GNUNET_ATS_SessionHandle *sh_head;
139
140 /**
141 * Kept in DLL per peer.
142 */
143 struct GNUNET_ATS_SessionHandle *sh_tail;
144
145 /**
146 * Which peer is this for?
147 */
148 struct GNUNET_PeerIdentity pid;
149
150 /**
151 * Array where we sum up the bandwidth requests received indexed
152 * by preference kind (see `struct GNUNET_MQ_PreferenceKind`)
153 */
154 uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT];
155
156 /**
157 * Watch context where we are currently looking for HELLOs for
158 * this peer.
159 */
160 struct GNUNET_PEERSTORE_WatchContext *wc;
161
162 /**
163 * Task used to try again to suggest an address for this peer.
164 */
165 struct GNUNET_SCHEDULER_TaskHandle *task;
166
167};
168
169
170/**
171 * Representation of a network (to be expanded...)
172 */
173struct Network
174{
175
176 /**
177 * Total inbound quota
178 */
179 unsigned long long total_quota_in;
180
181 /**
182 * Total outbound quota
183 */
184 unsigned long long total_quota_out;
185
186 /**
187 * ATS network type
188 */
189 enum GNUNET_NetworkType type;
190
191};
192
193
194/**
195 * A handle for the proportional solver
196 */
197struct SimpleHandle
198{
199
200 /**
201 * Our execution environment.
202 */
203 struct GNUNET_ATS_PluginEnvironment *env;
204
205 /**
206 * Information we track for each peer.
207 */
208 struct GNUNET_CONTAINER_MultiPeerMap *peers;
209
210 /**
211 * Information we track per network type (quotas).
212 */
213 struct Network networks[GNUNET_NT_COUNT];
214
215 /**
216 * Handle to the peerstore service.
217 */
218 struct GNUNET_PEERSTORE_Handle *ps;
219
220};
221
222
223/**
224 * The world changed, recalculate our allocations.
225 */
226static void
227update (struct SimpleHandle *h)
228{
229 // recalculate allocations
230 // notify transport if it makes sense (delta significant)
231}
232
233
234/**
235 * The plugin should begin to respect a new preference.
236 *
237 * @param cls the closure
238 * @param pref the preference to add
239 * @return plugin's internal representation, or NULL
240 */
241static struct GNUNET_ATS_PreferenceHandle *
242simple_preference_add (void *cls,
243 const struct GNUNET_ATS_Preference *pref)
244{
245 struct SimpleHandle *h = cls;
246 // Setup peer if necessary (-> including HELLO triggers!)
247 // add pref to bw_by_pk
248 // trigger update
249 return NULL;
250}
251
252
253/**
254 * The plugin should end respecting a preference.
255 *
256 * @param cls the closure
257 * @param ph whatever @e preference_add returned
258 * @param pref the preference to delete
259 * @return plugin's internal representation, or NULL
260 */
261static void
262simple_preference_del (void *cls,
263 struct GNUNET_ATS_PreferenceHandle *ph,
264 const struct GNUNET_ATS_Preference *pref)
265{
266 struct SimpleHandle *h = cls;
267 // find peer
268 // subtract pref from bw_by_pk
269 // remove peer if otherwise dead
270 // trigger update
271}
272
273
274/**
275 * Transport established a new session with performance
276 * characteristics given in @a data.
277 *
278 * @param cls closure
279 * @param data performance characteristics of @a sh
280 * @param address address information (for debugging)
281 * @return handle by which the plugin will identify this session
282 */
283static struct GNUNET_ATS_SessionHandle *
284simple_session_add (void *cls,
285 const struct GNUNET_ATS_SessionData *data,
286 const char *address)
287{
288 struct SimpleHandle *h = cls;
289
290 // find or add peer if necessary
291 // setup session
292 // match HELLO
293 // trigger update
294 return NULL;
295}
296
297
298/**
299 * @a data changed for a given @a sh, solver should consider
300 * the updated performance characteristics.
301 *
302 * @param cls closure
303 * @param sh session this is about
304 * @param data performance characteristics of @a sh
305 */
306static void
307simple_session_update (void *cls,
308 struct GNUNET_ATS_SessionHandle *sh,
309 const struct GNUNET_ATS_SessionData *data)
310{
311 struct SimpleHandle *h = cls;
312 // trigger update
313}
314
315
316/**
317 * A session went away. Solver should update accordingly.
318 *
319 * @param cls closure
320 * @param sh session this is about
321 * @param data (last) performance characteristics of @a sh
322 */
323static void
324simple_session_del (void *cls,
325 struct GNUNET_ATS_SessionHandle *sh,
326 const struct GNUNET_ATS_SessionData *data)
327{
328 struct SimpleHandle *h = cls;
329 // tear down session
330 // del peer if otherwise dead
331 // trigger update
332}
333
334
335#include "plugin_ats2_common.c"
336
337
338/**
339 * Function invoked when the plugin is loaded.
340 *
341 * @param[in,out] cls the `struct GNUNET_ATS_PluginEnvironment *` to use;
342 * modified to return the API functions (ugh).
343 * @return the `struct SimpleHandle` to pass as a closure
344 */
345void *
346libgnunet_plugin_ats2_simple_init (void *cls)
347{
348 static struct GNUNET_ATS_SolverFunctions sf;
349 struct GNUNET_ATS_PluginEnvironment *env = cls;
350 struct SimpleHandle *s;
351
352 s = GNUNET_new (struct SimpleHandle);
353 s->env = env;
354 s->peers = GNUNET_CONTAINER_multipeermap_create (128,
355 GNUNET_YES);
356 s->ps = GNUNET_PEERSTORE_connect (env->cfg);
357 sf.cls = s;
358 sf.preference_add = &simple_preference_add;
359 sf.preference_del = &simple_preference_del;
360 sf.session_add = &simple_session_add;
361 sf.session_update = &simple_session_update;
362 sf.session_del = &simple_session_del;
363 for (enum GNUNET_NetworkType nt = 0;
364 nt < GNUNET_NT_COUNT;
365 nt++)
366 {
367 const char *name = GNUNET_NT_to_string (nt);
368
369 if (NULL == name)
370 {
371 GNUNET_break (0);
372 break;
373 }
374 get_quota (env->cfg,
375 name,
376 "IN",
377 &s->networks[nt].total_quota_in);
378 get_quota (env->cfg,
379 name,
380 "OUT",
381 &s->networks[nt].total_quota_out);
382 s->networks[nt].type = nt;
383 }
384 return &sf;
385}
386
387
388/**
389 * Function used to unload the plugin.
390 *
391 * @param cls return value from #libgnunet_plugin_ats_proportional_init()
392 */
393void *
394libgnunet_plugin_ats2_simple_done (void *cls)
395{
396 struct GNUNET_ATS_SolverFunctions *sf = cls;
397 struct SimpleHandle *s = sf->cls;
398
399 // FIXME: iterate over peers and clean up!
400 GNUNET_CONTAINER_multipeermap_destroy (s->peers);
401 GNUNET_PEERSTORE_disconnect (s->ps,
402 GNUNET_NO);
403 GNUNET_free (s);
404 return NULL;
405}
406
407
408/* end of plugin_ats2_simple.c */