aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Bünger <buenger@mytum.de>2015-01-22 14:13:56 +0000
committerJulius Bünger <buenger@mytum.de>2015-01-22 14:13:56 +0000
commitfe99589f9fa55307b56552795874b95c2d0a17c0 (patch)
tree867cea193daa86fcaff3c2ed841f7c1cee114415
parentfea54eae46daf5fee2d88c7c00a0f191dfe07dfd (diff)
downloadgnunet-fe99589f9fa55307b56552795874b95c2d0a17c0.tar.gz
gnunet-fe99589f9fa55307b56552795874b95c2d0a17c0.zip
keep track of whom we sent pull requests to (avoid duplicate replys)
-rw-r--r--src/rps/gnunet-service-rps.c143
1 files changed, 111 insertions, 32 deletions
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index 929e47a42..8e710e580 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -72,7 +72,8 @@ static struct GNUNET_PeerIdentity *own_identity;
72 72
73 73
74 struct GNUNET_PeerIdentity * 74 struct GNUNET_PeerIdentity *
75get_rand_peer (const struct GNUNET_PeerIdentity *peer_list, unsigned int size); 75get_rand_peer_ignore_list (const struct GNUNET_PeerIdentity *peer_list, unsigned int size,
76 const struct GNUNET_PeerIdentity *ignore_list, unsigned int ignore_size);
76 77
77 78
78/*********************************************************************** 79/***********************************************************************
@@ -95,15 +96,15 @@ struct client_ctx
95 */ 96 */
96enum PeerFlags 97enum PeerFlags
97{ 98{
98 IN_OTHER_SAMPLER_LIST = 0x01, // unneeded? 99 PULL_REPLY_PENDING = 0x01,
99 IN_OTHER_GOSSIP_LIST = 0x02, // unneeded? 100 IN_OTHER_GOSSIP_LIST = 0x02, // unneeded?
100 IN_OWN_SAMPLER_LIST = 0x04, // unneeded? 101 IN_OWN_SAMPLER_LIST = 0x04, // unneeded?
101 IN_OWN_GOSSIP_LIST = 0x08, // unneeded? 102 IN_OWN_GOSSIP_LIST = 0x08, // unneeded?
102 103
103 /** 104 /**
104 * We set this bit when we can be sure the other peer is/was live. 105 * We set this bit when we can be sure the other peer is/was live.
105 */ 106 */
106 LIVING = 0x10 107 LIVING = 0x10
107}; 108};
108 109
109 110
@@ -336,6 +337,17 @@ static struct GNUNET_TIME_Relative request_rate;
336 337
337 338
338/** 339/**
340 * List with the peers we sent requests to.
341 */
342struct GNUNET_PeerIdentity *pending_pull_reply_list;
343
344/**
345 * Size of #pending_pull_reply_list.
346 */
347uint32_t pending_pull_reply_list_size;
348
349
350/**
339 * Number of history update tasks. 351 * Number of history update tasks.
340 */ 352 */
341uint32_t num_hist_update_tasks; 353uint32_t num_hist_update_tasks;
@@ -378,33 +390,75 @@ in_arr (const struct GNUNET_PeerIdentity *array,
378 return GNUNET_YES; 390 return GNUNET_YES;
379} 391}
380 392
393/**
394 * Remove peer from list.
395 */
396 void
397rem_from_list (struct GNUNET_PeerIdentity *peer_list,
398 unsigned int *list_size,
399 const struct GNUNET_PeerIdentity *peer)
400{
401 unsigned int i;
402
403 for ( i = 0 ; i < *list_size ; i++ )
404 {
405 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&peer_list[i], peer))
406 {
407 if (i < *list_size -1)
408 { /* Not at the last entry -- shift peers left */
409 memcpy (&peer_list[i], &peer_list[i +1],
410 (*list_size - i -1) * sizeof (struct GNUNET_PeerIdentity));
411 }
412 /* Remove last entry (should be now useless PeerID) */
413 GNUNET_array_grow (peer_list, *list_size, *list_size -1);
414 }
415 }
416}
381 417
382/** 418/**
383 * Get random peer from the gossip list. 419 * Get random peer from the given list but don't return one from the @a ignore_list.
384 */ 420 */
385 struct GNUNET_PeerIdentity * 421 struct GNUNET_PeerIdentity *
386get_rand_peer (const struct GNUNET_PeerIdentity *peer_list, unsigned int list_size) 422get_rand_peer_ignore_list (const struct GNUNET_PeerIdentity *peer_list,
423 uint32_t list_size,
424 const struct GNUNET_PeerIdentity *ignore_list,
425 uint32_t ignore_size)
387{ 426{
388 uint32_t r_index; 427 uint32_t r_index;
428 uint32_t tmp_size;
429 struct GNUNET_PeerIdentity *tmp_peer_list;
389 struct GNUNET_PeerIdentity *peer; 430 struct GNUNET_PeerIdentity *peer;
390 431
432 tmp_size = 0;
433 tmp_peer_list = NULL;
434 GNUNET_array_grow (tmp_peer_list, tmp_size, list_size);
435 memcpy (tmp_peer_list, peer_list, list_size * sizeof (struct GNUNET_PeerIdentity));
391 peer = GNUNET_new (struct GNUNET_PeerIdentity); 436 peer = GNUNET_new (struct GNUNET_PeerIdentity);
392 // FIXME if we have only NULL in gossip list this will block 437 // FIXME if we have only NULL in gossip list this will block
393 // but then we might have a problem nevertheless 438 // but then we might have a problem nevertheless
394 439
395 do 440 do
396 { 441 {
397
398 /**; 442 /**;
399 * Choose the r_index of the peer we want to return 443 * Choose the r_index of the peer we want to return
400 * at random from the interval of the gossip list 444 * at random from the interval of the gossip list
401 */ 445 */
402 r_index = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, 446 r_index = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
403 list_size); 447 tmp_size);
448
449 *peer = tmp_peer_list[r_index];
450 if (in_arr (tmp_peer_list, list_size, peer))
451 {
452 rem_from_list (tmp_peer_list, &tmp_size, peer);
453 if (0 == tmp_size)
454 return NULL;
455 continue;
456 }
404 457
405 *peer = peer_list[r_index];
406 } while (NULL == peer); 458 } while (NULL == peer);
407 459
460 GNUNET_free (tmp_peer_list);
461
408 return peer; 462 return peer;
409} 463}
410 464
@@ -947,6 +1001,8 @@ handle_peer_pull_reply (void *cls,
947 struct GNUNET_RPS_P2P_PullReplyMessage *in_msg; 1001 struct GNUNET_RPS_P2P_PullReplyMessage *in_msg;
948 struct GNUNET_PeerIdentity *peers; 1002 struct GNUNET_PeerIdentity *peers;
949 struct PeerContext *peer_ctx; 1003 struct PeerContext *peer_ctx;
1004 struct GNUNET_PeerIdentity *sender;
1005 struct PeerContext *sender_ctx;
950 struct PeerOutstandingOp out_op; 1006 struct PeerOutstandingOp out_op;
951 uint32_t i; 1007 uint32_t i;
952 1008
@@ -965,13 +1021,22 @@ handle_peer_pull_reply (void *cls,
965 return GNUNET_SYSERR; 1021 return GNUNET_SYSERR;
966 } 1022 }
967 1023
968 // TODO check that we sent a request and that it is the first reply 1024 sender = (struct GNUNET_PeerIdentity *) GNUNET_CADET_channel_get_info (
1025 (struct GNUNET_CADET_Channel *) channel, GNUNET_CADET_OPTION_PEER);
1026 // Guess simply casting isn't the nicest way...
1027 // FIXME wait for cadet to change this function
1028 sender_ctx = get_peer_ctx (peer_map, sender);
1029
1030 if (0 == (peer_ctx->peer_flags || PULL_REPLY_PENDING))
1031 {
1032 GNUNET_break_op (0);
1033 return GNUNET_OK;
1034 }
969 1035
970 peers = (struct GNUNET_PeerIdentity *) &msg[1]; 1036 peers = (struct GNUNET_PeerIdentity *) &msg[1];
971 for ( i = 0 ; i < ntohl (in_msg->num_peers) ; i++ ) 1037 for ( i = 0 ; i < ntohl (in_msg->num_peers) ; i++ )
972 { 1038 {
973 peer_ctx = get_peer_ctx (peer_map, &peers[i]); 1039 peer_ctx = get_peer_ctx (peer_map, &peers[i]);
974
975 if ((0 != (peer_ctx->peer_flags && LIVING)) || 1040 if ((0 != (peer_ctx->peer_flags && LIVING)) ||
976 NULL != peer_ctx->recv_channel) 1041 NULL != peer_ctx->recv_channel)
977 { 1042 {
@@ -985,7 +1050,8 @@ handle_peer_pull_reply (void *cls,
985 } 1050 }
986 } 1051 }
987 1052
988 // TODO check that id is valid - whether it is reachable 1053 sender_ctx->peer_flags &= (~PULL_REPLY_PENDING);
1054 rem_from_list (pending_pull_reply_list, &pending_pull_reply_list_size, sender);
989 1055
990 return GNUNET_OK; 1056 return GNUNET_OK;
991} 1057}
@@ -1027,15 +1093,20 @@ do_round (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1027 n_peers, alpha, gossip_list_size); 1093 n_peers, alpha, gossip_list_size);
1028 for ( i = 0 ; i < n_peers ; i++ ) 1094 for ( i = 0 ; i < n_peers ; i++ )
1029 { 1095 {
1030 peer = get_rand_peer (gossip_list, gossip_list_size); 1096 // TODO
1031 if (own_identity != peer) 1097 peer = get_rand_peer_ignore_list (gossip_list, gossip_list_size,
1032 { // FIXME if this fails schedule/loop this for later 1098 NULL, 0);
1033 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending PUSH to peer %s of gossiped list.\n", GNUNET_i2s (peer)); 1099 if (NULL != peer)
1034 1100 {
1035 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_PUSH); 1101 if (own_identity != peer) // TODO
1036 // FIXME sometimes it returns a pointer to a freed mq 1102 { // FIXME if this fails schedule/loop this for later
1037 mq = get_mq (peer_map, peer); 1103 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending PUSH to peer %s of gossiped list.\n", GNUNET_i2s (peer));
1038 GNUNET_MQ_send (mq, ev); 1104
1105 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_PUSH);
1106 // FIXME sometimes it returns a pointer to a freed mq
1107 mq = get_mq (peer_map, peer);
1108 GNUNET_MQ_send (mq, ev);
1109 }
1039 } 1110 }
1040 } 1111 }
1041 } 1112 }
@@ -1052,15 +1123,21 @@ do_round (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1052 n_peers, beta, gossip_list_size); 1123 n_peers, beta, gossip_list_size);
1053 for ( i = 0 ; i < n_peers ; i++ ) 1124 for ( i = 0 ; i < n_peers ; i++ )
1054 { 1125 {
1055 peer = get_rand_peer (gossip_list, gossip_list_size); 1126 peer = get_rand_peer_ignore_list (gossip_list, gossip_list_size,
1056 if (own_identity != peer) 1127 pending_pull_reply_list, pending_pull_reply_list_size);
1057 { // FIXME if this fails schedule/loop this for later 1128 if (NULL != peer)
1058 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending PULL request to peer %s of gossiped list.\n", GNUNET_i2s (peer)); 1129 {
1059 1130 GNUNET_array_append (pending_pull_reply_list, pending_pull_reply_list_size, *peer);
1060 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST); 1131
1061 //pull_msg = NULL; 1132 if (own_identity != peer)
1062 mq = get_mq (peer_map, peer); 1133 { // FIXME if this fails schedule/loop this for later
1063 GNUNET_MQ_send (mq, ev); 1134 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending PULL request to peer %s of gossiped list.\n", GNUNET_i2s (peer));
1135
1136 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST);
1137 //pull_msg = NULL;
1138 mq = get_mq (peer_map, peer);
1139 GNUNET_MQ_send (mq, ev);
1140 }
1064 } 1141 }
1065 } 1142 }
1066 } 1143 }
@@ -1555,6 +1632,8 @@ run (void *cls,
1555 push_list_size = 0; 1632 push_list_size = 0;
1556 pull_list = NULL; 1633 pull_list = NULL;
1557 pull_list_size = 0; 1634 pull_list_size = 0;
1635 pending_pull_reply_list = NULL;
1636 pending_pull_reply_list_size = 0;
1558 1637
1559 1638
1560 LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting peers from CADET\n"); 1639 LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting peers from CADET\n");