From c0419f24249005858bf394d6e6ce108b06047a33 Mon Sep 17 00:00:00 2001 From: jmjatlanta Date: Wed, 20 Sep 2017 07:32:12 -0500 Subject: [PATCH] Adding IpfsNode to api startup --- core/api.c | 51 +++++++++++++++++++++++++++++++------------- core/ipfs_node.c | 4 ++++ test/core/test_api.h | 30 +++++++++++++++++--------- 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/core/api.c b/core/api.c index 5df9cd3..ead3515 100644 --- a/core/api.c +++ b/core/api.c @@ -274,7 +274,7 @@ size_t boundary_size(char *str, char *boundary, size_t limit) * @param path is the ipfs address, obj is a pointer to be allocated and will be the return of the data, size is a pointer to return the data length. * @returns 1 when success is 0 when failure. */ -int get_object(char *path, unsigned char **obj, size_t *size) +int get_object(struct IpfsNode* local_node, char *path, unsigned char **obj, size_t *size) { FILE* memstream_file = NULL; char* memstream_char = NULL; @@ -327,15 +327,20 @@ int send_object(int socket, unsigned char *obj, size_t size) return 0; // fail. } +struct ApiConnectionParam { + int index; + struct IpfsNode* this_node; +}; + /** * Pthread to take care of each client connection. - * @param ptr is the connection index in api_list, integer not pointer, cast required. + * @param ptr an ApiConnectionParam * @returns nothing */ void *api_connection_thread (void *ptr) { int timeout, s, r; - const INT_TYPE i = (INT_TYPE) ptr; + struct ApiConnectionParam* params = (struct ApiConnectionParam*)ptr; char resp[MAX_READ+1], buf[MAX_READ+1], *p, *body; char client[INET_ADDRSTRLEN]; struct s_request req; @@ -345,7 +350,7 @@ void *api_connection_thread (void *ptr) buf[MAX_READ] = '\0'; - s = api_list.conns[i]->socket; + s = api_list.conns[params->index]->socket; timeout = api_list.timeout; if (socket_read_select4(s, timeout) <= 0) { @@ -427,7 +432,7 @@ void *api_connection_thread (void *ptr) path = req.buf + req.path; } - if (get_object(path, &obj, &size)) { + if (get_object(params->this_node, path, &obj, &size)) { if (!send_object(s, obj, size)) { libp2p_logger_error("api", "fail send_object.\n"); } @@ -504,16 +509,16 @@ void *api_connection_thread (void *ptr) quit: if (req.buf) free(req.buf); - if (inet_ntop(AF_INET, &(api_list.conns[i]->ipv4), client, INET_ADDRSTRLEN) == NULL) + if (inet_ntop(AF_INET, &(api_list.conns[params->index]->ipv4), client, INET_ADDRSTRLEN) == NULL) strcpy(client, "UNKNOW"); - libp2p_logger_error("api", "Closing client connection %s:%d (%d).\n", client, api_list.conns[i]->port, i+1); + libp2p_logger_error("api", "Closing client connection %s:%d (%d).\n", client, api_list.conns[params->index]->port, params->index+1); pthread_mutex_lock(&conns_lock); close(s); - free (api_list.conns[i]); - api_list.conns[i] = NULL; + free (api_list.conns[params->index]); + api_list.conns[params->index] = NULL; conns_count--; pthread_mutex_unlock(&conns_lock); - + free(params); return NULL; } @@ -555,6 +560,7 @@ void *api_listen_thread (void *ptr) uint32_t ipv4; uint16_t port; char client[INET_ADDRSTRLEN]; + struct IpfsNode* local_node = (struct IpfsNode*)ptr; conns_count = 0; @@ -583,7 +589,17 @@ void *api_listen_thread (void *ptr) api_list.conns[i]->socket = s; api_list.conns[i]->ipv4 = ipv4; api_list.conns[i]->port = port; - if (pthread_create(&(api_list.conns[i]->pthread), NULL, api_connection_thread, (void*)i)) { + // create a struct, which the thread is responsible to destroy + struct ApiConnectionParam* connection_param = (struct ApiConnectionParam*) malloc(sizeof(struct ApiConnectionParam)); + if (connection_param == NULL) { + libp2p_logger_error("api", "api_listen_thread: Unable to allocate memory.\n"); + pthread_mutex_unlock(&conns_lock); + close (s); + continue; + } + connection_param->index = i; + connection_param->this_node = local_node; + if (pthread_create(&(api_list.conns[i]->pthread), NULL, api_connection_thread, (void*)connection_param)) { libp2p_logger_error("api", "Create pthread fail.\n"); free (api_list.conns[i]); api_list.conns[i] = NULL; @@ -601,17 +617,22 @@ void *api_listen_thread (void *ptr) /** * Start API interface daemon. - * @param port. + * @param local_node the context * @param max_conns. * @param timeout time out of client connection. * @returns 0 when failure or 1 if success. */ -int api_start (uint16_t port, int max_conns, int timeout) +int api_start (struct IpfsNode* local_node, int max_conns, int timeout) { int s; size_t alloc_size = sizeof(void*) * max_conns; - api_list.ipv4 = hostname_to_ip("127.0.0.1"); // api is listening only on loopback. + struct MultiAddress* my_address = multiaddress_new_from_string(local_node->repo->config->addresses->api); + + char* ip = multiaddress_ip(my_address); + int port = multiaddress_port(my_address); + + api_list.ipv4 = hostname_to_ip(ip); // api is listening only on loopback. api_list.port = port; if (listen_thread != 0) { @@ -636,7 +657,7 @@ int api_start (uint16_t port, int max_conns, int timeout) } memset(api_list.conns, 0, alloc_size); - if (pthread_create(&listen_thread, NULL, api_listen_thread, NULL)) { + if (pthread_create(&listen_thread, NULL, api_listen_thread, (void*)local_node)) { close (s); free (api_list.conns); api_list.conns = NULL; diff --git a/core/ipfs_node.c b/core/ipfs_node.c index 6186ff4..5dcf8de 100644 --- a/core/ipfs_node.c +++ b/core/ipfs_node.c @@ -80,6 +80,9 @@ int ipfs_node_online_new(const char* repo_path, struct IpfsNode** node) { local_node->routing = ipfs_routing_new_online(local_node, &fs_repo->config->identity->private_key); local_node->exchange = ipfs_bitswap_new(local_node); + // fire up the API + api_start(local_node, 10, 5); + return 1; } @@ -138,6 +141,7 @@ int ipfs_node_offline_new(const char* repo_path, struct IpfsNode** node) { */ int ipfs_node_free(struct IpfsNode* node) { if (node != NULL) { + api_stop(); if (node->exchange != NULL) { node->exchange->Close(node->exchange); } diff --git a/test/core/test_api.h b/test/core/test_api.h index 2e79384..3ff7e87 100644 --- a/test/core/test_api.h +++ b/test/core/test_api.h @@ -2,14 +2,24 @@ #include "libp2p/utils/logger.h" int test_core_api_startup_shutdown() { - if (!api_start(1234, 10, 5)) { - libp2p_logger_error("test_api", "api_start failed.\n"); - return 0; - } - sleep(5); - if (!api_stop()) { - libp2p_logger_error("test_api", "api_stop failed.\n"); - return 0; - } - return 1; + struct IpfsNode* local_node = NULL; + char* repo_path = "/tmp/ipfs_1"; + char* peer_id = NULL; + int retVal = 0; + + if (!drop_and_build_repository(repo_path, 4001, NULL, &peer_id)) + goto exit; + + // this should start the api + if (!ipfs_node_online_new(repo_path, &local_node)) + goto exit; + + + // TODO: test to see if it works + + // TODO shut down + retVal = 1; + exit: + + return retVal; }