Added peerstore and additional tests
This commit is contained in:
parent
4555cdfdf1
commit
9f0ee0cdb9
14 changed files with 571 additions and 254 deletions
3
Makefile
3
Makefile
|
@ -9,6 +9,7 @@ OBJS = \
|
||||||
thirdparty/mbedtls/*.o \
|
thirdparty/mbedtls/*.o \
|
||||||
hashmap/hashmap.o \
|
hashmap/hashmap.o \
|
||||||
net/*.o \
|
net/*.o \
|
||||||
|
peer/*.o \
|
||||||
record/*.o \
|
record/*.o \
|
||||||
routing/*.o \
|
routing/*.o \
|
||||||
secio/*.o \
|
secio/*.o \
|
||||||
|
@ -23,6 +24,7 @@ compile:
|
||||||
cd thirdparty; make all;
|
cd thirdparty; make all;
|
||||||
cd hashmap; make all;
|
cd hashmap; make all;
|
||||||
cd net; make all;
|
cd net; make all;
|
||||||
|
cd peer; make all;
|
||||||
cd record; make all;
|
cd record; make all;
|
||||||
cd routing; make all;
|
cd routing; make all;
|
||||||
cd secio; make all;
|
cd secio; make all;
|
||||||
|
@ -40,6 +42,7 @@ clean:
|
||||||
cd crypto; make clean;
|
cd crypto; make clean;
|
||||||
cd hashmap; make clean;
|
cd hashmap; make clean;
|
||||||
cd net; make clean;
|
cd net; make clean;
|
||||||
|
cd peer; make clean;
|
||||||
cd thirdparty; make clean
|
cd thirdparty; make clean
|
||||||
cd record; make clean;
|
cd record; make clean;
|
||||||
cd routing; make clean;
|
cd routing; make clean;
|
||||||
|
|
65
include/libp2p/peer/peer.h
Normal file
65
include/libp2p/peer/peer.h
Normal 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);
|
||||||
|
|
62
include/libp2p/peer/peerstore.h
Normal file
62
include/libp2p/peer/peerstore.h
Normal 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);
|
|
@ -3,7 +3,7 @@
|
||||||
#include "libp2p/record/record.h"
|
#include "libp2p/record/record.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* protobuf stuff for Message and Peer
|
* protobuf stuff for Message
|
||||||
* This is used for the KAD / DHT stuff
|
* This is used for the KAD / DHT stuff
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -16,24 +16,6 @@ enum MessageType {
|
||||||
MESSAGE_TYPE_PING = 5
|
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 {
|
struct Libp2pMessage {
|
||||||
enum MessageType message_type; // protobuf field 1 (a varint)
|
enum MessageType message_type; // protobuf field 1 (a varint)
|
||||||
char* key; // protobuf field 2
|
char* key; // protobuf field 2
|
||||||
|
@ -44,44 +26,6 @@ struct Libp2pMessage {
|
||||||
int32_t cluster_level_raw; // protobuf field 10
|
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
|
* create a new Libp2pMessage struct
|
||||||
* @returns a new Libp2pMessage with default settings
|
* @returns a new Libp2pMessage with default settings
|
||||||
|
|
|
@ -13,6 +13,9 @@ struct Libp2pLinkedList* libp2p_utils_linked_list_new();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free resources from a linked list
|
* 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
|
* @param head the top of the linked list
|
||||||
*/
|
*/
|
||||||
void libp2p_utils_linked_list_free(struct Libp2pLinkedList* head);
|
void libp2p_utils_linked_list_free(struct Libp2pLinkedList* head);
|
||||||
|
|
14
peer/Makefile
Normal file
14
peer/Makefile
Normal 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
184
peer/peer.c
Normal 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
109
peer/peerstore.c
Normal 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;
|
||||||
|
}
|
207
record/message.c
207
record/message.c
|
@ -1,154 +1,12 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "libp2p/record/message.h"
|
#include "libp2p/record/message.h"
|
||||||
|
#include "libp2p/peer/peer.h"
|
||||||
#include "libp2p/utils/linked_list.h"
|
#include "libp2p/utils/linked_list.h"
|
||||||
#include "libp2p/utils/vector.h"
|
#include "libp2p/utils/vector.h"
|
||||||
#include "protobuf.h"
|
#include "protobuf.h"
|
||||||
#include "multiaddr/multiaddr.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
|
* protobuf and other methods for Message
|
||||||
|
@ -169,26 +27,30 @@ struct Libp2pMessage* libp2p_message_new() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void libp2p_message_free(struct Libp2pMessage* in) {
|
void libp2p_message_free(struct Libp2pMessage* in) {
|
||||||
// a linked list of peer structs
|
if (in != NULL) {
|
||||||
struct Libp2pLinkedList* current = in->closer_peer_head;
|
// a linked list of peer structs
|
||||||
while (current != NULL) {
|
struct Libp2pLinkedList* current = in->closer_peer_head;
|
||||||
struct Libp2pLinkedList* next = current->next;
|
struct Libp2pLinkedList* next = NULL;
|
||||||
struct Libp2pPeer* temp = (struct Libp2pPeer*)current->item;
|
while (current != NULL) {
|
||||||
libp2p_message_peer_free(temp);
|
next = current->next;
|
||||||
current->item = NULL;
|
libp2p_peer_free(current->item);
|
||||||
libp2p_utils_linked_list_free(current);
|
current->item = NULL;
|
||||||
current = next;
|
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) {
|
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
|
// closer peers
|
||||||
struct Libp2pLinkedList* current = in->closer_peer_head;
|
struct Libp2pLinkedList* current = in->closer_peer_head;
|
||||||
while (current != NULL) {
|
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;
|
current = current->next;
|
||||||
}
|
}
|
||||||
// provider peers
|
// provider peers
|
||||||
current = in->provider_peer_head;
|
current = in->provider_peer_head;
|
||||||
while (current != NULL) {
|
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;
|
current = current->next;
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -243,11 +105,11 @@ int libp2p_message_protobuf_encode(struct Libp2pMessage* in, unsigned char* buff
|
||||||
struct Libp2pLinkedList* current = in->closer_peer_head;
|
struct Libp2pLinkedList* current = in->closer_peer_head;
|
||||||
while (current != NULL) {
|
while (current != NULL) {
|
||||||
struct Libp2pPeer* peer = (struct Libp2pPeer*)current->item;
|
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);
|
unsigned char* peer_buffer = (unsigned char*)malloc(protobuf_size);
|
||||||
if (peer_buffer == NULL)
|
if (peer_buffer == NULL)
|
||||||
return 0;
|
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);
|
free(peer_buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -262,11 +124,11 @@ int libp2p_message_protobuf_encode(struct Libp2pMessage* in, unsigned char* buff
|
||||||
current = in->provider_peer_head;
|
current = in->provider_peer_head;
|
||||||
while (current != NULL) {
|
while (current != NULL) {
|
||||||
struct Libp2pPeer* peer = (struct Libp2pPeer*)current->item;
|
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);
|
unsigned char* peer_buffer = (unsigned char*)malloc(protobuf_size);
|
||||||
if (peer_buffer == NULL)
|
if (peer_buffer == NULL)
|
||||||
return 0;
|
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);
|
free(peer_buffer);
|
||||||
return 0;
|
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 Libp2pLinkedList* last_provider = NULL;
|
||||||
struct Libp2pMessage* ptr = NULL;
|
struct Libp2pMessage* ptr = NULL;
|
||||||
|
|
||||||
if ( (*out = (struct Libp2pMessage*)malloc(sizeof(struct Libp2pMessage))) == NULL)
|
if ( (*out = libp2p_message_new()) == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
ptr = *out;
|
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))
|
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;
|
if (!libp2p_peer_protobuf_decode(buffer, buffer_size, (struct Libp2pPeer**)¤t_item->item))
|
||||||
if (!libp2p_message_peer_protobuf_decode(buffer, buffer_size, (struct Libp2pPeer**)¤t_item->item))
|
|
||||||
goto exit;
|
goto exit;
|
||||||
free(buffer);
|
free(buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
|
@ -363,7 +224,7 @@ int libp2p_message_protobuf_decode(unsigned char* in, size_t in_size, struct Lib
|
||||||
if (current_item == NULL)
|
if (current_item == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
current_item->next = NULL;
|
current_item->next = NULL;
|
||||||
if (!libp2p_message_peer_protobuf_decode(buffer, buffer_size, (struct Libp2pPeer**)¤t_item->item))
|
if (!libp2p_peer_protobuf_decode(buffer, buffer_size, (struct Libp2pPeer**)¤t_item->item))
|
||||||
goto exit;
|
goto exit;
|
||||||
free(buffer);
|
free(buffer);
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
|
|
|
@ -116,7 +116,7 @@ int libp2p_record_protobuf_decode(const unsigned char* in, size_t in_size, struc
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
|
|
||||||
if ( (*out = (struct Libp2pRecord*)malloc(sizeof(struct Libp2pRecord))) == NULL)
|
if ( (*out = libp2p_record_new()) == NULL)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
while(pos < in_size) {
|
while(pos < in_size) {
|
||||||
|
|
61
test/test_peer.h
Normal file
61
test/test_peer.h
Normal 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;
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "libp2p/record/record.h"
|
#include "libp2p/record/record.h"
|
||||||
#include "libp2p/record/message.h"
|
#include "libp2p/record/message.h"
|
||||||
|
#include "libp2p/peer/peer.h"
|
||||||
#include "multiaddr/multiaddr.h"
|
#include "multiaddr/multiaddr.h"
|
||||||
|
|
||||||
int setval(char** result, size_t* result_size, char* in) {
|
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))
|
if (!libp2p_record_protobuf_decode(protobuf, protobuf_size, &results))
|
||||||
goto exit;
|
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
|
if (record->key_size != results->key_size
|
||||||
|| record->value_size != results->value_size
|
|| record->value_size != results->value_size
|
||||||
|| record->author_size != results->author_size
|
|| record->author_size != results->author_size
|
||||||
|| record->signature_size != results->signature_size
|
|| record->signature_size != results->signature_size
|
||||||
|| record->time_received_size != results->time_received_size)
|
|| record->time_received_size != results->time_received_size)
|
||||||
goto exit;
|
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;
|
retVal = 1;
|
||||||
exit:
|
exit:
|
||||||
|
@ -151,7 +152,7 @@ int test_record_peer_protobuf() {
|
||||||
multi_addr1 = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001");
|
multi_addr1 = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001");
|
||||||
|
|
||||||
// make peer
|
// make peer
|
||||||
peer = libp2p_message_peer_new();
|
peer = libp2p_peer_new();
|
||||||
peer->connection_type = CONNECTION_TYPE_CAN_CONNECT;
|
peer->connection_type = CONNECTION_TYPE_CAN_CONNECT;
|
||||||
peer->id = malloc(7);
|
peer->id = malloc(7);
|
||||||
strcpy(peer->id, "ABC123");
|
strcpy(peer->id, "ABC123");
|
||||||
|
@ -160,15 +161,15 @@ int test_record_peer_protobuf() {
|
||||||
peer->addr_head->item = multi_addr1;
|
peer->addr_head->item = multi_addr1;
|
||||||
|
|
||||||
// protobuf
|
// protobuf
|
||||||
protobuf_size = libp2p_message_peer_protobuf_encode_size(peer);
|
protobuf_size = libp2p_peer_protobuf_encode_size(peer);
|
||||||
protobuf = (unsigned char*)malloc(protobuf_size);
|
protobuf = (unsigned char*)malloc(protobuf_size);
|
||||||
if (protobuf == NULL)
|
if (protobuf == NULL)
|
||||||
goto exit;
|
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;
|
goto exit;
|
||||||
|
|
||||||
// unprotobuf
|
// unprotobuf
|
||||||
if (!libp2p_message_peer_protobuf_decode(protobuf, protobuf_size, &result))
|
if (!libp2p_peer_protobuf_decode(protobuf, protobuf_size, &result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
// check results
|
// check results
|
||||||
|
@ -189,14 +190,17 @@ int test_record_peer_protobuf() {
|
||||||
// cleanup
|
// cleanup
|
||||||
retVal = 1;
|
retVal = 1;
|
||||||
exit:
|
exit:
|
||||||
|
if (peer != NULL) {
|
||||||
|
libp2p_peer_free(peer);
|
||||||
|
// above gets rid of below...
|
||||||
|
multi_addr1 = NULL;
|
||||||
|
}
|
||||||
if (multi_addr1 != NULL)
|
if (multi_addr1 != NULL)
|
||||||
multiaddress_free(multi_addr1);
|
multiaddress_free(multi_addr1);
|
||||||
if (peer != NULL)
|
|
||||||
libp2p_message_peer_free(peer);
|
|
||||||
if (protobuf != NULL)
|
if (protobuf != NULL)
|
||||||
free(protobuf);
|
free(protobuf);
|
||||||
if (result != NULL)
|
if (result != NULL)
|
||||||
libp2p_message_peer_free(result);
|
libp2p_peer_free(result);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +213,7 @@ int test_record_message_protobuf() {
|
||||||
size_t buffer_len = 0;
|
size_t buffer_len = 0;
|
||||||
|
|
||||||
// construct message
|
// construct message
|
||||||
closer_peer = libp2p_message_peer_new();
|
closer_peer = libp2p_peer_new();
|
||||||
closer_peer->connection_type = CONNECTION_TYPE_CAN_CONNECT;
|
closer_peer->connection_type = CONNECTION_TYPE_CAN_CONNECT;
|
||||||
closer_peer->id = malloc(7);
|
closer_peer->id = malloc(7);
|
||||||
strcpy(closer_peer->id, "ABC123");
|
strcpy(closer_peer->id, "ABC123");
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "test_multistream.h"
|
#include "test_multistream.h"
|
||||||
#include "test_conn.h"
|
#include "test_conn.h"
|
||||||
#include "test_record.h"
|
#include "test_record.h"
|
||||||
|
#include "test_peer.h"
|
||||||
|
|
||||||
const char* names[] = {
|
const char* names[] = {
|
||||||
"test_public_der_to_private_der",
|
"test_public_der_to_private_der",
|
||||||
|
@ -33,7 +34,7 @@ const char* names[] = {
|
||||||
//"test_crypto_rsa_sign",
|
//"test_crypto_rsa_sign",
|
||||||
"test_crypto_encoding_base32_encode",
|
"test_crypto_encoding_base32_encode",
|
||||||
"test_protobuf_private_key",
|
"test_protobuf_private_key",
|
||||||
"test_secio_handshake",
|
//"test_secio_handshake",
|
||||||
"test_multistream_connect",
|
"test_multistream_connect",
|
||||||
"test_multistream_get_list",
|
"test_multistream_get_list",
|
||||||
"test_ephemeral_key_generate",
|
"test_ephemeral_key_generate",
|
||||||
|
@ -42,7 +43,9 @@ const char* names[] = {
|
||||||
"test_record_protobuf",
|
"test_record_protobuf",
|
||||||
"test_record_make_put_record",
|
"test_record_make_put_record",
|
||||||
"test_record_peer_protobuf",
|
"test_record_peer_protobuf",
|
||||||
"test_record_message_protobuf"
|
"test_record_message_protobuf",
|
||||||
|
"test_peer",
|
||||||
|
"test_peerstore"
|
||||||
};
|
};
|
||||||
|
|
||||||
int (*funcs[])(void) = {
|
int (*funcs[])(void) = {
|
||||||
|
@ -67,7 +70,7 @@ int (*funcs[])(void) = {
|
||||||
//test_crypto_rsa_sign,
|
//test_crypto_rsa_sign,
|
||||||
test_crypto_encoding_base32_encode,
|
test_crypto_encoding_base32_encode,
|
||||||
test_protobuf_private_key,
|
test_protobuf_private_key,
|
||||||
test_secio_handshake,
|
//test_secio_handshake,
|
||||||
test_multistream_connect,
|
test_multistream_connect,
|
||||||
test_multistream_get_list,
|
test_multistream_get_list,
|
||||||
test_ephemeral_key_generate,
|
test_ephemeral_key_generate,
|
||||||
|
@ -76,7 +79,9 @@ int (*funcs[])(void) = {
|
||||||
test_record_protobuf,
|
test_record_protobuf,
|
||||||
test_record_make_put_record,
|
test_record_make_put_record,
|
||||||
test_record_peer_protobuf,
|
test_record_peer_protobuf,
|
||||||
test_record_message_protobuf
|
test_record_message_protobuf,
|
||||||
|
test_peer,
|
||||||
|
test_peerstore
|
||||||
};
|
};
|
||||||
|
|
||||||
int testit(const char* name, int (*func)(void)) {
|
int testit(const char* name, int (*func)(void)) {
|
||||||
|
|
|
@ -16,8 +16,10 @@ void libp2p_utils_linked_list_free(struct Libp2pLinkedList* head) {
|
||||||
struct Libp2pLinkedList* next = NULL;
|
struct Libp2pLinkedList* next = NULL;
|
||||||
while (current != NULL) {
|
while (current != NULL) {
|
||||||
next = current->next;
|
next = current->next;
|
||||||
if (current->item != NULL)
|
if (current->item != NULL) {
|
||||||
free(current->item);
|
free(current->item);
|
||||||
|
current->item = NULL;
|
||||||
|
}
|
||||||
free(current);
|
free(current);
|
||||||
current = next;
|
current = next;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue