diff --git a/include/libp2p/utils/linked_list.h b/include/libp2p/utils/linked_list.h index 4a79a89..036d745 100644 --- a/include/libp2p/utils/linked_list.h +++ b/include/libp2p/utils/linked_list.h @@ -4,3 +4,15 @@ struct Libp2pLinkedList { void* item; void* next; }; + +/*** + * Create a new linked list struct + * @returns a new linked list struct + */ +struct Libp2pLinkedList* libp2p_utils_linked_list_new(); + +/** + * Free resources from a linked list + * @param head the top of the linked list + */ +void libp2p_utils_linked_list_free(struct Libp2pLinkedList* head); diff --git a/record/Makefile b/record/Makefile index 69e2c04..2ad702c 100644 --- a/record/Makefile +++ b/record/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -g3 +CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -I../../c-multiaddr/include -g3 LFLAGS = DEPS = OBJS = record.o message.o diff --git a/record/message.c b/record/message.c index b7e3409..65e4438 100644 --- a/record/message.c +++ b/record/message.c @@ -4,6 +4,8 @@ #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 @@ -27,7 +29,7 @@ void libp2p_message_peer_free(struct Libp2pPeer* in) { struct Libp2pLinkedList* current = in->addr_head; while (current != NULL) { struct Libp2pLinkedList* temp = current->next; - free(current->item); + multiaddress_free((struct MultiAddress*)current->item); current = temp; } free(in); @@ -40,12 +42,9 @@ size_t libp2p_message_peer_protobuf_encode_size(struct Libp2pPeer* in) { // loop through the multiaddresses struct Libp2pLinkedList* current = in->addr_head; while (current != NULL) { - unsigned char* data = (unsigned char*)current->item; - struct Libp2pVector* vector; - if (!libp2p_utils_vector_unserialize(data, &vector)) - return 0; - sz += 11 + vector->buffer_size; - libp2p_utils_vector_free(vector); + // 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; @@ -64,11 +63,8 @@ int libp2p_message_peer_protobuf_encode(struct Libp2pPeer* in, unsigned char* bu // field 2 (repeated) struct Libp2pLinkedList* current = in->addr_head; while (current != NULL) { - struct Libp2pVector* vector; - if (!libp2p_utils_vector_unserialize(current->item, &vector)) - return 0; - retVal = protobuf_encode_length_delimited(2, WIRETYPE_LENGTH_DELIMITED, vector->buffer, vector->buffer_size, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used); - libp2p_utils_vector_free(vector); + 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; @@ -85,13 +81,11 @@ int libp2p_message_peer_protobuf_encode(struct Libp2pPeer* in, unsigned char* bu int libp2p_message_peer_protobuf_decode(unsigned char* in, size_t in_size, struct Libp2pPeer** out) { size_t pos = 0; int retVal = 0; - unsigned char* buffer = NULL; + char* buffer = NULL; size_t buffer_size = 0; - struct Libp2pVector vector; struct Libp2pLinkedList* current = NULL; struct Libp2pLinkedList* last = NULL; - - vector.buffer = NULL; + struct MultiAddress* ma = NULL; if ( (*out = (struct Libp2pPeer*)malloc(sizeof(struct Libp2pPeer))) == NULL) goto exit; @@ -100,7 +94,6 @@ int libp2p_message_peer_protobuf_decode(unsigned char* in, size_t in_size, struc ptr->addr_head = NULL; - while(pos < in_size) { size_t bytes_read = 0; int field_no; @@ -115,23 +108,18 @@ int libp2p_message_peer_protobuf_decode(unsigned char* in, size_t in_size, struc goto exit; pos += bytes_read; break; - case (2): { // array of bytes that is a multiaddress, put it in a vector - if (!protobuf_decode_length_delimited(&in[pos], in_size - pos, (char**)&vector.buffer, &vector.buffer_size, &bytes_read)) + 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 a byte array + // now turn it into multiaddress struct Libp2pLinkedList* current = (struct Libp2pLinkedList*)malloc(sizeof(struct Libp2pLinkedList)); if (current == NULL) goto exit; current->next = NULL; - size_t vector_size; - if (!libp2p_utils_vector_serialize(&vector, (unsigned char**)¤t->item, &vector_size)) { - free(current); - goto exit; - } - // clean up vector - free(vector.buffer); - vector.buffer = NULL; + 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; @@ -159,8 +147,6 @@ exit: } if (buffer != NULL) free(buffer); - if (vector.buffer != NULL) - free(vector.buffer); return retVal; } diff --git a/test/test_record.h b/test/test_record.h index 7e8bf71..f4466bc 100644 --- a/test/test_record.h +++ b/test/test_record.h @@ -1,6 +1,8 @@ #include #include "libp2p/record/record.h" +#include "libp2p/record/message.h" +#include "multiaddr/multiaddr.h" int setval(char** result, size_t* result_size, char* in) { *result = malloc(strlen(in) + 1); @@ -129,3 +131,65 @@ int test_record_make_put_record() { return retVal; } + +int test_record_peer_protobuf() { + struct Libp2pPeer* peer = NULL; + struct MultiAddress* multi_addr1 = NULL; + struct MultiAddress* multi_addr2 = NULL; + int retVal = 0; + unsigned char* protobuf = NULL; + size_t protobuf_size = 0; + struct Libp2pPeer* result = NULL; + + // make multiaddress + multi_addr1 = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001"); + + // make peer + peer = libp2p_message_peer_new(); + peer->connection_type = CONNECTION_TYPE_CAN_CONNECT; + peer->id = malloc(7); + strcpy(peer->id, "ABC123"); + peer->id_size = strlen(peer->id); + peer->addr_head = libp2p_utils_linked_list_new(); + peer->addr_head->item = multi_addr1; + + // protobuf + protobuf_size = libp2p_message_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)) + goto exit; + + // unprotobuf + if (!libp2p_message_peer_protobuf_decode(protobuf, protobuf_size, &result)) + goto exit; + + // check results + if (!strncmp(peer->id, result->id, peer->id_size) == 0) + goto exit; + + if (peer->id_size != result->id_size + || peer->connection_type != result->connection_type) + goto exit; + + // check multiaddress + multi_addr2 = (struct MultiAddress*)result->addr_head->item; + if (multi_addr1->bsize != multi_addr2->bsize) + goto exit; + if (strncmp(multi_addr1->bytes, multi_addr2->bytes, multi_addr2->bsize) != 0) + goto exit; + + // cleanup + retVal = 1; + exit: + 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); + return retVal; +} diff --git a/test/testit.c b/test/testit.c index 59505c8..bc9dda6 100644 --- a/test/testit.c +++ b/test/testit.c @@ -40,7 +40,8 @@ const char* names[] = { "test_dialer_new", "test_dialer_dial", "test_record_protobuf", - "test_record_make_put_record" + "test_record_make_put_record", + "test_record_peer_protobuf" }; int (*funcs[])(void) = { @@ -72,7 +73,8 @@ int (*funcs[])(void) = { test_dialer_new, test_dialer_dial, test_record_protobuf, - test_record_make_put_record + test_record_make_put_record, + test_record_peer_protobuf }; int testit(const char* name, int (*func)(void)) { diff --git a/utils/Makefile b/utils/Makefile index bf6ccf9..15f7747 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -7,7 +7,7 @@ endif LFLAGS = DEPS = -OBJS = string_list.o vector.o +OBJS = string_list.o vector.o linked_list.o %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) diff --git a/utils/linked_list.c b/utils/linked_list.c new file mode 100644 index 0000000..295c3be --- /dev/null +++ b/utils/linked_list.c @@ -0,0 +1,20 @@ +#include + +#include "libp2p/utils/linked_list.h" + +struct Libp2pLinkedList* libp2p_utils_linked_list_new() { + struct Libp2pLinkedList* out = (struct Libp2pLinkedList*)malloc(sizeof(struct Libp2pLinkedList)); + if (out != NULL) { + out->item = NULL; + out->next = NULL; + } + return out; +} + +void libp2p_utils_linked_list_free(struct Libp2pLinkedList* head) { + struct Libp2pLinkedList* current = head; + while (current != NULL) { + free(current->item); + current = current->next; + } +}