aboutsummaryrefslogtreecommitdiff
path: root/src/cadet
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-26 18:34:29 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-26 18:34:29 +0100
commit6adc64ee122e9be37c6b83e9b745719b4d5940b8 (patch)
treeaecaf99f25c4630c07573b7b34472fcf67c4d636 /src/cadet
parent356cd09ec4f7d2c02300d5eae8bec8e6b8e49635 (diff)
downloadgnunet-6adc64ee122e9be37c6b83e9b745719b4d5940b8.tar.gz
gnunet-6adc64ee122e9be37c6b83e9b745719b4d5940b8.zip
implement random packet drop option, fix retransmission logic
Diffstat (limited to 'src/cadet')
-rw-r--r--src/cadet/gnunet-service-cadet-new.c22
-rw-r--r--src/cadet/gnunet-service-cadet-new.h5
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.c29
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.c55
-rw-r--r--src/cadet/gnunet-service-cadet-new_tunnels.c11
5 files changed, 100 insertions, 22 deletions
diff --git a/src/cadet/gnunet-service-cadet-new.c b/src/cadet/gnunet-service-cadet-new.c
index f24c9f518..d40d4f10e 100644
--- a/src/cadet/gnunet-service-cadet-new.c
+++ b/src/cadet/gnunet-service-cadet-new.c
@@ -188,6 +188,11 @@ struct GNUNET_TIME_Relative ratchet_time;
188 */ 188 */
189struct GNUNET_TIME_Relative keepalive_period; 189struct GNUNET_TIME_Relative keepalive_period;
190 190
191/**
192 * Set to non-zero values to create random drops to test retransmissions.
193 */
194unsigned long long drop_percent;
195
191 196
192/** 197/**
193 * Send a message to a client. 198 * Send a message to a client.
@@ -1352,7 +1357,22 @@ run (void *cls,
1352 "need delay value"); 1357 "need delay value");
1353 keepalive_period = GNUNET_TIME_UNIT_MINUTES; 1358 keepalive_period = GNUNET_TIME_UNIT_MINUTES;
1354 } 1359 }
1355 1360 if (GNUNET_OK !=
1361 GNUNET_CONFIGURATION_get_value_number (c,
1362 "CADET",
1363 "DROP_PERCENT",
1364 &drop_percent))
1365 {
1366 drop_percent = 0;
1367 }
1368 else
1369 {
1370 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1371 LOG (GNUNET_ERROR_TYPE_WARNING, "Cadet is running with DROP enabled.\n");
1372 LOG (GNUNET_ERROR_TYPE_WARNING, "This is NOT a good idea!\n");
1373 LOG (GNUNET_ERROR_TYPE_WARNING, "Remove DROP_PERCENT from config file.\n");
1374 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1375 }
1356 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c); 1376 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c);
1357 if (NULL == my_private_key) 1377 if (NULL == my_private_key)
1358 { 1378 {
diff --git a/src/cadet/gnunet-service-cadet-new.h b/src/cadet/gnunet-service-cadet-new.h
index 721044ac4..dff0d3c8c 100644
--- a/src/cadet/gnunet-service-cadet-new.h
+++ b/src/cadet/gnunet-service-cadet-new.h
@@ -235,6 +235,11 @@ extern struct GNUNET_TIME_Relative keepalive_period;
235 */ 235 */
236extern int shutting_down; 236extern int shutting_down;
237 237
238/**
239 * Set to non-zero values to create random drops to test retransmissions.
240 */
241extern unsigned long long drop_percent;
242
238 243
239/** 244/**
240 * Send a message to a client. 245 * Send a message to a client.
diff --git a/src/cadet/gnunet-service-cadet-new_channel.c b/src/cadet/gnunet-service-cadet-new_channel.c
index e55a9a77d..a923f19dc 100644
--- a/src/cadet/gnunet-service-cadet-new_channel.c
+++ b/src/cadet/gnunet-service-cadet-new_channel.c
@@ -1190,6 +1190,8 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
1190 1, 1190 1,
1191 GNUNET_NO); 1191 GNUNET_NO);
1192 GNUNET_MQ_discard (env); 1192 GNUNET_MQ_discard (env);
1193 if (GNUNET_YES == ch->reliable)
1194 send_channel_data_ack (ch);
1193 return; 1195 return;
1194 } 1196 }
1195 1197
@@ -1348,16 +1350,38 @@ GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
1348 crmn = crm->next; 1350 crmn = crm->next;
1349 if (ack->mid.mid == crm->data_message->mid.mid) 1351 if (ack->mid.mid == crm->data_message->mid.mid)
1350 { 1352 {
1353 LOG (GNUNET_ERROR_TYPE_DEBUG,
1354 "Got DATA_ACK with base %u matching message %u on %s\n",
1355 (unsigned int) mid_base,
1356 ntohl (crm->data_message->mid.mid),
1357 GCCH_2s (ch));
1351 handle_matching_ack (ch, 1358 handle_matching_ack (ch,
1352 crm); 1359 crm);
1353 found = GNUNET_YES; 1360 found = GNUNET_YES;
1354 continue; 1361 continue;
1355 } 1362 }
1356 delta = (unsigned int) (ntohl (crm->data_message->mid.mid) - mid_base) - 1; 1363 delta = (unsigned int) (ntohl (crm->data_message->mid.mid) - mid_base) - 1;
1364 if (delta >= UINT_MAX - ch->max_pending_messages)
1365 {
1366 /* overflow, means crm was way in the past, so this ACK counts for it. */
1367 LOG (GNUNET_ERROR_TYPE_DEBUG,
1368 "Got DATA_ACK with base %u past %u on %s\n",
1369 (unsigned int) mid_base,
1370 ntohl (crm->data_message->mid.mid),
1371 GCCH_2s (ch));
1372 handle_matching_ack (ch,
1373 crm);
1374 found = GNUNET_YES;
1375 continue;
1376 }
1357 if (delta >= 64) 1377 if (delta >= 64)
1358 continue; 1378 continue;
1359 if (0 != (mid_mask & (1LLU << delta))) 1379 if (0 != (mid_mask & (1LLU << delta)))
1360 { 1380 {
1381 LOG (GNUNET_ERROR_TYPE_DEBUG,
1382 "Got DATA_ACK with mask for %u on %s\n",
1383 ntohl (crm->data_message->mid.mid),
1384 GCCH_2s (ch));
1361 handle_matching_ack (ch, 1385 handle_matching_ack (ch,
1362 crm); 1386 crm);
1363 found = GNUNET_YES; 1387 found = GNUNET_YES;
@@ -1498,9 +1522,8 @@ data_sent_cb (void *cls)
1498 GCCH_2s (ch), 1522 GCCH_2s (ch),
1499 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (ch->head_sent->next_retry), 1523 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (ch->head_sent->next_retry),
1500 GNUNET_YES)); 1524 GNUNET_YES));
1501 if (crm == ch->head_sent) 1525 if (NULL == ch->head_sent->qe)
1502 { 1526 {
1503 /* We are the new head, need to reschedule retry task */
1504 if (NULL != ch->retry_data_task) 1527 if (NULL != ch->retry_data_task)
1505 GNUNET_SCHEDULER_cancel (ch->retry_data_task); 1528 GNUNET_SCHEDULER_cancel (ch->retry_data_task);
1506 ch->retry_data_task 1529 ch->retry_data_task
@@ -1698,7 +1721,7 @@ GCCH_handle_local_ack (struct CadetChannel *ch,
1698 } 1721 }
1699 1722
1700 LOG (GNUNET_ERROR_TYPE_DEBUG, 1723 LOG (GNUNET_ERROR_TYPE_DEBUG,
1701 "Got LOCAL ACK, passing payload message %u to %s-%X on %s\n", 1724 "Got LOCAL_ACK, passing payload message %u to %s-%X on %s\n",
1702 ntohl (com->mid.mid), 1725 ntohl (com->mid.mid),
1703 GSC_2s (ccc->c), 1726 GSC_2s (ccc->c),
1704 ntohl (ccc->ccn.channel_of_client), 1727 ntohl (ccc->ccn.channel_of_client),
diff --git a/src/cadet/gnunet-service-cadet-new_peer.c b/src/cadet/gnunet-service-cadet-new_peer.c
index fe40d76b6..97bb1378e 100644
--- a/src/cadet/gnunet-service-cadet-new_peer.c
+++ b/src/cadet/gnunet-service-cadet-new_peer.c
@@ -503,6 +503,34 @@ GCP_set_mq (struct CadetPeer *cp,
503 503
504 504
505/** 505/**
506 * Debug function should NEVER return true in production code, useful to
507 * simulate losses for testcases.
508 *
509 * @return #GNUNET_YES or #GNUNET_NO with the decision to drop.
510 */
511static int
512should_I_drop (void)
513{
514 if (0 == drop_percent)
515 return GNUNET_NO;
516 if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
517 101) < drop_percent)
518 return GNUNET_YES;
519 return GNUNET_NO;
520}
521
522
523/**
524 * Function called when CORE took one of the messages from
525 * a message queue manager and transmitted it.
526 *
527 * @param cls the `struct CadetPeeer` where we made progress
528 */
529static void
530mqm_send_done (void *cls);
531
532
533/**
506 * Transmit current envelope from this @a mqm. 534 * Transmit current envelope from this @a mqm.
507 * 535 *
508 * @param mqm mqm to transmit message for now 536 * @param mqm mqm to transmit message for now
@@ -512,10 +540,6 @@ mqm_execute (struct GCP_MessageQueueManager *mqm)
512{ 540{
513 struct CadetPeer *cp = mqm->cp; 541 struct CadetPeer *cp = mqm->cp;
514 542
515 LOG (GNUNET_ERROR_TYPE_DEBUG,
516 "Sending to peer %s from MQM %p\n",
517 GCP_2s (cp),
518 mqm);
519 /* Move entry to the end of the DLL, to be fair. */ 543 /* Move entry to the end of the DLL, to be fair. */
520 if (mqm != cp->mqm_tail) 544 if (mqm != cp->mqm_tail)
521 { 545 {
@@ -526,10 +550,27 @@ mqm_execute (struct GCP_MessageQueueManager *mqm)
526 cp->mqm_tail, 550 cp->mqm_tail,
527 mqm); 551 mqm);
528 } 552 }
529 GNUNET_MQ_send (cp->core_mq,
530 mqm->env);
531 mqm->env = NULL;
532 cp->mqm_ready_counter--; 553 cp->mqm_ready_counter--;
554 if (GNUNET_YES == should_I_drop ())
555 {
556 LOG (GNUNET_ERROR_TYPE_DEBUG,
557 "DROPPING message to peer %s from MQM %p\n",
558 GCP_2s (cp),
559 mqm);
560 GNUNET_MQ_discard (mqm->env);
561 mqm->env = NULL;
562 mqm_send_done (cp);
563 }
564 else
565 {
566 LOG (GNUNET_ERROR_TYPE_DEBUG,
567 "Sending to peer %s from MQM %p\n",
568 GCP_2s (cp),
569 mqm);
570 GNUNET_MQ_send (cp->core_mq,
571 mqm->env);
572 mqm->env = NULL;
573 }
533 mqm->cb (mqm->cb_cls, 574 mqm->cb (mqm->cb_cls,
534 GNUNET_YES); 575 GNUNET_YES);
535} 576}
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c
index 03067a605..592a8c683 100644
--- a/src/cadet/gnunet-service-cadet-new_tunnels.c
+++ b/src/cadet/gnunet-service-cadet-new_tunnels.c
@@ -361,17 +361,6 @@ struct CadetTunnel
361 */ 361 */
362 struct CadetTunnelQueueEntry *tq_tail; 362 struct CadetTunnelQueueEntry *tq_tail;
363 363
364
365 /**
366 * Ephemeral message in the queue (to avoid queueing more than one).
367 */
368 struct CadetConnectionQueue *ephm_hKILL;
369
370 /**
371 * Pong message in the queue.
372 */
373 struct CadetConnectionQueue *pong_hKILL;
374
375 /** 364 /**
376 * How long do we wait until we retry the KX? 365 * How long do we wait until we retry the KX?
377 */ 366 */