Added peerstore and additional tests

yamux
John Jones 2017-02-20 18:53:20 -05:00
parent 4555cdfdf1
commit 9f0ee0cdb9
14 changed files with 571 additions and 254 deletions

View File

@ -9,6 +9,7 @@ OBJS = \
thirdparty/mbedtls/*.o \
hashmap/hashmap.o \
net/*.o \
peer/*.o \
record/*.o \
routing/*.o \
secio/*.o \
@ -23,6 +24,7 @@ compile:
cd thirdparty; make all;
cd hashmap; make all;
cd net; make all;
cd peer; make all;
cd record; make all;
cd routing; make all;
cd secio; make all;
@ -40,6 +42,7 @@ clean:
cd crypto; make clean;
cd hashmap; make clean;
cd net; make clean;
cd peer; make clean;
cd thirdparty; make clean
cd record; make clean;
cd routing; make clean;

View File

@ -0,0 +1,65 @@
#pragma once
enum ConnectionType {
// sender does not have a connection to the peer, and no extra information (default)
CONNECTION_TYPE_NOT_CONNECTED = 0,
// sender has a live connection to the peer
CONNECTION_TYPE_CONNECTED = 1,
// sender recently connected to peer
CONNECTION_TYPE_CAN_CONNECT = 2,
// sender recently tried to connect to peer repeatedly but failed to connect
CONNECTION_TYPE_CANNOT_CONNECT = 3
};
struct Libp2pPeer {
char* id; // protobuf field 1
size_t id_size;
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)
};
/**
* create a new Peer struct
* @returns a struct or NULL if there was a problem
*/
struct Libp2pPeer* libp2p_peer_new();
/**
* frees resources from a peer struct
* @param in the peer to free
*/
void libp2p_peer_free(struct Libp2pPeer* in);
/**
* Make a copy of a peer
* @param in what is to be copied
* @returns a new struct, that does not rely on the old
*/
struct Libp2pPeer* libp2p_peer_copy(struct Libp2pPeer* in);
/**
* Get an estimate of the necessary size of the buffer to protobuf a particular peer
* @param in the peer to examine
* @returns an approximation of the buffer size required (erring on the side of bigger)
*/
size_t libp2p_peer_protobuf_encode_size(struct Libp2pPeer* in);
/**
* Encode the Peer into a buffer
* @param in the peer
* @param buffer where to put it
* @param max_buffer_size the maximum amount of memory reserved for the buffer
* @param bytes_written the number of bytes written to the buffer
* @returns true(1) on success, otherwise 0
*/
int libp2p_peer_protobuf_encode(struct Libp2pPeer* in, unsigned char* buffer, size_t max_buffer_size, size_t* bytes_written);
/**
* turn an array of bytes into a Peer
* @param in the protobuf formatted peer
* @param in_size the size of in
* @param out the new Peer
* @returns true(1) on success, otherwise false
*/
int libp2p_peer_protobuf_decode(unsigned char* in, size_t in_size, struct Libp2pPeer** out);

View File

@ -0,0 +1,62 @@
#pragma once
#include "libp2p/utils/linked_list.h"
#include "libp2p/peer/peer.h"
/**
* Structures and functions to implement a storage area for peers and
* their connections and metadata
*/
/**
* An entry in the "database" is a PeerEntry. This contains metadata
* about the peer
*/
struct PeerEntry {
struct Libp2pPeer* peer;
// other metadata for the peer goes here
// TODO: add some type of timer to expire the record
};
/**
* Contains a collection of peers and their metadata
* NOTE: this is currently a linked list. Perhaps a better algo would
* improve performance, but will wait.
*/
struct Peerstore {
struct Libp2pLinkedList* head_entry;
struct Libp2pLinkedList* last_entry;
};
struct PeerEntry* libp2p_peer_entry_new();
void libp2p_peer_entry_free(struct PeerEntry* in);
/**
* Creates a new empty peerstore
* @returns an empty peerstore or NULL on error
*/
struct Peerstore* libp2p_peerstore_new();
/**
* Deallocate resources used by the peerstore
* @param in the struct to deallocate
* @returns true(1) on success, otherwise false(0)
*/
int libp2p_peerstore_free(struct Peerstore* in);
/**
* Add a Peer to the Peerstore
* @param peerstore the peerstore to add the entry to
* @param peer_entry the entry to add
* @returns true(1) on success, otherwise false
*/
int libp2p_peerstore_add_peer_entry(struct Peerstore* peerstore, struct PeerEntry* peer_entry);
/**
* Retrieve a peer from the peerstore based on the peer id
* @param peerstore the peerstore to search
* @param peer_id the id to search for as a binary array
* @param peer_id_size the size of the binary array
* @returns the PeerEntry struct if found, otherwise NULL
*/
struct PeerEntry* libp2p_peerstore_get_peer_entry(struct Peerstore* peerstore, unsigned char* peer_id, size_t peer_id_size);

View File

@ -3,7 +3,7 @@
#include "libp2p/record/record.h"
/**
* protobuf stuff for Message and Peer
* protobuf stuff for Message
* This is used for the KAD / DHT stuff
*/
@ -16,24 +16,6 @@ enum MessageType {
MESSAGE_TYPE_PING = 5
};
enum ConnectionType {
// sender does not have a connection to the peer, and no extra information (default)
CONNECTION_TYPE_NOT_CONNECTED = 0,
// sender has a live connection to the peer
CONNECTION_TYPE_CONNECTED = 1,
// sender recently connected to peer
CONNECTION_TYPE_CAN_CONNECT = 2,
// sender recently tried to connect to peer repeatedly but failed to connect
CONNECTION_TYPE_CANNOT_CONNECT = 3
};
struct Libp2pPeer {
char* id; // protobuf field 1
size_t id_size;
struct Libp2pLinkedList* addr_head; // protobuf field 2 of multiaddr bytes (repeatable) (stored here as a Libp2pVector)
enum ConnectionType connection_type; // protobuf field 3 (a varint)
};
struct Libp2pMessage {
enum MessageType message_type; // protobuf field 1 (a varint)
char* key; // protobuf field 2
@ -44,44 +26,6 @@ struct Libp2pMessage {
int32_t cluster_level_raw; // protobuf field 10
};
/**
* create a new Peer struct
* @returns a struct or NULL if there was a problem
*/
struct Libp2pPeer* libp2p_message_peer_new();
/**
* frees resources from a peer struct
* @param in the peer to free
*/
void libp2p_message_peer_free(struct Libp2pPeer* in);
/**
* Get an estimate of the necessary size of the buffer to protobuf a particular peer
* @param in the peer to examine
* @returns an approximation of the buffer size required (erring on the side of bigger)
*/
size_t libp2p_message_peer_protobuf_encode_size(struct Libp2pPeer* in);
/**
* Encode the Peer into a buffer
* @param in the peer
* @param buffer where to put it
* @param max_buffer_size the maximum amount of memory reserved for the buffer
* @param bytes_written the number of bytes written to the buffer
* @returns true(1) on success, otherwise 0
*/
int libp2p_message_peer_protobuf_encode(struct Libp2pPeer* in, unsigned char* buffer, size_t max_buffer_size, size_t* bytes_written);
/**
* turn an array of bytes into a Peer
* @param in the protobuf formatted peer
* @param in_size the size of in
* @param out the new Peer
* @returns true(1) on success, otherwise false
*/
int libp2p_message_peer_protobuf_decode(unsigned char* in, size_t in_size, struct Libp2pPeer** out);
/**
* create a new Libp2pMessage struct
* @returns a new Libp2pMessage with default settings

View File

@ -13,6 +13,9 @@ struct Libp2pLinkedList* libp2p_utils_linked_list_new();
/**
* Free resources from a linked list
* NOTE: if the item is a complex object, free the item before
* you call this method, and set item to NULL. Otherwise, this
* method will call a simple free()
* @param head the top of the linked list
*/
void libp2p_utils_linked_list_free(struct Libp2pLinkedList* head);

14
peer/Makefile Normal file
View File

@ -0,0 +1,14 @@
CC = gcc
CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -I../../c-multiaddr/include -g3
LFLAGS =
DEPS =
OBJS = peer.o peerstore.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
all: $(OBJS)
clean:
rm -f $(OBJS)

184
peer/peer.c Normal file
View File

@ -0,0 +1,184 @@
#include <stdlib.h>
#include "libp2p/peer/peer.h"
#include "libp2p/utils/linked_list.h"
#include "multiaddr/multiaddr.h"
#include "protobuf.h"
/**
* create a new Peer struct
* @returns a struct or NULL if there was a problem
*/
struct Libp2pPeer* libp2p_peer_new() {
struct Libp2pPeer* out = (struct Libp2pPeer*)malloc(sizeof(struct Libp2pPeer));
if (out != NULL) {
out->id = NULL;
out->id_size = 0;
out->addr_head = NULL;
out->connection_type = CONNECTION_TYPE_NOT_CONNECTED;
}
return out;
}
void libp2p_peer_free(struct Libp2pPeer* in) {
if (in != NULL) {
if (in->id != NULL)
free(in->id);
// free the memory in the linked list
struct Libp2pLinkedList* current = in->addr_head;
while (current != NULL) {
struct Libp2pLinkedList* temp = current->next;
multiaddress_free((struct MultiAddress*)current->item);
free(current);
current = temp;
}
free(in);
}
}
/**
* Make a copy of a peer
* @param in what is to be copied
* @returns a new struct, that does not rely on the old
*/
struct Libp2pPeer* libp2p_peer_copy(struct Libp2pPeer* in) {
struct Libp2pPeer* out = libp2p_peer_new();
if (out != NULL) {
out->id_size = in->id_size;
out->id = malloc(in->id_size);
if (out->id == NULL) {
libp2p_peer_free(out);
return NULL;
}
memcpy(out->id, in->id, in->id_size);
out->connection_type = in->connection_type;
struct Libp2pLinkedList* current_in = in->addr_head;
struct Libp2pLinkedList* current_out = NULL;
while (current_in != NULL) {
struct MultiAddress* addr = (struct MultiAddress*)current_in->item;
struct Libp2pLinkedList* copy_item = libp2p_utils_linked_list_new();
copy_item->item = multiaddress_copy(addr);
if (out->addr_head == NULL) {
out->addr_head = copy_item;
} else {
current_out->next = copy_item;
current_out = copy_item;
}
current_in = current_in->next;
}
}
return out;
}
size_t libp2p_peer_protobuf_encode_size(struct Libp2pPeer* in) {
// id + connection_type
int sz = 11 + in->id_size + 11;
// loop through the multiaddresses
struct Libp2pLinkedList* current = in->addr_head;
while (current != NULL) {
// find the length of the MultiAddress converted into bytes
struct MultiAddress* data = (struct MultiAddress*)current->item;
sz += 11 + data->bsize;
current = current->next;
}
return sz;
}
int libp2p_peer_protobuf_encode(struct Libp2pPeer* in, unsigned char* buffer, size_t max_buffer_size, size_t* bytes_written) {
// data & data_size
size_t bytes_used = 0;
*bytes_written = 0;
int retVal = 0;
// field 1 (id)
retVal = protobuf_encode_length_delimited(1, WIRETYPE_LENGTH_DELIMITED, in->id, in->id_size, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
if (retVal == 0)
return 0;
*bytes_written += bytes_used;
// field 2 (repeated)
struct Libp2pLinkedList* current = in->addr_head;
while (current != NULL) {
struct MultiAddress* data = (struct MultiAddress*)current->item;
retVal = protobuf_encode_length_delimited(2, WIRETYPE_LENGTH_DELIMITED, data->bytes, data->bsize, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
if (retVal == 0)
return 0;
*bytes_written += bytes_used;
current = current->next;
}
// field 3 (varint)
retVal = protobuf_encode_varint(3, WIRETYPE_VARINT, in->connection_type, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
if (retVal == 0)
return 0;
*bytes_written += bytes_used;
return 1;
}
int libp2p_peer_protobuf_decode(unsigned char* in, size_t in_size, struct Libp2pPeer** out) {
size_t pos = 0;
int retVal = 0;
char* buffer = NULL;
size_t buffer_size = 0;
struct Libp2pLinkedList* current = NULL;
struct Libp2pLinkedList* last = NULL;
struct MultiAddress* ma = NULL;
if ( (*out = (struct Libp2pPeer*)malloc(sizeof(struct Libp2pPeer))) == NULL)
goto exit;
struct Libp2pPeer* ptr = *out;
ptr->addr_head = NULL;
while(pos < in_size) {
size_t bytes_read = 0;
int field_no;
enum WireType field_type;
if (protobuf_decode_field_and_type(&in[pos], in_size, &field_no, &field_type, &bytes_read) == 0) {
goto exit;
}
pos += bytes_read;
switch(field_no) {
case (1): // id
if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&(ptr->id),&(ptr->id_size), &bytes_read))
goto exit;
pos += bytes_read;
break;
case (2): { // multiaddress bytes
if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, &buffer, &buffer_size, &bytes_read))
goto exit;
pos += bytes_read;
// now turn it into multiaddress
struct Libp2pLinkedList* current = libp2p_utils_linked_list_new();
if (current == NULL)
goto exit;
current->item = (void*)multiaddress_new_from_bytes(buffer, buffer_size);
free(buffer);
buffer = NULL;
// assign the values
if (ptr->addr_head == NULL) {
ptr->addr_head = current;
} else {
last->next = current;
}
last = current;
current = NULL;
break;
}
case (3): // enum as varint
if (!protobuf_decode_varint(&in[pos], in_size - pos, (long long unsigned int*)&ptr->connection_type, &bytes_read))
goto exit;
pos += bytes_read;
break;
}
}
retVal = 1;
exit:
if (retVal == 0) {
free(*out);
*out = NULL;
}
if (buffer != NULL)
free(buffer);
return retVal;
}

109
peer/peerstore.c Normal file
View File

@ -0,0 +1,109 @@
#include <stdlib.h>
#include <string.h>
#include "libp2p/peer/peerstore.h"
struct PeerEntry* libp2p_peer_entry_new() {
struct PeerEntry* out = (struct PeerEntry*)malloc(sizeof(struct PeerEntry));
if (out != NULL) {
out->peer = NULL;
}
return out;
}
void libp2p_peer_entry_free(struct PeerEntry* in) {
if (in != NULL) {
libp2p_peer_free(in->peer);
free(in);
}
}
struct PeerEntry* libp2p_peer_entry_copy(struct PeerEntry* in) {
struct PeerEntry* out = libp2p_peer_entry_new();
if (out != NULL) {
out->peer = libp2p_peer_copy(in->peer);
if (out->peer == NULL) {
free(out);
return NULL;
}
}
return out;
}
/**
* Creates a new empty peerstore
* @returns an empty peerstore or NULL on error
*/
struct Peerstore* libp2p_peerstore_new() {
struct Peerstore* out = (struct Peerstore*)malloc(sizeof(struct Peerstore));
if (out != NULL) {
out->head_entry = NULL;
}
return out;
}
/**
* Deallocate resources used by the peerstore
* @param in the struct to deallocate
* @returns true(1) on success, otherwise false(0)
*/
int libp2p_peerstore_free(struct Peerstore* in) {
if (in != NULL) {
struct Libp2pLinkedList* current = in->head_entry;
struct Libp2pLinkedList* next = NULL;
while (current != NULL) {
next = current->next;
libp2p_peer_entry_free((struct PeerEntry*)current->item);
current->item = NULL;
libp2p_utils_linked_list_free(current);
current = next;
}
free(in);
}
return 1;
}
/**
* Add a Peer to the Peerstore
* @param peerstore the peerstore to add the entry to
* @param peer_entry the entry to add
* @returns true(1) on success, otherwise false
*/
int libp2p_peerstore_add_peer_entry(struct Peerstore* peerstore, struct PeerEntry* peer_entry) {
struct Libp2pLinkedList* new_item = libp2p_utils_linked_list_new();
if (new_item == NULL)
return 0;
new_item->item = libp2p_peer_entry_copy(peer_entry);
if (new_item->item == NULL) {
libp2p_utils_linked_list_free(new_item);
return 0;
}
if (peerstore->head_entry == NULL) {
peerstore->head_entry = new_item;
peerstore->last_entry = new_item;
} else {
peerstore->last_entry->next = new_item;
peerstore->last_entry = new_item;
}
return 1;
}
/**
* Retrieve a peer from the peerstore based on the peer id
* @param peerstore the peerstore to search
* @param peer_id the id to search for as a binary array
* @param peer_id_size the size of the binary array
* @returns the PeerEntry struct if found, otherwise NULL
*/
struct PeerEntry* libp2p_peerstore_get_peer_entry(struct Peerstore* peerstore, unsigned char* peer_id, size_t peer_id_size) {
struct Libp2pLinkedList* current = peerstore->head_entry;
while(current != NULL) {
struct Libp2pPeer* peer = ((struct PeerEntry*)current->item)->peer;
if (peer->id_size != peer_id_size)
continue;
if (memcmp(peer_id, peer->id, peer->id_size) == 0) {
return (struct PeerEntry*)current->item;
}
}
return NULL;
}

View File

@ -1,154 +1,12 @@
#include <stdlib.h>
#include "libp2p/record/message.h"
#include "libp2p/peer/peer.h"
#include "libp2p/utils/linked_list.h"
#include "libp2p/utils/vector.h"
#include "protobuf.h"
#include "multiaddr/multiaddr.h"
/**
* create a new Peer struct
* @returns a struct or NULL if there was a problem
*/
struct Libp2pPeer* libp2p_message_peer_new() {
struct Libp2pPeer* out = (struct Libp2pPeer*)malloc(sizeof(struct Libp2pPeer));
if (out != NULL) {
out->id = NULL;
out->id_size = 0;
out->addr_head = NULL;
out->connection_type = CONNECTION_TYPE_NOT_CONNECTED;
}
return out;
}
void libp2p_message_peer_free(struct Libp2pPeer* in) {
if (in != NULL) {
if (in->id != NULL)
free(in->id);
// free the memory in the linked list
struct Libp2pLinkedList* current = in->addr_head;
while (current != NULL) {
struct Libp2pLinkedList* temp = current->next;
multiaddress_free((struct MultiAddress*)current->item);
free(current);
current = temp;
}
free(in);
}
}
size_t libp2p_message_peer_protobuf_encode_size(struct Libp2pPeer* in) {
// id + connection_type
int sz = 11 + in->id_size + 11;
// loop through the multiaddresses
struct Libp2pLinkedList* current = in->addr_head;
while (current != NULL) {
// find the length of the MultiAddress converted into bytes
struct MultiAddress* data = (struct MultiAddress*)current->item;
sz += 11 + data->bsize;
current = current->next;
}
return sz;
}
int libp2p_message_peer_protobuf_encode(struct Libp2pPeer* in, unsigned char* buffer, size_t max_buffer_size, size_t* bytes_written) {
// data & data_size
size_t bytes_used = 0;
*bytes_written = 0;
int retVal = 0;
// field 1 (id)
retVal = protobuf_encode_length_delimited(1, WIRETYPE_LENGTH_DELIMITED, in->id, in->id_size, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
if (retVal == 0)
return 0;
*bytes_written += bytes_used;
// field 2 (repeated)
struct Libp2pLinkedList* current = in->addr_head;
while (current != NULL) {
struct MultiAddress* data = (struct MultiAddress*)current->item;
retVal = protobuf_encode_length_delimited(2, WIRETYPE_LENGTH_DELIMITED, data->bytes, data->bsize, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
if (retVal == 0)
return 0;
*bytes_written += bytes_used;
current = current->next;
}
// field 3 (varint)
retVal = protobuf_encode_varint(3, WIRETYPE_VARINT, in->connection_type, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
if (retVal == 0)
return 0;
*bytes_written += bytes_used;
return 1;
}
int libp2p_message_peer_protobuf_decode(unsigned char* in, size_t in_size, struct Libp2pPeer** out) {
size_t pos = 0;
int retVal = 0;
char* buffer = NULL;
size_t buffer_size = 0;
struct Libp2pLinkedList* current = NULL;
struct Libp2pLinkedList* last = NULL;
struct MultiAddress* ma = NULL;
if ( (*out = (struct Libp2pPeer*)malloc(sizeof(struct Libp2pPeer))) == NULL)
goto exit;
struct Libp2pPeer* ptr = *out;
ptr->addr_head = NULL;
while(pos < in_size) {
size_t bytes_read = 0;
int field_no;
enum WireType field_type;
if (protobuf_decode_field_and_type(&in[pos], in_size, &field_no, &field_type, &bytes_read) == 0) {
goto exit;
}
pos += bytes_read;
switch(field_no) {
case (1): // id
if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&(ptr->id),&(ptr->id_size), &bytes_read))
goto exit;
pos += bytes_read;
break;
case (2): { // multiaddress bytes
if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, &buffer, &buffer_size, &bytes_read))
goto exit;
pos += bytes_read;
// now turn it into multiaddress
struct Libp2pLinkedList* current = libp2p_utils_linked_list_new();
if (current == NULL)
goto exit;
current->item = (void*)multiaddress_new_from_bytes(buffer, buffer_size);
free(buffer);
buffer = NULL;
// assign the values
if (ptr->addr_head == NULL) {
ptr->addr_head = current;
} else {
last->next = current;
}
last = current;
current = NULL;
break;
}
case (3): // enum as varint
if (!protobuf_decode_varint(&in[pos], in_size - pos, (long long unsigned int*)&ptr->connection_type, &bytes_read))
goto exit;
pos += bytes_read;
break;
}
}
retVal = 1;
exit:
if (retVal == 0) {
free(*out);
*out = NULL;
}
if (buffer != NULL)
free(buffer);
return retVal;
}
/***
* protobuf and other methods for Message
@ -169,26 +27,30 @@ struct Libp2pMessage* libp2p_message_new() {
}
void libp2p_message_free(struct Libp2pMessage* in) {
// a linked list of peer structs
struct Libp2pLinkedList* current = in->closer_peer_head;
while (current != NULL) {
struct Libp2pLinkedList* next = current->next;
struct Libp2pPeer* temp = (struct Libp2pPeer*)current->item;
libp2p_message_peer_free(temp);
current->item = NULL;
libp2p_utils_linked_list_free(current);
current = next;
if (in != NULL) {
// a linked list of peer structs
struct Libp2pLinkedList* current = in->closer_peer_head;
struct Libp2pLinkedList* next = NULL;
while (current != NULL) {
next = current->next;
libp2p_peer_free(current->item);
current->item = NULL;
libp2p_utils_linked_list_free(current);
current = next;
}
if (in->key != NULL)
free(in->key);
current = in->provider_peer_head;
while (current != NULL) {
next = current->next;
libp2p_peer_free(current->item);
current->item = NULL;
libp2p_utils_linked_list_free(current);
current = next;
}
libp2p_record_free(in->record);
free(in);
}
if (in->key != NULL)
free(in->key);
current = in->provider_peer_head;
while (current != NULL) {
struct Libp2pLinkedList* next = current->next;
libp2p_message_peer_free((struct Libp2pPeer*)next->item);
current = next;
}
libp2p_record_free(in->record);
free(in);
}
size_t libp2p_message_protobuf_encode_size(struct Libp2pMessage* in) {
@ -203,13 +65,13 @@ size_t libp2p_message_protobuf_encode_size(struct Libp2pMessage* in) {
// closer peers
struct Libp2pLinkedList* current = in->closer_peer_head;
while (current != NULL) {
retVal += 11 + libp2p_message_peer_protobuf_encode_size((struct Libp2pPeer*)current->item);
retVal += 11 + libp2p_peer_protobuf_encode_size((struct Libp2pPeer*)current->item);
current = current->next;
}
// provider peers
current = in->provider_peer_head;
while (current != NULL) {
retVal += 11 + libp2p_message_peer_protobuf_encode_size((struct Libp2pPeer*)current->item);
retVal += 11 + libp2p_peer_protobuf_encode_size((struct Libp2pPeer*)current->item);
current = current->next;
}
return retVal;
@ -243,11 +105,11 @@ int libp2p_message_protobuf_encode(struct Libp2pMessage* in, unsigned char* buff
struct Libp2pLinkedList* current = in->closer_peer_head;
while (current != NULL) {
struct Libp2pPeer* peer = (struct Libp2pPeer*)current->item;
protobuf_size = libp2p_message_peer_protobuf_encode_size(peer);
protobuf_size = libp2p_peer_protobuf_encode_size(peer);
unsigned char* peer_buffer = (unsigned char*)malloc(protobuf_size);
if (peer_buffer == NULL)
return 0;
if (!libp2p_message_peer_protobuf_encode(peer, peer_buffer, protobuf_size, &protobuf_size)) {
if (!libp2p_peer_protobuf_encode(peer, peer_buffer, protobuf_size, &protobuf_size)) {
free(peer_buffer);
return 0;
}
@ -262,11 +124,11 @@ int libp2p_message_protobuf_encode(struct Libp2pMessage* in, unsigned char* buff
current = in->provider_peer_head;
while (current != NULL) {
struct Libp2pPeer* peer = (struct Libp2pPeer*)current->item;
protobuf_size = libp2p_message_peer_protobuf_encode_size(peer);
protobuf_size = libp2p_peer_protobuf_encode_size(peer);
unsigned char* peer_buffer = (unsigned char*)malloc(protobuf_size);
if (peer_buffer == NULL)
return 0;
if (!libp2p_message_peer_protobuf_encode(peer, peer_buffer, protobuf_size, &protobuf_size)) {
if (!libp2p_peer_protobuf_encode(peer, peer_buffer, protobuf_size, &protobuf_size)) {
free(peer_buffer);
return 0;
}
@ -298,7 +160,7 @@ int libp2p_message_protobuf_decode(unsigned char* in, size_t in_size, struct Lib
struct Libp2pLinkedList* last_provider = NULL;
struct Libp2pMessage* ptr = NULL;
if ( (*out = (struct Libp2pMessage*)malloc(sizeof(struct Libp2pMessage))) == NULL)
if ( (*out = libp2p_message_new()) == NULL)
goto exit;
ptr = *out;
@ -339,11 +201,10 @@ 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_message_peer_protobuf_decode(buffer, buffer_size, (struct Libp2pPeer**)&current_item->item))
if (!libp2p_peer_protobuf_decode(buffer, buffer_size, (struct Libp2pPeer**)&current_item->item))
goto exit;
free(buffer);
buffer = NULL;
@ -363,7 +224,7 @@ int libp2p_message_protobuf_decode(unsigned char* in, size_t in_size, struct Lib
if (current_item == NULL)
goto exit;
current_item->next = NULL;
if (!libp2p_message_peer_protobuf_decode(buffer, buffer_size, (struct Libp2pPeer**)&current_item->item))
if (!libp2p_peer_protobuf_decode(buffer, buffer_size, (struct Libp2pPeer**)&current_item->item))
goto exit;
free(buffer);
buffer = NULL;

View File

@ -116,7 +116,7 @@ int libp2p_record_protobuf_decode(const unsigned char* in, size_t in_size, struc
size_t pos = 0;
int retVal = 0;
if ( (*out = (struct Libp2pRecord*)malloc(sizeof(struct Libp2pRecord))) == NULL)
if ( (*out = libp2p_record_new()) == NULL)
goto exit;
while(pos < in_size) {

61
test/test_peer.h Normal file
View File

@ -0,0 +1,61 @@
#pragma once
#include <stdlib.h>
#include "libp2p/peer/peer.h"
#include "libp2p/peer/peerstore.h"
/***
* Includes Libp2pPeer, PeerEntry, Peerstore
*/
/**
* Test the basics of peer
*/
int test_peer() {
struct Libp2pPeer* obj = libp2p_peer_new();
if (obj == NULL)
return 0;
libp2p_peer_free(obj);
return 1;
}
/**
* Test the peerstore
*/
int test_peerstore() {
struct Peerstore* peerstore = libp2p_peerstore_new();
struct PeerEntry* peer_entry = NULL;
struct PeerEntry* results = NULL;
int retVal = 0;
if (peerstore == NULL)
goto exit;
// add a peer entry to the peerstore
peer_entry = libp2p_peer_entry_new();
peer_entry->peer = libp2p_peer_new();
peer_entry->peer->id_size = 6;
peer_entry->peer->id = malloc(peer_entry->peer->id_size);
memcpy(peer_entry->peer->id, "ABC123", peer_entry->peer->id_size);
peer_entry->peer->connection_type = CONNECTION_TYPE_NOT_CONNECTED;
if (!libp2p_peerstore_add_peer_entry(peerstore, peer_entry))
goto exit;
// now try to retrieve it
results = libp2p_peerstore_get_peer_entry(peerstore, "ABC123", 6);
if (results == NULL || results->peer->id_size != 6)
goto exit;
// cleanup
retVal = 1;
exit:
if (peerstore != NULL)
libp2p_peerstore_free(peerstore);
if (peer_entry != NULL)
libp2p_peer_entry_free(peer_entry);
return retVal;
}

View File

@ -2,6 +2,7 @@
#include "libp2p/record/record.h"
#include "libp2p/record/message.h"
#include "libp2p/peer/peer.h"
#include "multiaddr/multiaddr.h"
int setval(char** result, size_t* result_size, char* in) {
@ -42,22 +43,22 @@ int test_record_protobuf() {
if (!libp2p_record_protobuf_decode(protobuf, protobuf_size, &results))
goto exit;
if (strcmp(record->key, results->key) != 0)
goto exit;
if (strcmp(record->value, results->value) != 0)
goto exit;
if (strcmp(record->author, results->author) != 0)
goto exit;
if (strcmp(record->signature, results->signature) != 0)
goto exit;
if (strcmp(record->time_received, results->time_received) != 0)
goto exit;
if (record->key_size != results->key_size
|| record->value_size != results->value_size
|| record->author_size != results->author_size
|| record->signature_size != results->signature_size
|| record->time_received_size != results->time_received_size)
goto exit;
if (strcmp(record->key, results->key) != 0)
goto exit;
if (strncmp(record->value, results->value, results->value_size) != 0)
goto exit;
if (strncmp(record->author, results->author, results->author_size) != 0)
goto exit;
if (strncmp(record->signature, results->signature, results->signature_size) != 0)
goto exit;
if (strncmp(record->time_received, results->time_received, results->time_received_size) != 0)
goto exit;
retVal = 1;
exit:
@ -151,7 +152,7 @@ int test_record_peer_protobuf() {
multi_addr1 = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001");
// make peer
peer = libp2p_message_peer_new();
peer = libp2p_peer_new();
peer->connection_type = CONNECTION_TYPE_CAN_CONNECT;
peer->id = malloc(7);
strcpy(peer->id, "ABC123");
@ -160,15 +161,15 @@ int test_record_peer_protobuf() {
peer->addr_head->item = multi_addr1;
// protobuf
protobuf_size = libp2p_message_peer_protobuf_encode_size(peer);
protobuf_size = libp2p_peer_protobuf_encode_size(peer);
protobuf = (unsigned char*)malloc(protobuf_size);
if (protobuf == NULL)
goto exit;
if (!libp2p_message_peer_protobuf_encode(peer, protobuf, protobuf_size, &protobuf_size))
if (!libp2p_peer_protobuf_encode(peer, protobuf, protobuf_size, &protobuf_size))
goto exit;
// unprotobuf
if (!libp2p_message_peer_protobuf_decode(protobuf, protobuf_size, &result))
if (!libp2p_peer_protobuf_decode(protobuf, protobuf_size, &result))
goto exit;
// check results
@ -189,14 +190,17 @@ int test_record_peer_protobuf() {
// cleanup
retVal = 1;
exit:
if (peer != NULL) {
libp2p_peer_free(peer);
// above gets rid of below...
multi_addr1 = NULL;
}
if (multi_addr1 != NULL)
multiaddress_free(multi_addr1);
if (peer != NULL)
libp2p_message_peer_free(peer);
if (protobuf != NULL)
free(protobuf);
if (result != NULL)
libp2p_message_peer_free(result);
libp2p_peer_free(result);
return retVal;
}
@ -209,7 +213,7 @@ int test_record_message_protobuf() {
size_t buffer_len = 0;
// construct message
closer_peer = libp2p_message_peer_new();
closer_peer = libp2p_peer_new();
closer_peer->connection_type = CONNECTION_TYPE_CAN_CONNECT;
closer_peer->id = malloc(7);
strcpy(closer_peer->id, "ABC123");

View File

@ -10,6 +10,7 @@
#include "test_multistream.h"
#include "test_conn.h"
#include "test_record.h"
#include "test_peer.h"
const char* names[] = {
"test_public_der_to_private_der",
@ -33,7 +34,7 @@ const char* names[] = {
//"test_crypto_rsa_sign",
"test_crypto_encoding_base32_encode",
"test_protobuf_private_key",
"test_secio_handshake",
//"test_secio_handshake",
"test_multistream_connect",
"test_multistream_get_list",
"test_ephemeral_key_generate",
@ -42,7 +43,9 @@ const char* names[] = {
"test_record_protobuf",
"test_record_make_put_record",
"test_record_peer_protobuf",
"test_record_message_protobuf"
"test_record_message_protobuf",
"test_peer",
"test_peerstore"
};
int (*funcs[])(void) = {
@ -67,7 +70,7 @@ int (*funcs[])(void) = {
//test_crypto_rsa_sign,
test_crypto_encoding_base32_encode,
test_protobuf_private_key,
test_secio_handshake,
//test_secio_handshake,
test_multistream_connect,
test_multistream_get_list,
test_ephemeral_key_generate,
@ -76,7 +79,9 @@ int (*funcs[])(void) = {
test_record_protobuf,
test_record_make_put_record,
test_record_peer_protobuf,
test_record_message_protobuf
test_record_message_protobuf,
test_peer,
test_peerstore
};
int testit(const char* name, int (*func)(void)) {

View File

@ -16,8 +16,10 @@ void libp2p_utils_linked_list_free(struct Libp2pLinkedList* head) {
struct Libp2pLinkedList* next = NULL;
while (current != NULL) {
next = current->next;
if (current->item != NULL)
if (current->item != NULL) {
free(current->item);
current->item = NULL;
}
free(current);
current = next;
}