aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_channel.c
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2019-02-26 18:16:25 +0100
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2019-02-26 18:16:25 +0100
commit4e8df946bc7fe30a4711a8ffd9b0a737f0b73515 (patch)
treecb811975afbe356c6cc36382894c826ae978a113 /src/cadet/gnunet-service-cadet_channel.c
parentb34bcbb7859a01d453b0b2717103c840813dd894 (diff)
downloadgnunet-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.c85
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;