From a137c2c43ef70e869e42037134ad0fe1883daa56 Mon Sep 17 00:00:00 2001 From: jmjatlanta Date: Mon, 31 Jul 2017 12:49:41 -0500 Subject: [PATCH] Code Cleanup plus making providerstore smarter --- include/libp2p/peer/peer.h | 1 + include/libp2p/peer/peerstore.h | 4 +-- include/libp2p/peer/providerstore.h | 8 +++++- peer/peer.c | 2 ++ peer/peerstore.c | 13 ++------- peer/providerstore.c | 44 ++++++++++++++++++++--------- routing/dht_protocol.c | 31 +++++++++++++++++--- test/test_peer.h | 7 ++++- utils/logger.c | 5 +++- 9 files changed, 82 insertions(+), 33 deletions(-) diff --git a/include/libp2p/peer/peer.h b/include/libp2p/peer/peer.h index 6462c3a..9373355 100644 --- a/include/libp2p/peer/peer.h +++ b/include/libp2p/peer/peer.h @@ -21,6 +21,7 @@ struct Libp2pPeer { struct Libp2pLinkedList* addr_head; // protobuf field 2 of multiaddr bytes (repeatable) (stored here as a struct MultiAddr) enum ConnectionType connection_type; // protobuf field 3 (a varint) struct SessionContext *sessionContext; // not protobuf'd, the current connection to the peer + int is_local; // not protobuf'd, true if this is the local peer }; /** diff --git a/include/libp2p/peer/peerstore.h b/include/libp2p/peer/peerstore.h index fa3e114..96c054a 100644 --- a/include/libp2p/peer/peerstore.h +++ b/include/libp2p/peer/peerstore.h @@ -33,10 +33,10 @@ void libp2p_peer_entry_free(struct PeerEntry* in); /** * Creates a new empty peerstore - * @param peer_id the peer id as a null terminated string + * @param local_peer the local peer * @returns an empty peerstore or NULL on error */ -struct Peerstore* libp2p_peerstore_new(const char* peer_id); +struct Peerstore* libp2p_peerstore_new(const struct Libp2pPeer* local_peer); /** * Deallocate resources used by the peerstore diff --git a/include/libp2p/peer/providerstore.h b/include/libp2p/peer/providerstore.h index e79bb66..82f2eca 100644 --- a/include/libp2p/peer/providerstore.h +++ b/include/libp2p/peer/providerstore.h @@ -1,5 +1,8 @@ #pragma once +#include "libp2p/db/datastore.h" +#include "libp2p/peer/peer.h" + /** * Contains a hash and the peer id of * who can provide it @@ -18,13 +21,16 @@ struct ProviderEntry { */ struct ProviderStore { struct Libp2pVector* provider_entries; + // this is requred so we can look locally for requests + const struct Datastore* datastore; + const struct Libp2pPeer* local_peer; }; /** * Create a new ProviderStore * @returns a ProviderStore struct */ -struct ProviderStore* libp2p_providerstore_new(); +struct ProviderStore* libp2p_providerstore_new(const struct Datastore* datastore, const struct Libp2pPeer* local_peer); /*** * Clean resources used by a ProviderStore diff --git a/peer/peer.c b/peer/peer.c index c7f64db..f545d22 100644 --- a/peer/peer.c +++ b/peer/peer.c @@ -21,6 +21,7 @@ struct Libp2pPeer* libp2p_peer_new() { out->addr_head = NULL; out->connection_type = CONNECTION_TYPE_NOT_CONNECTED; out->sessionContext = NULL; + out->is_local = 0; } return out; } @@ -122,6 +123,7 @@ int libp2p_peer_connect(struct RsaPrivateKey* privateKey, struct Libp2pPeer* pee struct Libp2pPeer* libp2p_peer_copy(const struct Libp2pPeer* in) { struct Libp2pPeer* out = libp2p_peer_new(); if (out != NULL) { + out->is_local = in->is_local; out->id_size = in->id_size; out->id = malloc(in->id_size); if (out->id == NULL) { diff --git a/peer/peerstore.c b/peer/peerstore.c index d237240..491f02a 100644 --- a/peer/peerstore.c +++ b/peer/peerstore.c @@ -36,19 +36,13 @@ struct PeerEntry* libp2p_peer_entry_copy(struct PeerEntry* in) { * @param peer_id the peer id as a null terminated string * @returns an empty peerstore or NULL on error */ -struct Peerstore* libp2p_peerstore_new(const char* peer_id) { +struct Peerstore* libp2p_peerstore_new(const struct Libp2pPeer* local_peer) { struct Peerstore* out = (struct Peerstore*)malloc(sizeof(struct Peerstore)); if (out != NULL) { out->head_entry = NULL; out->last_entry = NULL; // now add this peer as the first entry - struct Libp2pPeer* peer = libp2p_peer_new(); - peer->connection_type = CONNECTION_TYPE_NOT_CONNECTED; - peer->id_size = strlen(peer_id); - peer->id = malloc(peer->id_size); - memcpy(peer->id, peer_id, peer->id_size); - libp2p_peerstore_add_peer(out, peer); - libp2p_peer_free(peer); + libp2p_peerstore_add_peer(out, local_peer); } return out; } @@ -149,10 +143,7 @@ int libp2p_peerstore_add_peer(struct Peerstore* peerstore, const struct Libp2pPe */ struct PeerEntry* libp2p_peerstore_get_peer_entry(struct Peerstore* peerstore, const unsigned char* peer_id, size_t peer_id_size) { struct Libp2pLinkedList* current = peerstore->head_entry; - // JMJ Debugging - int count = 0; while(current != NULL) { - count++; struct Libp2pPeer* peer = ((struct PeerEntry*)current->item)->peer; if (peer->id_size == peer_id_size) { if (memcmp(peer_id, peer->id, peer->id_size) == 0) { diff --git a/peer/providerstore.c b/peer/providerstore.c index 809f098..956833f 100644 --- a/peer/providerstore.c +++ b/peer/providerstore.c @@ -1,31 +1,25 @@ #include #include +#include "libp2p/peer/providerstore.h" #include "libp2p/utils/vector.h" #include "libp2p/utils/logger.h" -struct ProviderEntry { - unsigned char* hash; - int hash_size; - unsigned char* peer_id; - int peer_id_size; -}; - -struct ProviderStore { - struct Libp2pVector* provider_entries; -}; - /*** * Stores hashes, and peers where you can possibly get them */ /** * Create a new ProviderStore + * @param datastore the datastore (required in order to look for the file locally) + * @param local_peer the local peer * @returns a ProviderStore struct */ -struct ProviderStore* libp2p_providerstore_new() { +struct ProviderStore* libp2p_providerstore_new(const struct Datastore* datastore, const struct Libp2pPeer* local_peer) { struct ProviderStore* out = (struct ProviderStore*)malloc(sizeof(struct ProviderStore)); if (out != NULL) { + out->datastore = datastore; + out->local_peer = local_peer; out->provider_entries = libp2p_utils_vector_new(4); } return out; @@ -61,7 +55,7 @@ void libp2p_providerstore_free(struct ProviderStore* in) { } } -int libp2p_providerstore_add(struct ProviderStore* store, unsigned char* hash, int hash_size, const unsigned char* peer_id, int peer_id_size) { +int libp2p_providerstore_add(struct ProviderStore* store, const unsigned char* hash, int hash_size, const unsigned char* peer_id, int peer_id_size) { char hash_str[hash_size + 1]; memcpy(hash_str, hash, hash_size); hash_str[hash_size] = 0; @@ -80,8 +74,32 @@ int libp2p_providerstore_add(struct ProviderStore* store, unsigned char* hash, i return 1; } +/** + * See if someone has announced a key. If so, pass the peer_id + * NOTE: This will check to see if I can provide it from my datastore + * + * @param store the list of providers + * @param hash what we're looking for + * @param hash_size the length of the hash + * @param peer_id the peer_id of who can provide it + * @param peer_id_size the allocated size of peer_id + * @returns true(1) if we found something, false(0) if not. + */ int libp2p_providerstore_get(struct ProviderStore* store, const unsigned char* hash, int hash_size, unsigned char** peer_id, int *peer_id_size) { struct ProviderEntry* current = NULL; + // can I provide it locally? + size_t results_size = 65535; + unsigned char results[results_size]; + if (store->datastore->datastore_get((const char*)hash, hash_size, &results[0], results_size, &results_size, store->datastore)) { + // we found it locally. Let them know + *peer_id = malloc(store->local_peer->id_size); + if (*peer_id == NULL) + return 0; + *peer_id_size = store->local_peer->id_size; + memcpy(*peer_id, store->local_peer->id, *peer_id_size); + return 1; + } + // skip index 0, as we checked above... for (int i = 0; i < store->provider_entries->total; i++) { current = (struct ProviderEntry*)libp2p_utils_vector_get(store->provider_entries, i); if (current->hash_size == hash_size && memcmp(current->hash, hash, hash_size) == 0) { diff --git a/routing/dht_protocol.c b/routing/dht_protocol.c index 8179b78..85b139f 100644 --- a/routing/dht_protocol.c +++ b/routing/dht_protocol.c @@ -4,6 +4,7 @@ #include "libp2p/net/stream.h" #include "libp2p/routing/dht_protocol.h" #include "libp2p/record/message.h" +#include "libp2p/utils/linked_list.h" #include "libp2p/utils/logger.h" #include "libp2p/conn/session.h" @@ -96,19 +97,41 @@ int libp2p_routing_dht_handle_get_providers(struct SessionContext* session, stru // This shouldn't be needed, but just in case: message->provider_peer_head = NULL; - // Can I provide it? + // Can I provide it locally? + unsigned char buf[65535]; + size_t buf_size = 0; + if (session->datastore->datastore_get(message->key, message->key_size, &buf[0], buf_size, &buf_size, session->datastore)) { + // we can provide this hash from our datastore + message->provider_peer_head = libp2p_utils_linked_list_new(); + struct Libp2pPeer* local_peer = (struct Libp2pPeer*)peerstore->head_entry->item; + message->provider_peer_head->item = local_peer; + } + // Can I provide it because someone announced it earlier? if (libp2p_providerstore_get(providerstore, (unsigned char*)message->key, message->key_size, &peer_id, &peer_id_size)) { libp2p_logger_debug("dht_protocol", "I can provide a provider for this key.\n"); // we have a peer id, convert it to a peer object struct Libp2pPeer* peer = libp2p_peerstore_get_peer(peerstore, peer_id, peer_id_size); if (peer != NULL) { - message->provider_peer_head = libp2p_utils_linked_list_new(); - message->provider_peer_head->item = libp2p_peer_copy(peer); + // add it to the message + if (message->provider_peer_head == NULL) { + message->provider_peer_head = libp2p_utils_linked_list_new(); + message->provider_peer_head->item = peer; + } else { + struct Libp2pLinkedList* current = message->provider_peer_head; + // find the last one in the list + while (current->next != NULL) { + current = current->next; + } + // add to the list + current->next = libp2p_utils_linked_list_new(); + current->next->item = peer; + } } } else { libp2p_logger_debug("dht_protocol", "I cannot provide a provider for this key.\n"); } - free(peer_id); + if (peer_id != NULL) + free(peer_id); // TODO: find closer peers /* if (message->provider_peer_head == NULL) { diff --git a/test/test_peer.h b/test/test_peer.h index ed125d3..ad974a4 100644 --- a/test/test_peer.h +++ b/test/test_peer.h @@ -24,7 +24,10 @@ int test_peer() { * Test the peerstore */ int test_peerstore() { - struct Peerstore* peerstore = libp2p_peerstore_new("Qmabcdefg"); + struct Libp2pPeer* peer = libp2p_peer_new(); + peer->id = "Qmabcdefg"; + peer->id_size = strlen(peer->id); + struct Peerstore* peerstore = libp2p_peerstore_new(peer); struct PeerEntry* peer_entry = NULL; struct PeerEntry* results = NULL; int retVal = 0; @@ -57,6 +60,8 @@ int test_peerstore() { libp2p_peerstore_free(peerstore); if (peer_entry != NULL) libp2p_peer_entry_free(peer_entry); + if (peer != NULL) + libp2p_peer_free(peer); return retVal; } diff --git a/utils/logger.c b/utils/logger.c index ea8730a..69295a8 100644 --- a/utils/logger.c +++ b/utils/logger.c @@ -102,7 +102,10 @@ void libp2p_logger_vlog(const char* area, int log_level, const char* format, va_ else found = libp2p_logger_watching_class(area); if (found) { - vfprintf(stderr, format, argptr); + int new_format_size = strlen(format) + strlen(area) + 10; + char new_format[new_format_size]; + sprintf(&new_format[0], "[%s] %s", area, format); + vfprintf(stderr, new_format, argptr); } } }