diff --git a/include/libp2p/peer/peer.h b/include/libp2p/peer/peer.h index 4c88e85..4f96960 100644 --- a/include/libp2p/peer/peer.h +++ b/include/libp2p/peer/peer.h @@ -29,13 +29,11 @@ struct Libp2pPeer { struct Libp2pPeer* libp2p_peer_new(); /** - * Create a new peer struct with some data - * @param id the id - * @param id_size the length of the id - * @param multi_addr the MultiAddresss - * @returns the Libp2pPeer or NULL if there was a problem + * Create a new Peer based on a multiaddress + * @param in the multiaddress + * @returns a Peer initialized with the values from "in" */ -struct Libp2pPeer* libp2p_peer_new_from_data(const char* id, size_t id_size, const struct MultiAddress* multi_addr); +struct Libp2pPeer* libp2p_peer_new_from_multiaddress(const struct MultiAddress* multi_addr); /** * frees resources from a peer struct @@ -75,6 +73,15 @@ size_t libp2p_peer_protobuf_encode_size(struct Libp2pPeer* in); */ int libp2p_peer_protobuf_encode(struct Libp2pPeer* in, unsigned char* buffer, size_t max_buffer_size, size_t* bytes_written); +/** + * Encode the Peer into a buffer + * @param in the peer + * @param buffer where to put it (will be allocated by this function) + * @param buffer_size the number of bytes written to the buffer + * @returns true(1) on success, otherwise 0 + */ +int libp2p_peer_protobuf_encode_with_alloc(struct Libp2pPeer* in, unsigned char** buffer, size_t *buffer_size); + /** * turn an array of bytes into a Peer * @param in the protobuf formatted peer diff --git a/peer/peer.c b/peer/peer.c index 4f13f92..da140ee 100644 --- a/peer/peer.c +++ b/peer/peer.c @@ -22,6 +22,24 @@ struct Libp2pPeer* libp2p_peer_new() { return out; } +/** + * Create a new Peer based on a multiaddress + * @param in the multiaddress + * @returns a Peer initialized with the values from "in" + */ +struct Libp2pPeer* libp2p_peer_new_from_multiaddress(const struct MultiAddress* in) { + struct Libp2pPeer* out = libp2p_peer_new(); + char* id = multiaddress_get_peer_id(in); + if (id != NULL) { + out->id_size = strlen(id) + 1; + out->id = malloc(out->id_size); + strcpy(out->id, id); + } + out->addr_head = libp2p_utils_linked_list_new(); + out->addr_head->item = multiaddress_copy(in); + return out; +} + /** * Attempt to connect to the peer, setting connection_type correctly * NOTE: If successful, this will set peer->connection to the stream @@ -55,6 +73,7 @@ int libp2p_peer_connect(struct Libp2pPeer* peer) { * @param multi_addr the MultiAddresss * @returns the Libp2pPeer or NULL if there was a problem */ +/* struct Libp2pPeer* libp2p_peer_new_from_data(const char* id, size_t id_size, const struct MultiAddress* multi_addr) { struct Libp2pPeer* out = libp2p_peer_new(); if (out != NULL) { @@ -75,7 +94,7 @@ struct Libp2pPeer* libp2p_peer_new_from_data(const char* id, size_t id_size, con return out; } - +*/ void libp2p_peer_free(struct Libp2pPeer* in) { if (in != NULL) { @@ -174,6 +193,12 @@ int libp2p_peer_protobuf_encode(struct Libp2pPeer* in, unsigned char* buffer, si return 1; } +int libp2p_peer_protobuf_encode_with_alloc(struct Libp2pPeer* in, unsigned char** buffer, size_t *buffer_size) { + *buffer_size = libp2p_peer_protobuf_encode_size(in); + *buffer = malloc(*buffer_size); + return libp2p_peer_protobuf_encode(in, *buffer, *buffer_size, buffer_size); +} + int libp2p_peer_protobuf_decode(unsigned char* in, size_t in_size, struct Libp2pPeer** out) { size_t pos = 0; int retVal = 0; @@ -183,7 +208,8 @@ int libp2p_peer_protobuf_decode(unsigned char* in, size_t in_size, struct Libp2p struct Libp2pLinkedList* last = NULL; struct MultiAddress* ma = NULL; - if ( (*out = (struct Libp2pPeer*)malloc(sizeof(struct Libp2pPeer))) == NULL) + *out = libp2p_peer_new(); + if ( *out == NULL) goto exit; struct Libp2pPeer* ptr = *out; @@ -212,7 +238,8 @@ int libp2p_peer_protobuf_decode(unsigned char* in, size_t in_size, struct Libp2p struct Libp2pLinkedList* current = libp2p_utils_linked_list_new(); if (current == NULL) goto exit; - current->item = (void*)multiaddress_new_from_bytes(buffer, buffer_size); + struct MultiAddress* address = multiaddress_new_from_bytes(buffer, buffer_size); + current->item = (void*)address; free(buffer); buffer = NULL; // assign the values diff --git a/record/message.c b/record/message.c index 46ac064..0240ebc 100644 --- a/record/message.c +++ b/record/message.c @@ -255,12 +255,13 @@ int libp2p_message_protobuf_decode(unsigned char* in, size_t in_size, struct Lib if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&buffer, &buffer_size, &bytes_read)) goto exit; // turn this back into a peer - current_item = (struct Libp2pLinkedList*)malloc(sizeof(struct Libp2pLinkedList)); + current_item = libp2p_utils_linked_list_new(); if (current_item == NULL) goto exit; - current_item->next = NULL; - if (!libp2p_peer_protobuf_decode(buffer, buffer_size, (struct Libp2pPeer**)¤t_item->item)) + struct Libp2pPeer* peer = NULL; + if (!libp2p_peer_protobuf_decode(buffer, buffer_size, &peer)) goto exit; + current_item->item = peer; free(buffer); buffer = NULL; if (ptr->provider_peer_head == NULL) { diff --git a/routing/dht_protocol.c b/routing/dht_protocol.c index 5bb4352..93ec4b2 100644 --- a/routing/dht_protocol.c +++ b/routing/dht_protocol.c @@ -99,8 +99,10 @@ int libp2p_routing_dht_handle_get_providers(struct SessionContext* session, stru if (libp2p_providerstore_get(providerstore, message->key, message->key_size, &peer_id, &peer_id_size)) { // 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->addr_head != NULL) - message->provider_peer_head = peer->addr_head; + if (peer != NULL) { + message->provider_peer_head = libp2p_utils_linked_list_new(); + message->provider_peer_head->item = peer; + } } free(peer_id); // TODO: find closer peers @@ -167,7 +169,11 @@ int libp2p_routing_dht_handle_add_provider(struct SessionContext* session, struc } // there should only be 1 when adding a provider if (current != NULL) { - struct Libp2pPeer* peer = (struct Libp2pPeer*)current->item; + peer = current->item; + if (peer == NULL) { + libp2p_logger_error("dht_protocol", "Message add_provider has no peer\n"); + goto exit; + } struct MultiAddress *peer_ma = libp2p_routing_dht_find_peer_ip_multiaddress(peer->addr_head); if (peer_ma == NULL) { libp2p_logger_error("dht_protocol", "Peer has no IP MultiAddress.\n"); @@ -178,8 +184,10 @@ int libp2p_routing_dht_handle_add_provider(struct SessionContext* session, struc char new_string[255]; multiaddress_get_ip_address(session->default_stream->address, &ip); int port = multiaddress_get_ip_port(peer_ma); - sprintf(new_string, "/ip4/%s/tcp/%d", ip, port); + sprintf(new_string, "/ip4/%s/tcp/%d/ipfs/%s", ip, port, peer->id); struct MultiAddress* new_ma = multiaddress_new_from_string(new_string); + if (new_ma == NULL) + goto exit; libp2p_logger_debug("dht_protocol", "New MultiAddress made with %s.\n", new_string); // TODO: See if the sender is who he says he is // set it as the first in the list @@ -315,6 +323,7 @@ int libp2p_routing_dht_handle_message(struct SessionContext* session, struct Pee // unprotobuf if (!libp2p_message_protobuf_decode(buffer, buffer_size, &message)) goto exit; + // handle message switch(message->message_type) { case(MESSAGE_TYPE_PUT_VALUE): // store a value in local storage diff --git a/test/test_peer.h b/test/test_peer.h index 434e554..ea1bd9c 100644 --- a/test/test_peer.h +++ b/test/test_peer.h @@ -59,3 +59,33 @@ int test_peerstore() { libp2p_peer_entry_free(peer_entry); return retVal; } + +int test_peer_protobuf() { + struct Libp2pPeer *peer = NULL, *peer_result = NULL; + struct MultiAddress* ma = NULL, *ma_result = NULL; + char* peer_id = "QmW8CYQuoJhgfxTeNVFWktGFnTRzdUAimerSsHaE4rUXk8"; + unsigned char* protobuf; + size_t protobuf_size; + + peer = libp2p_peer_new(); + peer->id_size = strlen(peer_id); + peer->id = malloc(peer->id_size); + memcpy(peer->id, peer_id, peer->id_size); + peer->addr_head = libp2p_utils_linked_list_new(); + ma = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001/ipfs/QmW8CYQuoJhgfxTeNVFWktGFnTRzdUAimerSsHaE4rUXk8/"); + peer->addr_head->item = ma; + + // protobuf + libp2p_peer_protobuf_encode_with_alloc(peer, &protobuf, &protobuf_size); + + // unprotobuf + libp2p_peer_protobuf_decode(protobuf, protobuf_size, &peer_result); + ma_result = peer_result->addr_head->item; + + if (strcmp(ma->string, ma_result->string) != 0) { + fprintf(stderr, "Results to not match: %s vs %s\n", ma->string, ma_result->string); + return 0; + } + + return 1; +} diff --git a/test/test_record.h b/test/test_record.h index f178f52..02abf0c 100644 --- a/test/test_record.h +++ b/test/test_record.h @@ -30,6 +30,7 @@ struct Libp2pRecord* test_record_create() { int test_record_protobuf() { struct Libp2pRecord* record = test_record_create(); struct Libp2pRecord* results = NULL; + struct MultiAddress *ma = NULL, *ma_results = NULL; size_t protobuf_size = 0; char* protobuf = NULL; int retVal = 0; @@ -209,6 +210,7 @@ int test_record_message_protobuf() { struct Libp2pPeer* closer_peer = NULL; struct Libp2pMessage* message = NULL; struct Libp2pMessage* result = NULL; + struct MultiAddress *ma_result = NULL; char* buffer = NULL; size_t buffer_len = 0; @@ -219,7 +221,7 @@ int test_record_message_protobuf() { strcpy(closer_peer->id, "ABC123"); closer_peer->id_size = strlen(closer_peer->id); closer_peer->addr_head = libp2p_utils_linked_list_new(); - closer_peer->addr_head->item = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001"); + closer_peer->addr_head->item = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001/ipfs/QmW8CYQuoJhgfxTeNVFWktGFnTRzdUAimerSsHaE4rUXk8/"); message = libp2p_message_new(); message->closer_peer_head = libp2p_utils_linked_list_new(); @@ -245,6 +247,13 @@ int test_record_message_protobuf() { if (result->cluster_level_raw != 1) goto exit; + ma_result = ((struct Libp2pPeer*)result->closer_peer_head->item)->addr_head->item; + + if (strcmp(ma_result->string, ((struct MultiAddress*)closer_peer->addr_head->item)->string) != 0) { + fprintf(stderr, "MultiAddress strings do not match\n"); + goto exit; + } + // cleanup retVal = 1; exit: diff --git a/test/testit.c b/test/testit.c index c31a298..2166877 100644 --- a/test/testit.c +++ b/test/testit.c @@ -52,6 +52,7 @@ const char* names[] = { "test_record_peer_protobuf", "test_record_message_protobuf", "test_peer", + "test_peer_protobuf", "test_peerstore", "test_aes" }; @@ -94,6 +95,7 @@ int (*funcs[])(void) = { test_record_peer_protobuf, test_record_message_protobuf, test_peer, + test_peer_protobuf, test_peerstore, test_aes }; diff --git a/utils/vector.c b/utils/vector.c index e4e1d66..20bf86d 100644 --- a/utils/vector.c +++ b/utils/vector.c @@ -30,6 +30,11 @@ static void libp2p_utils_vector_resize(struct Libp2pVector *v, int capacity) } } +/**** + * Add an item to the vector. NOTE: This does not copy the item + * @param v the vector to add to + * @param item the item to add + */ void libp2p_utils_vector_add(struct Libp2pVector *v, void *item) { if (v->capacity == v->total)