aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-04-14 18:13:29 +0000
committerChristian Grothoff <christian@grothoff.org>2010-04-14 18:13:29 +0000
commit9858179cbb2a6b37c7a89f5fd20577a112259f15 (patch)
tree3fcc6cbfa8dd05c936149a18a8a88fab4bdffa5b /src/transport
parentecd595792c22186f1dc610296ad7c1e39b54a902 (diff)
downloadgnunet-9858179cbb2a6b37c7a89f5fd20577a112259f15.tar.gz
gnunet-9858179cbb2a6b37c7a89f5fd20577a112259f15.zip
work in progress
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/gnunet-service-transport.c148
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 */
994static void
995mark_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 */
1677static int
1678remove_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