diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-03-17 16:51:43 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-03-17 16:51:43 +0000 |
commit | 4759a55fd2bba8b4aabef3ef361c8c6183fbe3e5 (patch) | |
tree | 0bdc4f0589ec814515e8b5ad3466017ba182e466 /src | |
parent | 0d23056a4a35f254e930a22f47ae638bf7aea751 (diff) | |
download | gnunet-4759a55fd2bba8b4aabef3ef361c8c6183fbe3e5.tar.gz gnunet-4759a55fd2bba8b4aabef3ef361c8c6183fbe3e5.zip |
adding ats framework
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_transport_service.h | 20 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport.c | 194 |
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 | |||
399 | struct 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 | |||
409 | struct 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; | |||
904 | static struct GNUNET_STATISTICS_Handle *stats; | 904 | static struct GNUNET_STATISTICS_Handle *stats; |
905 | 905 | ||
906 | /** | 906 | /** |
907 | * Handle for ats information | ||
908 | */ | ||
909 | static 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); | |||
927 | static void try_transmission_to_peer (struct NeighbourList *neighbour); | 932 | static void try_transmission_to_peer (struct NeighbourList *neighbour); |
928 | 933 | ||
929 | 934 | ||
935 | struct ATS_info * ats_init (); | ||
936 | |||
937 | void ats_shutdown (struct ATS_info * ats); | ||
938 | |||
939 | void ats_notify_peer_connect (struct ATS_info * ats, | ||
940 | const struct GNUNET_PeerIdentity *peer, | ||
941 | const struct GNUNET_TRANSPORT_ATS_Information *ats_data); | ||
942 | |||
943 | void ats_notify_peer_disconnect (struct ATS_info * ats, | ||
944 | const struct GNUNET_PeerIdentity *peer); | ||
945 | |||
946 | void 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 | |||
2968 | do_blacklist_check (void *cls, | 2997 | do_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, | |||
4732 | static struct GNUNET_TIME_Relative | 4761 | static struct GNUNET_TIME_Relative |
4733 | plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, | 4762 | plugin_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 | ||
5525 | void 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 | |||
5543 | void | ||
5544 | ats_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 | |||
5565 | int 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 | |||
5581 | struct 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 | |||
5608 | void 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 | |||
5623 | void 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 | |||
5650 | void 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 | |||
5667 | void 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) |