aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-11-11 10:53:44 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-11-11 10:53:44 +0000
commit087399c801b807c44e47e4d08723cce88df0a122 (patch)
tree3ebe2bebd825cfe653863958d1cbefd9ed7d5591 /src
parent57a8f1c7659425b80299fffe58abdb9b1a9b1f1f (diff)
downloadgnunet-087399c801b807c44e47e4d08723cce88df0a122.tar.gz
gnunet-087399c801b807c44e47e4d08723cce88df0a122.zip
+ moved outbound quota setting to separate function
+ fixed validation error: race condition between address switching and disconnect
Diffstat (limited to 'src')
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c168
1 files changed, 85 insertions, 83 deletions
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 3a66be148..8e4a13683 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -220,6 +220,12 @@ enum State
220 S_DISCONNECT 220 S_DISCONNECT
221}; 221};
222 222
223enum Address_State
224{
225 USED,
226 UNUSED,
227 FRESH,
228};
223 229
224/** 230/**
225 * Entry in neighbours. 231 * Entry in neighbours.
@@ -341,6 +347,7 @@ struct NeighbourMapEntry
341 * Did we sent an KEEP_ALIVE message and are we expecting a response? 347 * Did we sent an KEEP_ALIVE message and are we expecting a response?
342 */ 348 */
343 int expect_latency_response; 349 int expect_latency_response;
350 int address_state;
344}; 351};
345 352
346 353
@@ -519,6 +526,7 @@ change (struct NeighbourMapEntry *n, int state, int line)
519 return GNUNET_SYSERR; 526 return GNUNET_SYSERR;
520 } 527 }
521#if DEBUG_TRANSPORT 528#if DEBUG_TRANSPORT
529
522 { 530 {
523 char *old = GNUNET_strdup (print_state (n->state)); 531 char *old = GNUNET_strdup (print_state (n->state));
524 char *new = GNUNET_strdup (print_state (state)); 532 char *new = GNUNET_strdup (print_state (state));
@@ -844,6 +852,7 @@ send_disconnect (const struct GNUNET_PeerIdentity *target,
844 return GNUNET_OK; 852 return GNUNET_OK;
845} 853}
846 854
855
847/** 856/**
848 * Disconnect from the given neighbour, clean up the record. 857 * Disconnect from the given neighbour, clean up the record.
849 * 858 *
@@ -876,15 +885,20 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
876 } 885 }
877 886
878 change_state (n, S_DISCONNECT); 887 change_state (n, S_DISCONNECT);
879 GST_validation_set_address_use (&n->id,
880 n->address,
881 n->session,
882 GNUNET_NO);
883 888
884 if (n->state == S_CONNECTED) 889 if (previous_state == S_CONNECTED)
885 { 890 {
886 GNUNET_assert (NULL != n->address); 891 GNUNET_assert (NULL != n->address);
887 GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO); 892 if (n->address_state == USED)
893 {
894 GST_validation_set_address_use (&n->id,
895 n->address,
896 n->session,
897 GNUNET_NO);
898
899 GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO);
900 n->address_state = UNUSED;
901 }
888 } 902 }
889 903
890 if (n->address != NULL) 904 if (n->address != NULL)
@@ -909,7 +923,7 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
909 923
910 switch (previous_state) { 924 switch (previous_state) {
911 case S_CONNECTED: 925 case S_CONNECTED:
912 GNUNET_assert (neighbours_connected > 0); 926// GNUNET_assert (neighbours_connected > 0);
913 neighbours_connected--; 927 neighbours_connected--;
914 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->keepalive_task); 928 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->keepalive_task);
915 GNUNET_SCHEDULER_cancel (n->keepalive_task); 929 GNUNET_SCHEDULER_cancel (n->keepalive_task);
@@ -1080,7 +1094,7 @@ GST_neighbours_stop ()
1080 GNUNET_CONTAINER_multihashmap_iterate (neighbours, &disconnect_all_neighbours, 1094 GNUNET_CONTAINER_multihashmap_iterate (neighbours, &disconnect_all_neighbours,
1081 NULL); 1095 NULL);
1082 GNUNET_CONTAINER_multihashmap_destroy (neighbours); 1096 GNUNET_CONTAINER_multihashmap_destroy (neighbours);
1083 GNUNET_assert (neighbours_connected == 0); 1097// GNUNET_assert (neighbours_connected == 0);
1084 neighbours = NULL; 1098 neighbours = NULL;
1085 callback_cls = NULL; 1099 callback_cls = NULL;
1086 connect_notify_cb = NULL; 1100 connect_notify_cb = NULL;
@@ -1094,6 +1108,21 @@ struct ContinutionContext
1094 struct Session *session; 1108 struct Session *session;
1095}; 1109};
1096 1110
1111static void send_outbound_quota (const struct GNUNET_PeerIdentity *target, struct GNUNET_BANDWIDTH_Value32NBO quota)
1112{
1113 struct QuotaSetMessage q_msg;
1114#if DEBUG_TRANSPORT
1115 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1116 "Sending outbound quota of %u Bps for peer `%s' to all clients\n",
1117 ntohl (quota.value__), GNUNET_i2s (target));
1118#endif
1119 q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
1120 q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
1121 q_msg.quota = quota;
1122 q_msg.peer = (*target);
1123 GST_clients_broadcast (&q_msg.header, GNUNET_NO);
1124}
1125
1097/** 1126/**
1098 * We tried to send a SESSION_CONNECT message to another peer. If this 1127 * We tried to send a SESSION_CONNECT message to another peer. If this
1099 * succeeded, we change the state. If it failed, we should tell 1128 * succeeded, we change the state. If it failed, we should tell
@@ -1155,7 +1184,6 @@ send_connect_continuation (void *cls, const struct GNUNET_PeerIdentity *target,
1155 GNUNET_free (cc); 1184 GNUNET_free (cc);
1156} 1185}
1157 1186
1158
1159/** 1187/**
1160 * We tried to switch addresses with an peer already connected. If it failed, 1188 * We tried to switch addresses with an peer already connected. If it failed,
1161 * we should tell ATS to not use this address anymore (until it is re-validated). 1189 * we should tell ATS to not use this address anymore (until it is re-validated).
@@ -1223,29 +1251,23 @@ send_switch_address_continuation (void *cls,
1223 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1, 1251 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
1224 GNUNET_NO); 1252 GNUNET_NO);
1225 1253
1226 GST_validation_set_address_use (&n->id, 1254 if (n->address_state == FRESH)
1227 cc->address, 1255 {
1228 cc->session, 1256 GST_validation_set_address_use (&n->id,
1229 GNUNET_YES); 1257 cc->address,
1230 1258 cc->session,
1259 GNUNET_YES);
1260 n->address_state = USED;
1261 }
1231 GNUNET_ATS_address_in_use (GST_ats, cc->address, cc->session, GNUNET_YES); 1262 GNUNET_ATS_address_in_use (GST_ats, cc->address, cc->session, GNUNET_YES);
1232 1263
1233 if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK) 1264 if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK)
1234 n->keepalive_task = GNUNET_SCHEDULER_add_now (&neighbour_keepalive_task, n); 1265 n->keepalive_task = GNUNET_SCHEDULER_add_now (&neighbour_keepalive_task, n);
1235 1266
1236 /* Updating quotas */ 1267 /* Updating quotas */
1237 struct QuotaSetMessage q_msg;
1238 GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in); 1268 GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in);
1239#if DEBUG_TRANSPORT 1269 send_outbound_quota(target, n->bandwidth_out);
1240 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1270
1241 "Sending outbound quota of %u Bps for peer `%s' to all clients\n",
1242 ntohl (n->bandwidth_out.value__), GNUNET_i2s (peer));
1243#endif
1244 q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
1245 q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
1246 q_msg.quota = n->bandwidth_out;
1247 q_msg.peer = (*target);
1248 GST_clients_broadcast (&q_msg.header, GNUNET_NO);
1249 default: 1271 default:
1250 break; 1272 break;
1251 } 1273 }
@@ -1369,7 +1391,7 @@ GST_neighbours_switch_to_address_3way (const struct GNUNET_PeerIdentity *peer,
1369 1391
1370 /* checks successful and neighbour != NULL */ 1392 /* checks successful and neighbour != NULL */
1371#if DEBUG_TRANSPORT 1393#if DEBUG_TRANSPORT
1372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1394 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1373 "ATS tells us to switch to address '%s' session %p for peer `%s' in state `%s'\n", 1395 "ATS tells us to switch to address '%s' session %p for peer `%s' in state `%s'\n",
1374 GST_plugins_a2s (address), 1396 GST_plugins_a2s (address),
1375 session, 1397 session,
@@ -1388,40 +1410,33 @@ GST_neighbours_switch_to_address_3way (const struct GNUNET_PeerIdentity *peer,
1388 n->address)) && 1410 n->address)) &&
1389 (n->session == session) ) 1411 (n->session == session) )
1390 { 1412 {
1391 struct QuotaSetMessage q_msg;
1392
1393 n->bandwidth_in = bandwidth_in; 1413 n->bandwidth_in = bandwidth_in;
1394 n->bandwidth_out = bandwidth_out; 1414 n->bandwidth_out = bandwidth_out;
1395 GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in); 1415 GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in);
1396 1416 send_outbound_quota(peer, n->bandwidth_out);
1397#if DEBUG_TRANSPORT
1398 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1399 "Sending outbound quota of %u Bps and inbound quota of %u Bps for peer `%s' to all clients\n",
1400 ntohl (n->bandwidth_out.value__),
1401 ntohl (n->bandwidth_in.value__), GNUNET_i2s (peer));
1402#endif
1403 q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
1404 q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
1405 q_msg.quota = n->bandwidth_out;
1406 q_msg.peer = (*peer);
1407 GST_clients_broadcast (&q_msg.header, GNUNET_NO);
1408 return GNUNET_NO; 1417 return GNUNET_NO;
1409 } 1418 }
1410 if (n->state == S_CONNECTED) 1419 if (n->state == S_CONNECTED)
1411 { 1420 {
1412 /* mark old address as no longer used */ 1421 /* mark old address as no longer used */
1413 GNUNET_assert (NULL != n->address); 1422 GNUNET_assert (NULL != n->address);
1414 GST_validation_set_address_use (&n->id, 1423 if (n->address_state == USED)
1415 n->address, 1424 {
1416 n->session, 1425 GST_validation_set_address_use (&n->id,
1417 GNUNET_NO); 1426 n->address,
1418 GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO); 1427 n->session,
1428 GNUNET_NO);
1429 GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO);
1430 n->address_state = UNUSED;
1431 }
1432
1419 } 1433 }
1420 1434
1421 /* set new address */ 1435 /* set new address */
1422 if (NULL != n->address) 1436 if (NULL != n->address)
1423 GNUNET_HELLO_address_free (n->address); 1437 GNUNET_HELLO_address_free (n->address);
1424 n->address = GNUNET_HELLO_address_copy (address); 1438 n->address = GNUNET_HELLO_address_copy (address);
1439 n->address_state = FRESH;
1425 n->session = session; 1440 n->session = session;
1426 n->bandwidth_in = bandwidth_in; 1441 n->bandwidth_in = bandwidth_in;
1427 n->bandwidth_out = bandwidth_out; 1442 n->bandwidth_out = bandwidth_out;
@@ -1472,10 +1487,6 @@ GST_neighbours_switch_to_address_3way (const struct GNUNET_PeerIdentity *peer,
1472 case S_CONNECTED: 1487 case S_CONNECTED:
1473 case S_FAST_RECONNECT: 1488 case S_FAST_RECONNECT:
1474 /* connected peer is switching addresses or tries fast reconnect*/ 1489 /* connected peer is switching addresses or tries fast reconnect*/
1475 GST_validation_set_address_use (&n->id,
1476 n->address,
1477 n->session,
1478 GNUNET_YES);
1479 msg_len = sizeof (struct SessionConnectMessage); 1490 msg_len = sizeof (struct SessionConnectMessage);
1480 connect_msg.header.size = htons (msg_len); 1491 connect_msg.header.size = htons (msg_len);
1481 connect_msg.header.type = 1492 connect_msg.header.type =
@@ -1652,7 +1663,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
1652 } 1663 }
1653 1664
1654#if DEBUG_TRANSPORT 1665#if DEBUG_TRANSPORT
1655 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %X to peer `%s' ended \n", 1666 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Session %X to peer `%s' ended \n",
1656 session, GNUNET_i2s (peer)); 1667 session, GNUNET_i2s (peer));
1657#endif 1668#endif
1658 1669
@@ -1663,11 +1674,15 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
1663 return; /* doesn't affect us */ 1674 return; /* doesn't affect us */
1664 if (n->state == S_CONNECTED) 1675 if (n->state == S_CONNECTED)
1665 { 1676 {
1666 GST_validation_set_address_use (&n->id, 1677 if (n->address_state == USED)
1667 n->address, 1678 {
1668 n->session, 1679 GST_validation_set_address_use (&n->id,
1669 GNUNET_NO); 1680 n->address,
1670 GNUNET_ATS_address_in_use (GST_ats,n->address, n->session, GNUNET_NO); 1681 n->session,
1682 GNUNET_NO);
1683 GNUNET_ATS_address_in_use (GST_ats,n->address, n->session, GNUNET_NO);
1684 n->address_state = UNUSED;
1685 }
1671 } 1686 }
1672 1687
1673 1688
@@ -2233,7 +2248,6 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
2233 uint32_t ats_count) 2248 uint32_t ats_count)
2234{ 2249{
2235 const struct SessionConnectMessage *scm; 2250 const struct SessionConnectMessage *scm;
2236 struct QuotaSetMessage q_msg;
2237 struct GNUNET_MessageHeader msg; 2251 struct GNUNET_MessageHeader msg;
2238 struct NeighbourMapEntry *n; 2252 struct NeighbourMapEntry *n;
2239 size_t msg_len; 2253 size_t msg_len;
@@ -2284,10 +2298,14 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
2284 GNUNET_assert (NULL != n->address); 2298 GNUNET_assert (NULL != n->address);
2285 2299
2286 change_state (n, S_CONNECTED); 2300 change_state (n, S_CONNECTED);
2287 GST_validation_set_address_use (&n->id, 2301 if (n->address_state == FRESH)
2288 n->address, 2302 {
2289 n->session, 2303 GST_validation_set_address_use (&n->id,
2290 GNUNET_YES); 2304 n->address,
2305 n->session,
2306 GNUNET_YES);
2307 n->address_state = USED;
2308 }
2291 GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_YES); 2309 GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_YES);
2292 2310
2293 GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in); 2311 GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in);
@@ -2324,17 +2342,7 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
2324 __LINE__); 2342 __LINE__);
2325#endif 2343#endif
2326 connect_notify_cb (callback_cls, &n->id, ats, ats_count); 2344 connect_notify_cb (callback_cls, &n->id, ats, ats_count);
2327 2345 send_outbound_quota(peer, n->bandwidth_out);
2328#if DEBUG_TRANSPORT
2329 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2330 "Sending outbound quota of %u Bps for peer `%s' to all clients\n",
2331 ntohl (n->bandwidth_out.value__), GNUNET_i2s (peer));
2332#endif
2333 q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
2334 q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
2335 q_msg.quota = n->bandwidth_out;
2336 q_msg.peer = (*peer);
2337 GST_clients_broadcast (&q_msg.header, GNUNET_NO);
2338 2346
2339} 2347}
2340 2348
@@ -2348,7 +2356,6 @@ GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message,
2348 uint32_t ats_count) 2356 uint32_t ats_count)
2349{ 2357{
2350 struct NeighbourMapEntry *n; 2358 struct NeighbourMapEntry *n;
2351 struct QuotaSetMessage q_msg;
2352 2359
2353#if DEBUG_TRANSPORT 2360#if DEBUG_TRANSPORT
2354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2361 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2391,10 +2398,14 @@ GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message,
2391 2398
2392 if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK) 2399 if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK)
2393 n->keepalive_task = GNUNET_SCHEDULER_add_now (&neighbour_keepalive_task, n); 2400 n->keepalive_task = GNUNET_SCHEDULER_add_now (&neighbour_keepalive_task, n);
2394 GST_validation_set_address_use (&n->id, 2401 if (n->address_state == FRESH)
2402 {
2403 GST_validation_set_address_use (&n->id,
2395 n->address, 2404 n->address,
2396 n->session, 2405 n->session,
2397 GNUNET_YES); 2406 GNUNET_YES);
2407 n->address_state = USED;
2408 }
2398 neighbours_connected++; 2409 neighbours_connected++;
2399 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1, 2410 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
2400 GNUNET_NO); 2411 GNUNET_NO);
@@ -2407,16 +2418,7 @@ GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message,
2407 __LINE__); 2418 __LINE__);
2408#endif 2419#endif
2409 connect_notify_cb (callback_cls, &n->id, ats, ats_count); 2420 connect_notify_cb (callback_cls, &n->id, ats, ats_count);
2410#if DEBUG_TRANSPORT 2421 send_outbound_quota(peer, n->bandwidth_out);
2411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2412 "Sending outbound quota of %u Bps for peer `%s' to all clients\n",
2413 ntohl (n->bandwidth_out.value__), GNUNET_i2s (peer));
2414#endif
2415 q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
2416 q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
2417 q_msg.quota = n->bandwidth_out;
2418 q_msg.peer = (*peer);
2419 GST_clients_broadcast (&q_msg.header, GNUNET_NO);
2420} 2422}
2421 2423
2422struct BlackListCheckContext 2424struct BlackListCheckContext