Fixes for various memory leaks

This commit is contained in:
John Jones 2017-05-11 13:53:52 -05:00
parent d6ee0f7d5d
commit a5e5a71ddd
9 changed files with 123 additions and 40 deletions

View file

@ -38,7 +38,7 @@ int ipfs_daemon_start(char* repo_path) {
//ipfs_bootstrap_routing(local_node); //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. // Wait for pthreads to finish.
while (count_pths) { while (count_pths) {

View file

@ -23,6 +23,9 @@
#define BUF_SIZE 4096 #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; 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) // check if they're looking for an upgrade (i.e. secio)
unsigned char* results = NULL; unsigned char* results = NULL;
size_t bytes_read = 0; 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"); libp2p_logger_debug("null", "stream transaction read returned false\n");
break; break;
} }
@ -94,7 +97,7 @@ void ipfs_null_connection (void *ptr)
while(_continue) { while(_continue) {
unsigned char* hash; unsigned char* hash;
size_t hash_length = 0; 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) { if (hash_length < 20) {
_continue = 0; _continue = 0;
continue; continue;
@ -161,13 +164,13 @@ void *ipfs_null_listen (void *ptr)
if ((socketfd = socket_listen(socket_tcp4(), &(listen_param->ipv4), &(listen_param->port))) <= 0) { 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); 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 (;;) { for (;;) {
int numDescriptors = socket_read_select4(socketfd, 5); int numDescriptors = socket_read_select4(socketfd, 2);
if (null_shutting_down) { if (null_shutting_down) {
break; break;
} }
@ -197,6 +200,8 @@ void *ipfs_null_listen (void *ptr)
} }
} }
close(socketfd);
thpool_destroy(thpool); thpool_destroy(thpool);
return (void*) 2; return (void*) 2;

View file

@ -95,10 +95,20 @@ int ipfs_repo_config_init(struct RepoConfig* config, unsigned int num_bits_for_k
// identity // identity
int counter = 0; int counter = 0;
while (counter < 5) { 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)) if (!repo_config_identity_init(config->identity, num_bits_for_keypair))
return 0; return 0;
if (ipfs_repo_config_is_valid_identity(config->identity)) if (ipfs_repo_config_is_valid_identity(config->identity))
break; break;
// we didn't get it right, try again
counter++; counter++;
} }

View file

@ -318,7 +318,7 @@ int _get_json_string_value(char* data, const jsmntok_t* tokens, int tok_length,
return 0; return 0;
// allocate memory // allocate memory
int str_len = curr_token->end - curr_token->start; int str_len = curr_token->end - curr_token->start;
*result = malloc(sizeof(char) * str_len + 1); *result = malloc(str_len + 1);
if (*result == NULL) if (*result == NULL)
return 0; return 0;
// copy in the string // copy in the string

View file

@ -42,7 +42,7 @@ int ipfs_routing_kademlia_get_value(struct IpfsRouting* routing, const unsigned
* @param routing the context * @param routing the context
* @param key the key to what we're looking for * @param key the key to what we're looking for
* @param key_size the size of the key * @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 * @param results_size the size of the results buffer
* @returns true(1) on success, otherwise false(0) * @returns true(1) on success, otherwise false(0)
*/ */

View file

@ -134,7 +134,7 @@ int ipfs_routing_online_find_providers(struct IpfsRouting* routing, const unsign
} }
*peers = libp2p_utils_vector_new(1); *peers = libp2p_utils_vector_new(1);
libp2p_utils_vector_add(*peers, libp2p_peer_copy(peer)); libp2p_utils_vector_add(*peers, peer);
return 1; 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); memcpy(message->key, peer_id, peer_id_size);
return_message = ipfs_routing_online_send_receive_message(whoToAsk->connection, message); 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; 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); *result = libp2p_peer_copy(return_message->provider_peer_head->item);
} else {
goto exit;
} }
retVal = 1; retVal = 1;
@ -406,10 +419,12 @@ int ipfs_routing_online_get_value (ipfs_routing* routing, const unsigned char *k
retVal = 1; retVal = 1;
exit: exit:
if (peers != NULL) { if (peers != NULL) {
/* Free the vector, not the items
for (int i = 0; i < peers->total; i++) { for (int i = 0; i < peers->total; i++) {
struct Libp2pPeer* current = libp2p_utils_vector_get(peers, i); struct Libp2pPeer* current = libp2p_utils_vector_get(peers, i);
libp2p_peer_free(current); libp2p_peer_free(current);
} }
*/
libp2p_utils_vector_free(peers); libp2p_utils_vector_free(peers);
} }
return retVal; return retVal;

View file

@ -35,6 +35,12 @@ int test_routing_find_peer() {
struct Libp2pPeer* result = NULL; struct Libp2pPeer* result = NULL;
struct HashtableNode *node = 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 // create peer 1
os_utils_setenv("IPFS_PATH", ipfs_path, 1); os_utils_setenv("IPFS_PATH", ipfs_path, 1);
drop_and_build_repository(ipfs_path, 4001, NULL, &peer_id_1); drop_and_build_repository(ipfs_path, 4001, NULL, &peer_id_1);
@ -46,6 +52,8 @@ int test_routing_find_peer() {
goto exit; goto exit;
thread1_started = 1; thread1_started = 1;
sleep(3);
// create peer 2 // create peer 2
ipfs_path = "/tmp/test2"; ipfs_path = "/tmp/test2";
os_utils_setenv("IPFS_PATH", ipfs_path, 1); 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... //TODO: Find a better way to do this...
size_t bytes_written = 0; size_t bytes_written = 0;
ipfs_node_online_new(ipfs_path, &local_node2); 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_import_file(NULL, "/home/parallels/ipfstest/hello_world.txt", &node, local_node2, &bytes_written, 0);
ipfs_node_free(local_node2); ipfs_node_free(local_node2);
// start the daemon in a separate thread // start the daemon in a separate thread
@ -63,7 +72,10 @@ int test_routing_find_peer() {
goto exit; goto exit;
thread2_started = 1; 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"; ipfs_path = "/tmp/test3";
os_utils_setenv("IPFS_PATH", ipfs_path, 1); os_utils_setenv("IPFS_PATH", ipfs_path, 1);
libp2p_utils_vector_add(ma_vector, ma_peer1); libp2p_utils_vector_add(ma_vector, ma_peer1);
@ -82,10 +94,13 @@ int test_routing_find_peer() {
local_node.routing->Bootstrap(local_node.routing); 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; goto exit;
}
if (result == NULL) { if (result == NULL) {
fprintf(stderr, "Result was NULL\n");
goto exit; goto exit;
} }
@ -117,6 +132,8 @@ int test_routing_find_peer() {
libp2p_peerstore_free(local_node.peerstore); libp2p_peerstore_free(local_node.peerstore);
if (local_node.routing != NULL) if (local_node.routing != NULL)
ipfs_routing_online_free(local_node.routing); ipfs_routing_online_free(local_node.routing);
if (result != NULL)
libp2p_peer_free(result);
return retVal; return retVal;
@ -264,10 +281,12 @@ int test_routing_find_providers() {
ipfs_hashtable_node_free(node); ipfs_hashtable_node_free(node);
if (result != NULL) { if (result != NULL) {
// we have a vector of peers. Clean 'em up: // we have a vector of peers. Clean 'em up:
/* free the vector, not the peers.
for(int i = 0; i < result->total; i++) { for(int i = 0; i < result->total; i++) {
struct Libp2pPeer* p = (struct Libp2pPeer*)libp2p_utils_vector_get(result, i); struct Libp2pPeer* p = (struct Libp2pPeer*)libp2p_utils_vector_get(result, i);
libp2p_peer_free(p); libp2p_peer_free(p);
} }
*/
libp2p_utils_vector_free(result); libp2p_utils_vector_free(result);
} }
return retVal; 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 // create a vector to hold peer1's multiaddress so we can connect as a peer
ma_vector2 = libp2p_utils_vector_new(1); ma_vector2 = libp2p_utils_vector_new(1);
libp2p_utils_vector_add(ma_vector2, ma_peer1); 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); 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 // add a file, to prime the connection to peer 1
//TODO: Find a better way to do this... //TODO: Find a better way to do this...
size_t bytes_written = 0; size_t bytes_written = 0;
@ -427,6 +447,7 @@ int test_routing_retrieve_file_third_party() {
ma_vector3 = libp2p_utils_vector_new(1); ma_vector3 = libp2p_utils_vector_new(1);
libp2p_utils_vector_add(ma_vector3, ma_peer1); libp2p_utils_vector_add(ma_vector3, ma_peer1);
drop_and_build_repository(ipfs_path, 4003, ma_vector3, &peer_id_3); 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_node_online_new(ipfs_path, &ipfs_node3);
ipfs_node3->routing->Bootstrap(ipfs_node3->routing); 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); libp2p_utils_vector_add(ma_vector2, ma_peer1);
// note: this distroys some things, as it frees the fs_repo_3: // note: this distroys some things, as it frees the fs_repo_3:
drop_and_build_repository(ipfs_path, 4002, ma_vector2, &peer_id_2); 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 // add a file, to prime the connection to peer 1
//TODO: Find a better way to do this... //TODO: Find a better way to do this...
size_t bytes_written = 0; size_t bytes_written = 0;
@ -560,6 +582,7 @@ int test_routing_retrieve_large_file() {
ma_vector3 = libp2p_utils_vector_new(1); ma_vector3 = libp2p_utils_vector_new(1);
libp2p_utils_vector_add(ma_vector3, ma_peer1); libp2p_utils_vector_add(ma_vector3, ma_peer1);
drop_and_build_repository(ipfs_path, 4003, ma_vector3, &peer_id_3); 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_node_online_new(ipfs_path, &ipfs_node3);
ipfs_node3->routing->Bootstrap(ipfs_node3->routing); ipfs_node3->routing->Bootstrap(ipfs_node3->routing);

View file

@ -150,6 +150,8 @@ int test_routing_supernode_get_remote_value() {
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
if (ipfs_node != NULL) if (ipfs_node != NULL)
free(ipfs_node); free(ipfs_node);
if (multiaddresses != NULL)
libp2p_utils_vector_free(multiaddresses);
return retVal; return retVal;
} }
@ -262,6 +264,8 @@ int test_routing_supernode_get_value() {
stop_kademlia(); stop_kademlia();
if (fs_repo != NULL) if (fs_repo != NULL)
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
if (multiaddresses != NULL)
libp2p_utils_vector_free(multiaddresses);
return retVal; return retVal;
} }

View file

@ -64,8 +64,8 @@ const char* names[] = {
"test_merkledag_get_data", "test_merkledag_get_data",
"test_merkledag_add_node", "test_merkledag_add_node",
"test_merkledag_add_node_with_links", "test_merkledag_add_node_with_links",
"test_resolver_get" /*, "test_resolver_get",
"test_routing_find_peer", "test_routing_find_peer"/*,
"test_routing_find_providers", "test_routing_find_providers",
"test_routing_provide", "test_routing_provide",
"test_routing_supernode_get_value", "test_routing_supernode_get_value",
@ -114,8 +114,8 @@ int (*funcs[])(void) = {
test_merkledag_get_data, test_merkledag_get_data,
test_merkledag_add_node, test_merkledag_add_node,
test_merkledag_add_node_with_links, test_merkledag_add_node_with_links,
test_resolver_get /*, test_resolver_get,
test_routing_find_peer, test_routing_find_peer/*,
test_routing_find_providers, test_routing_find_providers,
test_routing_provide, test_routing_provide,
test_routing_supernode_get_value, test_routing_supernode_get_value,
@ -127,46 +127,72 @@ int (*funcs[])(void) = {
test_ping, test_ping,
test_ping_remote, test_ping_remote,
test_null_add_provider, 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 main(int argc, char** argv) {
int counter = 0; int counter = 0;
int tests_ran = 0; int tests_ran = 0;
char* test_wanted; char* test_wanted = NULL;
int only_one = 0; int certain_tests = 0;
int current_test_arg = 1;
if(argc > 1) { if(argc > 1) {
only_one = 1; certain_tests = 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];
} }
int array_length = sizeof(funcs) / sizeof(funcs[0]); int array_length = sizeof(funcs) / sizeof(funcs[0]);
int array2_length = sizeof(names) / sizeof(names[0]); int array2_length = sizeof(names) / sizeof(names[0]);
if (array_length != array2_length) { if (array_length != array2_length) {
printf("Test arrays are not of the same length. Funcs: %d, Names: %d\n", 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++) { test_wanted = get_test(argc, argv, current_test_arg);
if (only_one) { while (!certain_tests || test_wanted != NULL) {
const char* currName = names[i]; for (int i = 0; i < array_length; i++) {
if (strcmp(currName, test_wanted) == 0) { if (certain_tests) {
tests_ran++; // get the test we currently want from the command line
counter += testit(names[i], funcs[i]); 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 (!certain_tests) // we did them all, not certain ones
if (!only_one) { break;
tests_ran++; free(test_wanted);
counter += testit(names[i], funcs[i]); test_wanted = get_test(argc, argv, ++current_test_arg);
}
} }
if (tests_ran == 0) if (tests_ran == 0)
printf("***** No tests found *****\n"); printf("***** No tests found *****\n");
else { else {