diff options
author | Julius Bünger <buenger@mytum.de> | 2015-01-22 14:13:56 +0000 |
---|---|---|
committer | Julius Bünger <buenger@mytum.de> | 2015-01-22 14:13:56 +0000 |
commit | fe99589f9fa55307b56552795874b95c2d0a17c0 (patch) | |
tree | 867cea193daa86fcaff3c2ed841f7c1cee114415 | |
parent | fea54eae46daf5fee2d88c7c00a0f191dfe07dfd (diff) | |
download | gnunet-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.c | 143 |
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 * |
75 | get_rand_peer (const struct GNUNET_PeerIdentity *peer_list, unsigned int size); | 75 | get_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 | */ |
96 | enum PeerFlags | 97 | enum 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 | */ | ||
342 | struct GNUNET_PeerIdentity *pending_pull_reply_list; | ||
343 | |||
344 | /** | ||
345 | * Size of #pending_pull_reply_list. | ||
346 | */ | ||
347 | uint32_t pending_pull_reply_list_size; | ||
348 | |||
349 | |||
350 | /** | ||
339 | * Number of history update tasks. | 351 | * Number of history update tasks. |
340 | */ | 352 | */ |
341 | uint32_t num_hist_update_tasks; | 353 | uint32_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 | ||
397 | rem_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 * |
386 | get_rand_peer (const struct GNUNET_PeerIdentity *peer_list, unsigned int list_size) | 422 | get_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"); |