diff options
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r-- | src/transport/gnunet-service-tng.c | 199 |
1 files changed, 130 insertions, 69 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index 1e77937e4..83c057795 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -834,23 +834,9 @@ struct TransportValidationChallengeMessage | |||
834 | struct GNUNET_MessageHeader header; | 834 | struct GNUNET_MessageHeader header; |
835 | 835 | ||
836 | /** | 836 | /** |
837 | * Maximum number of bytes of the flow control window of | 837 | * Always zero. |
838 | * the previous challenge that the sender may consume. | ||
839 | * After sending this message (with a new challenge), | ||
840 | * the sender promises to never use more than this number | ||
841 | * of bytes of the flow control window of a previous | ||
842 | * handshake. Note that the number set here might be larger | ||
843 | * than the actual number the sender will use: to avoid | ||
844 | * a stall, the sender would estimate how long it would | ||
845 | * take to receive a validation response and reserve itself | ||
846 | * a buffer so it can keep sending while waiting for the | ||
847 | * response. Note that the consumption limit must still be | ||
848 | * below the maximum value permitted by the receiver so far. | ||
849 | * | ||
850 | * If this is the first challenge (initial connection | ||
851 | * establishment), this value must be zero. | ||
852 | */ | 838 | */ |
853 | uint32_t last_window_consum_limit GNUNET_PACKED; | 839 | uint32_t reserved GNUNET_PACKED; |
854 | 840 | ||
855 | /** | 841 | /** |
856 | * Challenge to be signed by the receiving peer. | 842 | * Challenge to be signed by the receiving peer. |
@@ -903,11 +889,9 @@ struct TransportValidationResponseMessage | |||
903 | struct GNUNET_MessageHeader header; | 889 | struct GNUNET_MessageHeader header; |
904 | 890 | ||
905 | /** | 891 | /** |
906 | * Flow control window size in bytes, in NBO. | 892 | * Always zero. |
907 | * The receiver can now send this many bytes as per | ||
908 | * the @e challenge "account". | ||
909 | */ | 893 | */ |
910 | uint32_t fc_window_size GNUNET_PACKED; | 894 | uint32_t reserved GNUNET_PACKED; |
911 | 895 | ||
912 | /** | 896 | /** |
913 | * The peer's signature matching the | 897 | * The peer's signature matching the |
@@ -934,6 +918,66 @@ struct TransportValidationResponseMessage | |||
934 | }; | 918 | }; |
935 | 919 | ||
936 | 920 | ||
921 | /** | ||
922 | * Message for Transport-to-Transport Flow control. Specifies the size | ||
923 | * of the flow control window, including how much we believe to have | ||
924 | * consumed (at transmission time), how much we believe to be allowed | ||
925 | * (at transmission time), and how much the other peer is allowed to | ||
926 | * send to us, and how much data we already received from the other | ||
927 | * peer. | ||
928 | */ | ||
929 | struct TransportFlowControlMessage | ||
930 | { | ||
931 | /** | ||
932 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL | ||
933 | */ | ||
934 | struct GNUNET_MessageHeader header; | ||
935 | |||
936 | /** | ||
937 | * Sequence number of the flow control message. Incremented by one | ||
938 | * for each message. Starts at zero when a virtual link goes up. | ||
939 | * Used to detect one-sided connection drops. On wrap-around, the | ||
940 | * flow control counters will be reset as if the connection had | ||
941 | * dropped. | ||
942 | */ | ||
943 | uint32_t seq GNUNET_PACKED; | ||
944 | |||
945 | /** | ||
946 | * Flow control window size in bytes, in NBO. | ||
947 | * The receiver can send this many bytes at most. | ||
948 | */ | ||
949 | uint64_t inbound_window_size GNUNET_PACKED; | ||
950 | |||
951 | /** | ||
952 | * How many bytes has the sender sent that count for flow control at | ||
953 | * this time. Used to allow the receiver to estimate the packet | ||
954 | * loss rate. | ||
955 | */ | ||
956 | uint64_t outbound_sent GNUNET_PACKED; | ||
957 | |||
958 | /** | ||
959 | * Latest flow control window size we learned from the other peer, | ||
960 | * in bytes, in NBO. We are limited to sending at most this many | ||
961 | * bytes to the other peer. May help the other peer detect when | ||
962 | * flow control messages were lost and should thus be retransmitted. | ||
963 | * In particular, if the delta to @e outbound_sent is too small, | ||
964 | * this signals that we are stalled. | ||
965 | */ | ||
966 | uint64_t outbound_window_size GNUNET_PACKED; | ||
967 | |||
968 | /** | ||
969 | * Timestamp of the sender. Must be monotonically increasing! | ||
970 | * Used to enable receiver to ignore out-of-order packets in | ||
971 | * combination with the @e seq. Note that @e seq will go down | ||
972 | * (back to zero) whenever either side believes the connection | ||
973 | * was dropped, allowing the peers to detect that they need to | ||
974 | * reset the counters for the number of bytes sent! | ||
975 | */ | ||
976 | struct GNUNET_TIME_AbsoluteNBO sender_time; | ||
977 | |||
978 | }; | ||
979 | |||
980 | |||
937 | GNUNET_NETWORK_STRUCT_END | 981 | GNUNET_NETWORK_STRUCT_END |
938 | 982 | ||
939 | 983 | ||
@@ -1256,34 +1300,40 @@ struct VirtualLink | |||
1256 | * Distance vector used by this virtual link, NULL if @e n is used. | 1300 | * Distance vector used by this virtual link, NULL if @e n is used. |
1257 | */ | 1301 | */ |
1258 | struct DistanceVector *dv; | 1302 | struct DistanceVector *dv; |
1303 | |||
1304 | /** | ||
1305 | * Last challenge we received from @a n. | ||
1306 | * FIXME: where do we need this? | ||
1307 | */ | ||
1308 | struct ChallengeNonceP n_challenge; | ||
1259 | 1309 | ||
1260 | /** | 1310 | /** |
1261 | * Used to generate unique UUIDs for messages that are being | 1311 | * Last challenge we used with @a n for flow control. |
1262 | * fragmented. | 1312 | * FIXME: where do we need this? |
1263 | */ | 1313 | */ |
1264 | uint64_t message_uuid_ctr; | 1314 | struct ChallengeNonceP my_challenge; |
1265 | 1315 | ||
1266 | /** | 1316 | /** |
1267 | * Sender timestamp of @e n_challenge, used to generate out-of-order | 1317 | * Sender timestamp of @e n_challenge, used to generate out-of-order |
1268 | * challenges (as sender's timestamps must be monotonically | 1318 | * challenges (as sender's timestamps must be monotonically |
1269 | * increasing). Note that we do not persist this monotonic time | 1319 | * increasing). FIXME: where do we need this? |
1270 | * as we do not really have to worry about ancient flow control | ||
1271 | * window sizes after restarts. | ||
1272 | */ | 1320 | */ |
1273 | struct GNUNET_TIME_Absolute n_challenge_time; | 1321 | struct GNUNET_TIME_Absolute n_challenge_time; |
1274 | 1322 | ||
1275 | /** | 1323 | /** |
1276 | * Last challenge we received from @a n, for which we created the | 1324 | * Sender timestamp of the last |
1277 | * flow control window given in @e fc_window_size. | 1325 | * #GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL message we have |
1326 | * received. Note that we do not persist this monotonic time as we | ||
1327 | * do not really have to worry about ancient flow control window | ||
1328 | * sizes after restarts. | ||
1278 | */ | 1329 | */ |
1279 | struct ChallengeNonceP n_challenge; | 1330 | struct GNUNET_TIME_Absolute last_fc_timestamp; |
1280 | 1331 | ||
1281 | /** | 1332 | /** |
1282 | * Last challenge we used with @a n for flow control. If we receive | 1333 | * Used to generate unique UUIDs for messages that are being |
1283 | * window size increases for a different challenge, they are | 1334 | * fragmented. |
1284 | * out-of-order and must be discarded! | ||
1285 | */ | 1335 | */ |
1286 | struct ChallengeNonceP my_challenge; | 1336 | uint64_t message_uuid_ctr; |
1287 | 1337 | ||
1288 | /** | 1338 | /** |
1289 | * Memory allocated for this virtual link. Expresses how much RAM | 1339 | * Memory allocated for this virtual link. Expresses how much RAM |
@@ -1292,7 +1342,7 @@ struct VirtualLink | |||
1292 | * sticking to some overall RAM limit. For now, set to | 1342 | * sticking to some overall RAM limit. For now, set to |
1293 | * #DEFAULT_WINDOW_SIZE. | 1343 | * #DEFAULT_WINDOW_SIZE. |
1294 | */ | 1344 | */ |
1295 | uint32_t available_fc_window_size; | 1345 | uint64_t available_fc_window_size; |
1296 | 1346 | ||
1297 | /** | 1347 | /** |
1298 | * Memory actually used to buffer packets on this virtual link. | 1348 | * Memory actually used to buffer packets on this virtual link. |
@@ -1300,22 +1350,14 @@ struct VirtualLink | |||
1300 | * Note that once CORE is done with a packet, we decrement the value | 1350 | * Note that once CORE is done with a packet, we decrement the value |
1301 | * here. | 1351 | * here. |
1302 | */ | 1352 | */ |
1303 | uint32_t incoming_fc_window_size_ram; | 1353 | uint64_t incoming_fc_window_size_ram; |
1304 | 1354 | ||
1305 | /** | 1355 | /** |
1306 | * Last flow control window size we provided to the other peer, in | 1356 | * Last flow control window size we provided to the other peer, in |
1307 | * bytes. We are allowing the other peer to send this | 1357 | * bytes. We are allowing the other peer to send this |
1308 | * many bytes as per its last @e n_challenge "account". | 1358 | * many bytes. |
1309 | */ | 1359 | */ |
1310 | uint32_t incoming_fc_window_size; | 1360 | uint64_t incoming_fc_window_size; |
1311 | |||
1312 | /** | ||
1313 | * How many bytes could we still get from the previous flow control | ||
1314 | * window, in bytes. We need to consider this value | ||
1315 | * when calculating what we allow for the current window due to | ||
1316 | * the possibility of out-of-order challenges. | ||
1317 | */ | ||
1318 | uint32_t last_fc_window_size_remaining; | ||
1319 | 1361 | ||
1320 | /** | 1362 | /** |
1321 | * How much of the window did the other peer successfully use (and | 1363 | * How much of the window did the other peer successfully use (and |
@@ -1324,23 +1366,49 @@ struct VirtualLink | |||
1324 | * other peer that the window is this much bigger at the next | 1366 | * other peer that the window is this much bigger at the next |
1325 | * opportunity / challenge. | 1367 | * opportunity / challenge. |
1326 | */ | 1368 | */ |
1327 | uint32_t incoming_fc_window_size_used; | 1369 | uint64_t incoming_fc_window_size_used; |
1370 | |||
1371 | /** | ||
1372 | * What is our current estimate on the message loss rate for the sender? | ||
1373 | * Based on the difference between how much the sender sent according | ||
1374 | * to the last #GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL message | ||
1375 | * (@e outbound_sent field) and how much we actually received at that | ||
1376 | * time (@e incoming_fc_window_size_used). This delta is then | ||
1377 | * added onto the @e incoming_fc_window_size when determining the | ||
1378 | * @e outbound_window_size we send to the other peer. Initially zero. | ||
1379 | * May be negative if we (due to out-of-order delivery) actually received | ||
1380 | * more than the sender claims to have sent in its last FC message. | ||
1381 | */ | ||
1382 | int64_t incoming_fc_window_size_loss; | ||
1328 | 1383 | ||
1329 | /** | 1384 | /** |
1330 | * Our current flow control window size in bytes. We | 1385 | * Our current flow control window size in bytes. We |
1331 | * are allowed to transmit this many bytes to @a n as per | 1386 | * are allowed to transmit this many bytes to @a n as per |
1332 | * our @e my_challenge "account". | 1387 | * our @e my_challenge "account". |
1333 | */ | 1388 | */ |
1334 | uint32_t outbound_fc_window_size; | 1389 | uint64_t outbound_fc_window_size; |
1335 | 1390 | ||
1336 | /** | 1391 | /** |
1337 | * How much of our current flow control window size have we | 1392 | * How much of our current flow control window size have we |
1338 | * used (in bytes). Must be below | 1393 | * used (in bytes). Must be below |
1339 | * @e outbound_fc_window_size. | 1394 | * @e outbound_fc_window_size. |
1340 | */ | 1395 | */ |
1341 | uint32_t outbound_fc_window_size_used; | 1396 | uint64_t outbound_fc_window_size_used; |
1397 | |||
1398 | /** | ||
1399 | * Generator for the sequence numbers of | ||
1400 | * #GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL messages we send. | ||
1401 | */ | ||
1402 | uint32_t fc_seq_gen; | ||
1342 | 1403 | ||
1343 | /** | 1404 | /** |
1405 | * Last sequence number of a | ||
1406 | * #GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL message we have | ||
1407 | * received. | ||
1408 | */ | ||
1409 | uint32_t last_fc_seq; | ||
1410 | |||
1411 | /** | ||
1344 | * How many more messages can we send to CORE before we exhaust | 1412 | * How many more messages can we send to CORE before we exhaust |
1345 | * the receive window of CORE for this peer? If this hits zero, | 1413 | * the receive window of CORE for this peer? If this hits zero, |
1346 | * we must tell communicators to stop providing us more messages | 1414 | * we must tell communicators to stop providing us more messages |
@@ -7311,6 +7379,7 @@ check_incoming_msg (void *cls, | |||
7311 | } | 7379 | } |
7312 | 7380 | ||
7313 | 7381 | ||
7382 | #if 0 | ||
7314 | /** | 7383 | /** |
7315 | * We received a @a challenge from another peer, check if we can | 7384 | * We received a @a challenge from another peer, check if we can |
7316 | * increase the flow control window to that peer. | 7385 | * increase the flow control window to that peer. |
@@ -7323,10 +7392,10 @@ check_incoming_msg (void *cls, | |||
7323 | */ | 7392 | */ |
7324 | static void | 7393 | static void |
7325 | update_fc_window (struct VirtualLink *vl, | 7394 | update_fc_window (struct VirtualLink *vl, |
7326 | const struct ChallengeNonceP *challenge, | ||
7327 | struct GNUNET_TIME_Absolute sender_time, | 7395 | struct GNUNET_TIME_Absolute sender_time, |
7328 | uint32_t last_window_consum_limit) | 7396 | uint32_t last_window_consum_limit) |
7329 | { | 7397 | { |
7398 | // FIXME: update to new FC logic | ||
7330 | if (0 == GNUNET_memcmp (challenge, &vl->n_challenge)) | 7399 | if (0 == GNUNET_memcmp (challenge, &vl->n_challenge)) |
7331 | { | 7400 | { |
7332 | uint32_t avail; | 7401 | uint32_t avail; |
@@ -7390,6 +7459,7 @@ update_fc_window (struct VirtualLink *vl, | |||
7390 | vl->last_fc_window_size_remaining, | 7459 | vl->last_fc_window_size_remaining, |
7391 | GNUNET_i2s (&vl->target)); | 7460 | GNUNET_i2s (&vl->target)); |
7392 | } | 7461 | } |
7462 | #endif | ||
7393 | 7463 | ||
7394 | 7464 | ||
7395 | /** | 7465 | /** |
@@ -7592,13 +7662,14 @@ handle_validation_challenge ( | |||
7592 | struct IncomingRequest *ir; | 7662 | struct IncomingRequest *ir; |
7593 | struct Neighbour *n; | 7663 | struct Neighbour *n; |
7594 | 7664 | ||
7595 | /* We use a validity_duration of 0 for DV-routed messages, | 7665 | /* DV-routed messages are not allowed for validation challenges */ |
7596 | as we can neither control the validity and need to allow | ||
7597 | the receiver to tell DV paths from direct connections */ | ||
7598 | if (cmc->total_hops > 0) | 7666 | if (cmc->total_hops > 0) |
7599 | validity_duration = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_ZERO); | 7667 | { |
7600 | else | 7668 | GNUNET_break_op (0); |
7601 | validity_duration = cmc->im.expected_address_validity; | 7669 | finish_cmc_handling (cmc); |
7670 | return; | ||
7671 | } | ||
7672 | validity_duration = cmc->im.expected_address_validity; | ||
7602 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 7673 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
7603 | "Received address validation challenge %s\n", | 7674 | "Received address validation challenge %s\n", |
7604 | GNUNET_sh2s (&tvc->challenge.value)); | 7675 | GNUNET_sh2s (&tvc->challenge.value)); |
@@ -7606,16 +7677,10 @@ handle_validation_challenge ( | |||
7606 | size of the flow control window, and to allow the sender | 7677 | size of the flow control window, and to allow the sender |
7607 | to ask for increases. If for us the virtual link is still down, | 7678 | to ask for increases. If for us the virtual link is still down, |
7608 | we will always give a window size of zero. */ | 7679 | we will always give a window size of zero. */ |
7609 | vl = lookup_virtual_link (&cmc->im.sender); | ||
7610 | if (NULL != vl) | ||
7611 | update_fc_window (vl, | ||
7612 | &tvc->challenge, | ||
7613 | GNUNET_TIME_absolute_ntoh (tvc->sender_time), | ||
7614 | ntohl (tvc->last_window_consum_limit)); | ||
7615 | tvr.header.type = | 7680 | tvr.header.type = |
7616 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE); | 7681 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE); |
7617 | tvr.header.size = htons (sizeof (tvr)); | 7682 | tvr.header.size = htons (sizeof (tvr)); |
7618 | tvr.fc_window_size = htonl ((NULL == vl) ? 0 : vl->incoming_fc_window_size); | 7683 | tvr.reserved = htonl (0); |
7619 | tvr.challenge = tvc->challenge; | 7684 | tvr.challenge = tvc->challenge; |
7620 | tvr.origin_time = tvc->sender_time; | 7685 | tvr.origin_time = tvc->sender_time; |
7621 | tvr.validity_duration = validity_duration; | 7686 | tvr.validity_duration = validity_duration; |
@@ -7635,6 +7700,8 @@ handle_validation_challenge ( | |||
7635 | &tvr.header, | 7700 | &tvr.header, |
7636 | RMO_ANYTHING_GOES | RMO_REDUNDANT); | 7701 | RMO_ANYTHING_GOES | RMO_REDUNDANT); |
7637 | finish_cmc_handling (cmc); | 7702 | finish_cmc_handling (cmc); |
7703 | |||
7704 | vl = lookup_virtual_link (&cmc->im.sender); | ||
7638 | if (NULL != vl) | 7705 | if (NULL != vl) |
7639 | return; | 7706 | return; |
7640 | 7707 | ||
@@ -7898,11 +7965,6 @@ handle_validation_response ( | |||
7898 | { | 7965 | { |
7899 | GNUNET_assert (n == vl->n); | 7966 | GNUNET_assert (n == vl->n); |
7900 | } | 7967 | } |
7901 | if (0 == GNUNET_memcmp (&vl->my_challenge, &tvr->challenge)) | ||
7902 | { | ||
7903 | /* Update window size if the challenge matches */ | ||
7904 | vl->outbound_fc_window_size = ntohl (tvr->fc_window_size); | ||
7905 | } | ||
7906 | return; | 7968 | return; |
7907 | } | 7969 | } |
7908 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 7970 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -7914,7 +7976,6 @@ handle_validation_response ( | |||
7914 | n->vl = vl; | 7976 | n->vl = vl; |
7915 | vl->core_recv_window = RECV_WINDOW_SIZE; | 7977 | vl->core_recv_window = RECV_WINDOW_SIZE; |
7916 | vl->available_fc_window_size = DEFAULT_WINDOW_SIZE; | 7978 | vl->available_fc_window_size = DEFAULT_WINDOW_SIZE; |
7917 | vl->outbound_fc_window_size = ntohl (tvr->fc_window_size); | ||
7918 | vl->my_challenge = tvr->challenge; | 7979 | vl->my_challenge = tvr->challenge; |
7919 | vl->visibility_task = | 7980 | vl->visibility_task = |
7920 | GNUNET_SCHEDULER_add_at (q->validated_until, &check_link_down, vl); | 7981 | GNUNET_SCHEDULER_add_at (q->validated_until, &check_link_down, vl); |
@@ -8912,7 +8973,7 @@ validation_transmit_on_queue (struct Queue *q, struct ValidationState *vs) | |||
8912 | tvc.header.type = | 8973 | tvc.header.type = |
8913 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE); | 8974 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE); |
8914 | tvc.header.size = htons (sizeof (tvc)); | 8975 | tvc.header.size = htons (sizeof (tvc)); |
8915 | tvc.last_window_consum_limit = htonl (vs->last_window_consum_limit); | 8976 | tvc.reserved = htonl (0); |
8916 | tvc.challenge = vs->challenge; | 8977 | tvc.challenge = vs->challenge; |
8917 | tvc.sender_time = GNUNET_TIME_absolute_hton (vs->last_challenge_use); | 8978 | tvc.sender_time = GNUNET_TIME_absolute_hton (vs->last_challenge_use); |
8918 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 8979 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |