aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-08-12 10:54:28 +0000
committerChristian Grothoff <christian@grothoff.org>2011-08-12 10:54:28 +0000
commit3d016df6e9f16a224637ae1f525acdcbbce9fbed (patch)
treec198a1c8a918412d018f446d98ee553a3a1dac68 /src/transport
parent180f2e637029d045e3c72dc3e13fddb1f9f30141 (diff)
downloadgnunet-3d016df6e9f16a224637ae1f525acdcbbce9fbed.tar.gz
gnunet-3d016df6e9f16a224637ae1f525acdcbbce9fbed.zip
initial ATS service refactoring
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/Makefile.am2
-rw-r--r--src/transport/gnunet-service-transport-new.c8
-rw-r--r--src/transport/gnunet-service-transport.h2
-rw-r--r--src/transport/gnunet-service-transport_ats-new.c789
-rw-r--r--src/transport/gnunet-service-transport_ats-new.h230
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c14
-rw-r--r--src/transport/gnunet-service-transport_validation.c6
7 files changed, 16 insertions, 1035 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index b9ab214e0..372ff115e 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -153,7 +153,6 @@ gnunet_service_transport_LDADD = \
153 153
154gnunet_service_transport_new_SOURCES = \ 154gnunet_service_transport_new_SOURCES = \
155 gnunet-service-transport-new.c gnunet-service-transport.h \ 155 gnunet-service-transport-new.c gnunet-service-transport.h \
156 gnunet-service-transport_ats-new.h gnunet-service-transport_ats-new.c \
157 gnunet-service-transport_blacklist.h gnunet-service-transport_blacklist.c \ 156 gnunet-service-transport_blacklist.h gnunet-service-transport_blacklist.c \
158 gnunet-service-transport_clients.h gnunet-service-transport_clients.c \ 157 gnunet-service-transport_clients.h gnunet-service-transport_clients.c \
159 gnunet-service-transport_hello.h gnunet-service-transport_hello.c \ 158 gnunet-service-transport_hello.h gnunet-service-transport_hello.c \
@@ -161,6 +160,7 @@ gnunet_service_transport_new_SOURCES = \
161 gnunet-service-transport_plugins.h gnunet-service-transport_plugins.c \ 160 gnunet-service-transport_plugins.h gnunet-service-transport_plugins.c \
162 gnunet-service-transport_validation.h gnunet-service-transport_validation.c 161 gnunet-service-transport_validation.h gnunet-service-transport_validation.c
163gnunet_service_transport_new_LDADD = \ 162gnunet_service_transport_new_LDADD = \
163 $(top_builddir)/src/ats/libgnunetats.la \
164 $(top_builddir)/src/hello/libgnunethello.la \ 164 $(top_builddir)/src/hello/libgnunethello.la \
165 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ 165 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
166 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 166 $(top_builddir)/src/statistics/libgnunetstatistics.la \
diff --git a/src/transport/gnunet-service-transport-new.c b/src/transport/gnunet-service-transport-new.c
index 968145b1e..cd1901a27 100644
--- a/src/transport/gnunet-service-transport-new.c
+++ b/src/transport/gnunet-service-transport-new.c
@@ -28,8 +28,8 @@
28#include "gnunet_statistics_service.h" 28#include "gnunet_statistics_service.h"
29#include "gnunet_transport_service.h" 29#include "gnunet_transport_service.h"
30#include "gnunet_peerinfo_service.h" 30#include "gnunet_peerinfo_service.h"
31#include "gnunet_ats_service.h"
31#include "gnunet-service-transport.h" 32#include "gnunet-service-transport.h"
32#include "gnunet-service-transport_ats-new.h"
33#include "gnunet-service-transport_blacklist.h" 33#include "gnunet-service-transport_blacklist.h"
34#include "gnunet-service-transport_clients.h" 34#include "gnunet-service-transport_clients.h"
35#include "gnunet-service-transport_hello.h" 35#include "gnunet-service-transport_hello.h"
@@ -72,7 +72,7 @@ struct GNUNET_CRYPTO_RsaPrivateKey *GST_my_private_key;
72/** 72/**
73 * ATS handle. 73 * ATS handle.
74 */ 74 */
75struct GST_AtsHandle *GST_ats; 75struct GNUNET_ATS_Handle *GST_ats;
76 76
77 77
78/** 78/**
@@ -133,7 +133,7 @@ shutdown_task (void *cls,
133{ 133{
134 GST_validation_stop (); 134 GST_validation_stop ();
135 GST_neighbours_stop (); 135 GST_neighbours_stop ();
136 GST_ats_shutdown (GST_ats); GST_ats = NULL; 136 GNUNET_ATS_shutdown (GST_ats); GST_ats = NULL;
137 GST_clients_stop (); 137 GST_clients_stop ();
138 GST_blacklist_stop (); 138 GST_blacklist_stop ();
139 GST_plugins_unload (); 139 GST_plugins_unload ();
@@ -221,7 +221,7 @@ run (void *cls,
221 NULL, // FIXME... 221 NULL, // FIXME...
222 NULL, // FIXME... 222 NULL, // FIXME...
223 NULL); // FIXME... 223 NULL); // FIXME...
224 GST_ats = GST_ats_init (GST_cfg, 224 GST_ats = GNUNET_ATS_init (GST_cfg,
225 NULL, // FIXME... 225 NULL, // FIXME...
226 NULL); // FIXME... 226 NULL); // FIXME...
227 GST_neighbours_start (NULL, // FIXME... 227 GST_neighbours_start (NULL, // FIXME...
diff --git a/src/transport/gnunet-service-transport.h b/src/transport/gnunet-service-transport.h
index 69cb20e7b..17fcaa0ae 100644
--- a/src/transport/gnunet-service-transport.h
+++ b/src/transport/gnunet-service-transport.h
@@ -63,7 +63,7 @@ extern struct GNUNET_CRYPTO_RsaPrivateKey *GST_my_private_key;
63/** 63/**
64 * ATS handle. 64 * ATS handle.
65 */ 65 */
66extern struct GST_AtsHandle *GST_ats; 66extern struct GNUNET_ATS_Handle *GST_ats;
67 67
68 68
69#endif 69#endif
diff --git a/src/transport/gnunet-service-transport_ats-new.c b/src/transport/gnunet-service-transport_ats-new.c
deleted file mode 100644
index 3a8bc7497..000000000
--- a/src/transport/gnunet-service-transport_ats-new.c
+++ /dev/null
@@ -1,789 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010,2011 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20/**
21 * @file transport/gnunet-service-transport_ats-new.c
22 * @brief automatic transport selection API
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 */
26#include "platform.h"
27#include "gnunet-service-transport_ats-new.h"
28
29
30/**
31 * Allocation record for a peer's address.
32 */
33struct AllocationRecord
34{
35
36 /**
37 * Public key of the peer.
38 */
39 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key;
40
41 /**
42 * Performance information associated with this address (array).
43 */
44 struct GNUNET_TRANSPORT_ATS_Information *ats;
45
46 /**
47 * Name of the plugin
48 */
49 char *plugin_name;
50
51 /**
52 * Address this record represents, allocated at the end of this struct.
53 */
54 const void *plugin_addr;
55
56 /**
57 * Session associated with this record.
58 */
59 struct Session *session;
60
61 /**
62 * Number of bytes in plugin_addr.
63 */
64 size_t plugin_addr_len;
65
66 /**
67 * Number of entries in 'ats'.
68 */
69 uint32_t ats_count;
70
71 /**
72 * Bandwidth assigned to this address right now, 0 for none.
73 */
74 struct GNUNET_BANDWIDTH_Value32NBO bandwidth;
75
76 /**
77 * Set to GNUNET_YES if this is the connected address of a connected peer.
78 */
79 int connected;
80
81};
82
83
84/**
85 * Opaque handle to stop incremental validation address callbacks.
86 */
87struct GST_AtsSuggestionContext
88{
89
90 /**
91 * Function to call with our final suggestion.
92 */
93 GST_AtsAddressSuggestionCallback cb;
94
95 /**
96 * Closure for 'cb'.
97 */
98 void *cb_cls;
99
100 /**
101 * Global ATS handle.
102 */
103 struct GST_AtsHandle *atc;
104
105 /**
106 * Which peer are we monitoring?
107 */
108 struct GNUNET_PeerIdentity target;
109
110};
111
112
113/**
114 * Handle to the ATS subsystem.
115 */
116struct GST_AtsHandle
117{
118 /**
119 * Configuration.
120 */
121 const struct GNUNET_CONFIGURATION_Handle *cfg;
122
123 /**
124 * Function to call when the allocation changes.
125 */
126 GNUNET_TRANSPORT_ATS_AllocationNotification alloc_cb;
127
128 /**
129 * Closure for 'alloc_cb'.
130 */
131 void *alloc_cb_cls;
132
133 /**
134 * Information about all connected peers. Maps peer identities
135 * to one or more 'struct AllocationRecord' values.
136 */
137 struct GNUNET_CONTAINER_MultiHashMap *peers;
138
139 /**
140 * Map of PeerIdentities to 'struct GST_AtsSuggestionContext's.
141 */
142 struct GNUNET_CONTAINER_MultiHashMap *notify_map;
143
144
145 /**
146 * Task scheduled to update our bandwidth assignment.
147 */
148 GNUNET_SCHEDULER_TaskIdentifier ba_task;
149
150 /**
151 * Total bandwidth per configuration.
152 */
153 unsigned long long total_bps;
154};
155
156
157/**
158 * Count number of connected records.
159 *
160 * @param cls pointer to counter
161 * @param key identity of the peer associated with the records
162 * @param value a 'struct AllocationRecord'
163 * @return GNUNET_YES (continue iteration)
164 */
165static int
166count_connections (void *cls,
167 const GNUNET_HashCode *key,
168 void *value)
169{
170 unsigned int *ac = cls;
171 struct AllocationRecord *ar = value;
172
173 if (GNUNET_YES == ar->connected)
174 (*ac)++;
175 return GNUNET_YES;
176}
177
178struct SetBandwidthContext
179{
180 struct GST_AtsHandle *atc;
181 struct GNUNET_BANDWIDTH_Value32NBO bw;
182};
183
184/**
185 * Set bandwidth based on record.
186 *
187 * @param cls 'struct SetBandwidthContext'
188 * @param key identity of the peer associated with the records
189 * @param value a 'struct AllocationRecord'
190 * @return GNUNET_YES (continue iteration)
191 */
192static int
193set_bw_connections (void *cls,
194 const GNUNET_HashCode *key,
195 void *value)
196{
197 struct SetBandwidthContext *sbc = cls;
198 struct AllocationRecord *ar = value;
199
200 if (GNUNET_YES == ar->connected)
201 {
202 ar->bandwidth = sbc->bw;
203 sbc->atc->alloc_cb (sbc->atc->alloc_cb_cls,
204 (const struct GNUNET_PeerIdentity*) key,
205 ar->plugin_name,
206 ar->session,
207 ar->plugin_addr,
208 ar->plugin_addr_len,
209 ar->bandwidth);
210 }
211 else if (ntohl(ar->bandwidth.value__) > 0)
212 {
213 ar->bandwidth = GNUNET_BANDWIDTH_value_init (0);
214 sbc->atc->alloc_cb (sbc->atc->alloc_cb_cls,
215 (const struct GNUNET_PeerIdentity*) key,
216 ar->plugin_name,
217 ar->session,
218 ar->plugin_addr,
219 ar->plugin_addr_len,
220 ar->bandwidth);
221 }
222 return GNUNET_YES;
223}
224
225
226/**
227 * Task run to update bandwidth assignments.
228 *
229 * @param cls the 'struct GST_AtsHandle'
230 * @param tc scheduler context
231 */
232static void
233update_bandwidth_task (void *cls,
234 const struct GNUNET_SCHEDULER_TaskContext *tc)
235{
236 struct GST_AtsHandle *atc = cls;
237 unsigned int ac;
238 struct SetBandwidthContext bwc;
239
240 atc->ba_task = GNUNET_SCHEDULER_NO_TASK;
241 /* FIXME: update calculations NICELY; what follows is a naive version */
242 GNUNET_CONTAINER_multihashmap_iterate (atc->peers,
243 &count_connections,
244 &ac);
245 bwc.atc = atc;
246 bwc.bw = GNUNET_BANDWIDTH_value_init (atc->total_bps / ac);
247 GNUNET_CONTAINER_multihashmap_iterate (atc->peers,
248 &set_bw_connections,
249 &bwc);
250}
251
252
253/**
254 * Calculate an updated bandwidth assignment and notify.
255 *
256 * @param ats handle
257 * @param change which allocation record changed?
258 */
259static void
260update_bandwidth_assignment (struct GST_AtsHandle *atc,
261 struct AllocationRecord *change)
262{
263 /* FIXME: based on the 'change', update the LP-problem... */
264 if (atc->ba_task == GNUNET_SCHEDULER_NO_TASK)
265 atc->ba_task = GNUNET_SCHEDULER_add_now (&update_bandwidth_task,
266 atc);
267}
268
269
270/**
271 * Function called with feasbile addresses we might want to suggest.
272 *
273 * @param cls the 'struct GST_AtsSuggestionContext'
274 * @param key identity of the peer
275 * @param value a 'struct AllocationRecord' for the peer
276 * @return GNUNET_NO if we're done, GNUNET_YES if we did not suggest an address yet
277 */
278static int
279suggest_address (void *cls,
280 const GNUNET_HashCode *key,
281 void *value)
282{
283 struct GST_AtsSuggestionContest *asc = cls;
284 struct AllocationRecord *ar = value;
285
286 // FIXME...
287 return GNUNET_YES;
288}
289
290
291/**
292 * We would like to establish a new connection with a peer.
293 * ATS should suggest a good address to begin with.
294 *
295 * @param atc handle
296 * @param peer identity of the new peer
297 * @param cb function to call with the address
298 * @param cb_cls closure for cb
299 */
300struct GST_AtsSuggestionContext *
301GST_ats_suggest_address (struct GST_AtsHandle *atc,
302 const struct GNUNET_PeerIdentity *peer,
303 GST_AtsAddressSuggestionCallback cb,
304 void *cb_cls)
305{
306 struct GST_AtsSuggestionContext *asc;
307
308 asc = GNUNET_malloc (sizeof (struct GST_AtsSuggestionContext));
309 asc->cb = cb;
310 asc->cb_cls = cb_cls;
311 asc->atc = atc;
312 asc->target = *peer;
313 GNUNET_CONTAINER_multihashmap_get_multiple (atc->peers,
314 &peer->hashPubKey,
315 &suggest_address,
316 asc);
317 if (NULL == asc->cb)
318 {
319 GNUNET_free (asc);
320 return NULL;
321 }
322 GNUNET_CONTAINER_multihashmap_put (atc->notify_map,
323 &peer->hashPubKey,
324 asc,
325 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
326 return asc;
327}
328
329
330/**
331 * Cancel suggestion request.
332 *
333 * @param asc handle of the request to cancel
334 */
335void
336GST_ats_suggest_address_cancel (struct GST_AtsSuggestionContext *asc)
337{
338 GNUNET_assert (GNUNET_OK ==
339 GNUNET_CONTAINER_multihashmap_remove (asc->atc->notify_map,
340 &asc->target.hashPubKey,
341 asc));
342 GNUNET_free (asc);
343}
344
345
346/**
347 * Initialize the ATS subsystem.
348 *
349 * @param cfg configuration to use
350 * @param alloc_cb notification to call whenever the allocation changed
351 * @param alloc_cb_cls closure for 'alloc_cb'
352 * @return ats context
353 */
354struct GST_AtsHandle *
355GST_ats_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
356 GNUNET_TRANSPORT_ATS_AllocationNotification alloc_cb,
357 void *alloc_cb_cls)
358{
359 struct GST_AtsHandle *atc;
360
361 atc = GNUNET_malloc (sizeof (struct GST_AtsHandle));
362 atc->cfg = cfg;
363 atc->alloc_cb = alloc_cb;
364 atc->alloc_cb_cls = alloc_cb_cls;
365 atc->peers = GNUNET_CONTAINER_multihashmap_create (256);
366 GNUNET_CONFIGURATION_get_value_number (cfg,
367 "core",
368 "TOTAL_QUOTA_OUT",
369 &atc->total_bps);
370 return atc;
371}
372
373
374/**
375 * Free an allocation record.
376 *
377 * @param cls unused
378 * @param key identity of the peer associated with the record
379 * @param value the 'struct AllocationRecord' to free
380 * @return GNUNET_OK (continue to iterate)
381 */
382static int
383destroy_allocation_record (void *cls,
384 const GNUNET_HashCode *key,
385 void *value)
386{
387 struct AllocationRecord *ar = value;
388
389 GNUNET_array_grow (ar->ats, ar->ats_count, 0);
390 GNUNET_free (ar->plugin_name);
391 GNUNET_free (ar);
392 return GNUNET_OK;
393}
394
395
396/**
397 * Shutdown the ATS subsystem.
398 *
399 * @param atc handle
400 */
401void
402GST_ats_shutdown (struct GST_AtsHandle *atc)
403{
404 if (GNUNET_SCHEDULER_NO_TASK != atc->ba_task)
405 {
406 GNUNET_SCHEDULER_cancel (atc->ba_task);
407 atc->ba_task = GNUNET_SCHEDULER_NO_TASK;
408 }
409 GNUNET_CONTAINER_multihashmap_iterate (atc->peers,
410 &destroy_allocation_record,
411 NULL);
412 GNUNET_CONTAINER_multihashmap_destroy (atc->peers);
413 GNUNET_assert (GNUNET_CONTAINER_multihashmap_size (atc->notify_map) == 0);
414 GNUNET_CONTAINER_multihashmap_destroy (atc->notify_map);
415 atc->notify_map = NULL;
416 GNUNET_free (atc);
417}
418
419
420/**
421 * Closure for 'update_session'
422 */
423struct UpdateSessionContext
424{
425 /**
426 * Ats handle.
427 */
428 struct GST_AtsHandle *atc;
429
430 /**
431 * Allocation record with new information.
432 */
433 struct AllocationRecord *arnew;
434};
435
436
437/**
438 * Update an allocation record, merging with the new information
439 *
440 * @param cls a new 'struct AllocationRecord'
441 * @param key identity of the peer associated with the records
442 * @param value the old 'struct AllocationRecord'
443 * @return GNUNET_YES if the records do not match,
444 * GNUNET_NO if the record do match and 'old' was updated
445 */
446static int
447update_session (void *cls,
448 const GNUNET_HashCode *key,
449 void *value)
450{
451 struct UpdateSessionContext *usc = cls;
452 struct AllocationRecord *arnew = usc->arnew;
453 struct AllocationRecord *arold = value;
454 int change;
455
456 if (0 != strcmp (arnew->plugin_name, arold->plugin_name))
457 return GNUNET_YES;
458 if ( (arnew->session == arold->session) ||
459 ( (arold->session == NULL) &&
460 (arold->plugin_addr_len == arnew->plugin_addr_len) &&
461 (0 == memcmp (arold->plugin_addr,
462 arnew->plugin_addr,
463 arnew->plugin_addr_len)) ) )
464 {
465 change = GNUNET_NO;
466 /* records match */
467 if (arnew->session != arold->session)
468 {
469 arold->session = arnew->session;
470 change = GNUNET_YES;
471 }
472 if ( (arnew->connected == GNUNET_YES) &&
473 (arold->connected == GNUNET_NO) )
474 {
475 arold->connected = GNUNET_YES;
476 change = GNUNET_YES;
477 }
478 // FIXME: merge ats arrays of (arold, arnew);
479
480 if (GNUNET_YES == change)
481 update_bandwidth_assignment (usc->atc, arold);
482 return GNUNET_NO;
483 }
484 return GNUNET_YES;
485}
486
487
488/**
489 * Create an allocation record with the given properties.
490 *
491 * @param plugin_name name of the currently used transport plugin
492 * @param session session in use (if available)
493 * @param plugin_addr address in use (if available)
494 * @param plugin_addr_len number of bytes in plugin_addr
495 * @param ats performance data for the connection
496 * @param ats_count number of performance records in 'ats'
497 */
498static struct AllocationRecord *
499create_allocation_record (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
500 const char *plugin_name,
501 struct Session *session,
502 const void *plugin_addr,
503 size_t plugin_addr_len,
504 const struct GNUNET_TRANSPORT_ATS_Information *ats,
505 uint32_t ats_count)
506{
507 struct AllocationRecord *ar;
508
509 ar = GNUNET_malloc (sizeof (struct AllocationRecord) + plugin_addr_len);
510 ar->public_key = *public_key;
511 ar->plugin_name = GNUNET_strdup (plugin_name);
512 ar->plugin_addr = &ar[1];
513 memcpy (&ar[1], plugin_addr, plugin_addr_len);
514 ar->session = session;
515 ar->plugin_addr_len = plugin_addr_len;
516 GNUNET_array_grow (ar->ats,
517 ar->ats_count,
518 ats_count);
519 memcpy (ar->ats,
520 ats,
521 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
522 return ar;
523}
524
525
526/**
527 * Mark all matching allocation records as not connected.
528 *
529 * @param cls 'struct GTS_AtsHandle'
530 * @param key identity of the peer associated with the record
531 * @param value the 'struct AllocationRecord' to clear the 'connected' flag
532 * @return GNUNET_OK (continue to iterate)
533 */
534static int
535disconnect_peer (void *cls,
536 const GNUNET_HashCode *key,
537 void *value)
538{
539 struct GST_AtsHandle *atc = cls;
540 struct AllocationRecord *ar = value;
541
542 if (GNUNET_YES == ar->connected)
543 {
544 ar->connected = GNUNET_NO;
545 update_bandwidth_assignment (atc, ar);
546 }
547 return GNUNET_OK;
548}
549
550
551/**
552 * We established a new connection with a peer (for example, because
553 * core asked for it or because the other peer connected to us).
554 * Calculate bandwidth assignments including the new peer.
555 *
556 * @param atc handle
557 * @param public_key public key of the peer
558 * @param peer identity of the new peer
559 * @param plugin_name name of the currently used transport plugin
560 * @param session session in use (if available)
561 * @param plugin_addr address in use (if available)
562 * @param plugin_addr_len number of bytes in plugin_addr
563 * @param ats performance data for the connection
564 * @param ats_count number of performance records in 'ats'
565 */
566void
567GST_ats_peer_connect (struct GST_AtsHandle *atc,
568 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
569 const struct GNUNET_PeerIdentity *peer,
570 const char *plugin_name,
571 struct Session *session,
572 const void *plugin_addr,
573 size_t plugin_addr_len,
574 const struct GNUNET_TRANSPORT_ATS_Information *ats,
575 uint32_t ats_count)
576{
577 struct AllocationRecord *ar;
578 struct UpdateSessionContext usc;
579
580 (void) GNUNET_CONTAINER_multihashmap_iterate (atc->peers,
581 &disconnect_peer,
582 atc);
583 ar = create_allocation_record (public_key,
584 plugin_name,
585 session,
586 plugin_addr,
587 plugin_addr_len,
588 ats,
589 ats_count);
590 ar->connected = GNUNET_YES;
591 usc.atc = atc;
592 usc.arnew = ar;
593 if (GNUNET_SYSERR ==
594 GNUNET_CONTAINER_multihashmap_iterate (atc->peers,
595 &update_session,
596 &usc))
597 {
598 destroy_allocation_record (NULL, &peer->hashPubKey, ar);
599 return;
600 }
601 GNUNET_assert (GNUNET_OK ==
602 GNUNET_CONTAINER_multihashmap_put (atc->peers,
603 &peer->hashPubKey,
604 ar,
605 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
606}
607
608
609/**
610 * We disconnected from the given peer (for example, because ats, core
611 * or blacklist asked for it or because the other peer disconnected).
612 * Calculate bandwidth assignments without the peer.
613 *
614 * @param atc handle
615 * @param peer identity of the new peer
616 */
617void
618GST_ats_peer_disconnect (struct GST_AtsHandle *atc,
619 const struct GNUNET_PeerIdentity *peer)
620{
621 (void) GNUNET_CONTAINER_multihashmap_get_multiple (atc->peers,
622 &peer->hashPubKey,
623 &disconnect_peer,
624 atc);
625}
626
627
628/**
629 * Closure for 'destroy_allocation_record'
630 */
631struct SessionDestroyContext
632{
633 /**
634 * Ats handle.
635 */
636 struct GST_AtsHandle *atc;
637
638 /**
639 * Session being destroyed.
640 */
641 const struct Session *session;
642};
643
644
645/**
646 * Free an allocation record matching the given session.
647 *
648 * @param cls the 'struct SessionDestroyContext'
649 * @param key identity of the peer associated with the record
650 * @param value the 'struct AllocationRecord' to free
651 * @return GNUNET_OK (continue to iterate)
652 */
653static int
654destroy_session (void *cls,
655 const GNUNET_HashCode *key,
656 void *value)
657{
658 struct SessionDestroyContext *sdc = cls;
659 struct AllocationRecord *ar = value;
660
661 if (ar->session != sdc->session)
662 return GNUNET_OK;
663 ar->session = NULL;
664 if (ar->plugin_addr != NULL)
665 return GNUNET_OK;
666 GNUNET_assert (GNUNET_OK ==
667 GNUNET_CONTAINER_multihashmap_remove (sdc->atc->peers,
668 key,
669 ar));
670 if (GNUNET_YES == ar->connected);
671 {
672 /* FIXME: is this supposed to be allowed? What to do then? */
673 GNUNET_break (0);
674 }
675 destroy_allocation_record (NULL, key, ar);
676 return GNUNET_OK;
677}
678
679
680/**
681 * A session got destroyed, stop including it as a valid address.
682 *
683 * @param atc handle
684 * @param peer identity of the peer
685 * @param session session handle that is no longer valid
686 */
687void
688GST_ats_session_destroyed (struct GST_AtsHandle *atc,
689 const struct GNUNET_PeerIdentity *peer,
690 const struct Session *session)
691{
692 struct SessionDestroyContext sdc;
693
694 sdc.atc = atc;
695 sdc.session = session;
696 (void) GNUNET_CONTAINER_multihashmap_iterate (atc->peers,
697 &destroy_session,
698 &sdc);
699}
700
701
702/**
703 * Notify validation watcher that an entry is now valid
704 *
705 * @param cls 'struct ValidationEntry' that is now valid
706 * @param key peer identity (unused)
707 * @param value a 'GST_ValidationIteratorContext' to notify
708 * @return GNUNET_YES (continue to iterate)
709 */
710static int
711notify_valid (void *cls,
712 const GNUNET_HashCode *key,
713 void *value)
714{
715 struct AllocationRecord *ar = cls;
716 struct GST_AtsSuggestionContext *asc = value;
717
718 asc->cb (asc->cb_cls,
719 &ar->public_key,
720 &asc->target,
721 ar->plugin_name,
722 ar->plugin_addr,
723 ar->plugin_addr_len,
724 ar->ats, ar->ats_count);
725 return GNUNET_OK;
726}
727
728
729/**
730 * We have updated performance statistics for a given address. Note
731 * that this function can be called for addresses that are currently
732 * in use as well as addresses that are valid but not actively in use.
733 * Furthermore, the peer may not even be connected to us right now (in
734 * which case the call may be ignored or the information may be stored
735 * for later use). Update bandwidth assignments.
736 *
737 * @param atc handle
738 * @param public_key public key of the peer
739 * @param peer identity of the peer
740 * @param plugin_name name of the transport plugin
741 * @param session session handle (if available)
742 * @param plugin_addr address (if available)
743 * @param plugin_addr_len number of bytes in plugin_addr
744 * @param ats performance data for the address
745 * @param ats_count number of performance records in 'ats'
746 */
747void
748GST_ats_address_update (struct GST_AtsHandle *atc,
749 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
750 const struct GNUNET_PeerIdentity *peer,
751 const char *plugin_name,
752 struct Session *session,
753 const void *plugin_addr,
754 size_t plugin_addr_len,
755 const struct GNUNET_TRANSPORT_ATS_Information *ats,
756 uint32_t ats_count)
757{
758 struct AllocationRecord *ar;
759 struct UpdateSessionContext usc;
760
761 ar = create_allocation_record (public_key,
762 plugin_name,
763 session,
764 plugin_addr,
765 plugin_addr_len,
766 ats,
767 ats_count);
768 usc.atc = atc;
769 usc.arnew = ar;
770 if (GNUNET_SYSERR ==
771 GNUNET_CONTAINER_multihashmap_iterate (atc->peers,
772 &update_session,
773 &usc))
774 {
775 destroy_allocation_record (NULL, &peer->hashPubKey, ar);
776 return;
777 }
778 GNUNET_assert (GNUNET_OK ==
779 GNUNET_CONTAINER_multihashmap_put (atc->peers,
780 &peer->hashPubKey,
781 ar,
782 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
783 GNUNET_CONTAINER_multihashmap_get_multiple (atc->notify_map,
784 &peer->hashPubKey,
785 &notify_valid,
786 ar);
787}
788
789/* end of file gnunet-service-transport_ats.c */
diff --git a/src/transport/gnunet-service-transport_ats-new.h b/src/transport/gnunet-service-transport_ats-new.h
deleted file mode 100644
index ed72dd171..000000000
--- a/src/transport/gnunet-service-transport_ats-new.h
+++ /dev/null
@@ -1,230 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010,2011 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20/**
21 * @file transport/gnunet-service-transport_ats-new.h
22 * @brief automatic transport selection and outbound bandwidth determination
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 *
26 * TODO:
27 * - turn into service
28 * - extend API to express communication preferences to ATS
29 * (to be called DIRECTLY from apps, not from transport/core!)
30 */
31#ifndef GNUNET_SERVICE_TRANSPORT_ATS_H
32#define GNUNET_SERVICE_TRANSPORT_ATS_H
33
34#include "gnunet_constants.h"
35#include "gnunet_util_lib.h"
36#include "gnunet_transport_service.h"
37#include "gnunet_transport_plugin.h"
38
39
40/**
41 * Handle to the ATS subsystem.
42 */
43struct GST_AtsHandle;
44
45
46/**
47 * Signature of a function called by ATS to notify the callee that the
48 * assigned bandwidth or address for a given peer was changed. If the
49 * callback is called with address/bandwidth assignments of zero, the
50 * ATS disconnect function will still be called once the disconnect
51 * actually happened.
52 *
53 * @param cls closure
54 * @param peer identity of the peer
55 * @param plugin_name name of the transport plugin, NULL to disconnect
56 * @param session session to use (if available)
57 * @param plugin_addr address to use (if available)
58 * @param plugin_addr_len number of bytes in addr
59 * @param bandwidth assigned outbound bandwidth for the connection
60 */
61typedef void (*GNUNET_TRANSPORT_ATS_AllocationNotification)(void *cls,
62 const struct GNUNET_PeerIdentity *peer,
63 const char *plugin_name,
64 struct Session *session,
65 const void *plugin_addr,
66 size_t plugin_addr_len,
67 struct GNUNET_BANDWIDTH_Value32NBO bandwidth);
68
69
70/**
71 * Initialize the ATS subsystem.
72 *
73 * @param cfg configuration to use
74 * @param alloc_cb notification to call whenever the allocation changed
75 * @param alloc_cb_cls closure for 'alloc_cb'
76 * @return ats context
77 */
78struct GST_AtsHandle *
79GST_ats_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
80 GNUNET_TRANSPORT_ATS_AllocationNotification alloc_cb,
81 void *alloc_cb_cls);
82
83
84/**
85 * Shutdown the ATS subsystem.
86 *
87 * @param atc handle
88 */
89void
90GST_ats_shutdown (struct GST_AtsHandle *atc);
91
92
93/**
94 * Signature of a function that takes an address suggestion
95 *
96 * @param cls closure
97 * @param public_key public key of the peer
98 * @param peer identity of the new peer
99 * @param plugin_name name of the plugin, NULL if we have no suggestion
100 * @param plugin_addr suggested address, NULL if we have no suggestion
101 * @param plugin_addr_len number of bytes in plugin_addr
102 * @param ats performance data for the address (as far as known)
103 * @param ats_count number of performance records in 'ats'
104 */
105typedef void (*GST_AtsAddressSuggestionCallback)(void *cls,
106 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
107 const struct GNUNET_PeerIdentity *peer,
108 const char *plugin_name,
109 const void *plugin_addr,
110 size_t plugin_addr_len,
111 const struct GNUNET_TRANSPORT_ATS_Information *ats,
112 uint32_t ats_count);
113
114
115/**
116 * Handle to cancel suggestion request.
117 */
118struct GST_AtsSuggestionContext;
119
120
121/**
122 * We would like to establish a new connection with a peer.
123 * ATS should suggest a good address to begin with.
124 *
125 * @param atc handle
126 * @param peer identity of the new peer
127 * @param cb function to call with the address
128 * @param cb_cls closure for cb
129 */
130struct GST_AtsSuggestionContext *
131GST_ats_suggest_address (struct GST_AtsHandle *atc,
132 const struct GNUNET_PeerIdentity *peer,
133 GST_AtsAddressSuggestionCallback cb,
134 void *cb_cls);
135
136
137/**
138 * Cancel suggestion request.
139 *
140 * @param asc handle of the request to cancel
141 */
142void
143GST_ats_suggest_address_cancel (struct GST_AtsSuggestionContext *asc);
144
145
146/**
147 * We established a new connection with a peer (for example, because
148 * core asked for it or because the other peer connected to us).
149 * Calculate bandwidth assignments including the new peer.
150 *
151 * @param atc handle
152 * @param public_key public key of the peer
153 * @param peer identity of the new peer
154 * @param plugin_name name of the currently used transport plugin
155 * @param session session in use (if available)
156 * @param plugin_addr address in use (if available)
157 * @param plugin_addr_len number of bytes in plugin_addr
158 * @param ats performance data for the connection
159 * @param ats_count number of performance records in 'ats'
160 */
161void
162GST_ats_peer_connect (struct GST_AtsHandle *atc,
163 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
164 const struct GNUNET_PeerIdentity *peer,
165 const char *plugin_name,
166 struct Session *session,
167 const void *plugin_addr,
168 size_t plugin_addr_len,
169 const struct GNUNET_TRANSPORT_ATS_Information *ats,
170 uint32_t ats_count);
171
172
173/**
174 * We disconnected from the given peer (for example, because ats, core
175 * or blacklist asked for it or because the other peer disconnected).
176 * Calculate bandwidth assignments without the peer.
177 *
178 * @param atc handle
179 * @param peer identity of the peer
180 */
181void
182GST_ats_peer_disconnect (struct GST_AtsHandle *atc,
183 const struct GNUNET_PeerIdentity *peer);
184
185
186/**
187 * A session got destroyed, stop including it as a valid address.
188 *
189 * @param atc handle
190 * @param peer identity of the peer
191 * @param session session handle that is no longer valid
192 */
193void
194GST_ats_session_destroyed (struct GST_AtsHandle *atc,
195 const struct GNUNET_PeerIdentity *peer,
196 const struct Session *session);
197
198
199/**
200 * We have updated performance statistics for a given address. Note
201 * that this function can be called for addresses that are currently
202 * in use as well as addresses that are valid but not actively in use.
203 * Furthermore, the peer may not even be connected to us right now (in
204 * which case the call may be ignored or the information may be stored
205 * for later use). Update bandwidth assignments.
206 *
207 * @param atc handle
208 * @param public_key public key of the peer
209 * @param peer identity of the new peer
210 * @param plugin_name name of the transport plugin
211 * @param session session handle (if available)
212 * @param plugin_addr address (if available)
213 * @param plugin_addr_len number of bytes in plugin_addr
214 * @param ats performance data for the address
215 * @param ats_count number of performance records in 'ats'
216 */
217void
218GST_ats_address_update (struct GST_AtsHandle *atc,
219 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
220 const struct GNUNET_PeerIdentity *peer,
221 const char *plugin_name,
222 struct Session *session,
223 const void *plugin_addr,
224 size_t plugin_addr_len,
225 const struct GNUNET_TRANSPORT_ATS_Information *ats,
226 uint32_t ats_count);
227
228
229#endif
230/* end of file gnunet-service-transport_ats.h */
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index cff2bb595..2d23ebfa1 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -24,7 +24,7 @@
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet-service-transport_ats-new.h" 27#include "gnunet_ats_service.h"
28#include "gnunet-service-transport_neighbours.h" 28#include "gnunet-service-transport_neighbours.h"
29#include "gnunet-service-transport_validation.h" 29#include "gnunet-service-transport_validation.h"
30#include "gnunet-service-transport.h" 30#include "gnunet-service-transport.h"
@@ -129,7 +129,7 @@ struct NeighbourMapEntry
129 * Context for address suggestion. 129 * Context for address suggestion.
130 * NULL after we are connected. 130 * NULL after we are connected.
131 */ 131 */
132 struct GST_AtsSuggestionContext *asc; 132 struct GNUNET_ATS_SuggestionContext *asc;
133 133
134 /** 134 /**
135 * Performance data for the peer. 135 * Performance data for the peer.
@@ -341,7 +341,7 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
341 } 341 }
342 if (NULL != n->asc) 342 if (NULL != n->asc)
343 { 343 {
344 GST_ats_suggest_address_cancel (n->asc); 344 GNUNET_ATS_suggest_address_cancel (n->asc);
345 n->asc = NULL; 345 n->asc = NULL;
346 } 346 }
347 GNUNET_array_grow (n->ats, 347 GNUNET_array_grow (n->ats,
@@ -486,10 +486,10 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target)
486 } 486 }
487 if (n->asc != NULL) 487 if (n->asc != NULL)
488 return; /* already trying */ 488 return; /* already trying */
489 n->asc = GST_ats_suggest_address (GST_ats, 489 n->asc = GNUNET_ATS_suggest_address (GST_ats,
490 target, 490 target,
491 &try_connect_using_address, 491 &try_connect_using_address,
492 n); 492 n);
493} 493}
494 494
495 495
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c
index 1a619a901..2b03e3805 100644
--- a/src/transport/gnunet-service-transport_validation.c
+++ b/src/transport/gnunet-service-transport_validation.c
@@ -27,9 +27,9 @@
27#include "gnunet-service-transport_validation.h" 27#include "gnunet-service-transport_validation.h"
28#include "gnunet-service-transport_plugins.h" 28#include "gnunet-service-transport_plugins.h"
29#include "gnunet-service-transport_hello.h" 29#include "gnunet-service-transport_hello.h"
30#include "gnunet-service-transport_ats-new.h"
31#include "gnunet-service-transport.h" 30#include "gnunet-service-transport.h"
32#include "gnunet_hello_lib.h" 31#include "gnunet_hello_lib.h"
32#include "gnunet_ats_service.h"
33#include "gnunet_peerinfo_service.h" 33#include "gnunet_peerinfo_service.h"
34#include "gnunet_signatures.h" 34#include "gnunet_signatures.h"
35 35
@@ -418,7 +418,7 @@ add_valid_address (void *cls,
418 ve = find_validation_entry (&public_key, &pid, tname, addr, addrlen); 418 ve = find_validation_entry (&public_key, &pid, tname, addr, addrlen);
419 ve->valid_until = GNUNET_TIME_absolute_max (ve->valid_until, 419 ve->valid_until = GNUNET_TIME_absolute_max (ve->valid_until,
420 expiration); 420 expiration);
421 GST_ats_address_update (GST_ats, 421 GNUNET_ATS_address_update (GST_ats,
422 &public_key, 422 &public_key,
423 &pid, 423 &pid,
424 tname, 424 tname,
@@ -1037,7 +1037,7 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender,
1037 1037
1038 /* validity achieved, remember it! */ 1038 /* validity achieved, remember it! */
1039 ve->valid_until = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); 1039 ve->valid_until = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
1040 GST_ats_address_update (GST_ats, 1040 GNUNET_ATS_address_update (GST_ats,
1041 &ve->public_key, 1041 &ve->public_key,
1042 &ve->pid, 1042 &ve->pid,
1043 ve->transport_name, 1043 ve->transport_name,