aboutsummaryrefslogtreecommitdiff
path: root/src/rps
diff options
context:
space:
mode:
Diffstat (limited to 'src/rps')
-rw-r--r--src/rps/gnunet-rps-profiler.c284
-rw-r--r--src/rps/gnunet-service-rps.c676
-rw-r--r--src/rps/gnunet-service-rps_custommap.c2
-rw-r--r--src/rps/rps-test_util.c80
4 files changed, 621 insertions, 421 deletions
diff --git a/src/rps/gnunet-rps-profiler.c b/src/rps/gnunet-rps-profiler.c
index 16f23e86c..49714872f 100644
--- a/src/rps/gnunet-rps-profiler.c
+++ b/src/rps/gnunet-rps-profiler.c
@@ -49,7 +49,11 @@ static unsigned bits_needed;
49/** 49/**
50 * How long do we run the test? 50 * How long do we run the test?
51 */ 51 */
52//#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) 52static struct GNUNET_TIME_Relative duration;
53
54/**
55 * When do we do a hard shutdown?
56 */
53static struct GNUNET_TIME_Relative timeout; 57static struct GNUNET_TIME_Relative timeout;
54 58
55 59
@@ -446,6 +450,10 @@ struct RPSPeer
446 * @brief statistics values 450 * @brief statistics values
447 */ 451 */
448 uint64_t stats[STAT_TYPE_MAX]; 452 uint64_t stats[STAT_TYPE_MAX];
453 /**
454 * @brief Handle for the statistics get request
455 */
456 struct GNUNET_STATISTICS_GetHandle *h_stat_get[STAT_TYPE_MAX];
449}; 457};
450 458
451/** 459/**
@@ -489,15 +497,16 @@ static unsigned int view_sizes;
489static int ok; 497static int ok;
490 498
491/** 499/**
492 * Identifier for the churn task that runs periodically 500 * Identifier for the task that runs after the test to collect results
493 */ 501 */
494static struct GNUNET_SCHEDULER_Task *post_test_task; 502static struct GNUNET_SCHEDULER_Task *post_test_task;
495 503
496/** 504/**
497 * Identifier for the churn task that runs periodically 505 * Identifier for the shutdown task
498 */ 506 */
499static struct GNUNET_SCHEDULER_Task *shutdown_task; 507static struct GNUNET_SCHEDULER_Task *shutdown_task;
500 508
509
501/** 510/**
502 * Identifier for the churn task that runs periodically 511 * Identifier for the churn task that runs periodically
503 */ 512 */
@@ -874,6 +883,75 @@ static int check_statistics_collect_completed ()
874 return GNUNET_YES; 883 return GNUNET_YES;
875} 884}
876 885
886static void
887rps_disconnect_adapter (void *cls,
888 void *op_result);
889
890static void
891cancel_pending_req (struct PendingRequest *pending_req)
892{
893 struct RPSPeer *rps_peer;
894
895 rps_peer = pending_req->rps_peer;
896 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_req_head,
897 rps_peer->pending_req_tail,
898 pending_req);
899 rps_peer->num_pending_reqs--;
900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
901 "Cancelling pending rps get request\n");
902 GNUNET_SCHEDULER_cancel (pending_req->request_task);
903 GNUNET_free (pending_req);
904}
905
906static void
907cancel_request (struct PendingReply *pending_rep)
908{
909 struct RPSPeer *rps_peer;
910
911 rps_peer = pending_rep->rps_peer;
912 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_rep_head,
913 rps_peer->pending_rep_tail,
914 pending_rep);
915 rps_peer->num_pending_reps--;
916 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
917 "Cancelling rps get reply\n");
918 GNUNET_RPS_request_cancel (pending_rep->req_handle);
919 GNUNET_free (pending_rep);
920}
921
922void
923clean_peer (unsigned peer_index)
924{
925 struct PendingRequest *pending_req;
926
927 while (NULL != (pending_req = rps_peers[peer_index].pending_req_head))
928 {
929 cancel_pending_req (pending_req);
930 }
931 pending_req = rps_peers[peer_index].pending_req_head;
932 rps_disconnect_adapter (&rps_peers[peer_index],
933 &rps_peers[peer_index].rps_handle);
934 for (unsigned stat_type = STAT_TYPE_ROUNDS;
935 stat_type < STAT_TYPE_MAX;
936 stat_type++)
937 {
938 if (NULL != rps_peers[peer_index].h_stat_get[stat_type])
939 {
940 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
941 "(%u) did not yet receive stat value for `%s'\n",
942 rps_peers[peer_index].index,
943 stat_type_2_str (stat_type));
944 GNUNET_STATISTICS_get_cancel (
945 rps_peers[peer_index].h_stat_get[stat_type]);
946 }
947 }
948 if (NULL != rps_peers[peer_index].op)
949 {
950 GNUNET_TESTBED_operation_done (rps_peers[peer_index].op);
951 rps_peers[peer_index].op = NULL;
952 }
953}
954
877/** 955/**
878 * Task run on timeout to shut everything down. 956 * Task run on timeout to shut everything down.
879 */ 957 */
@@ -881,35 +959,55 @@ static void
881shutdown_op (void *cls) 959shutdown_op (void *cls)
882{ 960{
883 unsigned int i; 961 unsigned int i;
962 struct OpListEntry *entry;
884 963
885 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 964 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
886 "Shutdown task scheduled, going down.\n"); 965 "Shutdown task scheduled, going down.\n");
887 in_shutdown = GNUNET_YES; 966 in_shutdown = GNUNET_YES;
967
968 if (NULL != shutdown_task)
969 {
970 GNUNET_SCHEDULER_cancel (shutdown_task);
971 shutdown_task = NULL;
972 }
888 if (NULL != post_test_task) 973 if (NULL != post_test_task)
889 { 974 {
890 GNUNET_SCHEDULER_cancel (post_test_task); 975 GNUNET_SCHEDULER_cancel (post_test_task);
976 post_test_task = NULL;
891 } 977 }
892 if (NULL != churn_task) 978 if (NULL != churn_task)
893 { 979 {
894 GNUNET_SCHEDULER_cancel (churn_task); 980 GNUNET_SCHEDULER_cancel (churn_task);
895 churn_task = NULL; 981 churn_task = NULL;
896 } 982 }
983 entry = oplist_head;
984 while (NULL != (entry = oplist_head))
985 {
986 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
987 "Operation still pending on shutdown (%u)\n",
988 entry->index);
989 GNUNET_TESTBED_operation_done (entry->op);
990 GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
991 GNUNET_free (entry);
992 }
897 for (i = 0; i < num_peers; i++) 993 for (i = 0; i < num_peers; i++)
898 { 994 {
899 if (NULL != rps_peers[i].rps_handle) 995 clean_peer (i);
900 {
901 GNUNET_RPS_disconnect (rps_peers[i].rps_handle);
902 }
903 if (NULL != rps_peers[i].op)
904 {
905 GNUNET_TESTBED_operation_done (rps_peers[i].op);
906 }
907 } 996 }
908} 997}
909 998
999static void
1000trigger_shutdown (void *cls)
1001{
1002 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1003 "Shutdown was triggerd by timeout, going down.\n");
1004 shutdown_task = NULL;
1005 GNUNET_SCHEDULER_shutdown ();
1006}
1007
910 1008
911/** 1009/**
912 * Task run on timeout to collect statistics and potentially shut down. 1010 * Task run after #duration to collect statistics and potentially shut down.
913 */ 1011 */
914static void 1012static void
915post_test_op (void *cls) 1013post_test_op (void *cls)
@@ -919,7 +1017,7 @@ post_test_op (void *cls)
919 post_test_task = NULL; 1017 post_test_task = NULL;
920 post_test = GNUNET_YES; 1018 post_test = GNUNET_YES;
921 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1019 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
922 "Post test task scheduled, going down.\n"); 1020 "Post test task scheduled.\n");
923 if (NULL != churn_task) 1021 if (NULL != churn_task)
924 { 1022 {
925 GNUNET_SCHEDULER_cancel (churn_task); 1023 GNUNET_SCHEDULER_cancel (churn_task);
@@ -943,7 +1041,7 @@ post_test_op (void *cls)
943 GNUNET_YES == check_statistics_collect_completed()) 1041 GNUNET_YES == check_statistics_collect_completed())
944 { 1042 {
945 GNUNET_SCHEDULER_cancel (shutdown_task); 1043 GNUNET_SCHEDULER_cancel (shutdown_task);
946 shutdown_task = GNUNET_SCHEDULER_add_now (&shutdown_op, NULL); 1044 shutdown_task = NULL;
947 GNUNET_SCHEDULER_shutdown (); 1045 GNUNET_SCHEDULER_shutdown ();
948 } 1046 }
949} 1047}
@@ -1030,9 +1128,9 @@ info_cb (void *cb_cls,
1030 */ 1128 */
1031static void 1129static void
1032rps_connect_complete_cb (void *cls, 1130rps_connect_complete_cb (void *cls,
1033 struct GNUNET_TESTBED_Operation *op, 1131 struct GNUNET_TESTBED_Operation *op,
1034 void *ca_result, 1132 void *ca_result,
1035 const char *emsg) 1133 const char *emsg)
1036{ 1134{
1037 struct RPSPeer *rps_peer = cls; 1135 struct RPSPeer *rps_peer = cls;
1038 struct GNUNET_RPS_Handle *rps = ca_result; 1136 struct GNUNET_RPS_Handle *rps = ca_result;
@@ -1057,7 +1155,9 @@ rps_connect_complete_cb (void *cls,
1057 return; 1155 return;
1058 } 1156 }
1059 1157
1060 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started client successfully\n"); 1158 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1159 "Started client successfully (%u)\n",
1160 rps_peer->index);
1061 1161
1062 cur_test_run.main_test (rps_peer); 1162 cur_test_run.main_test (rps_peer);
1063} 1163}
@@ -1075,7 +1175,7 @@ rps_connect_complete_cb (void *cls,
1075 */ 1175 */
1076static void * 1176static void *
1077rps_connect_adapter (void *cls, 1177rps_connect_adapter (void *cls,
1078 const struct GNUNET_CONFIGURATION_Handle *cfg) 1178 const struct GNUNET_CONFIGURATION_Handle *cfg)
1079{ 1179{
1080 struct GNUNET_RPS_Handle *h; 1180 struct GNUNET_RPS_Handle *h;
1081 1181
@@ -1167,15 +1267,26 @@ stat_complete_cb (void *cls, struct GNUNET_TESTBED_Operation *op,
1167 */ 1267 */
1168static void 1268static void
1169rps_disconnect_adapter (void *cls, 1269rps_disconnect_adapter (void *cls,
1170 void *op_result) 1270 void *op_result)
1171{ 1271{
1172 struct RPSPeer *peer = cls; 1272 struct RPSPeer *peer = cls;
1173 struct GNUNET_RPS_Handle *h = op_result; 1273 struct GNUNET_RPS_Handle *h = op_result;
1274 struct PendingReply *pending_rep;
1174 1275
1175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "disconnect_adapter()\n"); 1276 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1277 "disconnect_adapter (%u)\n",
1278 peer->index);
1176 GNUNET_assert (NULL != peer); 1279 GNUNET_assert (NULL != peer);
1177 GNUNET_RPS_disconnect (h); 1280 if (NULL != peer->rps_handle)
1178 peer->rps_handle = NULL; 1281 {
1282 while (NULL != (pending_rep = peer->pending_rep_head))
1283 {
1284 cancel_request (pending_rep);
1285 }
1286 GNUNET_assert (h == peer->rps_handle);
1287 GNUNET_RPS_disconnect (h);
1288 peer->rps_handle = NULL;
1289 }
1179} 1290}
1180 1291
1181 1292
@@ -1219,13 +1330,15 @@ default_reply_handle (void *cls,
1219 rps_peer->num_recv_ids++; 1330 rps_peer->num_recv_ids++;
1220 } 1331 }
1221 1332
1222 if (0 == evaluate () && HAVE_QUICK_QUIT == cur_test_run.have_quick_quit) 1333 if (GNUNET_YES != post_test) return;
1334 if (HAVE_QUICK_QUIT != cur_test_run.have_quick_quit) return;
1335 if (0 == evaluate())
1223 { 1336 {
1224 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test succeeded before timeout\n"); 1337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1225 GNUNET_assert (NULL != post_test_task); 1338 "Test succeeded before end of duration\n");
1226 GNUNET_SCHEDULER_cancel (post_test_task); 1339 if (NULL != post_test_task) GNUNET_SCHEDULER_cancel (post_test_task);
1227 post_test_task = GNUNET_SCHEDULER_add_now (&post_test_op, NULL); 1340 post_test_task = GNUNET_SCHEDULER_add_now (&post_test_op, NULL);
1228 GNUNET_assert (NULL!= post_test_task); 1341 GNUNET_assert (NULL != post_test_task);
1229 } 1342 }
1230} 1343}
1231 1344
@@ -1239,13 +1352,13 @@ request_peers (void *cls)
1239 struct RPSPeer *rps_peer; 1352 struct RPSPeer *rps_peer;
1240 struct PendingReply *pending_rep; 1353 struct PendingReply *pending_rep;
1241 1354
1242 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1243 return;
1244 rps_peer = pending_req->rps_peer; 1355 rps_peer = pending_req->rps_peer;
1245 GNUNET_assert (1 <= rps_peer->num_pending_reqs); 1356 GNUNET_assert (1 <= rps_peer->num_pending_reqs);
1246 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_req_head, 1357 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_req_head,
1247 rps_peer->pending_req_tail, 1358 rps_peer->pending_req_tail,
1248 pending_req); 1359 pending_req);
1360 rps_peer->num_pending_reqs--;
1361 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test) return;
1249 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1362 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1250 "Requesting one peer\n"); 1363 "Requesting one peer\n");
1251 pending_rep = GNUNET_new (struct PendingReply); 1364 pending_rep = GNUNET_new (struct PendingReply);
@@ -1258,39 +1371,6 @@ request_peers (void *cls)
1258 rps_peer->pending_rep_tail, 1371 rps_peer->pending_rep_tail,
1259 pending_rep); 1372 pending_rep);
1260 rps_peer->num_pending_reps++; 1373 rps_peer->num_pending_reps++;
1261 rps_peer->num_pending_reqs--;
1262}
1263
1264static void
1265cancel_pending_req (struct PendingRequest *pending_req)
1266{
1267 struct RPSPeer *rps_peer;
1268
1269 rps_peer = pending_req->rps_peer;
1270 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_req_head,
1271 rps_peer->pending_req_tail,
1272 pending_req);
1273 rps_peer->num_pending_reqs--;
1274 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1275 "Cancelling pending request\n");
1276 GNUNET_SCHEDULER_cancel (pending_req->request_task);
1277 GNUNET_free (pending_req);
1278}
1279
1280static void
1281cancel_request (struct PendingReply *pending_rep)
1282{
1283 struct RPSPeer *rps_peer;
1284
1285 rps_peer = pending_rep->rps_peer;
1286 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_rep_head,
1287 rps_peer->pending_rep_tail,
1288 pending_rep);
1289 rps_peer->num_pending_reps--;
1290 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1291 "Cancelling request\n");
1292 GNUNET_RPS_request_cancel (pending_rep->req_handle);
1293 GNUNET_free (pending_rep);
1294} 1374}
1295 1375
1296 1376
@@ -2261,12 +2341,6 @@ void write_final_stats (void){
2261 stat_type < STAT_TYPE_MAX; 2341 stat_type < STAT_TYPE_MAX;
2262 stat_type++) 2342 stat_type++)
2263 { 2343 {
2264 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2265 "Add to sum (%" PRIu64 ") %" PRIu64 " of stat type %u - %s\n",
2266 sums[stat_type],
2267 rps_peers[i].stats[stat_type],
2268 stat_type,
2269 stat_type_2_str (stat_type));
2270 sums[stat_type] += rps_peers[i].stats[stat_type]; 2344 sums[stat_type] += rps_peers[i].stats[stat_type];
2271 } 2345 }
2272 } 2346 }
@@ -2312,6 +2386,8 @@ post_test_shutdown_ready_cb (void *cls,
2312{ 2386{
2313 struct STATcls *stat_cls = (struct STATcls *) cls; 2387 struct STATcls *stat_cls = (struct STATcls *) cls;
2314 struct RPSPeer *rps_peer = stat_cls->rps_peer; 2388 struct RPSPeer *rps_peer = stat_cls->rps_peer;
2389
2390 rps_peer->h_stat_get[stat_cls->stat_type] = NULL;
2315 if (GNUNET_OK == success) 2391 if (GNUNET_OK == success)
2316 { 2392 {
2317 /* set flag that we we got the value */ 2393 /* set flag that we we got the value */
@@ -2363,6 +2439,7 @@ stat_iterator (void *cls,
2363{ 2439{
2364 const struct STATcls *stat_cls = (const struct STATcls *) cls; 2440 const struct STATcls *stat_cls = (const struct STATcls *) cls;
2365 struct RPSPeer *rps_peer = (struct RPSPeer *) stat_cls->rps_peer; 2441 struct RPSPeer *rps_peer = (struct RPSPeer *) stat_cls->rps_peer;
2442
2366 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got stat value: %s - %" PRIu64 "\n", 2443 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got stat value: %s - %" PRIu64 "\n",
2367 //stat_type_2_str (stat_cls->stat_type), 2444 //stat_type_2_str (stat_cls->stat_type),
2368 name, 2445 name,
@@ -2455,12 +2532,13 @@ void post_profiler (struct RPSPeer *rps_peer)
2455 stat_cls->stat_type = stat_type; 2532 stat_cls->stat_type = stat_type;
2456 rps_peer->file_name_stats = 2533 rps_peer->file_name_stats =
2457 store_prefix_file_name (rps_peer->peer_id, "stats"); 2534 store_prefix_file_name (rps_peer->peer_id, "stats");
2458 GNUNET_STATISTICS_get (rps_peer->stats_h, 2535 rps_peer->h_stat_get[stat_type] = GNUNET_STATISTICS_get (
2459 "rps", 2536 rps_peer->stats_h,
2460 stat_type_2_str (stat_type), 2537 "rps",
2461 post_test_shutdown_ready_cb, 2538 stat_type_2_str (stat_type),
2462 stat_iterator, 2539 post_test_shutdown_ready_cb,
2463 (struct STATcls *) stat_cls); 2540 stat_iterator,
2541 (struct STATcls *) stat_cls);
2464 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2542 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2465 "Requested statistics for %s (peer %" PRIu32 ")\n", 2543 "Requested statistics for %s (peer %" PRIu32 ")\n",
2466 stat_type_2_str (stat_type), 2544 stat_type_2_str (stat_type),
@@ -2555,6 +2633,8 @@ test_run (void *cls,
2555 /* Connect all peers to statistics service */ 2633 /* Connect all peers to statistics service */
2556 if (COLLECT_STATISTICS == cur_test_run.have_collect_statistics) 2634 if (COLLECT_STATISTICS == cur_test_run.have_collect_statistics)
2557 { 2635 {
2636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2637 "Connecting to statistics service\n");
2558 rps_peers[i].stat_op = 2638 rps_peers[i].stat_op =
2559 GNUNET_TESTBED_service_connect (NULL, 2639 GNUNET_TESTBED_service_connect (NULL,
2560 peers[i], 2640 peers[i],
@@ -2569,11 +2649,12 @@ test_run (void *cls,
2569 2649
2570 if (NULL != churn_task) 2650 if (NULL != churn_task)
2571 GNUNET_SCHEDULER_cancel (churn_task); 2651 GNUNET_SCHEDULER_cancel (churn_task);
2572 post_test_task = GNUNET_SCHEDULER_add_delayed (timeout, &post_test_op, NULL); 2652 post_test_task = GNUNET_SCHEDULER_add_delayed (duration, &post_test_op, NULL);
2573 timeout = GNUNET_TIME_relative_multiply (timeout, 1 + (0.1 * num_peers)); 2653 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "timeout for shutdown is %lu\n", timeout.rel_value_us/1000000);
2574 shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_op, NULL); 2654 shutdown_task = GNUNET_SCHEDULER_add_delayed (timeout,
2575 shutdown_task = GNUNET_SCHEDULER_add_delayed (timeout, &shutdown_op, NULL); 2655 &trigger_shutdown,
2576 2656 NULL);
2657 GNUNET_SCHEDULER_add_shutdown (shutdown_op, NULL);
2577} 2658}
2578 2659
2579 2660
@@ -2609,7 +2690,7 @@ run (void *cls,
2609 if (0 == cur_test_run.num_requests) cur_test_run.num_requests = 5; 2690 if (0 == cur_test_run.num_requests) cur_test_run.num_requests = 5;
2610 //cur_test_run.have_churn = HAVE_CHURN; 2691 //cur_test_run.have_churn = HAVE_CHURN;
2611 cur_test_run.have_churn = HAVE_NO_CHURN; 2692 cur_test_run.have_churn = HAVE_NO_CHURN;
2612 cur_test_run.have_quick_quit = HAVE_NO_QUICK_QUIT; 2693 cur_test_run.have_quick_quit = HAVE_QUICK_QUIT;
2613 cur_test_run.have_collect_statistics = COLLECT_STATISTICS; 2694 cur_test_run.have_collect_statistics = COLLECT_STATISTICS;
2614 cur_test_run.stat_collect_flags = BIT(STAT_TYPE_ROUNDS) | 2695 cur_test_run.stat_collect_flags = BIT(STAT_TYPE_ROUNDS) |
2615 BIT(STAT_TYPE_BLOCKS) | 2696 BIT(STAT_TYPE_BLOCKS) |
@@ -2632,10 +2713,38 @@ run (void *cls,
2632 /* 'Clean' directory */ 2713 /* 'Clean' directory */
2633 (void) GNUNET_DISK_directory_remove ("/tmp/rps/"); 2714 (void) GNUNET_DISK_directory_remove ("/tmp/rps/");
2634 GNUNET_DISK_directory_create ("/tmp/rps/"); 2715 GNUNET_DISK_directory_create ("/tmp/rps/");
2635 if (0 == timeout.rel_value_us) 2716 if (0 == duration.rel_value_us)
2636 { 2717 {
2637 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 90); 2718 if (0 == timeout.rel_value_us)
2719 {
2720 duration = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 90);
2721 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
2722 (90 * 1.2) +
2723 (0.01 * num_peers));
2724 }
2725 else
2726 {
2727 duration = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
2728 (timeout.rel_value_us/1000000)
2729 * 0.75);
2730 }
2638 } 2731 }
2732 else
2733 {
2734 if (0 == timeout.rel_value_us)
2735 {
2736 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
2737 ((duration.rel_value_us/1000000)
2738 * 1.2) + (0.01 * num_peers));
2739 }
2740 }
2741 GNUNET_assert (duration.rel_value_us < timeout.rel_value_us);
2742 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2743 "duration is %lus\n",
2744 duration.rel_value_us/1000000);
2745 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2746 "timeout is %lus\n",
2747 timeout.rel_value_us/1000000);
2639 2748
2640 /* Compute number of bits for representing largest peer id */ 2749 /* Compute number of bits for representing largest peer id */
2641 for (bits_needed = 1; (1 << bits_needed) < num_peers; bits_needed++) 2750 for (bits_needed = 1; (1 << bits_needed) < num_peers; bits_needed++)
@@ -2685,6 +2794,12 @@ main (int argc, char *argv[])
2685 gettext_noop ("number of peers to start"), 2794 gettext_noop ("number of peers to start"),
2686 &num_peers), 2795 &num_peers),
2687 2796
2797 GNUNET_GETOPT_option_relative_time ('d',
2798 "duration",
2799 "DURATION",
2800 gettext_noop ("duration of the profiling"),
2801 &duration),
2802
2688 GNUNET_GETOPT_option_relative_time ('t', 2803 GNUNET_GETOPT_option_relative_time ('t',
2689 "timeout", 2804 "timeout",
2690 "TIMEOUT", 2805 "TIMEOUT",
@@ -2732,7 +2847,6 @@ main (int argc, char *argv[])
2732 GNUNET_free (rps_peers); 2847 GNUNET_free (rps_peers);
2733 GNUNET_free (rps_peer_ids); 2848 GNUNET_free (rps_peer_ids);
2734 GNUNET_CONTAINER_multipeermap_destroy (peer_map); 2849 GNUNET_CONTAINER_multipeermap_destroy (peer_map);
2735 printf ("test -1\n");
2736 return ret_value; 2850 return ret_value;
2737} 2851}
2738 2852
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index 84fb33be2..d601ac7d4 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -68,6 +68,7 @@ static struct GNUNET_STATISTICS_Handle *stats;
68 */ 68 */
69static struct GNUNET_PeerIdentity own_identity; 69static struct GNUNET_PeerIdentity own_identity;
70 70
71static int in_shutdown = GNUNET_NO;
71 72
72/** 73/**
73 * @brief Port used for cadet. 74 * @brief Port used for cadet.
@@ -97,11 +98,6 @@ static struct GNUNET_HashCode port;
97#define unset_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) &= ~(mask)) 98#define unset_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) &= ~(mask))
98 99
99/** 100/**
100 * Set a channel flag of given channel context.
101 */
102#define set_channel_flag(channel_flags, mask) ((*channel_flags) |= (mask))
103
104/**
105 * Get channel flag of given channel context. 101 * Get channel flag of given channel context.
106 */ 102 */
107#define check_channel_flag_set(channel_flags, mask)\ 103#define check_channel_flag_set(channel_flags, mask)\
@@ -164,6 +160,11 @@ struct PendingMessage
164}; 160};
165 161
166/** 162/**
163 * @brief Context for a channel
164 */
165struct ChannelCtx;
166
167/**
167 * Struct used to keep track of other peer's status 168 * Struct used to keep track of other peer's status
168 * 169 *
169 * This is stored in a multipeermap. 170 * This is stored in a multipeermap.
@@ -181,22 +182,12 @@ struct PeerContext
181 /** 182 /**
182 * Channel open to client. 183 * Channel open to client.
183 */ 184 */
184 struct GNUNET_CADET_Channel *send_channel; 185 struct ChannelCtx *send_channel_ctx;
185
186 /**
187 * Flags to the sending channel
188 */
189 uint32_t *send_channel_flags;
190 186
191 /** 187 /**
192 * Channel open from client. 188 * Channel open from client.
193 */ 189 */
194 struct GNUNET_CADET_Channel *recv_channel; // unneeded? 190 struct ChannelCtx *recv_channel_ctx;
195
196 /**
197 * Flags to the receiving channel
198 */
199 uint32_t *recv_channel_flags;
200 191
201 /** 192 /**
202 * Array of pending operations on this peer. 193 * Array of pending operations on this peer.
@@ -242,6 +233,11 @@ struct PeerContext
242 struct PendingMessage *pending_messages_tail; 233 struct PendingMessage *pending_messages_tail;
243 234
244 /** 235 /**
236 * @brief Task to destroy this context.
237 */
238 struct GNUNET_SCHEDULER_Task *destruction_task;
239
240 /**
245 * This is pobably followed by 'statistical' data (when we first saw 241 * This is pobably followed by 'statistical' data (when we first saw
246 * it, how did we get its ID, how many pushes (in a timeinterval), 242 * it, how did we get its ID, how many pushes (in a timeinterval),
247 * ...) 243 * ...)
@@ -265,6 +261,33 @@ struct PeersIteratorCls
265}; 261};
266 262
267/** 263/**
264 * @brief Context for a channel
265 */
266struct ChannelCtx
267{
268 /**
269 * @brief Meant to be used in a DLL
270 */
271 struct ChannelCtx *next;
272 struct ChannelCtx *prev;
273
274 /**
275 * @brief The channel itself
276 */
277 struct GNUNET_CADET_Channel *channel;
278
279 /**
280 * @brief The peer context associated with the channel
281 */
282 struct PeerContext *peer_ctx;
283
284 /**
285 * @brief Scheduled task that will destroy this context
286 */
287 struct GNUNET_SCHEDULER_Task *destruction_task;
288};
289
290/**
268 * @brief Hashmap of valid peers. 291 * @brief Hashmap of valid peers.
269 */ 292 */
270static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers; 293static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers;
@@ -332,8 +355,6 @@ create_peer_ctx (const struct GNUNET_PeerIdentity *peer)
332 355
333 ctx = GNUNET_new (struct PeerContext); 356 ctx = GNUNET_new (struct PeerContext);
334 ctx->peer_id = *peer; 357 ctx->peer_id = *peer;
335 ctx->send_channel_flags = GNUNET_new (uint32_t);
336 ctx->recv_channel_flags = GNUNET_new (uint32_t);
337 ret = GNUNET_CONTAINER_multipeermap_put (peer_map, peer, ctx, 358 ret = GNUNET_CONTAINER_multipeermap_put (peer_map, peer, ctx,
338 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 359 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
339 GNUNET_assert (GNUNET_OK == ret); 360 GNUNET_assert (GNUNET_OK == ret);
@@ -387,8 +408,8 @@ Peers_check_connected (const struct GNUNET_PeerIdentity *peer)
387 /* Get the context */ 408 /* Get the context */
388 peer_ctx = get_peer_ctx (peer); 409 peer_ctx = get_peer_ctx (peer);
389 /* If we have no channel to this peer we don't know whether it's online */ 410 /* If we have no channel to this peer we don't know whether it's online */
390 if ( (NULL == peer_ctx->send_channel) && 411 if ( (NULL == peer_ctx->send_channel_ctx) &&
391 (NULL == peer_ctx->recv_channel) ) 412 (NULL == peer_ctx->recv_channel_ctx) )
392 { 413 {
393 Peers_unset_peer_flag (peer, Peers_ONLINE); 414 Peers_unset_peer_flag (peer, Peers_ONLINE);
394 return GNUNET_NO; 415 return GNUNET_NO;
@@ -575,6 +596,24 @@ handle_peer_pull_reply (void *cls,
575 596
576/* End declaration of handlers */ 597/* End declaration of handlers */
577 598
599/**
600 * @brief Allocate memory for a new channel context and insert it into DLL
601 *
602 * @param peer_ctx context of the according peer
603 *
604 * @return The channel context
605 */
606static struct ChannelCtx *
607add_channel_ctx (struct PeerContext *peer_ctx);
608
609/**
610 * @brief Remove the channel context from the DLL and free the memory.
611 *
612 * @param channel_ctx The channel context.
613 */
614static void
615remove_channel_ctx (struct ChannelCtx *channel_ctx);
616
578 617
579/** 618/**
580 * @brief Get the channel of a peer. If not existing, create. 619 * @brief Get the channel of a peer. If not existing, create.
@@ -610,16 +649,17 @@ get_channel (const struct GNUNET_PeerIdentity *peer)
610 649
611 650
612 peer_ctx = get_peer_ctx (peer); 651 peer_ctx = get_peer_ctx (peer);
613 if (NULL == peer_ctx->send_channel) 652 if (NULL == peer_ctx->send_channel_ctx)
614 { 653 {
615 LOG (GNUNET_ERROR_TYPE_DEBUG, 654 LOG (GNUNET_ERROR_TYPE_DEBUG,
616 "Trying to establish channel to peer %s\n", 655 "Trying to establish channel to peer %s\n",
617 GNUNET_i2s (peer)); 656 GNUNET_i2s (peer));
618 ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity); 657 ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity);
619 *ctx_peer = *peer; 658 *ctx_peer = *peer;
620 peer_ctx->send_channel = 659 peer_ctx->send_channel_ctx = add_channel_ctx (peer_ctx);
660 peer_ctx->send_channel_ctx->channel =
621 GNUNET_CADET_channel_create (cadet_handle, 661 GNUNET_CADET_channel_create (cadet_handle,
622 (struct GNUNET_PeerIdentity *) ctx_peer, /* context */ 662 peer_ctx->send_channel_ctx, /* context */
623 peer, 663 peer,
624 &port, 664 &port,
625 GNUNET_CADET_OPTION_RELIABLE, 665 GNUNET_CADET_OPTION_RELIABLE,
@@ -627,8 +667,9 @@ get_channel (const struct GNUNET_PeerIdentity *peer)
627 cleanup_destroyed_channel, /* Disconnect handler */ 667 cleanup_destroyed_channel, /* Disconnect handler */
628 cadet_handlers); 668 cadet_handlers);
629 } 669 }
630 GNUNET_assert (NULL != peer_ctx->send_channel); 670 GNUNET_assert (NULL != peer_ctx->send_channel_ctx);
631 return peer_ctx->send_channel; 671 GNUNET_assert (NULL != peer_ctx->send_channel_ctx->channel);
672 return peer_ctx->send_channel_ctx->channel;
632} 673}
633 674
634 675
@@ -1045,12 +1086,10 @@ restore_valid_peers ()
1045 */ 1086 */
1046void 1087void
1047Peers_initialise (char* fn_valid_peers, 1088Peers_initialise (char* fn_valid_peers,
1048 struct GNUNET_CADET_Handle *cadet_h, 1089 struct GNUNET_CADET_Handle *cadet_h)
1049 const struct GNUNET_PeerIdentity *own_id)
1050{ 1090{
1051 filename_valid_peers = GNUNET_strdup (fn_valid_peers); 1091 filename_valid_peers = GNUNET_strdup (fn_valid_peers);
1052 cadet_handle = cadet_h; 1092 cadet_handle = cadet_h;
1053 own_identity = *own_id;
1054 peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); 1093 peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO);
1055 valid_peers = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); 1094 valid_peers = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO);
1056 restore_valid_peers (); 1095 restore_valid_peers ();
@@ -1136,14 +1175,12 @@ Peers_get_valid_peers (PeersIterator iterator,
1136 * @param peer the new #GNUNET_PeerIdentity 1175 * @param peer the new #GNUNET_PeerIdentity
1137 * 1176 *
1138 * @return #GNUNET_YES if peer was inserted 1177 * @return #GNUNET_YES if peer was inserted
1139 * #GNUNET_NO otherwise (if peer was already known or 1178 * #GNUNET_NO otherwise
1140 * peer was #own_identity)
1141 */ 1179 */
1142int 1180int
1143Peers_insert_peer (const struct GNUNET_PeerIdentity *peer) 1181Peers_insert_peer (const struct GNUNET_PeerIdentity *peer)
1144{ 1182{
1145 if ( (GNUNET_YES == Peers_check_peer_known (peer)) || 1183 if (GNUNET_YES == Peers_check_peer_known (peer))
1146 (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity)) )
1147 { 1184 {
1148 return GNUNET_NO; /* We already know this peer - nothing to do */ 1185 return GNUNET_NO; /* We already know this peer - nothing to do */
1149 } 1186 }
@@ -1161,8 +1198,7 @@ Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFl
1161 * 1198 *
1162 * @param peer the peer whose liveliness is to be checked 1199 * @param peer the peer whose liveliness is to be checked
1163 * @return #GNUNET_YES if peer had to be inserted 1200 * @return #GNUNET_YES if peer had to be inserted
1164 * #GNUNET_NO otherwise (if peer was already known or 1201 * #GNUNET_NO otherwise
1165 * peer was #own_identity)
1166 */ 1202 */
1167int 1203int
1168Peers_issue_peer_liveliness_check (const struct GNUNET_PeerIdentity *peer) 1204Peers_issue_peer_liveliness_check (const struct GNUNET_PeerIdentity *peer)
@@ -1170,13 +1206,10 @@ Peers_issue_peer_liveliness_check (const struct GNUNET_PeerIdentity *peer)
1170 struct PeerContext *peer_ctx; 1206 struct PeerContext *peer_ctx;
1171 int ret; 1207 int ret;
1172 1208
1173 if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity))
1174 {
1175 return GNUNET_NO;
1176 }
1177 ret = Peers_insert_peer (peer); 1209 ret = Peers_insert_peer (peer);
1178 peer_ctx = get_peer_ctx (peer); 1210 peer_ctx = get_peer_ctx (peer);
1179 if (GNUNET_NO == Peers_check_peer_flag (peer, Peers_ONLINE)) 1211 if ( (GNUNET_NO == Peers_check_peer_flag (peer, Peers_ONLINE)) &&
1212 (NULL == peer_ctx->liveliness_check_pending) )
1180 { 1213 {
1181 check_peer_live (peer_ctx); 1214 check_peer_live (peer_ctx);
1182 } 1215 }
@@ -1208,7 +1241,7 @@ Peers_check_removable (const struct GNUNET_PeerIdentity *peer)
1208 } 1241 }
1209 1242
1210 peer_ctx = get_peer_ctx (peer); 1243 peer_ctx = get_peer_ctx (peer);
1211 if ( (NULL != peer_ctx->recv_channel) || 1244 if ( (NULL != peer_ctx->recv_channel_ctx) ||
1212 (NULL != peer_ctx->pending_messages_head) || 1245 (NULL != peer_ctx->pending_messages_head) ||
1213 (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) ) 1246 (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) )
1214 { 1247 {
@@ -1225,6 +1258,65 @@ int
1225Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags); 1258Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags);
1226 1259
1227/** 1260/**
1261 * @brief Callback for the scheduler to destroy the knowledge of a peer.
1262 *
1263 * @param cls Context of the peer
1264 */
1265static void
1266destroy_peer (void *cls)
1267{
1268 struct PeerContext *peer_ctx = cls;
1269
1270 GNUNET_assert (NULL != peer_ctx);
1271 peer_ctx->destruction_task = NULL;
1272 Peers_remove_peer (&peer_ctx->peer_id);
1273}
1274
1275static void
1276destroy_channel (void *cls);
1277
1278
1279/**
1280 * @brief Schedule the destruction of the given channel.
1281 *
1282 * Do so only if it was not already scheduled and not during shutdown.
1283 *
1284 * @param channel_ctx The context of the channel to destroy.
1285 */
1286static void
1287schedule_channel_destruction (struct ChannelCtx *channel_ctx)
1288{
1289 GNUNET_assert (NULL != channel_ctx);
1290 if (NULL != channel_ctx->destruction_task &&
1291 GNUNET_NO == in_shutdown)
1292 {
1293 channel_ctx->destruction_task =
1294 GNUNET_SCHEDULER_add_now (destroy_channel, channel_ctx);
1295 }
1296}
1297
1298
1299/**
1300 * @brief Schedule the destruction of the given peer.
1301 *
1302 * Do so only if it was not already scheduled and not during shutdown.
1303 *
1304 * @param peer_ctx The context of the peer to destroy.
1305 */
1306static void
1307schedule_peer_destruction (struct PeerContext *peer_ctx)
1308{
1309 GNUNET_assert (NULL != peer_ctx);
1310 if (NULL != peer_ctx->destruction_task &&
1311 GNUNET_NO == in_shutdown)
1312 {
1313 peer_ctx->destruction_task =
1314 GNUNET_SCHEDULER_add_now (destroy_peer, peer_ctx);
1315 }
1316}
1317
1318
1319/**
1228 * @brief Remove peer 1320 * @brief Remove peer
1229 * 1321 *
1230 * @param peer the peer to clean 1322 * @param peer the peer to clean
@@ -1235,7 +1327,8 @@ int
1235Peers_remove_peer (const struct GNUNET_PeerIdentity *peer) 1327Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1236{ 1328{
1237 struct PeerContext *peer_ctx; 1329 struct PeerContext *peer_ctx;
1238 uint32_t *channel_flag; 1330
1331 GNUNET_assert (NULL != peer_map);
1239 1332
1240 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer)) 1333 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer))
1241 { 1334 {
@@ -1249,7 +1342,12 @@ Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1249 GNUNET_i2s (&peer_ctx->peer_id)); 1342 GNUNET_i2s (&peer_ctx->peer_id));
1250 Peers_unset_peer_flag (peer, Peers_ONLINE); 1343 Peers_unset_peer_flag (peer, Peers_ONLINE);
1251 1344
1345 /* Clear list of pending operations */
1346 // TODO this probably leaks memory
1347 // ('only' the cls to the function. Not sure what to do with it)
1252 GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0); 1348 GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0);
1349
1350 /* Remove all pending messages */
1253 while (NULL != peer_ctx->pending_messages_head) 1351 while (NULL != peer_ctx->pending_messages_head)
1254 { 1352 {
1255 LOG (GNUNET_ERROR_TYPE_DEBUG, 1353 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -1261,10 +1359,12 @@ Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1261 peer_ctx->liveliness_check_pending, 1359 peer_ctx->liveliness_check_pending,
1262 sizeof (struct PendingMessage))) ) 1360 sizeof (struct PendingMessage))) )
1263 { 1361 {
1362 // TODO this may leak memory
1264 peer_ctx->liveliness_check_pending = NULL; 1363 peer_ctx->liveliness_check_pending = NULL;
1265 } 1364 }
1266 remove_pending_message (peer_ctx->pending_messages_head, GNUNET_YES); 1365 remove_pending_message (peer_ctx->pending_messages_head, GNUNET_YES);
1267 } 1366 }
1367
1268 /* If we are still waiting for notification whether this peer is live 1368 /* If we are still waiting for notification whether this peer is live
1269 * cancel the according task */ 1369 * cancel the according task */
1270 if (NULL != peer_ctx->liveliness_check_pending) 1370 if (NULL != peer_ctx->liveliness_check_pending)
@@ -1277,28 +1377,40 @@ Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1277 remove_pending_message (peer_ctx->liveliness_check_pending, GNUNET_YES); 1377 remove_pending_message (peer_ctx->liveliness_check_pending, GNUNET_YES);
1278 peer_ctx->liveliness_check_pending = NULL; 1378 peer_ctx->liveliness_check_pending = NULL;
1279 } 1379 }
1280 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING); 1380
1281 if (NULL != peer_ctx->send_channel && 1381
1282 GNUNET_YES != Peers_check_channel_flag (channel_flag, Peers_CHANNEL_DESTROING)) 1382 /* Do we still have to wait for destruction of channels
1383 * or issue the destruction? */
1384 if (NULL != peer_ctx->send_channel_ctx &&
1385 NULL != peer_ctx->send_channel_ctx->destruction_task
1386 )
1283 { 1387 {
1284 LOG (GNUNET_ERROR_TYPE_DEBUG, 1388 schedule_peer_destruction (peer_ctx);
1285 "Destroying send channel\n"); 1389 return GNUNET_NO;
1286 GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
1287 peer_ctx->send_channel = NULL;
1288 peer_ctx->mq = NULL;
1289 } 1390 }
1290 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_RECEIVING); 1391 if (NULL != peer_ctx->recv_channel_ctx &&
1291 if (NULL != peer_ctx->recv_channel && 1392 NULL != peer_ctx->recv_channel_ctx->destruction_task)
1292 GNUNET_YES != Peers_check_channel_flag (channel_flag, Peers_CHANNEL_DESTROING))
1293 { 1393 {
1294 LOG (GNUNET_ERROR_TYPE_DEBUG, 1394 schedule_peer_destruction (peer_ctx);
1295 "Destroying recv channel\n"); 1395 return GNUNET_NO;
1296 GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); 1396 }
1297 peer_ctx->recv_channel = NULL; 1397 if (NULL != peer_ctx->recv_channel_ctx)
1398 {
1399 schedule_channel_destruction (peer_ctx->recv_channel_ctx);
1400 schedule_peer_destruction (peer_ctx);
1401 return GNUNET_NO;
1402 }
1403 if (NULL != peer_ctx->send_channel_ctx)
1404 {
1405 schedule_channel_destruction (peer_ctx->send_channel_ctx);
1406 schedule_peer_destruction (peer_ctx);
1407 return GNUNET_NO;
1298 } 1408 }
1299 1409
1300 GNUNET_free (peer_ctx->send_channel_flags); 1410 if (NULL != peer_ctx->destruction_task)
1301 GNUNET_free (peer_ctx->recv_channel_flags); 1411 {
1412 GNUNET_SCHEDULER_cancel (peer_ctx->destruction_task);
1413 }
1302 1414
1303 if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove_all (peer_map, &peer_ctx->peer_id)) 1415 if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove_all (peer_map, &peer_ctx->peer_id))
1304 { 1416 {
@@ -1308,7 +1420,6 @@ Peers_remove_peer (const struct GNUNET_PeerIdentity *peer)
1308 return GNUNET_YES; 1420 return GNUNET_YES;
1309} 1421}
1310 1422
1311
1312/** 1423/**
1313 * @brief set flags on a given peer. 1424 * @brief set flags on a given peer.
1314 * 1425 *
@@ -1364,77 +1475,6 @@ Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFl
1364 return check_peer_flag_set (peer_ctx, flags); 1475 return check_peer_flag_set (peer_ctx, flags);
1365} 1476}
1366 1477
1367
1368/**
1369 * @brief set flags on a given channel.
1370 *
1371 * @param channel the channel to set flags on
1372 * @param flags the flags
1373 */
1374void
1375Peers_set_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags)
1376{
1377 set_channel_flag (channel_flags, flags);
1378}
1379
1380
1381/**
1382 * @brief unset flags on a given channel.
1383 *
1384 * @param channel the channel to unset flags on
1385 * @param flags the flags
1386 */
1387void
1388Peers_unset_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags)
1389{
1390 unset_channel_flag (channel_flags, flags);
1391}
1392
1393
1394/**
1395 * @brief Check whether flags on a channel are set.
1396 *
1397 * @param channel the channel to check the flag of
1398 * @param flags the flags to check
1399 *
1400 * @return #GNUNET_YES if all given flags are set
1401 * #GNUNET_NO otherwise
1402 */
1403int
1404Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags)
1405{
1406 return check_channel_flag_set (channel_flags, flags);
1407}
1408
1409/**
1410 * @brief Get the flags for the channel in @a role for @a peer.
1411 *
1412 * @param peer Peer to get the channel flags for.
1413 * @param role Role of channel to get flags for
1414 *
1415 * @return The flags.
1416 */
1417uint32_t *
1418Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer,
1419 enum Peers_ChannelRole role)
1420{
1421 const struct PeerContext *peer_ctx;
1422
1423 peer_ctx = get_peer_ctx (peer);
1424 if (Peers_CHANNEL_ROLE_SENDING == role)
1425 {
1426 return peer_ctx->send_channel_flags;
1427 }
1428 else if (Peers_CHANNEL_ROLE_RECEIVING == role)
1429 {
1430 return peer_ctx->recv_channel_flags;
1431 }
1432 else
1433 {
1434 GNUNET_assert (0);
1435 }
1436}
1437
1438/** 1478/**
1439 * @brief Check whether we have information about the given peer. 1479 * @brief Check whether we have information about the given peer.
1440 * 1480 *
@@ -1505,7 +1545,7 @@ Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer)
1505 const struct PeerContext *peer_ctx; 1545 const struct PeerContext *peer_ctx;
1506 1546
1507 peer_ctx = get_peer_ctx (peer); 1547 peer_ctx = get_peer_ctx (peer);
1508 if (NULL != peer_ctx->recv_channel) 1548 if (NULL != peer_ctx->recv_channel_ctx)
1509 { 1549 {
1510 return GNUNET_YES; 1550 return GNUNET_YES;
1511 } 1551 }
@@ -1530,6 +1570,7 @@ Peers_handle_inbound_channel (void *cls,
1530{ 1570{
1531 struct PeerContext *peer_ctx; 1571 struct PeerContext *peer_ctx;
1532 struct GNUNET_PeerIdentity *ctx_peer; 1572 struct GNUNET_PeerIdentity *ctx_peer;
1573 struct ChannelCtx *channel_ctx;
1533 1574
1534 LOG (GNUNET_ERROR_TYPE_DEBUG, 1575 LOG (GNUNET_ERROR_TYPE_DEBUG,
1535 "New channel was established to us (Peer %s).\n", 1576 "New channel was established to us (Peer %s).\n",
@@ -1540,19 +1581,22 @@ Peers_handle_inbound_channel (void *cls,
1540 set_peer_live (peer_ctx); 1581 set_peer_live (peer_ctx);
1541 ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity); 1582 ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity);
1542 *ctx_peer = *initiator; 1583 *ctx_peer = *initiator;
1584 channel_ctx = add_channel_ctx (peer_ctx);
1585 channel_ctx->channel = channel;
1543 /* We only accept one incoming channel per peer */ 1586 /* We only accept one incoming channel per peer */
1544 if (GNUNET_YES == Peers_check_peer_send_intention (initiator)) 1587 if (GNUNET_YES == Peers_check_peer_send_intention (initiator))
1545 { 1588 {
1546 set_channel_flag (peer_ctx->recv_channel_flags, 1589 LOG (GNUNET_ERROR_TYPE_WARNING,
1547 Peers_CHANNEL_ESTABLISHED_TWICE); 1590 "Already got one receive channel. Destroying old one.\n");
1548 //GNUNET_CADET_channel_destroy (channel); 1591 GNUNET_break_op (0);
1549 GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); 1592 GNUNET_CADET_channel_destroy (peer_ctx->recv_channel_ctx->channel);
1550 peer_ctx->recv_channel = channel; 1593 remove_channel_ctx (peer_ctx->recv_channel_ctx);
1594 peer_ctx->recv_channel_ctx = channel_ctx;
1551 /* return the channel context */ 1595 /* return the channel context */
1552 return ctx_peer; 1596 return channel_ctx;
1553 } 1597 }
1554 peer_ctx->recv_channel = channel; 1598 peer_ctx->recv_channel_ctx = channel_ctx;
1555 return ctx_peer; 1599 return channel_ctx;
1556} 1600}
1557 1601
1558 1602
@@ -1574,7 +1618,7 @@ Peers_check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer)
1574 return GNUNET_NO; 1618 return GNUNET_NO;
1575 } 1619 }
1576 peer_ctx = get_peer_ctx (peer); 1620 peer_ctx = get_peer_ctx (peer);
1577 if (NULL == peer_ctx->send_channel) 1621 if (NULL == peer_ctx->send_channel_ctx)
1578 { 1622 {
1579 return GNUNET_NO; 1623 return GNUNET_NO;
1580 } 1624 }
@@ -1607,12 +1651,14 @@ Peers_check_channel_role (const struct GNUNET_PeerIdentity *peer,
1607 } 1651 }
1608 peer_ctx = get_peer_ctx (peer); 1652 peer_ctx = get_peer_ctx (peer);
1609 if ( (Peers_CHANNEL_ROLE_SENDING == role) && 1653 if ( (Peers_CHANNEL_ROLE_SENDING == role) &&
1610 (channel == peer_ctx->send_channel) ) 1654 (NULL != peer_ctx->send_channel_ctx) &&
1655 (channel == peer_ctx->send_channel_ctx->channel) )
1611 { 1656 {
1612 return GNUNET_YES; 1657 return GNUNET_YES;
1613 } 1658 }
1614 if ( (Peers_CHANNEL_ROLE_RECEIVING == role) && 1659 if ( (Peers_CHANNEL_ROLE_RECEIVING == role) &&
1615 (channel == peer_ctx->recv_channel) ) 1660 (NULL != peer_ctx->recv_channel_ctx) &&
1661 (channel == peer_ctx->recv_channel_ctx->channel) )
1616 { 1662 {
1617 return GNUNET_YES; 1663 return GNUNET_YES;
1618 } 1664 }
@@ -1642,12 +1688,9 @@ Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer)
1642 return GNUNET_NO; 1688 return GNUNET_NO;
1643 } 1689 }
1644 peer_ctx = get_peer_ctx (peer); 1690 peer_ctx = get_peer_ctx (peer);
1645 if (NULL != peer_ctx->send_channel) 1691 if (NULL != peer_ctx->send_channel_ctx)
1646 { 1692 {
1647 set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_CLEAN); 1693 schedule_channel_destruction (peer_ctx->send_channel_ctx);
1648 GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
1649 peer_ctx->send_channel = NULL;
1650 peer_ctx->mq = NULL;
1651 (void) Peers_check_connected (peer); 1694 (void) Peers_check_connected (peer);
1652 return GNUNET_YES; 1695 return GNUNET_YES;
1653 } 1696 }
@@ -1655,6 +1698,25 @@ Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer)
1655} 1698}
1656 1699
1657/** 1700/**
1701 * @brief Callback for scheduler to destroy a channel
1702 *
1703 * @param cls Context of the channel
1704 */
1705static void
1706destroy_channel (void *cls)
1707{
1708 struct ChannelCtx *channel_ctx = cls;
1709 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
1710
1711 GNUNET_assert (channel_ctx == peer_ctx->send_channel_ctx ||
1712 channel_ctx == peer_ctx->recv_channel_ctx);
1713
1714 channel_ctx->destruction_task = NULL;
1715 GNUNET_CADET_channel_destroy (channel_ctx->channel);
1716 remove_channel_ctx (peer_ctx->send_channel_ctx);
1717}
1718
1719/**
1658 * This is called when a channel is destroyed. 1720 * This is called when a channel is destroyed.
1659 * 1721 *
1660 * @param cls The closure 1722 * @param cls The closure
@@ -1664,77 +1726,45 @@ void
1664Peers_cleanup_destroyed_channel (void *cls, 1726Peers_cleanup_destroyed_channel (void *cls,
1665 const struct GNUNET_CADET_Channel *channel) 1727 const struct GNUNET_CADET_Channel *channel)
1666{ 1728{
1667 struct GNUNET_PeerIdentity *peer = cls; 1729 struct ChannelCtx *channel_ctx = cls;
1668 struct PeerContext *peer_ctx; 1730 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
1731 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
1669 1732
1670 if (GNUNET_NO == Peers_check_peer_known (peer)) 1733 if (GNUNET_NO == Peers_check_peer_known (peer))
1671 {/* We don't want to implicitly create a context that we're about to kill */ 1734 {/* We don't want to implicitly create a context that we're about to kill */
1672 LOG (GNUNET_ERROR_TYPE_DEBUG, 1735 LOG (GNUNET_ERROR_TYPE_WARNING,
1673 "channel (%s) without associated context was destroyed\n", 1736 "channel (%s) without associated context was destroyed\n",
1674 GNUNET_i2s (peer)); 1737 GNUNET_i2s (peer));
1675 return; 1738 return;
1676 } 1739 }
1677 peer_ctx = get_peer_ctx (peer);
1678 1740
1679 /* If our peer issued the destruction of the channel, the #Peers_TO_DESTROY 1741 /* If our peer issued the destruction of the channel, the #Peers_TO_DESTROY
1680 * flag will be set. In this case simply make sure that the channels are 1742 * flag will be set. In this case simply make sure that the channels are
1681 * cleaned. */ 1743 * cleaned. */
1682 /* FIXME This distinction seems to be redundant */ 1744 /* The distinction seems to be redundant */
1683 if (Peers_check_peer_flag (peer, Peers_TO_DESTROY)) 1745 LOG (GNUNET_ERROR_TYPE_DEBUG,
1684 {/* We initiatad the destruction of this particular peer */ 1746 "Peer is NOT in the process of being destroyed\n");
1747 if ( (NULL != peer_ctx->send_channel_ctx) &&
1748 (channel == peer_ctx->send_channel_ctx->channel) )
1749 { /* Something (but us) killd the channel - clean up peer */
1685 LOG (GNUNET_ERROR_TYPE_DEBUG, 1750 LOG (GNUNET_ERROR_TYPE_DEBUG,
1686 "Peer is in the process of being destroyed\n"); 1751 "send channel (%s) was destroyed - cleaning up\n",
1687 if (channel == peer_ctx->send_channel) 1752 GNUNET_i2s (peer));
1688 { 1753 remove_channel_ctx (peer_ctx->send_channel_ctx);
1689 peer_ctx->send_channel = NULL;
1690 peer_ctx->mq = NULL;
1691 }
1692 else if (channel == peer_ctx->recv_channel)
1693 {
1694 peer_ctx->recv_channel = NULL;
1695 }
1696
1697 if (NULL != peer_ctx->send_channel)
1698 {
1699 GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
1700 peer_ctx->send_channel = NULL;
1701 peer_ctx->mq = NULL;
1702 }
1703 if (NULL != peer_ctx->recv_channel)
1704 {
1705 GNUNET_CADET_channel_destroy (peer_ctx->recv_channel);
1706 peer_ctx->recv_channel = NULL;
1707 }
1708 /* Set the #Peers_ONLINE flag accordingly */
1709 (void) Peers_check_connected (peer);
1710 return;
1711 } 1754 }
1712 1755 else if ( (NULL != peer_ctx->recv_channel_ctx) &&
1713 else 1756 (channel == peer_ctx->recv_channel_ctx->channel) )
1714 { /* We did not initiate the destruction of this peer */ 1757 { /* Other peer doesn't want to send us messages anymore */
1715 LOG (GNUNET_ERROR_TYPE_DEBUG, 1758 LOG (GNUNET_ERROR_TYPE_DEBUG,
1716 "Peer is NOT in the process of being destroyed\n"); 1759 "Peer %s destroyed recv channel - cleaning up channel\n",
1717 if (channel == peer_ctx->send_channel) 1760 GNUNET_i2s (peer));
1718 { /* Something (but us) killd the channel - clean up peer */ 1761 remove_channel_ctx (peer_ctx->send_channel_ctx);
1719 LOG (GNUNET_ERROR_TYPE_DEBUG, 1762 }
1720 "send channel (%s) was destroyed - cleaning up\n", 1763 else
1721 GNUNET_i2s (peer)); 1764 {
1722 peer_ctx->send_channel = NULL; 1765 LOG (GNUNET_ERROR_TYPE_WARNING,
1723 peer_ctx->mq = NULL; 1766 "unknown channel (%s) was destroyed\n",
1724 } 1767 GNUNET_i2s (peer));
1725 else if (channel == peer_ctx->recv_channel)
1726 { /* Other peer doesn't want to send us messages anymore */
1727 LOG (GNUNET_ERROR_TYPE_DEBUG,
1728 "Peer %s destroyed recv channel - cleaning up channel\n",
1729 GNUNET_i2s (peer));
1730 peer_ctx->recv_channel = NULL;
1731 }
1732 else
1733 {
1734 LOG (GNUNET_ERROR_TYPE_WARNING,
1735 "unknown channel (%s) was destroyed\n",
1736 GNUNET_i2s (peer));
1737 }
1738 } 1768 }
1739 (void) Peers_check_connected (peer); 1769 (void) Peers_check_connected (peer);
1740} 1770}
@@ -1786,10 +1816,6 @@ Peers_schedule_operation (const struct GNUNET_PeerIdentity *peer,
1786 struct PeerPendingOp pending_op; 1816 struct PeerPendingOp pending_op;
1787 struct PeerContext *peer_ctx; 1817 struct PeerContext *peer_ctx;
1788 1818
1789 if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity))
1790 {
1791 return GNUNET_NO;
1792 }
1793 GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); 1819 GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
1794 1820
1795 //TODO if LIVE/ONLINE execute immediately 1821 //TODO if LIVE/ONLINE execute immediately
@@ -1823,7 +1849,7 @@ Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer)
1823 1849
1824 GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); 1850 GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
1825 peer_ctx = get_peer_ctx (peer); 1851 peer_ctx = get_peer_ctx (peer);
1826 return peer_ctx->recv_channel; 1852 return peer_ctx->recv_channel_ctx->channel;
1827} 1853}
1828/*********************************************************************** 1854/***********************************************************************
1829 * /Old gnunet-service-rps_peers.c 1855 * /Old gnunet-service-rps_peers.c
@@ -2484,6 +2510,9 @@ send_pull_reply (const struct GNUNET_PeerIdentity *peer_id,
2484 2510
2485 Peers_send_message (peer_id, ev, "PULL REPLY"); 2511 Peers_send_message (peer_id, ev, "PULL REPLY");
2486 GNUNET_STATISTICS_update(stats, "# pull reply send issued", 1, GNUNET_NO); 2512 GNUNET_STATISTICS_update(stats, "# pull reply send issued", 1, GNUNET_NO);
2513 // TODO check with send intention: as send_channel is used/opened we indicate
2514 // a sending intention without intending it.
2515 // -> clean peer afterwards?
2487} 2516}
2488 2517
2489 2518
@@ -2616,7 +2645,7 @@ remove_peer (const struct GNUNET_PeerIdentity *peer)
2616 CustomPeerMap_remove_peer (push_map, peer); 2645 CustomPeerMap_remove_peer (push_map, peer);
2617 RPS_sampler_reinitialise_by_value (prot_sampler, peer); 2646 RPS_sampler_reinitialise_by_value (prot_sampler, peer);
2618 RPS_sampler_reinitialise_by_value (client_sampler, peer); 2647 RPS_sampler_reinitialise_by_value (client_sampler, peer);
2619 Peers_remove_peer (peer); 2648 schedule_peer_destruction (get_peer_ctx (peer));
2620} 2649}
2621 2650
2622 2651
@@ -2660,6 +2689,58 @@ clean_peer (const struct GNUNET_PeerIdentity *peer)
2660} 2689}
2661 2690
2662/** 2691/**
2692 * @brief Allocate memory for a new channel context and insert it into DLL
2693 *
2694 * @param peer_ctx context of the according peer
2695 *
2696 * @return The channel context
2697 */
2698static struct ChannelCtx *
2699add_channel_ctx (struct PeerContext *peer_ctx)
2700{
2701 struct ChannelCtx *channel_ctx;
2702 channel_ctx = GNUNET_new (struct ChannelCtx);
2703 channel_ctx->peer_ctx = peer_ctx;
2704 return channel_ctx;
2705}
2706
2707/**
2708 * @brief Remove the channel context from the DLL and free the memory.
2709 *
2710 * @param channel_ctx The channel context.
2711 */
2712static void
2713remove_channel_ctx (struct ChannelCtx *channel_ctx)
2714{
2715 struct PeerContext *peer_ctx = channel_ctx->peer_ctx;
2716 if (NULL != channel_ctx->destruction_task)
2717 {
2718 GNUNET_SCHEDULER_cancel (channel_ctx->destruction_task);
2719 }
2720 GNUNET_free (channel_ctx);
2721
2722 if (channel_ctx == peer_ctx->send_channel_ctx)
2723 {
2724 peer_ctx->send_channel_ctx = NULL;
2725 peer_ctx->mq = NULL;
2726 }
2727 else if (channel_ctx == peer_ctx->recv_channel_ctx)
2728 {
2729 peer_ctx->recv_channel_ctx = NULL;
2730 }
2731 else
2732 {
2733 LOG (GNUNET_ERROR_TYPE_ERROR,
2734 "Trying to remove channel_ctx that is not associated with a peer\n");
2735 LOG (GNUNET_ERROR_TYPE_ERROR,
2736 "\trecv: %p\n", peer_ctx->recv_channel_ctx);
2737 LOG (GNUNET_ERROR_TYPE_ERROR,
2738 "\tsend: %p\n", peer_ctx->send_channel_ctx);
2739 GNUNET_assert (0);
2740 }
2741}
2742
2743/**
2663 * @brief This is called when a channel is destroyed. 2744 * @brief This is called when a channel is destroyed.
2664 * 2745 *
2665 * Removes peer completely from our knowledge if the send_channel was destroyed 2746 * Removes peer completely from our knowledge if the send_channel was destroyed
@@ -2675,8 +2756,8 @@ static void
2675cleanup_destroyed_channel (void *cls, 2756cleanup_destroyed_channel (void *cls,
2676 const struct GNUNET_CADET_Channel *channel) 2757 const struct GNUNET_CADET_Channel *channel)
2677{ 2758{
2678 struct GNUNET_PeerIdentity *peer = cls; 2759 struct ChannelCtx *channel_ctx = cls;
2679 uint32_t *channel_flag; 2760 struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
2680 struct PeerContext *peer_ctx; 2761 struct PeerContext *peer_ctx;
2681 2762
2682 GNUNET_assert (NULL != peer); 2763 GNUNET_assert (NULL != peer);
@@ -2686,94 +2767,26 @@ cleanup_destroyed_channel (void *cls,
2686 LOG (GNUNET_ERROR_TYPE_WARNING, 2767 LOG (GNUNET_ERROR_TYPE_WARNING,
2687 "channel (%s) without associated context was destroyed\n", 2768 "channel (%s) without associated context was destroyed\n",
2688 GNUNET_i2s (peer)); 2769 GNUNET_i2s (peer));
2689 GNUNET_free (peer); 2770 remove_channel_ctx (channel_ctx);
2690 return; 2771 return;
2691 } 2772 }
2692 2773
2693 peer_ctx = get_peer_ctx (peer); 2774 peer_ctx = get_peer_ctx (peer);
2694 if (GNUNET_YES == Peers_check_channel_role (peer, channel, Peers_CHANNEL_ROLE_RECEIVING))
2695 {
2696 LOG (GNUNET_ERROR_TYPE_DEBUG,
2697 "Callback on destruction of recv-channel was called (%s)\n",
2698 GNUNET_i2s (peer));
2699 set_channel_flag (peer_ctx->recv_channel_flags, Peers_CHANNEL_DESTROING);
2700 } else if (GNUNET_YES == Peers_check_channel_role (peer, channel, Peers_CHANNEL_ROLE_SENDING))
2701 {
2702 LOG (GNUNET_ERROR_TYPE_DEBUG,
2703 "Callback on destruction of send-channel was called (%s)\n",
2704 GNUNET_i2s (peer));
2705 set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_DESTROING);
2706 } else {
2707 LOG (GNUNET_ERROR_TYPE_ERROR,
2708 "Channel to be destroyed has is neither sending nor receiving role\n");
2709 }
2710 2775
2711 if (GNUNET_YES == Peers_check_peer_flag (peer, Peers_TO_DESTROY)) 2776 // What should be done here:
2712 { /* We are in the middle of removing that peer from our knowledge. In this 2777 // * cleanup everything related to the channel
2713 case simply make sure that the channels are cleaned. */ 2778 // * memory
2714 Peers_cleanup_destroyed_channel (cls, channel); 2779 // * remove peer if necessary
2715 to_file (file_name_view_log,
2716 "-%s\t(cleanup channel, ourself)",
2717 GNUNET_i2s_full (peer));
2718 GNUNET_free (peer);
2719 return;
2720 }
2721 2780
2722 if (GNUNET_YES == 2781 if (peer_ctx->recv_channel_ctx == channel_ctx)
2723 Peers_check_channel_role (peer, channel, Peers_CHANNEL_ROLE_SENDING)) 2782 {
2724 { /* Channel used for sending was destroyed */ 2783 remove_channel_ctx (channel_ctx);
2725 /* Possible causes of channel destruction:
2726 * - ourselves -> cleaning send channel -> clean context
2727 * - other peer -> peer probably went down -> remove
2728 */
2729 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING);
2730 if (GNUNET_YES == Peers_check_channel_flag (channel_flag, Peers_CHANNEL_CLEAN))
2731 { /* We are about to clean the sending channel. Clean the respective
2732 * context */
2733 Peers_cleanup_destroyed_channel (cls, channel);
2734 GNUNET_free (peer);
2735 return;
2736 }
2737 else
2738 { /* Other peer destroyed our sending channel that it is supposed to keep
2739 * open. It probably went down. Remove it from our knowledge. */
2740 Peers_cleanup_destroyed_channel (cls, channel);
2741 remove_peer (peer);
2742 GNUNET_free (peer);
2743 return;
2744 }
2745 }
2746 else if (GNUNET_YES ==
2747 Peers_check_channel_role (peer, channel, Peers_CHANNEL_ROLE_RECEIVING))
2748 { /* Channel used for receiving was destroyed */
2749 /* Possible causes of channel destruction:
2750 * - ourselves -> peer tried to establish channel twice -> clean context
2751 * - other peer -> peer doesn't want to send us data -> clean
2752 */
2753 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_RECEIVING);
2754 if (GNUNET_YES ==
2755 Peers_check_channel_flag (channel_flag, Peers_CHANNEL_ESTABLISHED_TWICE))
2756 { /* Other peer tried to establish a channel to us twice. We do not accept
2757 * that. Clean the context. */
2758 Peers_cleanup_destroyed_channel (cls, channel);
2759 GNUNET_free (peer);
2760 return;
2761 }
2762 else
2763 { /* Other peer doesn't want to send us data anymore. We are free to clean
2764 * it. */
2765 Peers_cleanup_destroyed_channel (cls, channel);
2766 clean_peer (peer);
2767 GNUNET_free (peer);
2768 return;
2769 }
2770 } 2784 }
2771 else 2785 else if (peer_ctx->send_channel_ctx == channel_ctx)
2772 { 2786 {
2773 LOG (GNUNET_ERROR_TYPE_WARNING, 2787 remove_channel_ctx (channel_ctx);
2774 "Destroyed channel is neither sending nor receiving channel\n"); 2788 remove_peer (&peer_ctx->peer_id);
2775 } 2789 }
2776 GNUNET_free (peer);
2777} 2790}
2778 2791
2779/*********************************************************************** 2792/***********************************************************************
@@ -3032,8 +3045,6 @@ handle_client_seed (void *cls,
3032 3045
3033 num_peers = ntohl (msg->num_peers); 3046 num_peers = ntohl (msg->num_peers);
3034 peers = (struct GNUNET_PeerIdentity *) &msg[1]; 3047 peers = (struct GNUNET_PeerIdentity *) &msg[1];
3035 //peers = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity);
3036 //GNUNET_memcpy (peers, &msg[1], num_peers * sizeof (struct GNUNET_PeerIdentity));
3037 3048
3038 LOG (GNUNET_ERROR_TYPE_DEBUG, 3049 LOG (GNUNET_ERROR_TYPE_DEBUG,
3039 "Client seeded peers:\n"); 3050 "Client seeded peers:\n");
@@ -3048,9 +3059,6 @@ handle_client_seed (void *cls,
3048 3059
3049 got_peer (&peers[i]); 3060 got_peer (&peers[i]);
3050 } 3061 }
3051
3052 ////GNUNET_free (peers);
3053
3054 GNUNET_SERVICE_client_continue (cli_ctx->client); 3062 GNUNET_SERVICE_client_continue (cli_ctx->client);
3055} 3063}
3056 3064
@@ -3168,11 +3176,12 @@ static void
3168handle_peer_check (void *cls, 3176handle_peer_check (void *cls,
3169 const struct GNUNET_MessageHeader *msg) 3177 const struct GNUNET_MessageHeader *msg)
3170{ 3178{
3171 const struct GNUNET_PeerIdentity *peer = cls; 3179 const struct ChannelCtx *channel_ctx = cls;
3180 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
3172 LOG (GNUNET_ERROR_TYPE_DEBUG, 3181 LOG (GNUNET_ERROR_TYPE_DEBUG,
3173 "Received CHECK_LIVE (%s)\n", GNUNET_i2s (peer)); 3182 "Received CHECK_LIVE (%s)\n", GNUNET_i2s (peer));
3174 3183
3175 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); 3184 GNUNET_CADET_receive_done (channel_ctx->channel);
3176} 3185}
3177 3186
3178/** 3187/**
@@ -3188,7 +3197,8 @@ static void
3188handle_peer_push (void *cls, 3197handle_peer_push (void *cls,
3189 const struct GNUNET_MessageHeader *msg) 3198 const struct GNUNET_MessageHeader *msg)
3190{ 3199{
3191 const struct GNUNET_PeerIdentity *peer = cls; 3200 const struct ChannelCtx *channel_ctx = cls;
3201 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
3192 3202
3193 // (check the proof of work (?)) 3203 // (check the proof of work (?))
3194 3204
@@ -3233,7 +3243,7 @@ handle_peer_push (void *cls,
3233 CustomPeerMap_put (push_map, peer); 3243 CustomPeerMap_put (push_map, peer);
3234 3244
3235 GNUNET_break_op (Peers_check_peer_known (peer)); 3245 GNUNET_break_op (Peers_check_peer_known (peer));
3236 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); 3246 GNUNET_CADET_receive_done (channel_ctx->channel);
3237} 3247}
3238 3248
3239 3249
@@ -3249,7 +3259,8 @@ static void
3249handle_peer_pull_request (void *cls, 3259handle_peer_pull_request (void *cls,
3250 const struct GNUNET_MessageHeader *msg) 3260 const struct GNUNET_MessageHeader *msg)
3251{ 3261{
3252 struct GNUNET_PeerIdentity *peer = cls; 3262 const struct ChannelCtx *channel_ctx = cls;
3263 const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id;
3253 const struct GNUNET_PeerIdentity *view_array; 3264 const struct GNUNET_PeerIdentity *view_array;
3254 3265
3255 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REQUEST (%s)\n", GNUNET_i2s (peer)); 3266 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REQUEST (%s)\n", GNUNET_i2s (peer));
@@ -3272,7 +3283,7 @@ handle_peer_pull_request (void *cls,
3272 #endif /* ENABLE_MALICIOUS */ 3283 #endif /* ENABLE_MALICIOUS */
3273 3284
3274 GNUNET_break_op (Peers_check_peer_known (peer)); 3285 GNUNET_break_op (Peers_check_peer_known (peer));
3275 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); 3286 GNUNET_CADET_receive_done (channel_ctx->channel);
3276 view_array = View_get_as_array (); 3287 view_array = View_get_as_array ();
3277 send_pull_reply (peer, view_array, View_size ()); 3288 send_pull_reply (peer, view_array, View_size ());
3278} 3289}
@@ -3312,7 +3323,8 @@ check_peer_pull_reply (void *cls,
3312 if (GNUNET_YES != Peers_check_peer_flag (sender, Peers_PULL_REPLY_PENDING)) 3323 if (GNUNET_YES != Peers_check_peer_flag (sender, Peers_PULL_REPLY_PENDING))
3313 { 3324 {
3314 LOG (GNUNET_ERROR_TYPE_WARNING, 3325 LOG (GNUNET_ERROR_TYPE_WARNING,
3315 "Received a pull reply from a peer we didn't request one from!\n"); 3326 "Received a pull reply from a peer (%s) we didn't request one from!\n",
3327 GNUNET_i2s (sender));
3316 GNUNET_break_op (0); 3328 GNUNET_break_op (0);
3317 return GNUNET_SYSERR; 3329 return GNUNET_SYSERR;
3318 } 3330 }
@@ -3329,8 +3341,9 @@ static void
3329handle_peer_pull_reply (void *cls, 3341handle_peer_pull_reply (void *cls,
3330 const struct GNUNET_RPS_P2P_PullReplyMessage *msg) 3342 const struct GNUNET_RPS_P2P_PullReplyMessage *msg)
3331{ 3343{
3344 const struct ChannelCtx *channel_ctx = cls;
3345 const struct GNUNET_PeerIdentity *sender = &channel_ctx->peer_ctx->peer_id;
3332 const struct GNUNET_PeerIdentity *peers; 3346 const struct GNUNET_PeerIdentity *peers;
3333 struct GNUNET_PeerIdentity *sender = cls;
3334 uint32_t i; 3347 uint32_t i;
3335#ifdef ENABLE_MALICIOUS 3348#ifdef ENABLE_MALICIOUS
3336 struct AttackedPeer *tmp_att_peer; 3349 struct AttackedPeer *tmp_att_peer;
@@ -3368,9 +3381,7 @@ handle_peer_pull_reply (void *cls,
3368 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (att_peer_set, 3381 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (att_peer_set,
3369 &peers[i]) 3382 &peers[i])
3370 && GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (mal_peer_set, 3383 && GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (mal_peer_set,
3371 &peers[i]) 3384 &peers[i]))
3372 && 0 != GNUNET_CRYPTO_cmp_peer_identity (&peers[i],
3373 &own_identity))
3374 { 3385 {
3375 tmp_att_peer = GNUNET_new (struct AttackedPeer); 3386 tmp_att_peer = GNUNET_new (struct AttackedPeer);
3376 tmp_att_peer->peer_id = peers[i]; 3387 tmp_att_peer->peer_id = peers[i];
@@ -3382,21 +3393,17 @@ handle_peer_pull_reply (void *cls,
3382 continue; 3393 continue;
3383 } 3394 }
3384 #endif /* ENABLE_MALICIOUS */ 3395 #endif /* ENABLE_MALICIOUS */
3385 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, 3396 /* Make sure we 'know' about this peer */
3386 &peers[i])) 3397 (void) Peers_insert_peer (&peers[i]);
3387 {
3388 /* Make sure we 'know' about this peer */
3389 (void) Peers_insert_peer (&peers[i]);
3390 3398
3391 if (GNUNET_YES == Peers_check_peer_valid (&peers[i])) 3399 if (GNUNET_YES == Peers_check_peer_valid (&peers[i]))
3392 { 3400 {
3393 CustomPeerMap_put (pull_map, &peers[i]); 3401 CustomPeerMap_put (pull_map, &peers[i]);
3394 } 3402 }
3395 else 3403 else
3396 { 3404 {
3397 Peers_schedule_operation (&peers[i], insert_in_pull_map); 3405 Peers_schedule_operation (&peers[i], insert_in_pull_map);
3398 (void) Peers_issue_peer_liveliness_check (&peers[i]); 3406 (void) Peers_issue_peer_liveliness_check (&peers[i]);
3399 }
3400 } 3407 }
3401 } 3408 }
3402 3409
@@ -3404,7 +3411,7 @@ handle_peer_pull_reply (void *cls,
3404 clean_peer (sender); 3411 clean_peer (sender);
3405 3412
3406 GNUNET_break_op (Peers_check_peer_known (sender)); 3413 GNUNET_break_op (Peers_check_peer_known (sender));
3407 GNUNET_CADET_receive_done (Peers_get_recv_channel (sender)); 3414 GNUNET_CADET_receive_done (channel_ctx->channel);
3408} 3415}
3409 3416
3410 3417
@@ -3831,10 +3838,8 @@ do_round (void *cls)
3831 for (i = 0; i < a_peers; i++) 3838 for (i = 0; i < a_peers; i++)
3832 { 3839 {
3833 peer = view_array[permut[i]]; 3840 peer = view_array[permut[i]];
3834 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, &peer)) // TODO 3841 // FIXME if this fails schedule/loop this for later
3835 { // FIXME if this fails schedule/loop this for later 3842 send_push (&peer);
3836 send_push (&peer);
3837 }
3838 } 3843 }
3839 3844
3840 /* Send PULL requests */ 3845 /* Send PULL requests */
@@ -3852,8 +3857,7 @@ do_round (void *cls)
3852 for (i = first_border; i < second_border; i++) 3857 for (i = first_border; i < second_border; i++)
3853 { 3858 {
3854 peer = view_array[permut[i]]; 3859 peer = view_array[permut[i]];
3855 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, &peer) && 3860 if ( GNUNET_NO == Peers_check_peer_flag (&peer, Peers_PULL_REPLY_PENDING))
3856 GNUNET_NO == Peers_check_peer_flag (&peer, Peers_PULL_REPLY_PENDING)) // TODO
3857 { // FIXME if this fails schedule/loop this for later 3861 { // FIXME if this fails schedule/loop this for later
3858 send_pull_request (&peer); 3862 send_pull_request (&peer);
3859 } 3863 }
@@ -3950,7 +3954,6 @@ do_round (void *cls)
3950 "-%s", 3954 "-%s",
3951 GNUNET_i2s_full (&peers_to_clean[i])); 3955 GNUNET_i2s_full (&peers_to_clean[i]));
3952 clean_peer (&peers_to_clean[i]); 3956 clean_peer (&peers_to_clean[i]);
3953 //peer_destroy_channel_send (sender);
3954 } 3957 }
3955 3958
3956 GNUNET_array_grow (peers_to_clean, peers_to_clean_size, 0); 3959 GNUNET_array_grow (peers_to_clean, peers_to_clean_size, 0);
@@ -4006,7 +4009,6 @@ do_round (void *cls)
4006 GNUNET_i2s (update_peer)); 4009 GNUNET_i2s (update_peer));
4007 insert_in_sampler (NULL, update_peer); 4010 insert_in_sampler (NULL, update_peer);
4008 clean_peer (update_peer); /* This cleans only if it is not in the view */ 4011 clean_peer (update_peer); /* This cleans only if it is not in the view */
4009 //peer_destroy_channel_send (sender);
4010 } 4012 }
4011 4013
4012 for (i = 0; i < CustomPeerMap_size (pull_map); i++) 4014 for (i = 0; i < CustomPeerMap_size (pull_map); i++)
@@ -4017,7 +4019,6 @@ do_round (void *cls)
4017 insert_in_sampler (NULL, CustomPeerMap_get_peer_by_index (pull_map, i)); 4019 insert_in_sampler (NULL, CustomPeerMap_get_peer_by_index (pull_map, i));
4018 /* This cleans only if it is not in the view */ 4020 /* This cleans only if it is not in the view */
4019 clean_peer (CustomPeerMap_get_peer_by_index (pull_map, i)); 4021 clean_peer (CustomPeerMap_get_peer_by_index (pull_map, i));
4020 //peer_destroy_channel_send (sender);
4021 } 4022 }
4022 4023
4023 4024
@@ -4120,6 +4121,8 @@ shutdown_task (void *cls)
4120 struct ClientContext *client_ctx; 4121 struct ClientContext *client_ctx;
4121 struct ReplyCls *reply_cls; 4122 struct ReplyCls *reply_cls;
4122 4123
4124 in_shutdown = GNUNET_YES;
4125
4123 LOG (GNUNET_ERROR_TYPE_DEBUG, 4126 LOG (GNUNET_ERROR_TYPE_DEBUG,
4124 "RPS is going down\n"); 4127 "RPS is going down\n");
4125 4128
@@ -4364,10 +4367,17 @@ run (void *cls,
4364 NULL, /* WindowSize handler */ 4367 NULL, /* WindowSize handler */
4365 cleanup_destroyed_channel, /* Disconnect handler */ 4368 cleanup_destroyed_channel, /* Disconnect handler */
4366 cadet_handlers); 4369 cadet_handlers);
4370 if (NULL == cadet_port)
4371 {
4372 LOG (GNUNET_ERROR_TYPE_ERROR,
4373 "Cadet port `%s' is already in use.\n",
4374 GNUNET_APPLICATION_PORT_RPS);
4375 GNUNET_assert (0);
4376 }
4367 4377
4368 4378
4369 peerinfo_handle = GNUNET_PEERINFO_connect (cfg); 4379 peerinfo_handle = GNUNET_PEERINFO_connect (cfg);
4370 Peers_initialise (fn_valid_peers, cadet_handle, &own_identity); 4380 Peers_initialise (fn_valid_peers, cadet_handle);
4371 GNUNET_free (fn_valid_peers); 4381 GNUNET_free (fn_valid_peers);
4372 4382
4373 /* Initialise sampler */ 4383 /* Initialise sampler */
diff --git a/src/rps/gnunet-service-rps_custommap.c b/src/rps/gnunet-service-rps_custommap.c
index 42507655b..9e003eb39 100644
--- a/src/rps/gnunet-service-rps_custommap.c
+++ b/src/rps/gnunet-service-rps_custommap.c
@@ -213,7 +213,7 @@ CustomPeerMap_remove_peer (const struct CustomPeerMap *c_peer_map,
213 GNUNET_assert (NULL != last_index); 213 GNUNET_assert (NULL != last_index);
214 GNUNET_assert (CustomPeerMap_size (c_peer_map) == *last_index); 214 GNUNET_assert (CustomPeerMap_size (c_peer_map) == *last_index);
215 GNUNET_CONTAINER_multihashmap32_put (c_peer_map->hash_map, *index, last_p, 215 GNUNET_CONTAINER_multihashmap32_put (c_peer_map->hash_map, *index, last_p,
216 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 216 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
217 GNUNET_CONTAINER_multihashmap32_remove_all (c_peer_map->hash_map, *last_index); 217 GNUNET_CONTAINER_multihashmap32_remove_all (c_peer_map->hash_map, *last_index);
218 *last_index = *index; 218 *last_index = *index;
219 } 219 }
diff --git a/src/rps/rps-test_util.c b/src/rps/rps-test_util.c
index d47e4952f..08fe96097 100644
--- a/src/rps/rps-test_util.c
+++ b/src/rps/rps-test_util.c
@@ -31,6 +31,17 @@
31 31
32#define LOG(kind, ...) GNUNET_log_from(kind,"rps-test_util",__VA_ARGS__) 32#define LOG(kind, ...) GNUNET_log_from(kind,"rps-test_util",__VA_ARGS__)
33 33
34#define B2B_PAT "%c%c%c%c%c%c%c%c"
35#define B2B(byte) \
36 (byte & 0x80 ? '1' : '0'), \
37 (byte & 0x40 ? '1' : '0'), \
38 (byte & 0x20 ? '1' : '0'), \
39 (byte & 0x10 ? '1' : '0'), \
40 (byte & 0x08 ? '1' : '0'), \
41 (byte & 0x04 ? '1' : '0'), \
42 (byte & 0x02 ? '1' : '0'), \
43 (byte & 0x01 ? '1' : '0')
44
34#ifndef TO_FILE 45#ifndef TO_FILE
35#define TO_FILE 46#define TO_FILE
36#endif /* TO_FILE */ 47#endif /* TO_FILE */
@@ -155,6 +166,9 @@ to_file_raw (const char *file_name, const char *buf, size_t size_buf)
155 166
156 return; 167 return;
157 } 168 }
169 LOG (GNUNET_ERROR_TYPE_WARNING,
170 "Wrote %u bytes raw.\n",
171 size_written);
158 if (GNUNET_YES != GNUNET_DISK_file_close (f)) 172 if (GNUNET_YES != GNUNET_DISK_file_close (f))
159 LOG (GNUNET_ERROR_TYPE_WARNING, 173 LOG (GNUNET_ERROR_TYPE_WARNING,
160 "Unable to close file\n"); 174 "Unable to close file\n");
@@ -180,6 +194,8 @@ to_file_raw_unaligned (const char *file_name,
180 // num_bits_buf_unaligned = bits_needed % 8; 194 // num_bits_buf_unaligned = bits_needed % 8;
181 // return; 195 // return;
182 //} 196 //}
197 LOG (GNUNET_ERROR_TYPE_DEBUG,
198 "Was asked to write %u bits\n", bits_needed);
183 199
184 char buf_write[size_buf + 1]; 200 char buf_write[size_buf + 1];
185 const unsigned bytes_iter = (0 != bits_needed % 8? 201 const unsigned bytes_iter = (0 != bits_needed % 8?
@@ -187,6 +203,14 @@ to_file_raw_unaligned (const char *file_name,
187 bits_needed/8); 203 bits_needed/8);
188 // TODO what if no iteration happens? 204 // TODO what if no iteration happens?
189 unsigned size_buf_write = 0; 205 unsigned size_buf_write = 0;
206 LOG (GNUNET_ERROR_TYPE_DEBUG,
207 "num_bits_buf_unaligned: %u\n",
208 num_bits_buf_unaligned);
209 LOG (GNUNET_ERROR_TYPE_DEBUG,
210 "ua args: size_buf: %u, bits_needed: %u -> iter: %u\n",
211 size_buf,
212 bits_needed,
213 bytes_iter);
190 buf_write[0] = buf_unaligned; 214 buf_write[0] = buf_unaligned;
191 /* Iterate over input bytes */ 215 /* Iterate over input bytes */
192 for (unsigned i = 0; i < bytes_iter; i++) 216 for (unsigned i = 0; i < bytes_iter; i++)
@@ -227,17 +251,57 @@ to_file_raw_unaligned (const char *file_name,
227 { 251 {
228 num_bits_needed_iter = 8; 252 num_bits_needed_iter = 8;
229 } 253 }
254 LOG (GNUNET_ERROR_TYPE_DEBUG,
255 "number of bits needed in this iteration: %u\n",
256 num_bits_needed_iter);
230 mask_bits_needed_iter = ((char) 1 << num_bits_needed_iter) - 1; 257 mask_bits_needed_iter = ((char) 1 << num_bits_needed_iter) - 1;
258 LOG (GNUNET_ERROR_TYPE_DEBUG,
259 "mask needed bits (current iter): "B2B_PAT"\n",
260 B2B(mask_bits_needed_iter));
261 LOG (GNUNET_ERROR_TYPE_DEBUG,
262 "Unaligned byte: "B2B_PAT" (%u bits)\n",
263 B2B(buf_unaligned),
264 num_bits_buf_unaligned);
231 byte_input = buf[i]; 265 byte_input = buf[i];
266 LOG (GNUNET_ERROR_TYPE_DEBUG,
267 "next whole input byte: "B2B_PAT"\n",
268 B2B(byte_input));
232 byte_input &= mask_bits_needed_iter; 269 byte_input &= mask_bits_needed_iter;
233 num_bits_to_align = 8 - num_bits_buf_unaligned; 270 num_bits_to_align = 8 - num_bits_buf_unaligned;
271 LOG (GNUNET_ERROR_TYPE_DEBUG,
272 "input byte, needed bits: "B2B_PAT"\n",
273 B2B(byte_input));
274 LOG (GNUNET_ERROR_TYPE_DEBUG,
275 "number of bits needed to align unaligned bit: %u\n",
276 num_bits_to_align);
234 num_bits_to_move = min (num_bits_to_align, num_bits_needed_iter); 277 num_bits_to_move = min (num_bits_to_align, num_bits_needed_iter);
278 LOG (GNUNET_ERROR_TYPE_DEBUG,
279 "number of bits of new byte to move: %u\n",
280 num_bits_to_move);
235 mask_input_to_move = ((char) 1 << num_bits_to_move) - 1; 281 mask_input_to_move = ((char) 1 << num_bits_to_move) - 1;
282 LOG (GNUNET_ERROR_TYPE_DEBUG,
283 "mask of bits of new byte to take for moving: "B2B_PAT"\n",
284 B2B(mask_input_to_move));
236 bits_to_move = byte_input & mask_input_to_move; 285 bits_to_move = byte_input & mask_input_to_move;
286 LOG (GNUNET_ERROR_TYPE_DEBUG,
287 "masked bits of new byte to take for moving: "B2B_PAT"\n",
288 B2B(bits_to_move));
237 distance_shift_bits = num_bits_buf_unaligned; 289 distance_shift_bits = num_bits_buf_unaligned;
290 LOG (GNUNET_ERROR_TYPE_DEBUG,
291 "distance needed to shift bits to their correct spot: %u\n",
292 distance_shift_bits);
238 bits_moving = bits_to_move << distance_shift_bits; 293 bits_moving = bits_to_move << distance_shift_bits;
294 LOG (GNUNET_ERROR_TYPE_DEBUG,
295 "shifted, masked bits of new byte being moved: "B2B_PAT"\n",
296 B2B(bits_moving));
239 byte_to_fill = buf_unaligned | bits_moving; 297 byte_to_fill = buf_unaligned | bits_moving;
240 if (num_bits_buf_unaligned + num_bits_needed_iter > 8) 298 LOG (GNUNET_ERROR_TYPE_DEBUG,
299 "byte being filled: "B2B_PAT"\n",
300 B2B(byte_to_fill));
301 LOG (GNUNET_ERROR_TYPE_DEBUG,
302 "pending bytes: %u\n",
303 num_bits_buf_unaligned + num_bits_needed_iter);
304 if (num_bits_buf_unaligned + num_bits_needed_iter >= 8)
241 { 305 {
242 /* buf_unaligned was aligned by filling 306 /* buf_unaligned was aligned by filling
243 * -> can be written to storage */ 307 * -> can be written to storage */
@@ -246,10 +310,22 @@ to_file_raw_unaligned (const char *file_name,
246 310
247 /* store the leftover, unaligned bits in buffer */ 311 /* store the leftover, unaligned bits in buffer */
248 mask_input_leftover = mask_bits_needed_iter & (~ mask_input_to_move); 312 mask_input_leftover = mask_bits_needed_iter & (~ mask_input_to_move);
313 LOG (GNUNET_ERROR_TYPE_DEBUG,
314 "mask of leftover bits of new byte: "B2B_PAT"\n",
315 B2B(mask_input_leftover));
249 byte_input_leftover = byte_input & mask_input_leftover; 316 byte_input_leftover = byte_input & mask_input_leftover;
317 LOG (GNUNET_ERROR_TYPE_DEBUG,
318 "masked, leftover bits of new byte: "B2B_PAT"\n",
319 B2B(byte_input_leftover));
250 num_bits_leftover = num_bits_needed_iter - num_bits_to_move; 320 num_bits_leftover = num_bits_needed_iter - num_bits_to_move;
251 num_bits_discard = 8 - num_bits_needed_iter; 321 LOG (GNUNET_ERROR_TYPE_DEBUG,
322 "number of unaligned bits left: %u\n",
323 num_bits_leftover);
324 //num_bits_discard = 8 - num_bits_needed_iter;
252 byte_unaligned_new = byte_input_leftover >> num_bits_to_move; 325 byte_unaligned_new = byte_input_leftover >> num_bits_to_move;
326 LOG (GNUNET_ERROR_TYPE_DEBUG,
327 "new unaligned byte: "B2B_PAT"\n",
328 B2B(byte_unaligned_new));
253 buf_unaligned = byte_unaligned_new; 329 buf_unaligned = byte_unaligned_new;
254 num_bits_buf_unaligned = num_bits_leftover % 8; 330 num_bits_buf_unaligned = num_bits_leftover % 8;
255 } 331 }