aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-03-17 16:51:43 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-03-17 16:51:43 +0000
commit4759a55fd2bba8b4aabef3ef361c8c6183fbe3e5 (patch)
tree0bdc4f0589ec814515e8b5ad3466017ba182e466 /src
parent0d23056a4a35f254e930a22f47ae638bf7aea751 (diff)
downloadgnunet-4759a55fd2bba8b4aabef3ef361c8c6183fbe3e5.tar.gz
gnunet-4759a55fd2bba8b4aabef3ef361c8c6183fbe3e5.zip
adding ats framework
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_transport_service.h20
-rw-r--r--src/transport/gnunet-service-transport.c194
2 files changed, 210 insertions, 4 deletions
diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h
index 5d25e7548..a72a3b467 100644
--- a/src/include/gnunet_transport_service.h
+++ b/src/include/gnunet_transport_service.h
@@ -390,6 +390,26 @@ struct GNUNET_TRANSPORT_ATS_Information
390 uint32_t value; 390 uint32_t value;
391}; 391};
392 392
393/* Minimum time between to calculations*/
394#define ATS_MIN_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS,250)
395#define ATS_EXEC_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,1)
396
397#define DEBUG_ATS GNUNET_NO
398
399struct ATS_info
400{
401 struct GNUNET_CONTAINER_MultiHashMap * peers;
402 struct GNUNET_TIME_Absolute last;
403 struct GNUNET_TIME_Relative min_delta;
404 struct GNUNET_TIME_Relative reg_delta;
405
406 GNUNET_SCHEDULER_TaskIdentifier ats_task;
407};
408
409struct ATS_peer
410{
411 struct GNUNET_PeerIdentity peer;
412};
393 413
394 414
395 415
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index de61b2199..44269d416 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -904,6 +904,11 @@ static struct GNUNET_CONTAINER_MultiHashMap *validation_map;
904static struct GNUNET_STATISTICS_Handle *stats; 904static struct GNUNET_STATISTICS_Handle *stats;
905 905
906/** 906/**
907 * Handle for ats information
908 */
909static struct ATS_info *ats;
910
911/**
907 * The peer specified by the given neighbour has timed-out or a plugin 912 * The peer specified by the given neighbour has timed-out or a plugin
908 * has disconnected. We may either need to do nothing (other plugins 913 * has disconnected. We may either need to do nothing (other plugins
909 * still up), or trigger a full disconnect and clean up. This 914 * still up), or trigger a full disconnect and clean up. This
@@ -927,6 +932,21 @@ static void disconnect_neighbour (struct NeighbourList *n, int check);
927static void try_transmission_to_peer (struct NeighbourList *neighbour); 932static void try_transmission_to_peer (struct NeighbourList *neighbour);
928 933
929 934
935struct ATS_info * ats_init ();
936
937void ats_shutdown (struct ATS_info * ats);
938
939void ats_notify_peer_connect (struct ATS_info * ats,
940 const struct GNUNET_PeerIdentity *peer,
941 const struct GNUNET_TRANSPORT_ATS_Information *ats_data);
942
943void ats_notify_peer_disconnect (struct ATS_info * ats,
944 const struct GNUNET_PeerIdentity *peer);
945
946void ats_notify_ats_data (struct ATS_info * ats,
947 const struct GNUNET_PeerIdentity *peer,
948 const struct GNUNET_TRANSPORT_ATS_Information *ats_data);
949
930/** 950/**
931 * Find an entry in the neighbour list for a particular peer. 951 * Find an entry in the neighbour list for a particular peer.
932 * 952 *
@@ -2261,12 +2281,17 @@ notify_clients_connect (const struct GNUNET_PeerIdentity *peer,
2261 (&(cim->ats))[2].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); 2281 (&(cim->ats))[2].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
2262 (&(cim->ats))[2].value = htonl (0); 2282 (&(cim->ats))[2].value = htonl (0);
2263 memcpy (&cim->id, peer, sizeof (struct GNUNET_PeerIdentity)); 2283 memcpy (&cim->id, peer, sizeof (struct GNUNET_PeerIdentity));
2284
2285 /* notify ats about connecting peer */
2286 ats_notify_peer_connect(ats, peer, &(cim->ats));
2287
2264 cpos = clients; 2288 cpos = clients;
2265 while (cpos != NULL) 2289 while (cpos != NULL)
2266 { 2290 {
2267 transmit_to_client (cpos, &(cim->header), GNUNET_NO); 2291 transmit_to_client (cpos, &(cim->header), GNUNET_NO);
2268 cpos = cpos->next; 2292 cpos = cpos->next;
2269 } 2293 }
2294
2270 GNUNET_free (cim); 2295 GNUNET_free (cim);
2271} 2296}
2272 2297
@@ -2293,6 +2318,10 @@ notify_clients_disconnect (const struct GNUNET_PeerIdentity *peer)
2293 dim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT); 2318 dim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT);
2294 dim.reserved = htonl (0); 2319 dim.reserved = htonl (0);
2295 memcpy (&dim.peer, peer, sizeof (struct GNUNET_PeerIdentity)); 2320 memcpy (&dim.peer, peer, sizeof (struct GNUNET_PeerIdentity));
2321
2322 /* notify ats about connecting peer */
2323 ats_notify_peer_disconnect(ats, peer);
2324
2296 cpos = clients; 2325 cpos = clients;
2297 while (cpos != NULL) 2326 while (cpos != NULL)
2298 { 2327 {
@@ -2968,7 +2997,6 @@ static void
2968do_blacklist_check (void *cls, 2997do_blacklist_check (void *cls,
2969 const struct GNUNET_SCHEDULER_TaskContext *tc); 2998 const struct GNUNET_SCHEDULER_TaskContext *tc);
2970 2999
2971
2972/** 3000/**
2973 * Transmit blacklist query to the client. 3001 * Transmit blacklist query to the client.
2974 * 3002 *
@@ -3722,6 +3750,7 @@ check_pending_validation (void *cls,
3722 if (GNUNET_NO == n->received_pong) 3750 if (GNUNET_NO == n->received_pong)
3723 { 3751 {
3724 n->received_pong = GNUNET_YES; 3752 n->received_pong = GNUNET_YES;
3753
3725 notify_clients_connect (&target, n->latency, n->distance); 3754 notify_clients_connect (&target, n->latency, n->distance);
3726 if (NULL != (prem = n->pre_connect_message_buffer)) 3755 if (NULL != (prem = n->pre_connect_message_buffer))
3727 { 3756 {
@@ -4732,7 +4761,7 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
4732static struct GNUNET_TIME_Relative 4761static struct GNUNET_TIME_Relative
4733plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, 4762plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
4734 const struct GNUNET_MessageHeader *message, 4763 const struct GNUNET_MessageHeader *message,
4735 const struct GNUNET_TRANSPORT_ATS_Information *ats, 4764 const struct GNUNET_TRANSPORT_ATS_Information *ats_data,
4736 uint32_t ats_count, 4765 uint32_t ats_count,
4737 struct Session *session, 4766 struct Session *session,
4738 const char *sender_address, 4767 const char *sender_address,
@@ -4760,11 +4789,14 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
4760 distance = 1; 4789 distance = 1;
4761 for (c=0; c<ats_count; c++) 4790 for (c=0; c<ats_count; c++)
4762 { 4791 {
4763 if (ntohl(ats[c].type) == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE) 4792 if (ntohl(ats_data[c].type) == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE)
4764 { 4793 {
4765 distance = ntohl(ats[c].value); 4794 distance = ntohl(ats_data[c].value);
4766 } 4795 }
4767 } 4796 }
4797 /* notify ATS about incoming data */
4798 ats_notify_ats_data(ats, peer, ats_data);
4799
4768 4800
4769 if (message != NULL) 4801 if (message != NULL)
4770 { 4802 {
@@ -5453,6 +5485,8 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
5453 GNUNET_CONTAINER_multihashmap_destroy (validation_map); 5485 GNUNET_CONTAINER_multihashmap_destroy (validation_map);
5454 validation_map = NULL; 5486 validation_map = NULL;
5455 5487
5488 ats_shutdown(ats);
5489
5456 /* free 'chvc' data structure */ 5490 /* free 'chvc' data structure */
5457 while (NULL != (chvc = chvc_head)) 5491 while (NULL != (chvc = chvc_head))
5458 { 5492 {
@@ -5488,6 +5522,157 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
5488 GNUNET_break (bc_head == NULL); 5522 GNUNET_break (bc_head == NULL);
5489} 5523}
5490 5524
5525void ats_calculate_bandwidth_distribution (struct ATS_info * ats)
5526{
5527 struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference(ats->last,GNUNET_TIME_absolute_get());
5528 if (delta.rel_value < ats->min_delta.rel_value)
5529 {
5530#if DEBUG_ATS
5531 //GNUNET_log (GNUNET_ERROR_TYPE_BULK, "Minimum time between cycles not reached\n");
5532#endif
5533 return;
5534 }
5535#if DEBUG_ATS
5536 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "CALCULATE DISTRIBUTION\n");
5537#endif
5538 ats->last = GNUNET_TIME_absolute_get();
5539
5540}
5541
5542
5543void
5544ats_schedule_calculation (void *cls,
5545 const struct GNUNET_SCHEDULER_TaskContext *tc)
5546{
5547 struct ATS_info *ats = (struct ATS_info *) cls;
5548 if (ats==NULL)
5549 return;
5550
5551 ats->ats_task = GNUNET_SCHEDULER_NO_TASK;
5552 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
5553 return;
5554
5555#if DEBUG_ATS
5556 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Running scheduled calculation\n");
5557#endif
5558 ats_calculate_bandwidth_distribution (ats);
5559
5560 ats->ats_task = GNUNET_SCHEDULER_add_delayed (ats->reg_delta,
5561 &ats_schedule_calculation, ats);
5562}
5563
5564
5565int ats_map_remove_peer (void *cls,
5566 const GNUNET_HashCode * key,
5567 void *value)
5568{
5569
5570 struct ATS_peer * p = (struct ATS_peer *) value;
5571#if DEBUG_ATS
5572 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "map_remove_peer_it: `%s'\n", GNUNET_i2s(&p->peer));
5573#endif
5574 /* cleanup peer */
5575 GNUNET_free(p);
5576
5577 return GNUNET_YES;
5578}
5579
5580
5581struct ATS_info * ats_init ()
5582{
5583 struct ATS_info * ats;
5584#if DEBUG_ATS
5585 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ats_init\n");
5586#endif
5587 ats = GNUNET_malloc(sizeof (struct ATS_info));
5588 ats->peers = GNUNET_CONTAINER_multihashmap_create(10);
5589 GNUNET_assert(ats->peers!=NULL);
5590
5591 ats->min_delta = ATS_MIN_INTERVAL;
5592 ats->reg_delta = ATS_EXEC_INTERVAL;
5593
5594 ats->ats_task = GNUNET_SCHEDULER_NO_TASK;
5595/*
5596 ats->ats_task = GNUNET_SCHEDULER_add_delayed (ats->reg_delta,
5597 &schedule_calculation, NULL);
5598
5599 ats->ats_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
5600 &schedule_calculation, NULL);
5601*/
5602 ats->ats_task = GNUNET_SCHEDULER_add_now(&ats_schedule_calculation, ats);
5603
5604 return ats;
5605}
5606
5607
5608void ats_shutdown (struct ATS_info * ats)
5609{
5610#if DEBUG_ATS
5611 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ats_destroy\n");
5612#endif
5613 if (ats->ats_task != GNUNET_SCHEDULER_NO_TASK)
5614 GNUNET_SCHEDULER_cancel(ats->ats_task);
5615 ats->ats_task = GNUNET_SCHEDULER_NO_TASK;
5616
5617 GNUNET_CONTAINER_multihashmap_iterate (ats->peers,ats_map_remove_peer,NULL);
5618 GNUNET_CONTAINER_multihashmap_destroy (ats->peers);
5619 GNUNET_free (ats);
5620}
5621
5622
5623void ats_notify_peer_connect (struct ATS_info * ats,
5624 const struct GNUNET_PeerIdentity *peer,
5625 const struct GNUNET_TRANSPORT_ATS_Information *ats_data)
5626{
5627 int c = 0;
5628#if DEBUG_ATS
5629 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ats_notify_peer_connect: %s\n",GNUNET_i2s(peer));
5630#endif
5631
5632 while (ntohl(ats_data[c].type)!=0)
5633 {
5634#if DEBUG_ATS
5635 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ats type [%i]: %i\n",ntohl(ats_data[c].type), ntohl(ats_data[c].value));
5636#endif
5637 c++;
5638 }
5639 /* check if peer is already known */
5640 if (!GNUNET_CONTAINER_multihashmap_contains (ats->peers,&peer->hashPubKey))
5641 {
5642 struct ATS_peer * p = GNUNET_malloc (sizeof (struct ATS_peer));
5643 memcpy(&p->peer, peer, sizeof (struct GNUNET_PeerIdentity));
5644 GNUNET_CONTAINER_multihashmap_put(ats->peers, &p->peer.hashPubKey, p, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
5645 }
5646
5647 ats_calculate_bandwidth_distribution(ats);
5648}
5649
5650void ats_notify_peer_disconnect (struct ATS_info * ats,
5651 const struct GNUNET_PeerIdentity *peer)
5652{
5653#if DEBUG_ATS
5654 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ats_notify_peer_disconnect: %s\n",GNUNET_i2s(peer));
5655#endif
5656 /* remove peer */
5657 if (GNUNET_CONTAINER_multihashmap_contains (ats->peers, &peer->hashPubKey))
5658 {
5659 ats_map_remove_peer(NULL, &peer->hashPubKey, GNUNET_CONTAINER_multihashmap_get (ats->peers, &peer->hashPubKey));
5660 GNUNET_CONTAINER_multihashmap_remove_all (ats->peers, &peer->hashPubKey);
5661 }
5662
5663 ats_calculate_bandwidth_distribution (ats);
5664}
5665
5666
5667void ats_notify_ats_data (struct ATS_info * ats,
5668 const struct GNUNET_PeerIdentity *peer,
5669 const struct GNUNET_TRANSPORT_ATS_Information *ats_data)
5670{
5671#if DEBUG_ATS
5672 GNUNET_log (GNUNET_ERROR_TYPE_BULK, "ATS_notify_ats_data: %s\n",GNUNET_i2s(peer));
5673#endif
5674 ats_calculate_bandwidth_distribution(ats);
5675}
5491 5676
5492/** 5677/**
5493 * Initiate transport service. 5678 * Initiate transport service.
@@ -5554,6 +5739,7 @@ run (void *cls,
5554 validation_map = NULL; 5739 validation_map = NULL;
5555 return; 5740 return;
5556 } 5741 }
5742 ats = ats_init();
5557 max_connect_per_transport = (uint32_t) tneigh; 5743 max_connect_per_transport = (uint32_t) tneigh;
5558 peerinfo = GNUNET_PEERINFO_connect (cfg); 5744 peerinfo = GNUNET_PEERINFO_connect (cfg);
5559 if (peerinfo == NULL) 5745 if (peerinfo == NULL)