diff options
Diffstat (limited to 'src/ats')
-rw-r--r-- | src/ats/Makefile.am | 11 | ||||
-rw-r--r-- | src/ats/ats2.h | 7 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats-new.c | 653 |
3 files changed, 667 insertions, 4 deletions
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index 648849b1a..52a1e7d11 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am | |||
@@ -99,7 +99,8 @@ libgnunet_plugin_ats_ril_la_LDFLAGS = \ | |||
99 | $(GN_PLUGIN_LDFLAGS) | 99 | $(GN_PLUGIN_LDFLAGS) |
100 | 100 | ||
101 | libexec_PROGRAMS = \ | 101 | libexec_PROGRAMS = \ |
102 | gnunet-service-ats | 102 | gnunet-service-ats \ |
103 | gnunet-service-ats-new | ||
103 | 104 | ||
104 | gnunet_service_ats_SOURCES = \ | 105 | gnunet_service_ats_SOURCES = \ |
105 | gnunet-service-ats.c gnunet-service-ats.h \ | 106 | gnunet-service-ats.c gnunet-service-ats.h \ |
@@ -118,6 +119,14 @@ gnunet_service_ats_LDADD = \ | |||
118 | libgnunetats.la \ | 119 | libgnunetats.la \ |
119 | $(GN_LIBINTL) | 120 | $(GN_LIBINTL) |
120 | 121 | ||
122 | gnunet_service_ats_new_SOURCES = \ | ||
123 | gnunet-service-ats-new.c | ||
124 | gnunet_service_ats_new_LDADD = \ | ||
125 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
126 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
127 | $(GN_LIBINTL) | ||
128 | |||
129 | |||
121 | if HAVE_TESTING | 130 | if HAVE_TESTING |
122 | TESTING_TESTS = \ | 131 | TESTING_TESTS = \ |
123 | test_ats_api_proportional \ | 132 | test_ats_api_proportional \ |
diff --git a/src/ats/ats2.h b/src/ats/ats2.h index 883ac7c38..0882c5f20 100644 --- a/src/ats/ats2.h +++ b/src/ats/ats2.h | |||
@@ -16,13 +16,13 @@ | |||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
18 | /** | 18 | /** |
19 | * @file ats/ats.h | 19 | * @file ats/ats2.h |
20 | * @brief automatic transport selection messages | 20 | * @brief automatic transport selection messages |
21 | * @author Christian Grothoff | 21 | * @author Christian Grothoff |
22 | * @author Matthias Wachs | 22 | * @author Matthias Wachs |
23 | */ | 23 | */ |
24 | #ifndef ATS_H | 24 | #ifndef ATS2_H |
25 | #define ATS_H | 25 | #define ATS2_H |
26 | 26 | ||
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_ats_transport_service.h" | 28 | #include "gnunet_ats_transport_service.h" |
@@ -118,6 +118,7 @@ struct ExpressPreferenceMessage | |||
118 | 118 | ||
119 | /** | 119 | /** |
120 | * What type of performance preference does the client have? | 120 | * What type of performance preference does the client have? |
121 | * A `enum GNUNET_MQ_PreferenceKind` in NBO. | ||
121 | */ | 122 | */ |
122 | uint32_t pk GNUNET_PACKED; | 123 | uint32_t pk GNUNET_PACKED; |
123 | 124 | ||
diff --git a/src/ats/gnunet-service-ats-new.c b/src/ats/gnunet-service-ats-new.c new file mode 100644 index 000000000..57398e641 --- /dev/null +++ b/src/ats/gnunet-service-ats-new.c | |||
@@ -0,0 +1,653 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011, 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/gnunet-service-ats-new.c | ||
20 | * @brief ats service | ||
21 | * @author Matthias Wachs | ||
22 | * @author Christian Grothoff | ||
23 | * | ||
24 | * TODO: | ||
25 | * - implement messages ATS -> transport | ||
26 | * - implement loading / unloading of ATS plugins | ||
27 | * - expose plugin the API to send messages ATS -> transport | ||
28 | */ | ||
29 | #include "platform.h" | ||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "gnunet_statistics_service.h" | ||
32 | #include "gnunet_ats_plugin_new.h" | ||
33 | #include "ats2.h" | ||
34 | |||
35 | |||
36 | /** | ||
37 | * What type of client is this client? | ||
38 | */ | ||
39 | enum ClientType { | ||
40 | /** | ||
41 | * We don't know yet. | ||
42 | */ | ||
43 | CT_NONE = 0, | ||
44 | |||
45 | /** | ||
46 | * Transport service. | ||
47 | */ | ||
48 | CT_TRANSPORT, | ||
49 | |||
50 | /** | ||
51 | * Application. | ||
52 | */ | ||
53 | CT_APPLICATION | ||
54 | }; | ||
55 | |||
56 | |||
57 | /** | ||
58 | * Information we track per client. | ||
59 | */ | ||
60 | struct Client; | ||
61 | |||
62 | /** | ||
63 | * Preferences expressed by a client are kept in a DLL per client. | ||
64 | */ | ||
65 | struct ClientPreference | ||
66 | { | ||
67 | /** | ||
68 | * DLL pointer. | ||
69 | */ | ||
70 | struct ClientPreference *next; | ||
71 | |||
72 | /** | ||
73 | * DLL pointer. | ||
74 | */ | ||
75 | struct ClientPreference *prev; | ||
76 | |||
77 | /** | ||
78 | * Which client expressed the preference? | ||
79 | */ | ||
80 | struct Client *client; | ||
81 | |||
82 | /** | ||
83 | * Plugin's representation of the preference. | ||
84 | */ | ||
85 | struct GNUNET_ATS_PreferenceHandle *ph; | ||
86 | |||
87 | /** | ||
88 | * Details about the preference. | ||
89 | */ | ||
90 | struct GNUNET_ATS_Preference pref; | ||
91 | }; | ||
92 | |||
93 | |||
94 | /** | ||
95 | * Information about ongoing sessions of the transport client. | ||
96 | */ | ||
97 | struct GNUNET_ATS_Session | ||
98 | { | ||
99 | |||
100 | /** | ||
101 | * Session data exposed to the plugin. | ||
102 | */ | ||
103 | struct GNUNET_ATS_SessionData data; | ||
104 | |||
105 | /** | ||
106 | * The transport client that provided the session. | ||
107 | */ | ||
108 | struct Client *client; | ||
109 | |||
110 | /** | ||
111 | * Session state in the plugin. | ||
112 | */ | ||
113 | struct GNUNET_ATS_SessionHandle *sh; | ||
114 | |||
115 | /** | ||
116 | * Unique ID for the session when talking with the client. | ||
117 | */ | ||
118 | uint32_t session_id; | ||
119 | |||
120 | }; | ||
121 | |||
122 | |||
123 | /** | ||
124 | * Information we track per client. | ||
125 | */ | ||
126 | struct Client | ||
127 | { | ||
128 | /** | ||
129 | * Type of the client, initially #CT_NONE. | ||
130 | */ | ||
131 | enum ClientType type; | ||
132 | |||
133 | /** | ||
134 | * Service handle of the client. | ||
135 | */ | ||
136 | struct GNUNET_SERVICE_Client *client; | ||
137 | |||
138 | /** | ||
139 | * Message queue to talk to the client. | ||
140 | */ | ||
141 | struct GNUNET_MQ_Handle *mq; | ||
142 | |||
143 | /** | ||
144 | * Details depending on @e type. | ||
145 | */ | ||
146 | union { | ||
147 | |||
148 | struct { | ||
149 | |||
150 | /** | ||
151 | * Head of DLL of preferences expressed by this client. | ||
152 | */ | ||
153 | struct ClientPreference *cp_head; | ||
154 | |||
155 | /** | ||
156 | * Tail of DLL of preferences expressed by this client. | ||
157 | */ | ||
158 | struct ClientPreference *cp_tail; | ||
159 | |||
160 | } application; | ||
161 | |||
162 | struct { | ||
163 | |||
164 | /** | ||
165 | * Map from session IDs to `struct GNUNET_ATS_Session` objects. | ||
166 | */ | ||
167 | struct GNUNET_CONTAINER_MultiHashMap32 *sessions; | ||
168 | |||
169 | } transport; | ||
170 | |||
171 | } details; | ||
172 | |||
173 | }; | ||
174 | |||
175 | |||
176 | /** | ||
177 | * Handle for statistics. | ||
178 | */ | ||
179 | static struct GNUNET_STATISTICS_Handle *GSA_stats; | ||
180 | |||
181 | /** | ||
182 | * Our solver. | ||
183 | */ | ||
184 | static struct GNUNET_ATS_SolverFunctions *plugin; | ||
185 | |||
186 | /** | ||
187 | * The transport client (there can only be one at a time). | ||
188 | */ | ||
189 | static struct Client *transport_client; | ||
190 | |||
191 | |||
192 | /** | ||
193 | * Convert @a properties to @a prop | ||
194 | * | ||
195 | * @param properties in NBO | ||
196 | * @param prop[out] in HBO | ||
197 | */ | ||
198 | static void | ||
199 | prop_ntoh (const struct PropertiesNBO *properties, | ||
200 | struct GNUNET_ATS_Properties *prop) | ||
201 | { | ||
202 | prop->delay = GNUNET_TIME_relative_ntoh (properties->delay); | ||
203 | prop->goodput_out = ntohl (properties->goodput_out); | ||
204 | prop->goodput_in = ntohl (properties->goodput_in); | ||
205 | prop->utilization_out = ntohl (properties->utilization_out); | ||
206 | prop->utilization_in = ntohl (properties->utilization_in); | ||
207 | prop->distance = ntohl (properties->distance); | ||
208 | prop->mtu = ntohl (properties->mtu); | ||
209 | prop->nt = (enum GNUNET_NetworkType) ntohl (properties->nt); | ||
210 | prop->cc = (enum GNUNET_TRANSPORT_CommunicatorCharacteristics) ntohl (properties->cc); | ||
211 | } | ||
212 | |||
213 | |||
214 | /** | ||
215 | * We have received a `struct ExpressPreferenceMessage` from an application client. | ||
216 | * | ||
217 | * @param cls handle to the client | ||
218 | * @param msg the start message | ||
219 | */ | ||
220 | static void | ||
221 | handle_suggest (void *cls, | ||
222 | const struct ExpressPreferenceMessage *msg) | ||
223 | { | ||
224 | struct Client *c = cls; | ||
225 | struct ClientPreference *cp; | ||
226 | |||
227 | if (CT_NONE == c->type) | ||
228 | c->type = CT_APPLICATION; | ||
229 | if (CT_APPLICATION != c->type) | ||
230 | { | ||
231 | GNUNET_break (0); | ||
232 | GNUNET_SERVICE_client_drop (c->client); | ||
233 | return; | ||
234 | } | ||
235 | cp = GNUNET_new (struct ClientPreference); | ||
236 | cp->client = c; | ||
237 | cp->pref.peer = msg->peer; | ||
238 | cp->pref.bw = msg->bw; | ||
239 | cp->pref.pk = (enum GNUNET_MQ_PreferenceKind) ntohl (msg->pk); | ||
240 | cp->ph = plugin->preference_add (plugin->cls, | ||
241 | &cp->pref); | ||
242 | GNUNET_CONTAINER_DLL_insert (c->details.application.cp_head, | ||
243 | c->details.application.cp_tail, | ||
244 | cp); | ||
245 | GNUNET_SERVICE_client_continue (c->client); | ||
246 | } | ||
247 | |||
248 | |||
249 | /** | ||
250 | * We have received a `struct ExpressPreferenceMessage` from an application client. | ||
251 | * | ||
252 | * @param cls handle to the client | ||
253 | * @param msg the start message | ||
254 | */ | ||
255 | static void | ||
256 | handle_suggest_cancel (void *cls, | ||
257 | const struct ExpressPreferenceMessage *msg) | ||
258 | { | ||
259 | struct Client *c = cls; | ||
260 | struct ClientPreference *cp; | ||
261 | |||
262 | if (CT_NONE == c->type) | ||
263 | c->type = CT_APPLICATION; | ||
264 | if (CT_APPLICATION != c->type) | ||
265 | { | ||
266 | GNUNET_break (0); | ||
267 | GNUNET_SERVICE_client_drop (c->client); | ||
268 | return; | ||
269 | } | ||
270 | for (cp = c->details.application.cp_head; | ||
271 | NULL != cp; | ||
272 | cp = cp->next) | ||
273 | if ( (cp->pref.pk == (enum GNUNET_MQ_PreferenceKind) ntohl (msg->pk)) && | ||
274 | (cp->pref.bw.value__ == msg->bw.value__) && | ||
275 | (0 == memcmp (&cp->pref.peer, | ||
276 | &msg->peer, | ||
277 | sizeof (struct GNUNET_PeerIdentity))) ) | ||
278 | break; | ||
279 | if (NULL == cp) | ||
280 | { | ||
281 | GNUNET_break (0); | ||
282 | GNUNET_SERVICE_client_drop (c->client); | ||
283 | return; | ||
284 | } | ||
285 | plugin->preference_del (plugin->cls, | ||
286 | cp->ph, | ||
287 | &cp->pref); | ||
288 | GNUNET_CONTAINER_DLL_remove (c->details.application.cp_head, | ||
289 | c->details.application.cp_tail, | ||
290 | cp); | ||
291 | GNUNET_free (cp); | ||
292 | GNUNET_SERVICE_client_continue (c->client); | ||
293 | } | ||
294 | |||
295 | |||
296 | /** | ||
297 | * Handle 'start' messages from transport clients. | ||
298 | * | ||
299 | * @param cls client that sent the request | ||
300 | * @param message the request message | ||
301 | */ | ||
302 | static void | ||
303 | handle_start (void *cls, | ||
304 | const struct GNUNET_MessageHeader *hdr) | ||
305 | { | ||
306 | struct Client *c = cls; | ||
307 | |||
308 | if (CT_NONE != c->type) | ||
309 | { | ||
310 | GNUNET_break (0); | ||
311 | GNUNET_SERVICE_client_drop (c->client); | ||
312 | return; | ||
313 | } | ||
314 | c->type = CT_TRANSPORT; | ||
315 | c->details.transport.sessions | ||
316 | = GNUNET_CONTAINER_multihashmap32_create (128); | ||
317 | if (NULL != transport_client) | ||
318 | { | ||
319 | GNUNET_SERVICE_client_drop (transport_client->client); | ||
320 | transport_client = NULL; | ||
321 | } | ||
322 | transport_client = c; | ||
323 | GNUNET_SERVICE_client_continue (c->client); | ||
324 | } | ||
325 | |||
326 | |||
327 | /** | ||
328 | * Check 'session_add' message is well-formed and comes from a | ||
329 | * transport client. | ||
330 | * | ||
331 | * @param cls client that sent the request | ||
332 | * @param message the request message | ||
333 | * @return #GNUNET_OK if @a message is well-formed | ||
334 | */ | ||
335 | static int | ||
336 | check_session_add (void *cls, | ||
337 | const struct SessionAddMessage *message) | ||
338 | { | ||
339 | struct Client *c = cls; | ||
340 | |||
341 | GNUNET_MQ_check_zero_termination (message); | ||
342 | if (CT_TRANSPORT != c->type) | ||
343 | { | ||
344 | GNUNET_break (0); | ||
345 | return GNUNET_SYSERR; | ||
346 | } | ||
347 | return GNUNET_OK; | ||
348 | } | ||
349 | |||
350 | |||
351 | /** | ||
352 | * Handle 'session add' messages from transport clients. | ||
353 | * | ||
354 | * @param cls client that sent the request | ||
355 | * @param message the request message | ||
356 | */ | ||
357 | static void | ||
358 | handle_session_add (void *cls, | ||
359 | const struct SessionAddMessage *message) | ||
360 | { | ||
361 | struct Client *c = cls; | ||
362 | struct GNUNET_ATS_Session *session; | ||
363 | int inbound_only = (GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY == | ||
364 | ntohs (message->header.type)); | ||
365 | |||
366 | session = GNUNET_CONTAINER_multihashmap32_get (c->details.transport.sessions, | ||
367 | message->session_id); | ||
368 | if (NULL != session) | ||
369 | { | ||
370 | GNUNET_break (0); | ||
371 | GNUNET_SERVICE_client_drop (c->client); | ||
372 | return; | ||
373 | } | ||
374 | session = GNUNET_new (struct GNUNET_ATS_Session); | ||
375 | session->data.session = session; | ||
376 | session->client = c; | ||
377 | session->session_id = message->session_id; | ||
378 | session->data.peer = message->peer; | ||
379 | prop_ntoh (&message->properties, | ||
380 | &session->data.prop); | ||
381 | session->data.inbound_only = inbound_only; | ||
382 | GNUNET_assert (GNUNET_YES == | ||
383 | GNUNET_CONTAINER_multihashmap32_put (c->details.transport.sessions, | ||
384 | message->session_id, | ||
385 | session, | ||
386 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
387 | session->sh = plugin->session_add (plugin->cls, | ||
388 | &session->data); | ||
389 | GNUNET_SERVICE_client_continue (c->client); | ||
390 | } | ||
391 | |||
392 | |||
393 | |||
394 | /** | ||
395 | * Handle 'session update' messages from transport clients. | ||
396 | * | ||
397 | * @param cls client that sent the request | ||
398 | * @param msg the request message | ||
399 | */ | ||
400 | static void | ||
401 | handle_session_update (void *cls, | ||
402 | const struct SessionUpdateMessage *msg) | ||
403 | { | ||
404 | struct Client *c = cls; | ||
405 | struct GNUNET_ATS_Session *session; | ||
406 | |||
407 | if (CT_TRANSPORT != c->type) | ||
408 | { | ||
409 | GNUNET_break (0); | ||
410 | GNUNET_SERVICE_client_drop (c->client); | ||
411 | return; | ||
412 | } | ||
413 | session = GNUNET_CONTAINER_multihashmap32_get (c->details.transport.sessions, | ||
414 | msg->session_id); | ||
415 | if (NULL == session) | ||
416 | { | ||
417 | GNUNET_break (0); | ||
418 | GNUNET_SERVICE_client_drop (c->client); | ||
419 | return; | ||
420 | } | ||
421 | prop_ntoh (&msg->properties, | ||
422 | &session->data.prop); | ||
423 | plugin->session_update (plugin->cls, | ||
424 | session->sh, | ||
425 | &session->data); | ||
426 | GNUNET_SERVICE_client_continue (c->client); | ||
427 | } | ||
428 | |||
429 | |||
430 | /** | ||
431 | * Handle 'session delete' messages from transport clients. | ||
432 | * | ||
433 | * @param cls client that sent the request | ||
434 | * @param message the request message | ||
435 | */ | ||
436 | static void | ||
437 | handle_session_del (void *cls, | ||
438 | const struct SessionDelMessage *message) | ||
439 | { | ||
440 | struct Client *c = cls; | ||
441 | struct GNUNET_ATS_Session *session; | ||
442 | |||
443 | if (CT_TRANSPORT != c->type) | ||
444 | { | ||
445 | GNUNET_break (0); | ||
446 | GNUNET_SERVICE_client_drop (c->client); | ||
447 | return; | ||
448 | } | ||
449 | session = GNUNET_CONTAINER_multihashmap32_get (c->details.transport.sessions, | ||
450 | message->session_id); | ||
451 | if (NULL == session) | ||
452 | { | ||
453 | GNUNET_break (0); | ||
454 | GNUNET_SERVICE_client_drop (c->client); | ||
455 | return; | ||
456 | } | ||
457 | plugin->session_del (plugin->cls, | ||
458 | session->sh, | ||
459 | &session->data); | ||
460 | GNUNET_assert (GNUNET_YES == | ||
461 | GNUNET_CONTAINER_multihashmap32_remove (c->details.transport.sessions, | ||
462 | session->session_id, | ||
463 | session)); | ||
464 | GNUNET_free (session); | ||
465 | GNUNET_SERVICE_client_continue (c->client); | ||
466 | } | ||
467 | |||
468 | |||
469 | /** | ||
470 | * A client connected to us. Setup the local client | ||
471 | * record. | ||
472 | * | ||
473 | * @param cls unused | ||
474 | * @param client handle of the client | ||
475 | * @param mq message queue to talk to @a client | ||
476 | * @return @a client | ||
477 | */ | ||
478 | static void * | ||
479 | client_connect_cb (void *cls, | ||
480 | struct GNUNET_SERVICE_Client *client, | ||
481 | struct GNUNET_MQ_Handle *mq) | ||
482 | { | ||
483 | struct Client *c = GNUNET_new (struct Client); | ||
484 | |||
485 | c->client = client; | ||
486 | c->mq = mq; | ||
487 | return c; | ||
488 | } | ||
489 | |||
490 | |||
491 | /** | ||
492 | * Function called on each session to release associated state | ||
493 | * on transport disconnect. | ||
494 | * | ||
495 | * @param cls the `struct Client` | ||
496 | * @param key unused (session_id) | ||
497 | * @param value a `struct GNUNET_ATS_Session` | ||
498 | */ | ||
499 | static int | ||
500 | free_session (void *cls, | ||
501 | uint32_t key, | ||
502 | void *value) | ||
503 | { | ||
504 | struct Client *c = cls; | ||
505 | struct GNUNET_ATS_Session *session = value; | ||
506 | |||
507 | (void) key; | ||
508 | GNUNET_assert (c == session->client); | ||
509 | plugin->session_del (plugin->cls, | ||
510 | session->sh, | ||
511 | &session->data); | ||
512 | GNUNET_free (session); | ||
513 | return GNUNET_OK; | ||
514 | } | ||
515 | |||
516 | |||
517 | /** | ||
518 | * A client disconnected from us. Tear down the local client | ||
519 | * record. | ||
520 | * | ||
521 | * @param cls unused | ||
522 | * @param client handle of the client | ||
523 | * @param app_ctx our `struct Client` | ||
524 | */ | ||
525 | static void | ||
526 | client_disconnect_cb (void *cls, | ||
527 | struct GNUNET_SERVICE_Client *client, | ||
528 | void *app_ctx) | ||
529 | { | ||
530 | struct Client *c = app_ctx; | ||
531 | |||
532 | (void) cls; | ||
533 | GNUNET_assert (c->client == client); | ||
534 | switch (c->type) | ||
535 | { | ||
536 | case CT_NONE: | ||
537 | break; | ||
538 | case CT_APPLICATION: | ||
539 | for (struct ClientPreference *cp = c->details.application.cp_head; | ||
540 | NULL != cp; | ||
541 | cp = c->details.application.cp_head) | ||
542 | { | ||
543 | plugin->preference_del (plugin->cls, | ||
544 | cp->ph, | ||
545 | &cp->pref); | ||
546 | GNUNET_CONTAINER_DLL_remove (c->details.application.cp_head, | ||
547 | c->details.application.cp_tail, | ||
548 | cp); | ||
549 | GNUNET_free (cp); | ||
550 | } | ||
551 | break; | ||
552 | case CT_TRANSPORT: | ||
553 | if (transport_client == c) | ||
554 | transport_client = NULL; | ||
555 | GNUNET_CONTAINER_multihashmap32_iterate (c->details.transport.sessions, | ||
556 | &free_session, | ||
557 | c); | ||
558 | GNUNET_CONTAINER_multihashmap32_destroy (c->details.transport.sessions); | ||
559 | break; | ||
560 | } | ||
561 | GNUNET_free (c); | ||
562 | } | ||
563 | |||
564 | |||
565 | /** | ||
566 | * Task run during shutdown. | ||
567 | * | ||
568 | * @param cls unused | ||
569 | */ | ||
570 | static void | ||
571 | cleanup_task (void *cls) | ||
572 | { | ||
573 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
574 | "ATS shutdown initiated\n"); | ||
575 | if (NULL != GSA_stats) | ||
576 | { | ||
577 | GNUNET_STATISTICS_destroy (GSA_stats, | ||
578 | GNUNET_NO); | ||
579 | GSA_stats = NULL; | ||
580 | } | ||
581 | } | ||
582 | |||
583 | |||
584 | /** | ||
585 | * Process template requests. | ||
586 | * | ||
587 | * @param cls closure | ||
588 | * @param cfg configuration to use | ||
589 | * @param service the initialized service | ||
590 | */ | ||
591 | static void | ||
592 | run (void *cls, | ||
593 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
594 | struct GNUNET_SERVICE_Handle *service) | ||
595 | { | ||
596 | GSA_stats = GNUNET_STATISTICS_create ("ats", | ||
597 | cfg); | ||
598 | GNUNET_SCHEDULER_add_shutdown (&cleanup_task, | ||
599 | NULL); | ||
600 | #if 0 | ||
601 | if (GNUNET_OK != | ||
602 | GAS_plugin_init (cfg)) | ||
603 | { | ||
604 | GNUNET_break (0); | ||
605 | GNUNET_SCHEDULER_shutdown (); | ||
606 | return; | ||
607 | } | ||
608 | #endif | ||
609 | } | ||
610 | |||
611 | |||
612 | /** | ||
613 | * Define "main" method using service macro. | ||
614 | */ | ||
615 | GNUNET_SERVICE_MAIN | ||
616 | ("ats", | ||
617 | GNUNET_SERVICE_OPTION_NONE, | ||
618 | &run, | ||
619 | &client_connect_cb, | ||
620 | &client_disconnect_cb, | ||
621 | NULL, | ||
622 | GNUNET_MQ_hd_fixed_size (suggest, | ||
623 | GNUNET_MESSAGE_TYPE_ATS_SUGGEST, | ||
624 | struct ExpressPreferenceMessage, | ||
625 | NULL), | ||
626 | GNUNET_MQ_hd_fixed_size (suggest_cancel, | ||
627 | GNUNET_MESSAGE_TYPE_ATS_SUGGEST_CANCEL, | ||
628 | struct ExpressPreferenceMessage, | ||
629 | NULL), | ||
630 | GNUNET_MQ_hd_fixed_size (start, | ||
631 | GNUNET_MESSAGE_TYPE_ATS_START, | ||
632 | struct GNUNET_MessageHeader, | ||
633 | NULL), | ||
634 | GNUNET_MQ_hd_var_size (session_add, | ||
635 | GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD, | ||
636 | struct SessionAddMessage, | ||
637 | NULL), | ||
638 | GNUNET_MQ_hd_var_size (session_add, | ||
639 | GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY, | ||
640 | struct SessionAddMessage, | ||
641 | NULL), | ||
642 | GNUNET_MQ_hd_fixed_size (session_update, | ||
643 | GNUNET_MESSAGE_TYPE_ATS_SESSION_UPDATE, | ||
644 | struct SessionUpdateMessage, | ||
645 | NULL), | ||
646 | GNUNET_MQ_hd_fixed_size (session_del, | ||
647 | GNUNET_MESSAGE_TYPE_ATS_SESSION_DEL, | ||
648 | struct SessionDelMessage, | ||
649 | NULL), | ||
650 | GNUNET_MQ_handler_end ()); | ||
651 | |||
652 | |||
653 | /* end of gnunet-service-ats.c */ | ||