aboutsummaryrefslogtreecommitdiff
path: root/src/ats/plugin_ats2_simple.c
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/plugin_ats2_simple.c
parentaa6e0a1941f98ed90947aa5e3671438cb381995c (diff)
downloadgnunet-5a1d7b406639cb12640c9906ca38c3c08f912a85.tar.gz
gnunet-5a1d7b406639cb12640c9906ca38c3c08f912a85.zip
skeleton for 'simple' ATS2 plugin
Diffstat (limited to 'src/ats/plugin_ats2_simple.c')
-rw-r--r--src/ats/plugin_ats2_simple.c408
1 files changed, 408 insertions, 0 deletions
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 */