aboutsummaryrefslogtreecommitdiff
path: root/src/ats/gnunet-service-ats_performance.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-02-05 16:09:26 +0000
committerChristian Grothoff <christian@grothoff.org>2015-02-05 16:09:26 +0000
commitb2a4dcbce4f56046fbdcd4b114ec7a3feb4793fd (patch)
tree80877f12acf494cafd50d574bdc1a2b2a218bacb /src/ats/gnunet-service-ats_performance.c
parent5d063af93ad3de2223ff3078acac13761ab308fb (diff)
downloadgnunet-b2a4dcbce4f56046fbdcd4b114ec7a3feb4793fd.tar.gz
gnunet-b2a4dcbce4f56046fbdcd4b114ec7a3feb4793fd.zip
-cleaning up gnunet-service-ats_performance-*
Diffstat (limited to 'src/ats/gnunet-service-ats_performance.c')
-rw-r--r--src/ats/gnunet-service-ats_performance.c448
1 files changed, 46 insertions, 402 deletions
diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c
index c49821227..3f064308a 100644
--- a/src/ats/gnunet-service-ats_performance.c
+++ b/src/ats/gnunet-service-ats_performance.c
@@ -17,7 +17,6 @@
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20
21/** 20/**
22 * @file ats/gnunet-service-ats_performance.c 21 * @file ats/gnunet-service-ats_performance.c
23 * @brief ats service, interaction with 'performance' API 22 * @brief ats service, interaction with 'performance' API
@@ -31,92 +30,23 @@
31#include "gnunet-service-ats_reservations.h" 30#include "gnunet-service-ats_reservations.h"
32#include "ats.h" 31#include "ats.h"
33 32
34/**
35 * We keep clients that are interested in performance in a linked list.
36 */
37struct PerformanceClient
38{
39 /**
40 * Next in doubly-linked list.
41 */
42 struct PerformanceClient *next;
43
44 /**
45 * Previous in doubly-linked list.
46 */
47 struct PerformanceClient *prev;
48
49 /**
50 * Actual handle to the client.
51 */
52 struct GNUNET_SERVER_Client *client;
53
54 /**
55 * Options for the client.
56 */
57 enum StartFlag flag;
58
59};
60
61 33
62/** 34/**
63 * Head of linked list of all clients to this service. 35 * Context for sending messages to performance clients without PIC.
64 */
65static struct PerformanceClient *pc_head;
66
67/**
68 * Tail of linked list of all clients to this service.
69 */
70static struct PerformanceClient *pc_tail;
71
72
73/**
74 * Context for sending messages to performance clients.
75 */ 36 */
76static struct GNUNET_SERVER_NotificationContext *nc; 37static struct GNUNET_SERVER_NotificationContext *nc;
77 38
78
79/** 39/**
80 * Find the performance client associated with the given handle. 40 * Context for sending messages to performance clients with PIC.
81 *
82 * @param client server handle
83 * @return internal handle
84 */ 41 */
85static struct PerformanceClient * 42static struct GNUNET_SERVER_NotificationContext *nc_pic;
86find_client (struct GNUNET_SERVER_Client *client)
87{
88 struct PerformanceClient *pc;
89
90 for (pc = pc_head; pc != NULL; pc = pc->next)
91 if (pc->client == client)
92 return pc;
93 return NULL;
94}
95
96/**
97 * Unregister a client (which may have been a performance client,
98 * but this is not assured).
99 *
100 * @param client handle of the (now dead) client
101 */
102void
103GAS_performance_remove_client (struct GNUNET_SERVER_Client *client)
104{
105 struct PerformanceClient *pc;
106
107 pc = find_client (client);
108 if (NULL == pc)
109 return;
110 GNUNET_CONTAINER_DLL_remove (pc_head, pc_tail, pc);
111 GNUNET_free (pc);
112}
113 43
114 44
115/** 45/**
116 * Transmit the given performance information to all performance 46 * Transmit the given performance information to all performance
117 * clients. 47 * clients.
118 * 48 *
119 * @param pc performance client to send to 49 * @param pc client to send to, NULL for all
120 * @param peer peer for which this is an address suggestion 50 * @param peer peer for which this is an address suggestion
121 * @param plugin_name 0-termintated string specifying the transport plugin 51 * @param plugin_name 0-termintated string specifying the transport plugin
122 * @param plugin_addr binary address for the plugin to use 52 * @param plugin_addr binary address for the plugin to use
@@ -131,7 +61,7 @@ GAS_performance_remove_client (struct GNUNET_SERVER_Client *client)
131 * @param bandwidth_in assigned inbound bandwidth 61 * @param bandwidth_in assigned inbound bandwidth
132 */ 62 */
133void 63void
134GAS_performance_notify_client (struct PerformanceClient *pc, 64GAS_performance_notify_client (struct GNUNET_SERVER_Client *client,
135 const struct GNUNET_PeerIdentity *peer, 65 const struct GNUNET_PeerIdentity *peer,
136 const char *plugin_name, 66 const char *plugin_name,
137 const void *plugin_addr, 67 const void *plugin_addr,
@@ -142,7 +72,6 @@ GAS_performance_notify_client (struct PerformanceClient *pc,
142 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 72 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
143 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) 73 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
144{ 74{
145
146 struct PeerInformationMessage *msg; 75 struct PeerInformationMessage *msg;
147 size_t plugin_name_length = strlen (plugin_name) + 1; 76 size_t plugin_name_length = strlen (plugin_name) + 1;
148 size_t msize = 77 size_t msize =
@@ -153,10 +82,6 @@ GAS_performance_notify_client (struct PerformanceClient *pc,
153 struct GNUNET_ATS_Information *atsp; 82 struct GNUNET_ATS_Information *atsp;
154 char *addrp; 83 char *addrp;
155 84
156 GNUNET_assert (NULL != pc);
157 if (NULL == find_client (pc->client))
158 return; /* Client disconnected */
159
160 GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); 85 GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE);
161 GNUNET_assert (atsi_count < 86 GNUNET_assert (atsi_count <
162 GNUNET_SERVER_MAX_MESSAGE_SIZE / 87 GNUNET_SERVER_MAX_MESSAGE_SIZE /
@@ -177,10 +102,19 @@ GAS_performance_notify_client (struct PerformanceClient *pc,
177 addrp = (char *) &atsp[atsi_count]; 102 addrp = (char *) &atsp[atsi_count];
178 memcpy (addrp, plugin_addr, plugin_addr_len); 103 memcpy (addrp, plugin_addr, plugin_addr_len);
179 strcpy (&addrp[plugin_addr_len], plugin_name); 104 strcpy (&addrp[plugin_addr_len], plugin_name);
180 GNUNET_SERVER_notification_context_unicast (nc, 105 if (NULL == client)
181 pc->client, 106 {
182 &msg->header, 107 GNUNET_SERVER_notification_context_broadcast (nc_pic,
183 GNUNET_YES); 108 &msg->header,
109 GNUNET_YES);
110 }
111 else
112 {
113 GNUNET_SERVER_notification_context_unicast (nc,
114 client,
115 &msg->header,
116 GNUNET_YES);
117 }
184} 118}
185 119
186 120
@@ -212,31 +146,26 @@ GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer,
212 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 146 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
213 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) 147 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
214{ 148{
215 struct PerformanceClient *pc; 149 GAS_performance_notify_client (NULL,
216 150 peer,
217 for (pc = pc_head; pc != NULL; pc = pc->next) 151 plugin_name,
218 if (pc->flag == START_FLAG_PERFORMANCE_WITH_PIC) 152 plugin_addr,
219 { 153 plugin_addr_len,
220 GAS_performance_notify_client (pc, 154 active,
221 peer, 155 atsi, atsi_count,
222 plugin_name, 156 bandwidth_out,
223 plugin_addr, 157 bandwidth_in);
224 plugin_addr_len,
225 active,
226 atsi, atsi_count,
227 bandwidth_out, bandwidth_in);
228 }
229 GNUNET_STATISTICS_update (GSA_stats, 158 GNUNET_STATISTICS_update (GSA_stats,
230 "# performance updates given to clients", 1, 159 "# performance updates given to clients",
160 1,
231 GNUNET_NO); 161 GNUNET_NO);
232} 162}
233 163
234 164
235
236/** 165/**
237 * Iterator for called from #GAS_addresses_get_peer_info() 166 * Iterator for called from #GAS_addresses_get_peer_info()
238 * 167 *
239 * @param cls closure with the `struct PerformanceClient *` 168 * @param cls closure with the `struct GNUNET_SERVER_Client *` to inform.
240 * @param id the peer id 169 * @param id the peer id
241 * @param plugin_name plugin name 170 * @param plugin_name plugin name
242 * @param plugin_addr address 171 * @param plugin_addr address
@@ -259,9 +188,8 @@ peerinfo_it (void *cls,
259 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 188 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
260 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) 189 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
261{ 190{
262 struct PerformanceClient *pc = cls; 191 struct GNUNET_SERVER_Client *client = cls;
263 192
264 GNUNET_assert (NULL != pc);
265 if (NULL == id) 193 if (NULL == id)
266 return; 194 return;
267 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 195 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -270,7 +198,7 @@ peerinfo_it (void *cls,
270 plugin_name, 198 plugin_name,
271 (unsigned int) ntohl (bandwidth_out.value__), 199 (unsigned int) ntohl (bandwidth_out.value__),
272 (unsigned int) ntohl (bandwidth_in.value__)); 200 (unsigned int) ntohl (bandwidth_in.value__));
273 GAS_performance_notify_client (pc, 201 GAS_performance_notify_client (client,
274 id, 202 id,
275 plugin_name, 203 plugin_name,
276 plugin_addr, 204 plugin_addr,
@@ -292,318 +220,32 @@ void
292GAS_performance_add_client (struct GNUNET_SERVER_Client *client, 220GAS_performance_add_client (struct GNUNET_SERVER_Client *client,
293 enum StartFlag flag) 221 enum StartFlag flag)
294{ 222{
295 struct PerformanceClient *pc; 223 if (START_FLAG_PERFORMANCE_WITH_PIC == flag)
296
297 GNUNET_break (NULL == find_client (client));
298 pc = GNUNET_new (struct PerformanceClient);
299 pc->client = client;
300 pc->flag = flag;
301
302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
303 "Adding performance client %s PIC\n",
304 (flag == START_FLAG_PERFORMANCE_WITH_PIC) ? "with" : "without");
305
306 GNUNET_SERVER_notification_context_add (nc,
307 client);
308 GNUNET_CONTAINER_DLL_insert (pc_head,
309 pc_tail,
310 pc);
311 GAS_addresses_get_peer_info (NULL,
312 &peerinfo_it,
313 pc);
314}
315
316
317/**
318 * Information we need for the callbacks to return a list of addresses
319 * back to the client.
320 */
321struct AddressIteration
322{
323 /**
324 * Actual handle to the client.
325 */
326 struct PerformanceClient *pc;
327
328 /**
329 * Are we sending all addresses, or only those that are active?
330 */
331 int all;
332
333 /**
334 * Which ID should be included in the response?
335 */
336 uint32_t id;
337
338};
339
340
341/**
342 * Send a #GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE with the
343 * given address details to the client identified in @a ai.
344 *
345 * @param ai our address information context (identifies the client)
346 * @param id the peer id this address is for
347 * @param plugin_name name of the plugin that supports this address
348 * @param plugin_addr address
349 * @param plugin_addr_len length of @a plugin_addr
350 * @param active #GNUNET_YES if this address is actively used
351 * @param atsi ats performance information
352 * @param atsi_count number of ats performance elements in @a atsi
353 * @param bandwidth_out current outbound bandwidth assigned to address
354 * @param bandwidth_in current inbound bandwidth assigned to address
355 */
356static void
357transmit_req_addr (struct AddressIteration *ai,
358 const struct GNUNET_PeerIdentity *id,
359 const char *plugin_name,
360 const void *plugin_addr,
361 size_t plugin_addr_len,
362 int active,
363 const struct GNUNET_ATS_Information *atsi,
364 uint32_t atsi_count,
365 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
366 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
367
368{
369 struct GNUNET_ATS_Information *atsp;
370 struct PeerInformationMessage *msg;
371 char *addrp;
372 size_t plugin_name_length;
373 size_t msize;
374
375 if (NULL != plugin_name)
376 plugin_name_length = strlen (plugin_name) + 1;
377 else
378 plugin_name_length = 0;
379 msize = sizeof (struct PeerInformationMessage) +
380 atsi_count * sizeof (struct GNUNET_ATS_Information) +
381 plugin_addr_len + plugin_name_length;
382 char buf[msize] GNUNET_ALIGN;
383
384 GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE);
385 GNUNET_assert (atsi_count <
386 GNUNET_SERVER_MAX_MESSAGE_SIZE /
387 sizeof (struct GNUNET_ATS_Information));
388 msg = (struct PeerInformationMessage *) buf;
389 msg->header.size = htons (msize);
390 msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE);
391 msg->ats_count = htonl (atsi_count);
392 msg->id = htonl (ai->id);
393 if (NULL != id)
394 msg->peer = *id;
395 else
396 memset (&msg->peer, '\0', sizeof (struct GNUNET_PeerIdentity));
397 msg->address_length = htons (plugin_addr_len);
398 msg->address_active = ntohl (active);
399 msg->plugin_name_length = htons (plugin_name_length);
400 msg->bandwidth_out = bandwidth_out;
401 msg->bandwidth_in = bandwidth_in;
402 atsp = (struct GNUNET_ATS_Information *) &msg[1];
403 memcpy (atsp, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count);
404 addrp = (char *) &atsp[atsi_count];
405 if (NULL != plugin_addr)
406 memcpy (addrp, plugin_addr, plugin_addr_len);
407 if (NULL != plugin_name)
408 strcpy (&addrp[plugin_addr_len], plugin_name);
409 GNUNET_SERVER_notification_context_unicast (nc,
410 ai->pc->client,
411 &msg->header,
412 GNUNET_NO);
413}
414
415
416/**
417 * Iterator for #GAS_addresses_get_peer_info(), called with peer-specific
418 * information to be passed back to the client.
419 *
420 * @param cls closure with our `struct AddressIteration *`
421 * @param id the peer id
422 * @param plugin_name plugin name
423 * @param plugin_addr address
424 * @param plugin_addr_len length of @a plugin_addr
425 * @param active is address actively used
426 * @param atsi ats performance information
427 * @param atsi_count number of ats performance elements in @a atsi
428 * @param bandwidth_out current outbound bandwidth assigned to address
429 * @param bandwidth_in current inbound bandwidth assigned to address
430 */
431static void
432req_addr_peerinfo_it (void *cls,
433 const struct GNUNET_PeerIdentity *id,
434 const char *plugin_name,
435 const void *plugin_addr,
436 size_t plugin_addr_len,
437 int active,
438 const struct GNUNET_ATS_Information *atsi,
439 uint32_t atsi_count,
440 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
441 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
442{
443 struct AddressIteration *ai = cls;
444
445 if ( (NULL == id) &&
446 (NULL == plugin_name) &&
447 (NULL == plugin_addr) )
448 { 224 {
449 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 225 GNUNET_SERVER_notification_context_add (nc_pic,
450 "Address iteration done for one peer\n"); 226 client);
451 return; 227 GNUNET_SERVER_notification_context_add (nc,
452 } 228 client);
453 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
454 "Callback for %s peer `%s' plugin `%s' BW out %u, BW in %u\n",
455 (active == GNUNET_YES) ? "ACTIVE" : "INACTIVE",
456 GNUNET_i2s (id),
457 plugin_name,
458 (unsigned int) ntohl (bandwidth_out.value__),
459 (unsigned int) ntohl (bandwidth_in.value__));
460
461 /* Transmit result (either if address is active, or if
462 client wanted all addresses) */
463 if ( (GNUNET_YES == ai->all) ||
464 (GNUNET_YES == active))
465 {
466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
467 "Sending result for %s peer `%s' plugin `%s' BW out %u, BW in %u\n",
468 (active == GNUNET_YES) ? "ACTIVE" : "INACTIVE",
469 GNUNET_i2s (id),
470 plugin_name,
471 (unsigned int) ntohl (bandwidth_out.value__),
472 (unsigned int) ntohl (bandwidth_in.value__));
473 transmit_req_addr (ai,
474 id,
475 plugin_name,
476 plugin_addr, plugin_addr_len,
477 active,
478 atsi,
479 atsi_count,
480 bandwidth_out,
481 bandwidth_in);
482 }
483}
484
485
486/**
487 * Handle 'address list request' messages from clients.
488 *
489 * @param cls unused, NULL
490 * @param client client that sent the request
491 * @param message the request message
492 */
493void
494GAS_handle_request_address_list (void *cls,
495 struct GNUNET_SERVER_Client *client,
496 const struct GNUNET_MessageHeader *message)
497{
498 struct PerformanceClient *pc;
499 struct AddressIteration ai;
500 const struct AddressListRequestMessage *alrm;
501 struct GNUNET_PeerIdentity allzeros;
502 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_zero;
503
504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
505 "Received `%s' message\n",
506 "ADDRESSLIST_REQUEST");
507 if (NULL == (pc = find_client(client)))
508 {
509 GNUNET_break (0);
510 return;
511 }
512 alrm = (const struct AddressListRequestMessage *) message;
513 ai.all = ntohl (alrm->all);
514 ai.id = ntohl (alrm->id);
515 ai.pc = pc;
516
517 memset (&allzeros, '\0', sizeof (struct GNUNET_PeerIdentity));
518 bandwidth_zero.value__ = htonl (0);
519 if (0 == memcmp (&alrm->peer,
520 &allzeros,
521 sizeof (struct GNUNET_PeerIdentity)))
522 {
523 /* Return addresses for all peers */
524 GAS_addresses_get_peer_info (NULL,
525 &req_addr_peerinfo_it,
526 &ai);
527 } 229 }
528 else 230 else
529 { 231 GNUNET_SERVER_notification_context_add (nc,
530 /* Return addresses for a specific peer */ 232 client);
531 GAS_addresses_get_peer_info (&alrm->peer, 233 GAS_addresses_get_peer_info (NULL,
532 &req_addr_peerinfo_it, 234 &peerinfo_it,
533 &ai); 235 client);
534 }
535 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
536 "Finished handling `%s' message\n",
537 "ADDRESSLIST_REQUEST");
538 transmit_req_addr (&ai,
539 NULL, NULL, NULL,
540 0, GNUNET_NO,
541 NULL, 0,
542 bandwidth_zero,
543 bandwidth_zero);
544 GNUNET_SERVER_receive_done (client,
545 GNUNET_OK);
546}
547
548
549/**
550 * Handle 'reservation request' messages from clients.
551 *
552 * @param cls unused, NULL
553 * @param client client that sent the request
554 * @param message the request message
555 */
556void
557GAS_handle_reservation_request (void *cls,
558 struct GNUNET_SERVER_Client *client,
559 const struct GNUNET_MessageHeader *message)
560{
561 const struct ReservationRequestMessage *msg =
562 (const struct ReservationRequestMessage *) message;
563 struct ReservationResultMessage result;
564 int32_t amount;
565 struct GNUNET_TIME_Relative res_delay;
566
567 if (NULL == find_client (client))
568 {
569 /* missing start message! */
570 GNUNET_break (0);
571 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
572 return;
573 }
574 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
575 "Received `%s' message\n",
576 "RESERVATION_REQUEST");
577 amount = (int32_t) ntohl (msg->amount);
578 res_delay = GAS_reservations_reserve (&msg->peer, amount);
579 if (res_delay.rel_value_us > 0)
580 amount = 0;
581 result.header.size = htons (sizeof (struct ReservationResultMessage));
582 result.header.type = htons (GNUNET_MESSAGE_TYPE_ATS_RESERVATION_RESULT);
583 result.amount = htonl (amount);
584 result.peer = msg->peer;
585 result.res_delay = GNUNET_TIME_relative_hton (res_delay);
586 GNUNET_STATISTICS_update (GSA_stats,
587 "# reservation requests processed", 1,
588 GNUNET_NO);
589 GNUNET_SERVER_notification_context_unicast (nc, client, &result.header,
590 GNUNET_NO);
591 GNUNET_SERVER_receive_done (client, GNUNET_OK);
592} 236}
593 237
594 238
595
596
597/** 239/**
598 * Initialize performance subsystem. 240 * Initialize performance subsystem.
599 * 241 *
600 * @param server handle to our server 242 * @param server handle to our server
601 * @param addresses the address handle to use
602 */ 243 */
603void 244void
604GAS_performance_init (struct GNUNET_SERVER_Handle *server) 245GAS_performance_init (struct GNUNET_SERVER_Handle *server)
605{ 246{
606 nc = GNUNET_SERVER_notification_context_create (server, 128); 247 nc = GNUNET_SERVER_notification_context_create (server, 32);
248 nc_pic = GNUNET_SERVER_notification_context_create (server, 32);
607} 249}
608 250
609 251
@@ -615,6 +257,8 @@ GAS_performance_done ()
615{ 257{
616 GNUNET_SERVER_notification_context_destroy (nc); 258 GNUNET_SERVER_notification_context_destroy (nc);
617 nc = NULL; 259 nc = NULL;
260 GNUNET_SERVER_notification_context_destroy (nc_pic);
261 nc_pic = NULL;
618} 262}
619 263
620/* end of gnunet-service-ats_performance.c */ 264/* end of gnunet-service-ats_performance.c */