From f494344b15b4a682a23dc2ca68f32d95bb0675ab Mon Sep 17 00:00:00 2001 From: John Jones Date: Thu, 9 Mar 2017 18:03:21 -0500 Subject: [PATCH] Adding kademlia routing to daemon --- core/bootstrap.c | 13 ++++++ core/daemon.c | 8 ++-- include/ipfs/core/ipfs_node.h | 1 + include/ipfs/routing/routing.h | 7 ++- routing/k_routing.c | 83 ++++++++++++++++++++++++++++++++++ 5 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 routing/k_routing.c diff --git a/core/bootstrap.c b/core/bootstrap.c index d2b6acb..39f85d2 100644 --- a/core/bootstrap.c +++ b/core/bootstrap.c @@ -28,3 +28,16 @@ void *ipfs_bootstrap_swarm(void* param) { } return (void*)1; } + +/*** + * Listen for connections on the API port (usually 5001) + * NOTE: This fills in the IpfsNode->routing struct + * + * @param param the IpfsNode information + * @returns nothing useful + */ +void *ipfs_bootstrap_routing(void* param) { + struct IpfsNode* local_node = (struct IpfsNode*)param; + local_node->routing = ipfs_routing_new_kademlia(local_node, local_node->identity->private_key, NULL); + return NULL; +} diff --git a/core/daemon.c b/core/daemon.c index fdb4342..c8081ac 100644 --- a/core/daemon.c +++ b/core/daemon.c @@ -40,15 +40,15 @@ int ipfs_daemon_start(char* repo_path) { listen_param.port = 4001; listen_param.local_node = &local_node; - // Create pthread for ipfs_null_listen. + // Create pthread for swarm listener. if (pthread_create(&work_pths[count_pths++], NULL, ipfs_null_listen, &listen_param)) { fprintf(stderr, "Error creating thread for ipfs_null_listen\n"); return 1; } - // create pthread for connecting to the swarm bootstrap - if (pthread_create(&work_pths[count_pths++], NULL, ipfs_bootstrap_swarm, &local_node)) { - + // create pthread for the API + if (pthread_create(&work_pths[count_pths++], NULL, ipfs_bootstrap_routing, &local_node)) { + fprintf(stderr, "Error creating thread for routing\n"); } fprintf(stderr, "Daemon is ready\n"); diff --git a/include/ipfs/core/ipfs_node.h b/include/ipfs/core/ipfs_node.h index b76c33d..97bbb92 100644 --- a/include/ipfs/core/ipfs_node.h +++ b/include/ipfs/core/ipfs_node.h @@ -11,6 +11,7 @@ struct IpfsNode { struct Identity* identity; struct FSRepo* repo; struct Peerstore* peerstore; + struct Routing* routing; //struct Pinner pinning; // an interface //struct Mount** mounts; // TODO: Add more here diff --git a/include/ipfs/routing/routing.h b/include/ipfs/routing/routing.h index 5159c89..c36aa72 100644 --- a/include/ipfs/routing/routing.h +++ b/include/ipfs/routing/routing.h @@ -51,6 +51,11 @@ typedef struct s_ipfs_routing ipfs_routing; // offline routing routines. ipfs_routing* ipfs_routing_new_offline (struct IpfsNode* local_node, struct RsaPrivateKey *private_key); +// online using secio, should probably be deprecated ipfs_routing* ipfs_routing_new_online (struct IpfsNode* local_node, struct RsaPrivateKey* private_key, struct Stream* stream); -int ipfs_routing_generic_put_value (ipfs_routing* offlineRouting, char *key, size_t key_size, void *val, size_t vlen);int ipfs_routing_generic_get_value (ipfs_routing* offlineRouting, char *key, size_t key_size, void **val, size_t *vlen); +// online using DHT/kademlia, the recommended router +ipfs_routing* ipfs_routing_new_kademlia(struct IpfsNode* local_node, struct RsaPrivateKey* private_key, struct Stream* stream); +// generic routines +int ipfs_routing_generic_put_value (ipfs_routing* offlineRouting, char *key, size_t key_size, void *val, size_t vlen); +int ipfs_routing_generic_get_value (ipfs_routing* offlineRouting, char *key, size_t key_size, void **val, size_t *vlen); diff --git a/routing/k_routing.c b/routing/k_routing.c new file mode 100644 index 0000000..3d179c7 --- /dev/null +++ b/routing/k_routing.c @@ -0,0 +1,83 @@ +#include "ipfs/routing/routing.h" + +/** + * Routing using Kademlia and DHT + */ + +/** + * Put a value in the datastore + * @param routing the struct that contains connection information + * @param key the key + * @param key_size the size of the key + * @param value the value + * @param value_size the size of the value + * @returns 0 on success, otherwise -1 + */ +int ipfs_routing_kademlia_put_value(struct s_ipfs_routing routing, char* key, size_t key_size, void* value, size_t value_size) { + +} + +/** + * Get a value from the datastore + * @param 1 the struct that contains the connection information + * @param 2 the key to look for + * @param 3 the size of the key + * @param 4 a place to store the value + * @param 5 the size of the value + */ +int ipfs_routing_kademlia_get_value(struct s_ipfs_routing*, char*, size_t, void**, size_t*) { + return 0; +} + +/** + * Find a provider + */ +int ipfs_routing_kademlia_find_providers(struct s_ipfs_routing*, char*, size_t, void*, size_t*) { + return 0; +} + +/** + * Find a peer + */ +int ipfs_routing_kademlia_find_peer(struct s_ipfs_routing*, char*, size_t, void*, size_t*) { + return 0; +} +int ipfs_routing_kademlia_provide(struct s_ipfs_routing*, char*) { + return 0; +} + +/** + * Ping this instance + */ +int ipfs_routing_kademlia_ping(struct s_ipfs_routing* routing, struct Libp2pMessage* message) { + return ipfs_routing_online_ping(routing, message); +} + +int ipfs_routing_kademlia_bootstrap(struct s_ipfs_routing*) { + return 0; +} + +struct s_ipfs_routing* ipfs_routing_new_kademlia(struct IpfsNode* local_node, struct RsaPrivateKey* private_key, struct Stream* stream) { + struct s_ipfs_routing* routing = (struct s_ipfs_routing*)malloc(sizeof(struct s_ipfs_routing)); + if (routing != NULL) { + routing->local_node = local_node; + routing->sk = private_key; + routing->stream = stream; + routing->PutValue = ipfs_routing_kademlia_put_value; + routing->GetValue = ipfs_routing_kademlia_get_value; + routing->FindProviders = ipfs_routing_kademlia_find_providers; + routing->FindPeer = ipfs_routing_kademlia_find_peer; + routing->Provide = ipfs_routing_kademlia_provide; + routing->Ping = ipfs_routing_kademlia_ping; + routing->Bootstrap = ipfs_routing_kademlia_bootstrap; + } + // connect to nodes and listen for connections + struct MultiAddress* address = multiaddresss_new_from_string(local_node->repo->config->addresses->api); + if (multiaddress_is_ip(address)) { + int port = multiaddress_get_ip_port(address); + int family = multiaddress_get_ip_family(address); + start_kademlia(port, family, local_node->identity->peer_id, 10); + } + + return routing; +}