From: Julius Bünger Date: Fri, 13 May 2016 22:49:10 +0000 (+0000) Subject: rps: store valid peer ids in file X-Git-Tag: initial-import-from-subversion-38251~878 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=c771f534d05d56a44da6390e1409d30fec438e5a;p=oweals%2Fgnunet.git rps: store valid peer ids in file --- diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c index 38a644b01..822c5e655 100644 --- a/src/rps/gnunet-service-rps.c +++ b/src/rps/gnunet-service-rps.c @@ -2183,6 +2183,7 @@ run (void *cls, { int size; int out_size; + char* fn_valid_peers; GNUNET_log_setup ("rps", GNUNET_error_type_to_string (GNUNET_ERROR_TYPE_DEBUG), NULL); cfg = c; @@ -2223,6 +2224,16 @@ run (void *cls, } LOG (GNUNET_ERROR_TYPE_DEBUG, "INITSIZE is %u\n", sampler_size_est_need); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, + "rps", + "FILENAME_VALID_PEERS", + &fn_valid_peers)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "rps", "FILENAME_VALID_PEERS"); + } + View_create (4); @@ -2273,8 +2284,10 @@ run (void *cls, &cleanup_destroyed_channel, cadet_handlers, ports); + peerinfo_handle = GNUNET_PEERINFO_connect (cfg); - Peers_initialise (cadet_handle, &own_identity); + Peers_initialise (fn_valid_peers, cadet_handle, &own_identity); + GNUNET_free (fn_valid_peers); /* Initialise sampler */ struct GNUNET_TIME_Relative half_round_interval; diff --git a/src/rps/gnunet-service-rps_peers.c b/src/rps/gnunet-service-rps_peers.c index 70ae30f76..2bbb8d705 100644 --- a/src/rps/gnunet-service-rps_peers.c +++ b/src/rps/gnunet-service-rps_peers.c @@ -214,6 +214,11 @@ static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers; */ static uint32_t num_valid_peers_max = UINT32_MAX; +/** + * @brief Filename of the file that stores the valid peers persistently. + */ +static char *filename_valid_peers; + /** * Set of all peers to keep track of them. */ @@ -385,7 +390,6 @@ static const struct GNUNET_PeerIdentity * get_random_peer_from_peermap (const struct GNUNET_CONTAINER_MultiPeerMap *peer_map) { - uint32_t rand_index; struct GetRandPeerIteratorCls *iterator_cls; const struct GNUNET_PeerIdentity *ret; @@ -704,25 +708,222 @@ mq_notify_sent_cb (void *cls) remove_pending_message (pending_msg); } +/** + * @brief Clear the stored valid peers. + */ +static void +clear_valid_peer_storage () +{ + struct GNUNET_DISK_FileHandle *fh; + + if (GNUNET_OK != GNUNET_DISK_file_test (filename_valid_peers)) + { + return; + } + fh = GNUNET_DISK_file_open (filename_valid_peers, + GNUNET_DISK_OPEN_WRITE, + GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE); + if (NULL == fh) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Not able to clear file `%s' containing valid peers\n", + filename_valid_peers); + return; + } + GNUNET_DISK_file_write (fh, "", 0); + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); +} + +/** + * @brief Iterator function for #store_valid_peers. + * + * Implements #GNUNET_CONTAINER_PeerMapIterator. + * Writes single peer to disk. + * + * @param cls the file handle to write to. + * @param peer current peer + * @param value unused + * + * @return #GNUNET_YES if we should continue to + * iterate, + * #GNUNET_NO if not. + */ +static int +store_peer_presistently_iterator (void *cls, + const struct GNUNET_PeerIdentity *peer, + void *value) +{ + const struct GNUNET_DISK_FileHandle *fh = cls; + char peer_string[128]; + int size; + ssize_t ret; + + if (NULL == peer) + { + return GNUNET_YES; + } + size = GNUNET_snprintf (peer_string, + sizeof (peer_string), + "%s\n", + GNUNET_i2s_full (peer)); + GNUNET_assert (53 == size); + ret = GNUNET_DISK_file_write (fh, + peer_string, + size); + GNUNET_assert (size == ret); + return GNUNET_YES; +} + +/** + * @brief Store the peers currently in #valid_peers to disk. + */ +static void +store_valid_peers () +{ + struct GNUNET_DISK_FileHandle *fh; + uint32_t number_written_peers; + + if (GNUNET_OK != + GNUNET_DISK_directory_create_for_file (filename_valid_peers)) + { + GNUNET_break (0); + } + clear_valid_peer_storage (); + fh = GNUNET_DISK_file_open (filename_valid_peers, + GNUNET_DISK_OPEN_WRITE | + GNUNET_DISK_OPEN_CREATE | + GNUNET_DISK_OPEN_APPEND, + GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE); + if (NULL == fh) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Not able to write valid peers to file `%s'\n", + filename_valid_peers); + return; + } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Writing %u valid peers to disk\n", + GNUNET_CONTAINER_multipeermap_size (valid_peers)); + number_written_peers = + GNUNET_CONTAINER_multipeermap_iterate (valid_peers, + store_peer_presistently_iterator, + fh); + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); + GNUNET_assert (number_written_peers == + GNUNET_CONTAINER_multipeermap_size (valid_peers)); +} + +/** + * @brief Convert string representation of peer id to peer id. + * + * Counterpart to #GNUNET_i2s_full. + * + * @param string_repr The string representation of the peer id + * + * @return The peer id + */ +static const struct GNUNET_PeerIdentity * +s2i_full (const char *string_repr) +{ + struct GNUNET_PeerIdentity *peer; + size_t len; + int ret; + + peer = GNUNET_new (struct GNUNET_PeerIdentity); + len = strlen (string_repr); + if (52 > len) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Not able to convert string representation of PeerID to PeerID\n" + "Sting representation: %s (len %u) - too short\n", + string_repr, + len); + GNUNET_break (0); + } + else if (52 < len) + { + len = 52; + } + ret = GNUNET_CRYPTO_eddsa_public_key_from_string (string_repr, + len, + &peer->public_key); + if (GNUNET_OK != ret) + { + LOG (GNUNET_ERROR_TYPE_WARNING, + "Not able to convert string representation of PeerID to PeerID\n" + "Sting representation: %s\n", + string_repr); + GNUNET_break (0); + } + return peer; +} + +/** + * @brief Restore the peers on disk to #valid_peers. + */ +static void +restore_valid_peers () +{ + off_t file_size; + uint32_t num_peers; + struct GNUNET_DISK_FileHandle *fh; + char *buf; + ssize_t size_read; + char *iter_buf; + const char *str_repr; + const struct GNUNET_PeerIdentity *peer; + + if (GNUNET_OK != GNUNET_DISK_file_test (filename_valid_peers)) + { + return; + } + fh = GNUNET_DISK_file_open (filename_valid_peers, + GNUNET_DISK_OPEN_READ, + GNUNET_DISK_PERM_USER_READ); + GNUNET_assert (NULL != fh); + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_handle_size (fh, &file_size)); + num_peers = file_size / 53; + buf = GNUNET_malloc (file_size); + size_read = GNUNET_DISK_file_read (fh, buf, file_size); + GNUNET_assert (size_read == file_size); + for (iter_buf = buf; iter_buf < buf + file_size - 1; iter_buf += 53) + { + str_repr = GNUNET_strndup (iter_buf, 53); + peer = s2i_full (str_repr); + add_valid_peer (peer); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Restored valid peer %s from disk\n", + GNUNET_i2s_full (peer)); + } + GNUNET_assert (num_peers == GNUNET_CONTAINER_multipeermap_size (valid_peers)); + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Restored %u valid peers from disk\n", + num_peers); +} /** * @brief Initialise storage of peers * + * @param fn_valid_peers filename of the file used to store valid peer ids * @param cadet_h cadet handle * @param own_id own peer identity */ void -Peers_initialise (struct GNUNET_CADET_Handle *cadet_h, +Peers_initialise (char* fn_valid_peers, + struct GNUNET_CADET_Handle *cadet_h, const struct GNUNET_PeerIdentity *own_id) { + filename_valid_peers = GNUNET_strdup (fn_valid_peers); cadet_handle = cadet_h; own_identity = own_id; peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); valid_peers = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); + restore_valid_peers (); } -// TODO read stored valid peers - /** * @brief Delete storage of peers that was created with #Peers_initialise () */ @@ -738,6 +939,8 @@ Peers_terminate () "Iteration destroying peers was aborted.\n"); } GNUNET_CONTAINER_multipeermap_destroy (peer_map); + store_valid_peers (); + GNUNET_free (filename_valid_peers); GNUNET_CONTAINER_multipeermap_destroy (valid_peers); } @@ -1232,6 +1435,18 @@ Peers_cleanup_destroyed_channel (void *cls, peer_ctx->send_channel = NULL; else if (channel == peer_ctx->recv_channel) peer_ctx->recv_channel = NULL; + + if (NULL != peer_ctx->send_channel) + { + GNUNET_CADET_channel_destroy (peer_ctx->send_channel); + peer_ctx->send_channel = NULL; + } + if (NULL != peer_ctx->recv_channel) + { + GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); + peer_ctx->recv_channel = NULL; + } + /* Set the #Peers_ONLINE flag accordingly */ (void) Peers_check_connected (peer); return; } diff --git a/src/rps/gnunet-service-rps_peers.h b/src/rps/gnunet-service-rps_peers.h index 79db8185b..8a163f8cf 100644 --- a/src/rps/gnunet-service-rps_peers.h +++ b/src/rps/gnunet-service-rps_peers.h @@ -102,11 +102,13 @@ typedef void (* PeerOp) (void *cls, const struct GNUNET_PeerIdentity *peer); /** * @brief Initialise storage of peers * + * @param fn_valid_peers filename of the file used to store valid peer ids * @param cadet_h cadet handle * @param own_id own peer identity */ void -Peers_initialise (struct GNUNET_CADET_Handle *cadet_h, +Peers_initialise (char* fn_valid_peers, + struct GNUNET_CADET_Handle *cadet_h, const struct GNUNET_PeerIdentity *own_id); /** diff --git a/src/rps/test_rps.conf b/src/rps/test_rps.conf index e3c563e99..a629451e4 100644 --- a/src/rps/test_rps.conf +++ b/src/rps/test_rps.conf @@ -12,6 +12,7 @@ NOARMBIND = YES # This is the timeinterval between the rounds ROUNDINTERVAL = 2 s +FILENAME_VALID_PEERS = $GNUNET_DATA_HOME/rps/valid_peers.txt # This is the 'estimate' in the beginning. # This determines the size of the peers we keep in memory diff --git a/src/rps/test_service_rps_peers.c b/src/rps/test_service_rps_peers.c index 264a63e41..ede3d05a5 100644 --- a/src/rps/test_service_rps_peers.c +++ b/src/rps/test_service_rps_peers.c @@ -59,25 +59,25 @@ check () memset (&own_id, 1, sizeof (own_id)); /* Do nothing */ - Peers_initialise (NULL, &own_id); + Peers_initialise ("", NULL, &own_id); Peers_terminate (); /* Create peer */ - Peers_initialise (NULL, &own_id); + Peers_initialise ("", NULL, &own_id); CHECK (GNUNET_YES == Peers_insert_peer (&k1)); Peers_terminate (); /* Create peer */ - Peers_initialise (NULL, &own_id); + Peers_initialise ("", NULL, &own_id); CHECK (GNUNET_YES == Peers_insert_peer (&k1)); CHECK (GNUNET_YES == Peers_remove_peer (&k1)); Peers_terminate (); /* Insertion and Removal */ - Peers_initialise (NULL, &own_id); + Peers_initialise ("", NULL, &own_id); CHECK (GNUNET_NO == Peers_check_peer_known (&k1)); CHECK (GNUNET_YES == Peers_insert_peer (&k1));