diff --git a/core/daemon.c b/core/daemon.c index c6481d4..3d3e43c 100644 --- a/core/daemon.c +++ b/core/daemon.c @@ -38,7 +38,7 @@ int ipfs_daemon_start(char* repo_path) { //ipfs_bootstrap_routing(local_node); - libp2p_logger_info("daemon", "Daemon is ready\n"); + libp2p_logger_info("daemon", "Daemon for %s is ready on port %d\n", listen_param.local_node->identity->peer_id, listen_param.port); // Wait for pthreads to finish. while (count_pths) { diff --git a/core/null.c b/core/null.c index 531f124..470f3a3 100644 --- a/core/null.c +++ b/core/null.c @@ -23,6 +23,9 @@ #define BUF_SIZE 4096 +// this should be set to 5 for normal operation, perhaps higher for debugging purposes +#define DEFAULT_NETWORK_TIMEOUT 5 + static int null_shutting_down = 0; /*** @@ -64,7 +67,7 @@ void ipfs_null_connection (void *ptr) // check if they're looking for an upgrade (i.e. secio) unsigned char* results = NULL; size_t bytes_read = 0; - if (!session.default_stream->read(&session, &results, &bytes_read, 5) ) { + if (!session.default_stream->read(&session, &results, &bytes_read, DEFAULT_NETWORK_TIMEOUT) ) { libp2p_logger_debug("null", "stream transaction read returned false\n"); break; } @@ -94,7 +97,7 @@ void ipfs_null_connection (void *ptr) while(_continue) { unsigned char* hash; size_t hash_length = 0; - _continue = session.default_stream->read(&session, &hash, &hash_length, 5); + _continue = session.default_stream->read(&session, &hash, &hash_length, DEFAULT_NETWORK_TIMEOUT); if (hash_length < 20) { _continue = 0; continue; @@ -161,13 +164,13 @@ void *ipfs_null_listen (void *ptr) if ((socketfd = socket_listen(socket_tcp4(), &(listen_param->ipv4), &(listen_param->port))) <= 0) { libp2p_logger_error("null", "Failed to init null router. Address: %d, Port: %d\n", listen_param->ipv4, listen_param->port); - exit (1); + return (void*) 2; } - libp2p_logger_log("null", LOGLEVEL_ERROR, "Ipfs listening on %d\n", listen_param->port); + libp2p_logger_error("null", "Ipfs listening on %d\n", listen_param->port); for (;;) { - int numDescriptors = socket_read_select4(socketfd, 5); + int numDescriptors = socket_read_select4(socketfd, 2); if (null_shutting_down) { break; } @@ -197,6 +200,8 @@ void *ipfs_null_listen (void *ptr) } } + close(socketfd); + thpool_destroy(thpool); return (void*) 2; diff --git a/repo/config/config.c b/repo/config/config.c index fb41346..2ad7265 100644 --- a/repo/config/config.c +++ b/repo/config/config.c @@ -95,10 +95,20 @@ int ipfs_repo_config_init(struct RepoConfig* config, unsigned int num_bits_for_k // identity int counter = 0; while (counter < 5) { + if (counter > 0) { + //TODO: This shouldn't be here, but it was the only way to cleanup. Need to find a better way... + if (config->identity->private_key.public_key_der != NULL) + free(config->identity->private_key.public_key_der); + if (config->identity->private_key.der != NULL) + free(config->identity->private_key.der); + if (config->identity->peer_id != NULL) + free(config->identity->peer_id); + } if (!repo_config_identity_init(config->identity, num_bits_for_keypair)) return 0; if (ipfs_repo_config_is_valid_identity(config->identity)) break; + // we didn't get it right, try again counter++; } diff --git a/repo/fsrepo/fs_repo.c b/repo/fsrepo/fs_repo.c index 1501d1c..7843b65 100644 --- a/repo/fsrepo/fs_repo.c +++ b/repo/fsrepo/fs_repo.c @@ -318,7 +318,7 @@ int _get_json_string_value(char* data, const jsmntok_t* tokens, int tok_length, return 0; // allocate memory int str_len = curr_token->end - curr_token->start; - *result = malloc(sizeof(char) * str_len + 1); + *result = malloc(str_len + 1); if (*result == NULL) return 0; // copy in the string diff --git a/routing/k_routing.c b/routing/k_routing.c index 6e42edf..9c567c2 100644 --- a/routing/k_routing.c +++ b/routing/k_routing.c @@ -42,7 +42,7 @@ int ipfs_routing_kademlia_get_value(struct IpfsRouting* routing, const unsigned * @param routing the context * @param key the key to what we're looking for * @param key_size the size of the key - * @param results the results + * @param results the results, which is a vector of MultiAddress* * @param results_size the size of the results buffer * @returns true(1) on success, otherwise false(0) */ diff --git a/routing/online.c b/routing/online.c index 1d858a8..efabc8a 100644 --- a/routing/online.c +++ b/routing/online.c @@ -134,7 +134,7 @@ int ipfs_routing_online_find_providers(struct IpfsRouting* routing, const unsign } *peers = libp2p_utils_vector_new(1); - libp2p_utils_vector_add(*peers, libp2p_peer_copy(peer)); + libp2p_utils_vector_add(*peers, peer); return 1; } @@ -158,9 +158,22 @@ int ipfs_routing_online_ask_peer_for_peer(struct Libp2pPeer* whoToAsk, const uns memcpy(message->key, peer_id, peer_id_size); return_message = ipfs_routing_online_send_receive_message(whoToAsk->connection, message); - if (return_message == NULL || return_message->provider_peer_head == NULL || return_message->provider_peer_head->item == NULL) + if (return_message == NULL) { + // some kind of network error + whoToAsk->connection_type = CONNECTION_TYPE_NOT_CONNECTED; + char* id[whoToAsk->id_size + 1]; + memcpy(id, whoToAsk->id, whoToAsk->id_size); + id[whoToAsk->id_size] = 0; + libp2p_logger_error("online", "Connection to %s is broken\n", id); goto exit; + } + if ( return_message->provider_peer_head == NULL || return_message->provider_peer_head->item == NULL) + goto exit; + *result = libp2p_peer_copy(return_message->provider_peer_head->item); + + } else { + goto exit; } retVal = 1; @@ -406,10 +419,12 @@ int ipfs_routing_online_get_value (ipfs_routing* routing, const unsigned char *k retVal = 1; exit: if (peers != NULL) { + /* Free the vector, not the items for (int i = 0; i < peers->total; i++) { struct Libp2pPeer* current = libp2p_utils_vector_get(peers, i); libp2p_peer_free(current); } + */ libp2p_utils_vector_free(peers); } return retVal; diff --git a/test/routing/test_routing.h b/test/routing/test_routing.h index 22161cb..0dd5b0f 100644 --- a/test/routing/test_routing.h +++ b/test/routing/test_routing.h @@ -35,6 +35,12 @@ int test_routing_find_peer() { struct Libp2pPeer* result = NULL; struct HashtableNode *node = NULL; + //libp2p_logger_add_class("online"); + //libp2p_logger_add_class("null"); + //libp2p_logger_add_class("daemon"); + //libp2p_logger_add_class("dht_protocol"); + //libp2p_logger_add_class("peerstore"); + // create peer 1 os_utils_setenv("IPFS_PATH", ipfs_path, 1); drop_and_build_repository(ipfs_path, 4001, NULL, &peer_id_1); @@ -46,6 +52,8 @@ int test_routing_find_peer() { goto exit; thread1_started = 1; + sleep(3); + // create peer 2 ipfs_path = "/tmp/test2"; os_utils_setenv("IPFS_PATH", ipfs_path, 1); @@ -56,6 +64,7 @@ int test_routing_find_peer() { //TODO: Find a better way to do this... size_t bytes_written = 0; ipfs_node_online_new(ipfs_path, &local_node2); + local_node2->routing->Bootstrap(local_node2->routing); ipfs_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, local_node2, &bytes_written, 0); ipfs_node_free(local_node2); // start the daemon in a separate thread @@ -63,7 +72,10 @@ int test_routing_find_peer() { goto exit; thread2_started = 1; - // create my peer, peer 3 + // JMJ wait for everything to start up + sleep(3); + + // create my peer, peer 3 ipfs_path = "/tmp/test3"; os_utils_setenv("IPFS_PATH", ipfs_path, 1); libp2p_utils_vector_add(ma_vector, ma_peer1); @@ -82,10 +94,13 @@ int test_routing_find_peer() { local_node.routing->Bootstrap(local_node.routing); - if (!local_node.routing->FindPeer(local_node.routing, (unsigned char*)peer_id_2, strlen(peer_id_2), &result)) + if (!local_node.routing->FindPeer(local_node.routing, (unsigned char*)peer_id_2, strlen(peer_id_2), &result)) { + fprintf(stderr, "Unable to find peer %s by asking %s\n", peer_id_2, peer_id_1); goto exit; + } if (result == NULL) { + fprintf(stderr, "Result was NULL\n"); goto exit; } @@ -117,6 +132,8 @@ int test_routing_find_peer() { libp2p_peerstore_free(local_node.peerstore); if (local_node.routing != NULL) ipfs_routing_online_free(local_node.routing); + if (result != NULL) + libp2p_peer_free(result); return retVal; @@ -264,10 +281,12 @@ int test_routing_find_providers() { ipfs_hashtable_node_free(node); if (result != NULL) { // we have a vector of peers. Clean 'em up: + /* free the vector, not the peers. for(int i = 0; i < result->total; i++) { struct Libp2pPeer* p = (struct Libp2pPeer*)libp2p_utils_vector_get(result, i); libp2p_peer_free(p); } + */ libp2p_utils_vector_free(result); } return retVal; @@ -398,8 +417,9 @@ int test_routing_retrieve_file_third_party() { // create a vector to hold peer1's multiaddress so we can connect as a peer ma_vector2 = libp2p_utils_vector_new(1); libp2p_utils_vector_add(ma_vector2, ma_peer1); - // note: this distroys some things, as it frees the fs_repo_3: + // note: this destroys some things, as it frees the fs_repo_3: drop_and_build_repository(ipfs_path, 4002, ma_vector2, &peer_id_2); + multiaddress_free(ma_peer1); // add a file, to prime the connection to peer 1 //TODO: Find a better way to do this... size_t bytes_written = 0; @@ -427,6 +447,7 @@ int test_routing_retrieve_file_third_party() { ma_vector3 = libp2p_utils_vector_new(1); libp2p_utils_vector_add(ma_vector3, ma_peer1); drop_and_build_repository(ipfs_path, 4003, ma_vector3, &peer_id_3); + multiaddress_free(ma_peer1); ipfs_node_online_new(ipfs_path, &ipfs_node3); ipfs_node3->routing->Bootstrap(ipfs_node3->routing); @@ -532,6 +553,7 @@ int test_routing_retrieve_large_file() { libp2p_utils_vector_add(ma_vector2, ma_peer1); // note: this distroys some things, as it frees the fs_repo_3: drop_and_build_repository(ipfs_path, 4002, ma_vector2, &peer_id_2); + multiaddress_free(ma_peer1); // add a file, to prime the connection to peer 1 //TODO: Find a better way to do this... size_t bytes_written = 0; @@ -560,6 +582,7 @@ int test_routing_retrieve_large_file() { ma_vector3 = libp2p_utils_vector_new(1); libp2p_utils_vector_add(ma_vector3, ma_peer1); drop_and_build_repository(ipfs_path, 4003, ma_vector3, &peer_id_3); + multiaddress_free(ma_peer1); ipfs_node_online_new(ipfs_path, &ipfs_node3); ipfs_node3->routing->Bootstrap(ipfs_node3->routing); diff --git a/test/routing/test_supernode.h b/test/routing/test_supernode.h index 89581f7..41f4770 100644 --- a/test/routing/test_supernode.h +++ b/test/routing/test_supernode.h @@ -150,6 +150,8 @@ int test_routing_supernode_get_remote_value() { ipfs_repo_fsrepo_free(fs_repo); if (ipfs_node != NULL) free(ipfs_node); + if (multiaddresses != NULL) + libp2p_utils_vector_free(multiaddresses); return retVal; } @@ -262,6 +264,8 @@ int test_routing_supernode_get_value() { stop_kademlia(); if (fs_repo != NULL) ipfs_repo_fsrepo_free(fs_repo); + if (multiaddresses != NULL) + libp2p_utils_vector_free(multiaddresses); return retVal; } diff --git a/test/testit.c b/test/testit.c index 0c937ff..734ff2a 100644 --- a/test/testit.c +++ b/test/testit.c @@ -64,8 +64,8 @@ const char* names[] = { "test_merkledag_get_data", "test_merkledag_add_node", "test_merkledag_add_node_with_links", - "test_resolver_get" /*, - "test_routing_find_peer", + "test_resolver_get", + "test_routing_find_peer"/*, "test_routing_find_providers", "test_routing_provide", "test_routing_supernode_get_value", @@ -114,8 +114,8 @@ int (*funcs[])(void) = { test_merkledag_get_data, test_merkledag_add_node, test_merkledag_add_node_with_links, - test_resolver_get /*, - test_routing_find_peer, + test_resolver_get, + test_routing_find_peer/*, test_routing_find_providers, test_routing_provide, test_routing_supernode_get_value, @@ -127,46 +127,72 @@ int (*funcs[])(void) = { test_ping, test_ping_remote, test_null_add_provider, - test_resolver_remote_get*/ + test_resolver_remote_get + */ }; /** - * run 1 test or run all + * Pull the next test name from the command line + * @param the count of arguments on the command line + * @param argv the command line arguments + * @param arg_number the current argument we want + * @returns a null terminated string of the next test or NULL + */ +char* get_test(int argc, char** argv, int arg_number) { + char* retVal = NULL; + char* ptr = NULL; + if (argc > arg_number) { + ptr = argv[arg_number]; + if (ptr[0] == '\'') + ptr++; + retVal = malloc(strlen(ptr) + 1); + strcpy(retVal, ptr); + ptr = strchr(ptr, '\''); + if (ptr != NULL) + ptr[0] = 0; + } + return retVal; +} + +/** + * run certain tests or run all */ int main(int argc, char** argv) { int counter = 0; int tests_ran = 0; - char* test_wanted; - int only_one = 0; + char* test_wanted = NULL; + int certain_tests = 0; + int current_test_arg = 1; if(argc > 1) { - only_one = 1; - if (argv[1][0] == '\'') { // some shells put quotes around arguments - argv[1][strlen(argv[1])-1] = 0; - test_wanted = &(argv[1][1]); - } - else - test_wanted = argv[1]; + certain_tests = 1; } int array_length = sizeof(funcs) / sizeof(funcs[0]); int array2_length = sizeof(names) / sizeof(names[0]); if (array_length != array2_length) { printf("Test arrays are not of the same length. Funcs: %d, Names: %d\n", array_length, array2_length); } - for (int i = 0; i < array_length; i++) { - if (only_one) { - const char* currName = names[i]; - if (strcmp(currName, test_wanted) == 0) { - tests_ran++; - counter += testit(names[i], funcs[i]); + test_wanted = get_test(argc, argv, current_test_arg); + while (!certain_tests || test_wanted != NULL) { + for (int i = 0; i < array_length; i++) { + if (certain_tests) { + // get the test we currently want from the command line + const char* currName = names[i]; + if (strcmp(currName, test_wanted) == 0) { + tests_ran++; + counter += testit(names[i], funcs[i]); + } } + else + if (!certain_tests) { + tests_ran++; + counter += testit(names[i], funcs[i]); + } } - else - if (!only_one) { - tests_ran++; - counter += testit(names[i], funcs[i]); - } + if (!certain_tests) // we did them all, not certain ones + break; + free(test_wanted); + test_wanted = get_test(argc, argv, ++current_test_arg); } - if (tests_ran == 0) printf("***** No tests found *****\n"); else {