Implemented find providers from remote peers
This commit is contained in:
parent
e886fe3288
commit
f3de55999f
8 changed files with 107 additions and 17 deletions
|
@ -29,13 +29,11 @@ struct Libp2pPeer {
|
||||||
struct Libp2pPeer* libp2p_peer_new();
|
struct Libp2pPeer* libp2p_peer_new();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new peer struct with some data
|
* Create a new Peer based on a multiaddress
|
||||||
* @param id the id
|
* @param in the multiaddress
|
||||||
* @param id_size the length of the id
|
* @returns a Peer initialized with the values from "in"
|
||||||
* @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* libp2p_peer_new_from_multiaddress(const struct MultiAddress* multi_addr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* frees resources from a peer struct
|
* 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);
|
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
|
* turn an array of bytes into a Peer
|
||||||
* @param in the protobuf formatted peer
|
* @param in the protobuf formatted peer
|
||||||
|
|
33
peer/peer.c
33
peer/peer.c
|
@ -22,6 +22,24 @@ struct Libp2pPeer* libp2p_peer_new() {
|
||||||
return out;
|
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
|
* Attempt to connect to the peer, setting connection_type correctly
|
||||||
* NOTE: If successful, this will set peer->connection to the stream
|
* 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
|
* @param multi_addr the MultiAddresss
|
||||||
* @returns the Libp2pPeer or NULL if there was a problem
|
* @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* libp2p_peer_new_from_data(const char* id, size_t id_size, const struct MultiAddress* multi_addr) {
|
||||||
struct Libp2pPeer* out = libp2p_peer_new();
|
struct Libp2pPeer* out = libp2p_peer_new();
|
||||||
if (out != NULL) {
|
if (out != NULL) {
|
||||||
|
@ -75,7 +94,7 @@ struct Libp2pPeer* libp2p_peer_new_from_data(const char* id, size_t id_size, con
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void libp2p_peer_free(struct Libp2pPeer* in) {
|
void libp2p_peer_free(struct Libp2pPeer* in) {
|
||||||
if (in != NULL) {
|
if (in != NULL) {
|
||||||
|
@ -174,6 +193,12 @@ int libp2p_peer_protobuf_encode(struct Libp2pPeer* in, unsigned char* buffer, si
|
||||||
return 1;
|
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) {
|
int libp2p_peer_protobuf_decode(unsigned char* in, size_t in_size, struct Libp2pPeer** out) {
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
int retVal = 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 Libp2pLinkedList* last = NULL;
|
||||||
struct MultiAddress* ma = NULL;
|
struct MultiAddress* ma = NULL;
|
||||||
|
|
||||||
if ( (*out = (struct Libp2pPeer*)malloc(sizeof(struct Libp2pPeer))) == NULL)
|
*out = libp2p_peer_new();
|
||||||
|
if ( *out == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
struct Libp2pPeer* ptr = *out;
|
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();
|
struct Libp2pLinkedList* current = libp2p_utils_linked_list_new();
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
goto exit;
|
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);
|
free(buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
// assign the values
|
// assign the values
|
||||||
|
|
|
@ -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))
|
if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&buffer, &buffer_size, &bytes_read))
|
||||||
goto exit;
|
goto exit;
|
||||||
// turn this back into a peer
|
// 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)
|
if (current_item == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
current_item->next = NULL;
|
struct Libp2pPeer* peer = NULL;
|
||||||
if (!libp2p_peer_protobuf_decode(buffer, buffer_size, (struct Libp2pPeer**)¤t_item->item))
|
if (!libp2p_peer_protobuf_decode(buffer, buffer_size, &peer))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
current_item->item = peer;
|
||||||
free(buffer);
|
free(buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
if (ptr->provider_peer_head == NULL) {
|
if (ptr->provider_peer_head == NULL) {
|
||||||
|
|
|
@ -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)) {
|
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
|
// we have a peer id, convert it to a peer object
|
||||||
struct Libp2pPeer* peer = libp2p_peerstore_get_peer(peerstore, peer_id, peer_id_size);
|
struct Libp2pPeer* peer = libp2p_peerstore_get_peer(peerstore, peer_id, peer_id_size);
|
||||||
if (peer->addr_head != NULL)
|
if (peer != NULL) {
|
||||||
message->provider_peer_head = peer->addr_head;
|
message->provider_peer_head = libp2p_utils_linked_list_new();
|
||||||
|
message->provider_peer_head->item = peer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(peer_id);
|
free(peer_id);
|
||||||
// TODO: find closer peers
|
// 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
|
// there should only be 1 when adding a provider
|
||||||
if (current != NULL) {
|
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);
|
struct MultiAddress *peer_ma = libp2p_routing_dht_find_peer_ip_multiaddress(peer->addr_head);
|
||||||
if (peer_ma == NULL) {
|
if (peer_ma == NULL) {
|
||||||
libp2p_logger_error("dht_protocol", "Peer has no IP MultiAddress.\n");
|
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];
|
char new_string[255];
|
||||||
multiaddress_get_ip_address(session->default_stream->address, &ip);
|
multiaddress_get_ip_address(session->default_stream->address, &ip);
|
||||||
int port = multiaddress_get_ip_port(peer_ma);
|
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);
|
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);
|
libp2p_logger_debug("dht_protocol", "New MultiAddress made with %s.\n", new_string);
|
||||||
// TODO: See if the sender is who he says he is
|
// TODO: See if the sender is who he says he is
|
||||||
// set it as the first in the list
|
// set it as the first in the list
|
||||||
|
@ -315,6 +323,7 @@ int libp2p_routing_dht_handle_message(struct SessionContext* session, struct Pee
|
||||||
// unprotobuf
|
// unprotobuf
|
||||||
if (!libp2p_message_protobuf_decode(buffer, buffer_size, &message))
|
if (!libp2p_message_protobuf_decode(buffer, buffer_size, &message))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
// handle message
|
// handle message
|
||||||
switch(message->message_type) {
|
switch(message->message_type) {
|
||||||
case(MESSAGE_TYPE_PUT_VALUE): // store a value in local storage
|
case(MESSAGE_TYPE_PUT_VALUE): // store a value in local storage
|
||||||
|
|
|
@ -59,3 +59,33 @@ int test_peerstore() {
|
||||||
libp2p_peer_entry_free(peer_entry);
|
libp2p_peer_entry_free(peer_entry);
|
||||||
return retVal;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct Libp2pRecord* test_record_create() {
|
||||||
int test_record_protobuf() {
|
int test_record_protobuf() {
|
||||||
struct Libp2pRecord* record = test_record_create();
|
struct Libp2pRecord* record = test_record_create();
|
||||||
struct Libp2pRecord* results = NULL;
|
struct Libp2pRecord* results = NULL;
|
||||||
|
struct MultiAddress *ma = NULL, *ma_results = NULL;
|
||||||
size_t protobuf_size = 0;
|
size_t protobuf_size = 0;
|
||||||
char* protobuf = NULL;
|
char* protobuf = NULL;
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
|
@ -209,6 +210,7 @@ int test_record_message_protobuf() {
|
||||||
struct Libp2pPeer* closer_peer = NULL;
|
struct Libp2pPeer* closer_peer = NULL;
|
||||||
struct Libp2pMessage* message = NULL;
|
struct Libp2pMessage* message = NULL;
|
||||||
struct Libp2pMessage* result = NULL;
|
struct Libp2pMessage* result = NULL;
|
||||||
|
struct MultiAddress *ma_result = NULL;
|
||||||
char* buffer = NULL;
|
char* buffer = NULL;
|
||||||
size_t buffer_len = 0;
|
size_t buffer_len = 0;
|
||||||
|
|
||||||
|
@ -219,7 +221,7 @@ int test_record_message_protobuf() {
|
||||||
strcpy(closer_peer->id, "ABC123");
|
strcpy(closer_peer->id, "ABC123");
|
||||||
closer_peer->id_size = strlen(closer_peer->id);
|
closer_peer->id_size = strlen(closer_peer->id);
|
||||||
closer_peer->addr_head = libp2p_utils_linked_list_new();
|
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 = libp2p_message_new();
|
||||||
message->closer_peer_head = libp2p_utils_linked_list_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)
|
if (result->cluster_level_raw != 1)
|
||||||
goto exit;
|
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
|
// cleanup
|
||||||
retVal = 1;
|
retVal = 1;
|
||||||
exit:
|
exit:
|
||||||
|
|
|
@ -52,6 +52,7 @@ const char* names[] = {
|
||||||
"test_record_peer_protobuf",
|
"test_record_peer_protobuf",
|
||||||
"test_record_message_protobuf",
|
"test_record_message_protobuf",
|
||||||
"test_peer",
|
"test_peer",
|
||||||
|
"test_peer_protobuf",
|
||||||
"test_peerstore",
|
"test_peerstore",
|
||||||
"test_aes"
|
"test_aes"
|
||||||
};
|
};
|
||||||
|
@ -94,6 +95,7 @@ int (*funcs[])(void) = {
|
||||||
test_record_peer_protobuf,
|
test_record_peer_protobuf,
|
||||||
test_record_message_protobuf,
|
test_record_message_protobuf,
|
||||||
test_peer,
|
test_peer,
|
||||||
|
test_peer_protobuf,
|
||||||
test_peerstore,
|
test_peerstore,
|
||||||
test_aes
|
test_aes
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
void libp2p_utils_vector_add(struct Libp2pVector *v, void *item)
|
||||||
{
|
{
|
||||||
if (v->capacity == v->total)
|
if (v->capacity == v->total)
|
||||||
|
|
Loading…
Reference in a new issue