X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Frps%2Fgnunet-service-rps.c;h=9e3a1a6c87d57394619efbea7bc1a570378f45dd;hb=5e11eb124cc16bc65d42a47076e13d3b0147b838;hp=67e79daf73b9176968de6deacacd79794be3bb63;hpb=b25eb3c3774f491c303fe4f68dd7c225246afdfe;p=oweals%2Fgnunet.git diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c index 67e79daf7..9e3a1a6c8 100644 --- a/src/rps/gnunet-service-rps.c +++ b/src/rps/gnunet-service-rps.c @@ -371,6 +371,12 @@ uint32_t mal_type = 0; */ static struct GNUNET_PeerIdentity *mal_peers = NULL; +/** + * Hashmap of malicious peers used as set. + * Used to more efficiently check whether we know that peer. + */ +static struct GNUNET_CONTAINER_MultiPeerMap *mal_peer_set = NULL; + /** * Number of other malicious peers */ @@ -391,7 +397,7 @@ struct AttackedPeer /** * PeerID */ - struct GNUNET_PeerIdentity *peer_id; + struct GNUNET_PeerIdentity peer_id; }; /** @@ -406,10 +412,16 @@ static struct AttackedPeer *att_peers_tail = NULL; */ static struct AttackedPeer *att_peer_index = NULL; +/** + * Hashmap of attacked peers used as set. + * Used to more efficiently check whether we know that peer. + */ +static struct GNUNET_CONTAINER_MultiPeerMap *att_peer_set = NULL; + /** * Number of attacked peers */ -//static uint32_t num_attacked_peers = 0; +static uint32_t num_attacked_peers = 0; /** @@ -1032,6 +1044,82 @@ est_request_rate() } +/** + * Add all peers in @a peer_array to @peer_map used as set. + * + * @param peer_array array containing the peers + * @param num_peers number of peers in @peer_array + * @param peer_map the peermap to use as set + */ +static void +add_peer_array_to_set (const struct GNUNET_PeerIdentity *peer_array, + unsigned int num_peers, + struct GNUNET_CONTAINER_MultiPeerMap *peer_map) +{ + unsigned int i; + if (NULL == peer_map) + peer_map = GNUNET_CONTAINER_multipeermap_create (num_peers, + GNUNET_NO); + for (i = 0 ; i < num_peers ; i++) + { + GNUNET_CONTAINER_multipeermap_put (peer_map, + &peer_array[i], + NULL, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + } +} + + +/** + * Send a PULL REPLY to @a peer_id + * + * @param peer_id the peer to send the reply to. + * @param peer_ids the peers to send to @a peer_id + * @param num_peer_ids the number of peers to send to @a peer_id + */ +static void +send_pull_reply (const struct GNUNET_PeerIdentity *peer_id, + const struct GNUNET_PeerIdentity *peer_ids, + unsigned int num_peer_ids) +{ + uint32_t send_size; + struct GNUNET_MQ_Handle *mq; + struct GNUNET_MQ_Envelope *ev; + struct GNUNET_RPS_P2P_PullReplyMessage *out_msg; + + /* Compute actual size */ + send_size = sizeof (struct GNUNET_RPS_P2P_PullReplyMessage) + + num_peer_ids * sizeof (struct GNUNET_PeerIdentity); + + if (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < send_size) + /* Compute number of peers to send + * If too long, simply truncate */ + // TODO select random ones via permutation + // or even better: do good protocol design + send_size = + (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - + sizeof (struct GNUNET_RPS_P2P_PullReplyMessage)) / + sizeof (struct GNUNET_PeerIdentity); + else + send_size = num_peer_ids; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "PULL REQUEST from peer %s received, going to send %u peers\n", + GNUNET_i2s (peer_id), send_size); + + mq = get_mq (peer_map, peer_id); + + ev = GNUNET_MQ_msg_extra (out_msg, + send_size * sizeof (struct GNUNET_PeerIdentity), + GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY); + out_msg->num_peers = htonl (send_size); + memcpy (&out_msg[1], peer_ids, + send_size * sizeof (struct GNUNET_PeerIdentity)); + + GNUNET_MQ_send (mq, ev); +} + + /*********************************************************************** * /Util functions ***********************************************************************/ @@ -1243,10 +1331,40 @@ handle_peer_push (void *cls, // (check the proof of work) - peer = (const struct GNUNET_PeerIdentity *) GNUNET_CADET_channel_get_info (channel, GNUNET_CADET_OPTION_PEER); + peer = (const struct GNUNET_PeerIdentity *) + GNUNET_CADET_channel_get_info (channel, GNUNET_CADET_OPTION_PEER); // FIXME wait for cadet to change this function + LOG (GNUNET_ERROR_TYPE_DEBUG, "PUSH received (%s)\n", GNUNET_i2s (peer)); + #ifdef ENABLE_MALICIOUS + struct AttackedPeer *tmp_att_peer; + + tmp_att_peer = GNUNET_new (struct AttackedPeer); + memcpy (&tmp_att_peer->peer_id, peer, sizeof (struct GNUNET_PeerIdentity)); + if (1 == mal_type) + { /* Try to maximise representation */ + if (NULL == att_peer_set) + att_peer_set = GNUNET_CONTAINER_multipeermap_create (1, GNUNET_NO); + if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (att_peer_set, + peer)) + { + GNUNET_CONTAINER_DLL_insert (att_peers_head, + att_peers_tail, + tmp_att_peer); + add_peer_array_to_set (peer, 1, att_peer_set); + } + return GNUNET_OK; + } + + + else if (2 == mal_type) + { /* We attack one single well-known peer - simply ignore */ + return GNUNET_OK; + } + + #endif /* ENABLE_MALICIOUS */ + /* Add the sending peer to the push_list */ if (GNUNET_NO == in_arr (push_list, push_list_size, peer)) GNUNET_array_append (push_list, push_list_size, *peer); @@ -1254,6 +1372,7 @@ handle_peer_push (void *cls, return GNUNET_OK; } + /** * Handle PULL REQUEST request message from another peer. * @@ -1271,47 +1390,30 @@ handle_peer_pull_request (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_PeerIdentity *peer; - uint32_t send_size; - struct GNUNET_MQ_Handle *mq; - struct GNUNET_MQ_Envelope *ev; - struct GNUNET_RPS_P2P_PullReplyMessage *out_msg; - peer = (struct GNUNET_PeerIdentity *) GNUNET_CADET_channel_get_info (channel, GNUNET_CADET_OPTION_PEER); // FIXME wait for cadet to change this function - /* Compute actual size */ - send_size = sizeof (struct GNUNET_RPS_P2P_PullReplyMessage) + - gossip_list_size * sizeof (struct GNUNET_PeerIdentity); - - if (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < send_size) - /* Compute number of peers to send - * If too long, simply truncate */ - // TODO select random ones via permutation - send_size = - (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - - sizeof (struct GNUNET_RPS_P2P_PullReplyMessage)) / - sizeof (struct GNUNET_PeerIdentity); - else - send_size = gossip_list_size; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "PULL REQUEST from peer %s received, going to send %u peers\n", - GNUNET_i2s (peer), send_size); - - mq = get_mq (peer_map, peer); + #ifdef ENABLE_MALICIOUS + if (1 == mal_type) + { /* Try to maximise representation */ + send_pull_reply (peer, mal_peers, num_mal_peers); + return GNUNET_OK; + } - ev = GNUNET_MQ_msg_extra (out_msg, - send_size * sizeof (struct GNUNET_PeerIdentity), - GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY); - //out_msg->num_peers = htonl (gossip_list_size); - out_msg->num_peers = htonl (send_size); - memcpy (&out_msg[1], gossip_list, - send_size * sizeof (struct GNUNET_PeerIdentity)); + else if (2 == mal_type) + { /* Try to partition network */ + if (GNUNET_YES == GNUNET_CRYPTO_cmp_peer_identity (&attacked_peer, peer)) + { + send_pull_reply (peer, mal_peers, num_mal_peers); + } + return GNUNET_OK; + } + #endif /* ENABLE_MALICIOUS */ - GNUNET_MQ_send (mq, ev); + send_pull_reply (peer, gossip_list, gossip_list_size); return GNUNET_OK; } @@ -1554,6 +1656,7 @@ handle_client_act_malicious (void *cls, if (1 == mal_type) { /* Try to maximise representation */ /* Add other malicious peers to those we already know */ + num_mal_peers_sent = ntohl (in_msg->num_peers); num_mal_peers_old = num_mal_peers; GNUNET_array_grow (mal_peers, @@ -1563,10 +1666,16 @@ handle_client_act_malicious (void *cls, peers, num_mal_peers_sent * sizeof (struct GNUNET_PeerIdentity)); + /* Add all mal peers to mal_peer_set */ + add_peer_array_to_set (&mal_peers[num_mal_peers_old], + num_mal_peers_sent, + mal_peer_set); + /* Substitute do_round () with do_mal_round () */ GNUNET_SCHEDULER_cancel (do_round_task); do_round_task = GNUNET_SCHEDULER_add_now (&do_mal_round, NULL); } + else if (2 == mal_type) { /* Try to partition the network */ /* Add other malicious peers to those we already know */ @@ -1579,6 +1688,11 @@ handle_client_act_malicious (void *cls, peers, num_mal_peers_sent * sizeof (struct GNUNET_PeerIdentity)); + /* Add all mal peers to mal_peer_set */ + add_peer_array_to_set (&mal_peers[num_mal_peers_old], + num_mal_peers_sent, + mal_peer_set); + /* Store the one attacked peer */ memcpy (&attacked_peer, &peers[num_mal_peers_sent], @@ -1619,34 +1733,53 @@ do_mal_round (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) uint32_t num_pushes; uint32_t i; struct GNUNET_TIME_Relative time_next_round; + struct AttackedPeer *tmp_att_peer; LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to execute next round maliciously.\n"); /* Do malicious actions */ if (1 == mal_type) { /* Try to maximise representation */ - num_pushes = min (min (push_limit, /* FIXME: attacked peer */ num_mal_peers), GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE); + + /* The maximum of pushes we're going to send this round */ + num_pushes = min (min (push_limit, + num_attacked_peers), + GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE); + + /* Send PUSHes to attacked peers */ for (i = 0 ; i < num_pushes ; i++) - { /* Send PUSHes to attacked peers */ + { if (att_peers_tail == att_peer_index) att_peer_index = att_peers_head; else att_peer_index = att_peer_index->next; - send_push (att_peer_index->peer_id); + send_push (&att_peer_index->peer_id); + } + + /* Send PULLs to some peers to learn about additional peers to attack */ + for (i = 0 ; i < num_pushes * alpha ; i++) + { + if (att_peers_tail == tmp_att_peer) + tmp_att_peer = att_peers_head; + else + att_peer_index = tmp_att_peer->next; - // TODO send pulls - // send_pull_request + send_pull_request (&tmp_att_peer->peer_id); } } + + else if (2 == mal_type) { /** * Try to partition the network - * Send as many pushes to attacked peer as possible + * Send as many pushes to the attacked peer as possible + * That is one push per round as it will ignore more. */ send_push (&attacked_peer); } + /* Schedule next round */ time_next_round = compute_rand_delay (round_interval, 2); @@ -2018,6 +2151,10 @@ shutdown_task (void *cls, GNUNET_array_grow (pull_list, pull_list_size, 0); #ifdef ENABLE_MALICIOUS GNUNET_array_grow (mal_peers, num_mal_peers, 0); + if (NULL != mal_peer_set) + GNUNET_CONTAINER_multipeermap_destroy (mal_peer_set); + if (NULL != att_peer_set) + GNUNET_CONTAINER_multipeermap_destroy (att_peer_set); // TODO empty attacked_peers DLL #endif /* ENABLE_MALICIOUS */ }