diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-04-14 18:13:29 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-04-14 18:13:29 +0000 |
commit | 9858179cbb2a6b37c7a89f5fd20577a112259f15 (patch) | |
tree | 3fcc6cbfa8dd05c936149a18a8a88fab4bdffa5b /src/transport | |
parent | ecd595792c22186f1dc610296ad7c1e39b54a902 (diff) | |
download | gnunet-9858179cbb2a6b37c7a89f5fd20577a112259f15.tar.gz gnunet-9858179cbb2a6b37c7a89f5fd20577a112259f15.zip |
work in progress
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/gnunet-service-transport.c | 148 |
1 files changed, 107 insertions, 41 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 543033c1d..bb23c1b21 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -24,13 +24,14 @@ | |||
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * | 25 | * |
26 | * TODO: | 26 | * TODO: |
27 | * - Need to validate *inbound* bi-directional transports (i.e., TCP) | 27 | * - Need to SIGNAL connection in 'mark_address_connected' |
28 | * using PING-PONG and then SIGNAL 'connected' to core/etc.! | 28 | * (if cnt == GNUNET_YES at the end!) |
29 | * (currently we neither validate those nor do we signal the | 29 | * - Need to SIGNAL disconnect when we no longer have any validated |
30 | * connection); only after those, we should transmit data | 30 | * address (NAT case!) |
31 | * (we currently send and receive arbitrary data on inbound TCP | 31 | * - Need to defer forwarding messages until after CONNECT message |
32 | * connections even if they have not been validated and hand it | 32 | * - MIGHT want to track connected state with neighbour |
33 | * to our clients!) | 33 | * - CHECK that 'address' being NULL in 'struct ForeignAddressList' is |
34 | * tolerated in the code everywhere (could not happen before) | ||
34 | * | 35 | * |
35 | * NOTE: | 36 | * NOTE: |
36 | * - This code uses 'GNUNET_a2s' for debug printing in many places, | 37 | * - This code uses 'GNUNET_a2s' for debug printing in many places, |
@@ -716,6 +717,11 @@ struct ValidationEntry | |||
716 | struct GNUNET_TIME_Absolute send_time; | 717 | struct GNUNET_TIME_Absolute send_time; |
717 | 718 | ||
718 | /** | 719 | /** |
720 | * Session being validated (or NULL for none). | ||
721 | */ | ||
722 | struct Session *session; | ||
723 | |||
724 | /** | ||
719 | * Length of addr. | 725 | * Length of addr. |
720 | */ | 726 | */ |
721 | size_t addrlen; | 727 | size_t addrlen; |
@@ -979,6 +985,42 @@ transmit_to_client_callback (void *cls, size_t size, void *buf) | |||
979 | 985 | ||
980 | 986 | ||
981 | /** | 987 | /** |
988 | * Mark the given FAL entry as 'connected' (and hence preferred for | ||
989 | * sending); also mark all others for the same peer as 'not connected' | ||
990 | * (since only one can be preferred). | ||
991 | * | ||
992 | * @param fal address to set to 'connected' | ||
993 | */ | ||
994 | static void | ||
995 | mark_address_connected (struct ForeignAddressList *fal) | ||
996 | { | ||
997 | struct ForeignAddressList *pos; | ||
998 | int cnt; | ||
999 | |||
1000 | if (fal->connected == GNUNET_YES) | ||
1001 | return; /* nothing to do */ | ||
1002 | cnt = GNUNET_YES; | ||
1003 | pos = fal->ready_list->addresses; | ||
1004 | while (pos != NULL) | ||
1005 | { | ||
1006 | if (GNUNET_YES == pos->connected) | ||
1007 | { | ||
1008 | GNUNET_break (cnt == GNUNET_YES); | ||
1009 | cnt = GNUNET_NO; | ||
1010 | pos->connected = GNUNET_NO; | ||
1011 | } | ||
1012 | pos = pos->next; | ||
1013 | } | ||
1014 | fal->connected = GNUNET_YES; | ||
1015 | if (GNUNET_YES == cnt) | ||
1016 | GNUNET_STATISTICS_update (stats, | ||
1017 | gettext_noop ("# connected addresses"), | ||
1018 | 1, | ||
1019 | GNUNET_NO); | ||
1020 | } | ||
1021 | |||
1022 | |||
1023 | /** | ||
982 | * Send the specified message to the specified client. Since multiple | 1024 | * Send the specified message to the specified client. Since multiple |
983 | * messages may be pending for the same client at a time, this code | 1025 | * messages may be pending for the same client at a time, this code |
984 | * makes sure that no message is lost. | 1026 | * makes sure that no message is lost. |
@@ -1098,14 +1140,7 @@ transmit_send_continuation (void *cls, | |||
1098 | mq->specific_address->timeout = | 1140 | mq->specific_address->timeout = |
1099 | GNUNET_TIME_relative_to_absolute | 1141 | GNUNET_TIME_relative_to_absolute |
1100 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | 1142 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); |
1101 | if (mq->specific_address->connected != GNUNET_YES) | 1143 | mark_address_connected (mq->specific_address); |
1102 | { | ||
1103 | GNUNET_STATISTICS_update (stats, | ||
1104 | gettext_noop ("# connected addresses"), | ||
1105 | 1, | ||
1106 | GNUNET_NO); | ||
1107 | mq->specific_address->connected = GNUNET_YES; | ||
1108 | } | ||
1109 | } | 1144 | } |
1110 | else | 1145 | else |
1111 | { | 1146 | { |
@@ -1631,6 +1666,29 @@ expire_address_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1631 | 1666 | ||
1632 | 1667 | ||
1633 | /** | 1668 | /** |
1669 | * Iterator over hash map entries that NULLs the session of validation | ||
1670 | * entries that match the given session. | ||
1671 | * | ||
1672 | * @param cls closure (the 'struct Session*' to match against) | ||
1673 | * @param key current key code (peer ID, not used) | ||
1674 | * @param value value in the hash map ('struct ValidationEntry*') | ||
1675 | * @return GNUNET_YES (we should continue to iterate) | ||
1676 | */ | ||
1677 | static int | ||
1678 | remove_session_validations (void *cls, | ||
1679 | const GNUNET_HashCode * key, | ||
1680 | void *value) | ||
1681 | { | ||
1682 | struct Session *session = cls; | ||
1683 | struct ValidationEntry *ve = value; | ||
1684 | |||
1685 | if (session == ve->session) | ||
1686 | ve->session = NULL; | ||
1687 | return GNUNET_YES; | ||
1688 | } | ||
1689 | |||
1690 | |||
1691 | /** | ||
1634 | * Function that will be called whenever the plugin internally | 1692 | * Function that will be called whenever the plugin internally |
1635 | * cleans up a session pointer and hence the service needs to | 1693 | * cleans up a session pointer and hence the service needs to |
1636 | * discard all of those sessions as well. Plugins that do not | 1694 | * discard all of those sessions as well. Plugins that do not |
@@ -1652,6 +1710,9 @@ plugin_env_session_end (void *cls, | |||
1652 | struct ForeignAddressList *pos; | 1710 | struct ForeignAddressList *pos; |
1653 | struct ForeignAddressList *prev; | 1711 | struct ForeignAddressList *prev; |
1654 | 1712 | ||
1713 | GNUNET_CONTAINER_multihashmap_iterate (validation_map, | ||
1714 | &remove_session_validations, | ||
1715 | session); | ||
1655 | nl = find_neighbour (peer); | 1716 | nl = find_neighbour (peer); |
1656 | if (nl == NULL) | 1717 | if (nl == NULL) |
1657 | return; | 1718 | return; |
@@ -1877,8 +1938,15 @@ add_peer_address (struct NeighbourList *neighbour, | |||
1877 | return NULL; | 1938 | return NULL; |
1878 | ret = GNUNET_malloc(sizeof(struct ForeignAddressList) + addrlen); | 1939 | ret = GNUNET_malloc(sizeof(struct ForeignAddressList) + addrlen); |
1879 | ret->session = session; | 1940 | ret->session = session; |
1880 | ret->addr = (const char*) &ret[1]; | 1941 | if (addrlen > 0) |
1881 | memcpy (&ret[1], addr, addrlen); | 1942 | { |
1943 | ret->addr = (const char*) &ret[1]; | ||
1944 | memcpy (&ret[1], addr, addrlen); | ||
1945 | } | ||
1946 | else | ||
1947 | { | ||
1948 | ret->addr = NULL; | ||
1949 | } | ||
1882 | ret->addrlen = addrlen; | 1950 | ret->addrlen = addrlen; |
1883 | ret->expires = GNUNET_TIME_relative_to_absolute | 1951 | ret->expires = GNUNET_TIME_relative_to_absolute |
1884 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | 1952 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); |
@@ -2302,6 +2370,7 @@ send_periodic_ping (void *cls, | |||
2302 | va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | 2370 | va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
2303 | (unsigned int) -1); | 2371 | (unsigned int) -1); |
2304 | va->send_time = GNUNET_TIME_absolute_get(); | 2372 | va->send_time = GNUNET_TIME_absolute_get(); |
2373 | va->session = peer_address->session; | ||
2305 | va->addr = (const void*) &va[1]; | 2374 | va->addr = (const void*) &va[1]; |
2306 | memcpy (&va[1], peer_address->addr, peer_address->addrlen); | 2375 | memcpy (&va[1], peer_address->addr, peer_address->addrlen); |
2307 | va->addrlen = peer_address->addrlen; | 2376 | va->addrlen = peer_address->addrlen; |
@@ -2431,12 +2500,13 @@ check_pending_validation (void *cls, | |||
2431 | } | 2500 | } |
2432 | 2501 | ||
2433 | #if DEBUG_TRANSPORT | 2502 | #if DEBUG_TRANSPORT |
2434 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2503 | if (ve->addr != NULL) |
2435 | "Confirmed validity of address, peer `%4s' has address `%s' (%s).\n", | 2504 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2436 | GNUNET_h2s (key), | 2505 | "Confirmed validity of address, peer `%4s' has address `%s' (%s).\n", |
2437 | GNUNET_a2s ((const struct sockaddr *) ve->addr, | 2506 | GNUNET_h2s (key), |
2438 | ve->addrlen), | 2507 | GNUNET_a2s ((const struct sockaddr *) ve->addr, |
2439 | ve->transport_name); | 2508 | ve->addrlen), |
2509 | ve->transport_name); | ||
2440 | #endif | 2510 | #endif |
2441 | GNUNET_STATISTICS_update (stats, | 2511 | GNUNET_STATISTICS_update (stats, |
2442 | gettext_noop ("# address validation successes"), | 2512 | gettext_noop ("# address validation successes"), |
@@ -2462,12 +2532,13 @@ check_pending_validation (void *cls, | |||
2462 | n->public_key_valid = GNUNET_YES; | 2532 | n->public_key_valid = GNUNET_YES; |
2463 | fal = add_peer_address (n, | 2533 | fal = add_peer_address (n, |
2464 | ve->transport_name, | 2534 | ve->transport_name, |
2465 | NULL, | 2535 | ve->session, |
2466 | ve->addr, | 2536 | ve->addr, |
2467 | ve->addrlen); | 2537 | ve->addrlen); |
2468 | GNUNET_assert (fal != NULL); | 2538 | GNUNET_assert (fal != NULL); |
2469 | fal->expires = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); | 2539 | fal->expires = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); |
2470 | fal->validated = GNUNET_YES; | 2540 | fal->validated = GNUNET_YES; |
2541 | mark_address_connected (fal); | ||
2471 | GNUNET_STATISTICS_update (stats, | 2542 | GNUNET_STATISTICS_update (stats, |
2472 | gettext_noop ("# peer addresses considered valid"), | 2543 | gettext_noop ("# peer addresses considered valid"), |
2473 | 1, | 2544 | 1, |
@@ -2675,7 +2746,7 @@ run_validation (void *cls, | |||
2675 | neighbour = setup_new_neighbour(&id); | 2746 | neighbour = setup_new_neighbour(&id); |
2676 | neighbour->publicKey = va->publicKey; | 2747 | neighbour->publicKey = va->publicKey; |
2677 | neighbour->public_key_valid = GNUNET_YES; | 2748 | neighbour->public_key_valid = GNUNET_YES; |
2678 | peer_address = add_peer_address(neighbour, tname, NULL, addr, addrlen); | 2749 | peer_address = add_peer_address (neighbour, tname, NULL, addr, addrlen); |
2679 | GNUNET_assert(peer_address != NULL); | 2750 | GNUNET_assert(peer_address != NULL); |
2680 | hello_size = GNUNET_HELLO_size(our_hello); | 2751 | hello_size = GNUNET_HELLO_size(our_hello); |
2681 | tsize = sizeof(struct TransportPingMessage) + hello_size; | 2752 | tsize = sizeof(struct TransportPingMessage) + hello_size; |
@@ -3184,31 +3255,26 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3184 | 3255 | ||
3185 | n = find_neighbour (peer); | 3256 | n = find_neighbour (peer); |
3186 | if (n == NULL) | 3257 | if (n == NULL) |
3187 | n = setup_new_neighbour (peer); | 3258 | n = setup_new_neighbour (peer); |
3188 | service_context = n->plugins; | 3259 | service_context = n->plugins; |
3189 | while ((service_context != NULL) && (plugin != service_context->plugin)) | 3260 | while ((service_context != NULL) && (plugin != service_context->plugin)) |
3190 | service_context = service_context->next; | 3261 | service_context = service_context->next; |
3191 | GNUNET_assert ((plugin->api->send == NULL) || (service_context != NULL)); | 3262 | GNUNET_assert ((plugin->api->send == NULL) || (service_context != NULL)); |
3263 | peer_address = NULL; | ||
3192 | if (message != NULL) | 3264 | if (message != NULL) |
3193 | { | 3265 | { |
3194 | peer_address = add_peer_address(n, | 3266 | if ( (session != NULL) || |
3195 | plugin->short_name, | 3267 | (sender_address != NULL) ) |
3196 | session, | 3268 | peer_address = add_peer_address (n, |
3197 | sender_address, | 3269 | plugin->short_name, |
3198 | sender_address_len); | 3270 | session, |
3271 | sender_address, | ||
3272 | sender_address_len); | ||
3199 | if (peer_address != NULL) | 3273 | if (peer_address != NULL) |
3200 | { | 3274 | { |
3201 | peer_address->distance = distance; | 3275 | peer_address->distance = distance; |
3202 | if (peer_address->connected == GNUNET_NO) | 3276 | if (GNUNET_YES == peer_address->validated) |
3203 | { | 3277 | mark_address_connected (peer_address); |
3204 | /* FIXME: be careful here to not mark | ||
3205 | MULTIPLE addresses as connected! */ | ||
3206 | peer_address->connected = GNUNET_YES; | ||
3207 | GNUNET_STATISTICS_update (stats, | ||
3208 | gettext_noop ("# connected addresses"), | ||
3209 | 1, | ||
3210 | GNUNET_NO); | ||
3211 | } | ||
3212 | peer_address->timeout | 3278 | peer_address->timeout |
3213 | = | 3279 | = |
3214 | GNUNET_TIME_relative_to_absolute | 3280 | GNUNET_TIME_relative_to_absolute |