diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-02-26 18:16:25 +0100 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2019-02-26 18:16:25 +0100 |
commit | 4e8df946bc7fe30a4711a8ffd9b0a737f0b73515 (patch) | |
tree | cb811975afbe356c6cc36382894c826ae978a113 /src/cadet/gnunet-service-cadet_channel.c | |
parent | b34bcbb7859a01d453b0b2717103c840813dd894 (diff) | |
download | gnunet-4e8df946bc7fe30a4711a8ffd9b0a737f0b73515.tar.gz gnunet-4e8df946bc7fe30a4711a8ffd9b0a737f0b73515.zip |
try fix #5597
Diffstat (limited to 'src/cadet/gnunet-service-cadet_channel.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_channel.c | 85 |
1 files changed, 68 insertions, 17 deletions
diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c index 9b434ea68..031da9e4d 100644 --- a/src/cadet/gnunet-service-cadet_channel.c +++ b/src/cadet/gnunet-service-cadet_channel.c | |||
@@ -1306,23 +1306,35 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch, | |||
1306 | &msg[1], | 1306 | &msg[1], |
1307 | payload_size); | 1307 | payload_size); |
1308 | ccc = (NULL != ch->owner) ? ch->owner : ch->dest; | 1308 | ccc = (NULL != ch->owner) ? ch->owner : ch->dest; |
1309 | if ( (GNUNET_YES == ccc->client_ready) && | 1309 | if (GNUNET_YES == ccc->client_ready) |
1310 | ( (GNUNET_YES == ch->out_of_order) || | ||
1311 | (msg->mid.mid == ch->mid_recv.mid) ) ) | ||
1312 | { | 1310 | { |
1313 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1311 | /* |
1314 | "Giving %u bytes of payload with MID %u from %s to client %s\n", | 1312 | * We ad-hoc send the message if |
1315 | (unsigned int) payload_size, | 1313 | * - The channel is out-of-order |
1316 | ntohl (msg->mid.mid), | 1314 | * - The channel is reliable and MID matches next expected MID |
1317 | GCCH_2s (ch), | 1315 | * - The channel is unreliable and MID is before lowest seen MID |
1318 | GSC_2s (ccc->c)); | 1316 | */ |
1319 | ccc->client_ready = GNUNET_NO; | 1317 | if ( (GNUNET_YES == ch->out_of_order) || |
1320 | GSC_send_to_client (ccc->c, | 1318 | ((msg->mid.mid == ch->mid_recv.mid) && |
1321 | env); | 1319 | (GNUNET_YES == ch->reliable)) || |
1322 | ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid)); | 1320 | ((GNUNET_NO == ch->reliable) && |
1323 | ch->mid_futures >>= 1; | 1321 | ((NULL == ccc->head_recv) || |
1324 | send_channel_data_ack (ch); | 1322 | (msg->mid.mid < ccc->head_recv->mid.mid))) ) |
1325 | return; | 1323 | { |
1324 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1325 | "Giving %u bytes of payload with MID %u from %s to client %s\n", | ||
1326 | (unsigned int) payload_size, | ||
1327 | ntohl (msg->mid.mid), | ||
1328 | GCCH_2s (ch), | ||
1329 | GSC_2s (ccc->c)); | ||
1330 | ccc->client_ready = GNUNET_NO; | ||
1331 | GSC_send_to_client (ccc->c, | ||
1332 | env); | ||
1333 | ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid)); | ||
1334 | ch->mid_futures >>= 1; | ||
1335 | send_channel_data_ack (ch); | ||
1336 | return; | ||
1337 | } | ||
1326 | } | 1338 | } |
1327 | 1339 | ||
1328 | if (GNUNET_YES == ch->reliable) | 1340 | if (GNUNET_YES == ch->reliable) |
@@ -1379,6 +1391,45 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch, | |||
1379 | } | 1391 | } |
1380 | else /* ! ch->reliable */ | 1392 | else /* ! ch->reliable */ |
1381 | { | 1393 | { |
1394 | struct CadetOutOfOrderMessage *next_msg; | ||
1395 | |||
1396 | /** | ||
1397 | * We always send if possible in this case. | ||
1398 | * It is guaranteed that the queued MID < received MID | ||
1399 | **/ | ||
1400 | if (GNUNET_YES == ccc->client_ready) | ||
1401 | { | ||
1402 | next_msg = ccc->head_recv; | ||
1403 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1404 | "Giving queued MID %u from %s to client %s\n", | ||
1405 | ntohl (next_msg->mid.mid), | ||
1406 | GCCH_2s (ch), | ||
1407 | GSC_2s (ccc->c)); | ||
1408 | ccc->client_ready = GNUNET_NO; | ||
1409 | GSC_send_to_client (ccc->c, | ||
1410 | next_msg->env); | ||
1411 | ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid)); | ||
1412 | ch->mid_futures >>= 1; | ||
1413 | send_channel_data_ack (ch); | ||
1414 | GNUNET_CONTAINER_DLL_remove (ccc->head_recv, | ||
1415 | ccc->tail_recv, | ||
1416 | next_msg); | ||
1417 | ccc->num_recv--; | ||
1418 | /* Do not process duplicate MID */ | ||
1419 | if (msg->mid.mid == next_msg->mid.mid) | ||
1420 | { | ||
1421 | /* Duplicate within the queue, drop */ | ||
1422 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1423 | "Duplicate message on %s (mid %u) dropped\n", | ||
1424 | GCCH_2s (ch), | ||
1425 | ntohl (msg->mid.mid)); | ||
1426 | GNUNET_free (next_msg); | ||
1427 | GNUNET_MQ_discard (env); | ||
1428 | return; | ||
1429 | } | ||
1430 | GNUNET_free (next_msg); | ||
1431 | } | ||
1432 | |||
1382 | /* Channel is unreliable, so we do not ACK. But we also cannot | 1433 | /* Channel is unreliable, so we do not ACK. But we also cannot |
1383 | allow buffering everything, so check if we have space... */ | 1434 | allow buffering everything, so check if we have space... */ |
1384 | if (ccc->num_recv >= ch->max_pending_messages) | 1435 | if (ccc->num_recv >= ch->max_pending_messages) |
@@ -1584,7 +1635,7 @@ GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch, | |||
1584 | mid_mask = GNUNET_htonll (ack->futures); | 1635 | mid_mask = GNUNET_htonll (ack->futures); |
1585 | found = GNUNET_NO; | 1636 | found = GNUNET_NO; |
1586 | for (crm = ch->head_sent; | 1637 | for (crm = ch->head_sent; |
1587 | NULL != crm; | 1638 | NULL != crm; |
1588 | crm = crmn) | 1639 | crm = crmn) |
1589 | { | 1640 | { |
1590 | crmn = crm->next; | 1641 | crmn = crm->next; |