From ced96dcf819de02474092e188e43b38270096c2f Mon Sep 17 00:00:00 2001 From: John Jones Date: Wed, 9 Aug 2017 08:04:17 -0500 Subject: [PATCH] IPFS protocols now implement an interface to make marshalling easier --- core/ipfs_node.c | 19 ++++++++++++++++ core/null.c | 21 +++++------------ exchange/bitswap/bitswap.c | 30 +++++++++++++++++++++++++ exchange/bitswap/engine.c | 2 +- include/ipfs/core/ipfs_node.h | 1 + include/ipfs/exchange/bitswap/bitswap.h | 7 +++++- 6 files changed, 63 insertions(+), 17 deletions(-) diff --git a/core/ipfs_node.c b/core/ipfs_node.c index 8bf9988..bb65939 100644 --- a/core/ipfs_node.c +++ b/core/ipfs_node.c @@ -1,8 +1,26 @@ #include +#include "libp2p/utils/vector.h" +#include "libp2p/secio/secio.h" +#include "libp2p/routing/dht_protocol.h" #include "ipfs/core/ipfs_node.h" #include "ipfs/exchange/bitswap/bitswap.h" +struct Libp2pVector* ipfs_node_online_build_protocol_handlers(struct IpfsNode* node) { + struct Libp2pVector* retVal = libp2p_utils_vector_new(1); + if (retVal != NULL) { + // secio + libp2p_utils_vector_add(retVal, libp2p_secio_build_protocol_handler(&node->identity->private_key, node->peerstore)); + // nodeio + //libp2p_utils_vector_add(retVal, libp2p_nodeio_build_protocol_handler()); + // kademlia + libp2p_utils_vector_add(retVal, libp2p_routing_dht_build_protocol_handler(node->peerstore, node->providerstore)); + // bitswap + libp2p_utils_vector_add(retVal, ipfs_bitswap_build_protocol_handler(node)); + } + return retVal; +} + /*** * build an online IpfsNode * @param repo_path where the IPFS repository directory is @@ -40,6 +58,7 @@ int ipfs_node_online_new(const char* repo_path, struct IpfsNode** node) { // fill in the node local_node->repo = fs_repo; local_node->identity = fs_repo->config->identity; + local_node->protocol_handlers = ipfs_node_online_build_protocol_handlers(*node); local_node->peerstore = libp2p_peerstore_new(local_node->identity->peer); local_node->providerstore = libp2p_providerstore_new(fs_repo->config->datastore, local_node->identity->peer); local_node->blockstore = ipfs_blockstore_new(fs_repo); diff --git a/core/null.c b/core/null.c index fad726d..4c0726e 100644 --- a/core/null.c +++ b/core/null.c @@ -10,6 +10,7 @@ #include "libp2p/conn/session.h" #include "libp2p/net/multistream.h" #include "libp2p/net/p2pnet.h" +#include "libp2p/net/protocol.h" #include "libp2p/nodeio/nodeio.h" #include "libp2p/record/message.h" #include "libp2p/routing/dht_protocol.h" @@ -30,20 +31,6 @@ static int null_shutting_down = 0; -/*** - * Compare incoming to see if they are requesting a protocol upgrade - * @param incoming the incoming string - * @param incoming_size the size of the incoming string - * @param test the protocol string to compare it with (i.e. "/secio" or "/nodeio" - * @returns true(1) if there was a match, false(0) otherwise - */ -int protocol_compare(const unsigned char* incoming, size_t incoming_size, const char* test) { - int test_size = strlen(test); - if (incoming_size >= test_size && strncmp((char*)incoming, test, test_size) == 0) - return 1; - return 0; -} - /*** * Handle the incoming request from a Multistream * @param incoming the incoming request @@ -53,6 +40,8 @@ int protocol_compare(const unsigned char* incoming, size_t incoming_size, const * @returns 1 to indicate it was handled, 0 to indicate that the daemon should no longer loop (future messages will be handled by another message loop), and -1 to indicate a problem */ int ipfs_multistream_marshal(const unsigned char* incoming, size_t incoming_size, struct SessionContext* session, struct IpfsNode* local_node) { + /* to be deleted after we get rid of nodeio*/ + /* if (protocol_compare(incoming, incoming_size, "/secio")) { libp2p_logger_debug("null", "Attempting secure io connection...\n"); if (!libp2p_secio_handshake(session, &local_node->identity->private_key, local_node->peerstore, 1)) { @@ -114,7 +103,9 @@ int ipfs_multistream_marshal(const unsigned char* incoming, size_t incoming_size libp2p_logger_error("null", "There was a problem with this connection. It is nothing I can handle. Disconnecting.\n"); return -1; } +*/ return 1; + } /** @@ -185,7 +176,7 @@ void ipfs_null_connection (void *ptr) { // We actually got something. Process the request... unsuccessful_counter = 0; libp2p_logger_debug("null", "Read %lu bytes from a stream tranaction\n", bytes_read); - retVal = ipfs_multistream_marshal(results, bytes_read, session, connection_param->local_node); + retVal = libp2p_protocol_marshal(results, bytes_read, session, connection_param->local_node->protocol_handlers); free(results); if (retVal == -1) { libp2p_logger_debug("null", "ipfs_null_marshal returned false\n"); diff --git a/exchange/bitswap/bitswap.c b/exchange/bitswap/bitswap.c index d7320cd..7e9c0f7 100644 --- a/exchange/bitswap/bitswap.c +++ b/exchange/bitswap/bitswap.c @@ -8,9 +8,39 @@ #include "ipfs/exchange/exchange.h" #include "ipfs/exchange/bitswap/bitswap.h" #include "ipfs/exchange/bitswap/message.h" +#include "ipfs/exchange/bitswap/network.h" #include "ipfs/exchange/bitswap/peer_request_queue.h" #include "ipfs/exchange/bitswap/want_manager.h" +int ipfs_bitswap_can_handle(const uint8_t* incoming, size_t incoming_size) { + if (incoming_size < 8) + return 0; + char* result = strstr((char*)incoming, "/ipfs/bitswap"); + if(result == NULL || result != (char*)incoming) + return 0; + return 1; +} + +int ipfs_bitswap_shutdown_handler(void* context) { + return 1; +} + +int ipfs_bitswap_handle_message(const uint8_t* incoming, size_t incoming_size, struct SessionContext* session_context, void* protocol_context) { + struct IpfsNode* local_node = (struct IpfsNode*)protocol_context; + return ipfs_bitswap_network_handle_message(local_node, session_context, incoming, incoming_size); +} + +struct Libp2pProtocolHandler* ipfs_bitswap_build_protocol_handler(const struct IpfsNode* local_node) { + struct Libp2pProtocolHandler* handler = (struct Libp2pProtocolHandler*) malloc(sizeof(struct Libp2pProtocolHandler)); + if (handler != NULL) { + handler->context = (void*)local_node; + handler->CanHandle = ipfs_bitswap_can_handle; + handler->HandleMessage = ipfs_bitswap_handle_message; + handler->Shutdown = ipfs_bitswap_shutdown_handler; + } + return handler; +} + /** * Create a new bitswap exchange * @param sessionContext the context diff --git a/exchange/bitswap/engine.c b/exchange/bitswap/engine.c index 2520dfc..b327de6 100644 --- a/exchange/bitswap/engine.c +++ b/exchange/bitswap/engine.c @@ -96,7 +96,7 @@ void* ipfs_bitswap_engine_peer_request_processor_start(void* ctx) { size_t buffer_len = 0; if (current_peer_entry->sessionContext->default_stream->read(current_peer_entry->sessionContext, &buffer, &buffer_len, 1)) { // handle it - int retVal = ipfs_multistream_marshal(buffer, buffer_len, current_peer_entry->sessionContext, context->ipfsNode); + int retVal = libp2p_protocol_marshal(buffer, buffer_len, current_peer_entry->sessionContext, context->ipfsNode->protocol_handlers); free(buffer); did_some_processing = 1; if (retVal == -1) { diff --git a/include/ipfs/core/ipfs_node.h b/include/ipfs/core/ipfs_node.h index 69a0495..3a2cff6 100644 --- a/include/ipfs/core/ipfs_node.h +++ b/include/ipfs/core/ipfs_node.h @@ -19,6 +19,7 @@ struct IpfsNode { struct IpfsRouting* routing; struct Blockstore* blockstore; struct Exchange* exchange; + struct Libp2pVector* protocol_handlers; //struct Pinner pinning; // an interface //struct Mount** mounts; // TODO: Add more here diff --git a/include/ipfs/exchange/bitswap/bitswap.h b/include/ipfs/exchange/bitswap/bitswap.h index 5425c39..e722ade 100644 --- a/include/ipfs/exchange/bitswap/bitswap.h +++ b/include/ipfs/exchange/bitswap/bitswap.h @@ -1,14 +1,19 @@ #pragma once /*** - * Bitswap implements the exchange "interface" + * Bitswap implements the "exchange" and "Libp2pProtocolHandler" interfaces * @see ../exchange.h + * @see libp2p/net/protocol.h */ +#include "libp2p/net/protocol.h" #include "ipfs/core/ipfs_node.h" #include "ipfs/exchange/exchange.h" #include "ipfs/exchange/bitswap/engine.h" +struct Libp2pProtocolHandler* ipfs_bitswap_build_protocol_handler(const struct IpfsNode* local_node); + + struct BitswapContext { struct IpfsNode* ipfsNode; struct WantListQueue* localWantlist;