*/
static unsigned long long malicious_droppers;
+/**
+ * Bloom filter to restrict malicious nodes chosen.
+ */
+struct GNUNET_CONTAINER_BloomFilter *malicious_bloom;
+
+/**
+ * Whether malicious droppers should be chosen based on proximity to a key.
+ */
+static int malicious_sybil;
+
+/**
+ * Target for the malicious sybil nodes (choose the closest to this key).
+ */
+static GNUNET_HashCode sybil_target;
+
/**
* How often to send malicious GET messages.
*/
GNUNET_DHT_put(test_put->dht_handle,
&known_keys[test_put->uid],
put_replication,
- GNUNET_DHT_RO_NONE,
+ GNUNET_DHT_RO_NONE,
GNUNET_BLOCK_TYPE_TEST,
sizeof(data), data,
GNUNET_TIME_UNIT_FOREVER_ABS,
}
/**
- * Set up some all of the put and get operations we want
- * to do. Allocate data structure for each, add to list,
- * then call actual insert functions.
+ * Set up all of the put and get operations we want to do
+ * in the current round. Allocate data structure for each,
+ * add to list, then schedule the actual PUT operations.
*/
static void
setup_puts_and_gets (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
{
int i;
- uint32_t temp_daemon;
struct TestPutContext *test_put;
struct TestGetContext *test_get;
#if REMEMBER
test_put = GNUNET_malloc(sizeof(struct TestPutContext));
test_put->uid = i;
GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &known_keys[i]);
- temp_daemon = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers);
- test_put->daemon = GNUNET_TESTING_daemon_get(pg, temp_daemon);
+ /* Set first X bits to match the chosen sybil location if we want to do the sybil attack! */
+ if (GNUNET_YES == malicious_sybil)
+ {
+ memcpy(&known_keys[i], &sybil_target, sizeof(GNUNET_HashCode) / 2);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Distance between sybil location and key is %d\n", GNUNET_CRYPTO_hash_matching_bits(&known_keys[i], &sybil_target));
+ }
+ test_put->daemon = GNUNET_TESTING_daemon_get(pg, GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers));
+ /* Don't start PUTs at malicious peers! */
+ if (malicious_bloom != NULL)
+ {
+ while (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test(malicious_bloom, &test_put->daemon->id.hashPubKey))
+ test_put->daemon = GNUNET_TESTING_daemon_get(pg, GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers));
+ }
+
test_put->next = all_puts;
all_puts = test_put;
}
remember[test_get->uid][temp_daemon] = 1;
#endif
test_get->daemon = GNUNET_TESTING_daemon_get(pg, GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers));
+ /* Don't start GETs at malicious peers! */
+ if (malicious_bloom != NULL)
+ {
+ while (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test(malicious_bloom, &test_get->daemon->id.hashPubKey))
+ test_get->daemon = GNUNET_TESTING_daemon_get(pg, GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers));
+ }
test_get->next = all_gets;
all_gets = test_get;
}
&malicious_disconnect_task, ctx);
}
+/**
+ * Choose the next peer from the peer group to set as malicious.
+ * If we are doing a sybil attack, find the nearest peer to the
+ * sybil location that has not already been set malicious. Otherwise
+ * just choose a random not already chosen peer.
+ *
+ * @param pg the peer group
+ * @param bloom the bloomfilter which contains all peer already
+ * chosen to be malicious
+ */
+static uint32_t
+choose_next_malicious (struct GNUNET_TESTING_PeerGroup *pg, struct GNUNET_CONTAINER_BloomFilter *bloom)
+{
+ int i;
+ int nearest;
+ int bits_match;
+ int curr_distance;
+ struct GNUNET_TESTING_Daemon *temp_daemon;
+
+ curr_distance = 0;
+
+ if (GNUNET_YES == malicious_sybil)
+ {
+ for (i = 0; i < num_peers; i++)
+ {
+ temp_daemon = GNUNET_TESTING_daemon_get(pg, i);
+ /* Check if this peer matches the bloomfilter */
+ if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (bloom, &temp_daemon->id.hashPubKey))
+ continue;
+
+ bits_match = GNUNET_CRYPTO_hash_matching_bits (&temp_daemon->id.hashPubKey, &sybil_target);
+ if (bits_match >= curr_distance)
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Found nearer peer %s to %s, old matching bits %d, new %d\n", GNUNET_i2s(&temp_daemon->id), GNUNET_h2s(&sybil_target), curr_distance, bits_match);
+ nearest = i;
+ curr_distance = bits_match;
+ }
+ }
+ }
+ else
+ {
+ nearest = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers);
+ while (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (bloom, &temp_daemon->id.hashPubKey))
+ {
+ nearest = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers);
+ }
+ }
+
+ return nearest;
+}
+
/**
* Select randomly from set of known peers,
* set the desired number of peers to the
for (i = 0; i < malicious_getters; i++)
{
ctx = GNUNET_malloc(sizeof(struct MaliciousContext));
- temp_daemon = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers);
+ temp_daemon = choose_next_malicious(pg, malicious_bloom);
ctx->daemon = GNUNET_TESTING_daemon_get(pg, temp_daemon);
+ GNUNET_CONTAINER_bloomfilter_add(malicious_bloom, &ctx->daemon->id.hashPubKey);
ctx->malicious_type = GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_GET;
GNUNET_SCHEDULER_add_now (&set_malicious, ctx);
for (i = 0; i < malicious_putters; i++)
{
ctx = GNUNET_malloc(sizeof(struct MaliciousContext));
- temp_daemon = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers);
+ temp_daemon = choose_next_malicious(pg, malicious_bloom);
ctx->daemon = GNUNET_TESTING_daemon_get(pg, temp_daemon);
+ GNUNET_CONTAINER_bloomfilter_add(malicious_bloom, &ctx->daemon->id.hashPubKey);
ctx->malicious_type = GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_PUT;
GNUNET_SCHEDULER_add_now (&set_malicious, ctx);
for (i = 0; i < malicious_droppers; i++)
{
ctx = GNUNET_malloc(sizeof(struct MaliciousContext));
- temp_daemon = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, num_peers);
+ temp_daemon = choose_next_malicious(pg, malicious_bloom);
ctx->daemon = GNUNET_TESTING_daemon_get(pg, temp_daemon);
+ GNUNET_CONTAINER_bloomfilter_add(malicious_bloom, &ctx->daemon->id.hashPubKey);
ctx->malicious_type = GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_DROP;
GNUNET_SCHEDULER_add_now (&set_malicious, ctx);
}
if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg, "DHT_TESTING", "MALICIOUS_AFTER_SETTLE"))
malicious_after_settle = GNUNET_YES;
+ if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg, "DHT_TESTING", "MALICIOUS_SYBIL"))
+ {
+ /* Set up the malicious target at random for this round */
+ GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &sybil_target);
+ malicious_sybil = GNUNET_YES;
+ }
+
+ if ((malicious_droppers > 0) || (malicious_getters > 0) || (malicious_putters > 0))
+ {
+ /* Create the bloomfilter for choosing which peers to set malicious */
+ malicious_bloom = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
+ }
+
/* The normal behavior of the DHT is to do find peer requests
* on its own. Only if this is explicitly turned off should
* the testing driver issue find peer requests (even though
options, &run, &ok);
+ if (malicious_bloom != NULL)
+ GNUNET_CONTAINER_bloomfilter_free (malicious_bloom);
+
if (ret != GNUNET_OK)
{
GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "`gnunet-dht-driver': Failed with error code %d\n", ret);