From 81263fc1a2a9d0bcf081bcbe20f55af96cb92780 Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 13 Feb 2017 13:26:41 -0500 Subject: [PATCH] Beginnings of dialers and connections --- Makefile | 9 ++++- conn/Makefile | 14 +++++++ conn/connection.c | 15 +++++++ conn/dialer.c | 55 ++++++++++++++++++++++++++ conn/transport_dialer.c | 37 +++++++++++++++++ include/libp2p/conn/connection.h | 29 ++++++++++++++ include/libp2p/conn/dialer.h | 26 ++++++++++-- include/libp2p/conn/transport_dialer.h | 13 ++++++ include/libp2p/utils/linked_list.h | 6 +++ test/Makefile | 2 +- test/test_conn.h | 12 ++++++ test/testit.c | 5 ++- 12 files changed, 216 insertions(+), 7 deletions(-) create mode 100644 conn/Makefile create mode 100644 conn/connection.c create mode 100644 conn/transport_dialer.c create mode 100644 include/libp2p/conn/connection.h create mode 100644 include/libp2p/conn/transport_dialer.h create mode 100644 include/libp2p/utils/linked_list.h create mode 100644 test/test_conn.h diff --git a/Makefile b/Makefile index 5770f92..907f588 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,10 @@ DEBUG = true export DEBUG -OBJS = crypto/*.o crypto/encoding/*.o \ +OBJS = \ + conn/*.o \ + crypto/*.o \ + crypto/encoding/*.o \ thirdparty/mbedtls/*.o \ hashmap/hashmap.o \ net/*.o \ @@ -14,7 +17,8 @@ OBJS = crypto/*.o crypto/encoding/*.o \ link: ar rcs libp2p.a $(OBJS) -compile: +compile: + cd conn; make all; cd crypto; make all; cd thirdparty; make all; cd hashmap; make all; @@ -32,6 +36,7 @@ rebuild: clean all all: test clean: + cd conn; make clean; cd crypto; make clean; cd hashmap; make clean; cd net; make clean; diff --git a/conn/Makefile b/conn/Makefile new file mode 100644 index 0000000..c341f15 --- /dev/null +++ b/conn/Makefile @@ -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 = dialer.o transport_dialer.o connection.o + +%.o: %.c $(DEPS) + $(CC) -c -o $@ $< $(CFLAGS) + + +all: $(OBJS) + +clean: + rm -f *.o diff --git a/conn/connection.c b/conn/connection.c new file mode 100644 index 0000000..8e18ea9 --- /dev/null +++ b/conn/connection.c @@ -0,0 +1,15 @@ +#include + +#include "libp2p/conn/connection.h" + +struct Connection* libp2p_conn_connection_open(struct TransportDialer* transport_dialer, struct maddr* multiaddress) { + struct Connection* out = NULL; + + if (transport_dialer != NULL) { + out = (struct Connection*)malloc(sizeof(struct Connection)); + if (out != NULL) { + //TODO implement this + } + } + return out; +} diff --git a/conn/dialer.c b/conn/dialer.c index ed0dbcf..65b0c26 100644 --- a/conn/dialer.c +++ b/conn/dialer.c @@ -1,3 +1,58 @@ +#include /** * Functions for handling the local dialer */ + +#include "libp2p/conn/dialer.h" +#include "libp2p/conn/connection.h" +#include "libp2p/conn/transport_dialer.h" +#include "libp2p/crypto/key.h" +#include "libp2p/utils/linked_list.h" + +/** + * Create a Dialer with the specified local information + */ +struct Dialer* libp2p_conn_dialer_new(char* peer_id, struct PrivateKey* private_key) { + struct Dialer* dialer = (struct Dialer*)malloc(sizeof(struct Dialer)); + if (dialer != NULL) { + dialer->peer_id = peer_id; + dialer->private_key = private_key; + dialer->fallback_dialer = NULL; + dialer->transport_dialers = NULL; + } + return dialer; +} + +/** + * free resources from the Dialer + */ +void libp2p_conn_dialer_free(struct Dialer* in) { + if (in != NULL) { + free(in->peer_id); + libp2p_crypto_private_key_free(in->private_key); + if (in->transport_dialers != NULL) { + struct Libp2pLinkedList* current = in->transport_dialers; + while(current != NULL) { + libp2p_conn_transport_dialer_free((struct TransportDialer*)current->item); + current = current->next; + } + } + if (in->fallback_dialer != NULL) + libp2p_conn_transport_dialer_free((struct TransportDialer*)in->fallback_dialer); + } + return; +} + +/** + * Retrieve a Connection struct from the dialer + * @param dialer the dialer to use + * @param muiltiaddress who to connect to + * @returns a Connection, or NULL + */ +struct Connection* libp2p_conn_dialer_get_connection(struct Dialer* dialer, struct maddr* multiaddress) { + struct Connection* conn = libp2p_conn_transport_dialer_get(dialer->transport_dialers, multiaddress); + if (conn == NULL) { + conn = libp2p_conn_connection_open(dialer->fallback_dialer, multiaddress); + } + return conn; +} diff --git a/conn/transport_dialer.c b/conn/transport_dialer.c new file mode 100644 index 0000000..1a6dc45 --- /dev/null +++ b/conn/transport_dialer.c @@ -0,0 +1,37 @@ +#include + +#include "libp2p/conn/transport_dialer.h" + +struct TransportDialer* libp2p_conn_transport_dialer_new(struct maddr* multiaddr) { + struct TransportDialer* out = (struct TransportDialer*)malloc(sizeof(struct TransportDialer)); + if (out != NULL) { + out->multiaddr = (struct maddr*)malloc(sizeof(struct maddr)); + if (out->multiaddr == NULL) { + free(out); + return NULL; + } + out->multiaddr->bsize[0] = multiaddr->bsize[0]; + memcpy(out->multiaddr->bytes, multiaddr->bytes, 400); + memcpy(out->multiaddr->string, multiaddr->string, 800); + } + return out; +} + +/** + * free resources from a TransportDialer struct + * @param in the struct to be freed + */ +void libp2p_conn_transport_dialer_free(struct TransportDialer* in) { + free(in); +} + +/** + * Given a list of dialers, find the appropriate dialer for this multiaddress + * @param transport_dialers a list of dialers + * @param multiaddr the address + * @returns a connection, or NULL if no appropriate dialer was found + */ +struct Connection* libp2p_conn_transport_dialer_get(struct Libp2pLinkedList* transport_dialers, struct maddr* multiaddr) { + //TODO: implement this method + return NULL; +} diff --git a/include/libp2p/conn/connection.h b/include/libp2p/conn/connection.h new file mode 100644 index 0000000..7a37da5 --- /dev/null +++ b/include/libp2p/conn/connection.h @@ -0,0 +1,29 @@ +/** + * Implements an interface to connect and talk to different nodes. + * A Dialer will connect, and return a Connection structure + */ + +#include "libp2p/conn/transport_dialer.h" +#include "multiaddr/multiaddr.h" + +struct Connection { + int socket_handle; + /** + * Read from the stream + * @param socket_handle the socket to read from + * @param in what was read in NOTE: this allocates memory + * @param in_size the number of bytes read in + * @returns 0 on success, otherwise an error code + */ + int (*read)(int socket_handle, char** in, size_t* in_size); + /** + * Write to the stream + * @param socket_handle the socket to write to + * @param out the bytes to write to the stream + * @param out_size the number of bytes to write + * @returns 0 on success, otherwise an error code + */ + int (*write)(int socket_handle, char* out, size_t* out_size); +}; + +struct Connection* libp2p_conn_connection_open(struct TransportDialer* transport_dialer, struct maddr* multiaddress); diff --git a/include/libp2p/conn/dialer.h b/include/libp2p/conn/dialer.h index 8d610a0..635e452 100644 --- a/include/libp2p/conn/dialer.h +++ b/include/libp2p/conn/dialer.h @@ -1,9 +1,11 @@ /*** * A local dialer. Uses MultiAddr to figure out the best way to - * connect to a client. + * connect to a client, then returns an open Connection that can be + * closed, read from and written to. */ #include "libp2p/crypto/key.h" +#include "multiaddr/multiaddr.h" struct Dialer { /** @@ -16,9 +18,27 @@ struct Dialer { * A linked list of transport dialers. A transport dialer can be selected * based on the MultiAddr being dialed. Most common: TCP and UDP */ - struct TransportDialer* transport_dialers; + struct Libp2pLinkedList* transport_dialers; //TODO: See dial.go, need to implement Protector - struct TransportDialer* fallback_dialer; // the default dialer + struct TransportDialer* fallback_dialer; // the default dialer. NOTE: this should not be in the list of transport_dialers }; + +/** + * Create a Dialer with the specified local information + */ +struct Dialer* libp2p_conn_dialer_new(char* peer_id, struct PrivateKey* private_key); + +/** + * free resources from the Dialer + */ +void libp2p_conn_dialer_free(struct Dialer* in); + +/** + * Retrieve a Connection struct from the dialer + * @param dialer the dialer to use + * @param muiltiaddress who to connect to + * @returns a Connection, or NULL + */ +struct Connection* libp2p_conn_dialer_get_connection(struct Dialer* dialer, struct maddr* multiaddress); diff --git a/include/libp2p/conn/transport_dialer.h b/include/libp2p/conn/transport_dialer.h new file mode 100644 index 0000000..8aac91a --- /dev/null +++ b/include/libp2p/conn/transport_dialer.h @@ -0,0 +1,13 @@ +#pragma once + +#include "multiaddr/multiaddr.h" +#include "libp2p/utils/linked_list.h" + +struct TransportDialer { + struct maddr* multiaddr; +}; + +struct TransportDialer* libp2p_conn_transport_dialer_new(struct maddr* multiaddr); +void libp2p_conn_transport_dialer_free(struct TransportDialer* in); + +struct Connection* libp2p_conn_transport_dialer_get(struct Libp2pLinkedList* transport_dialers, struct maddr* multiaddr); diff --git a/include/libp2p/utils/linked_list.h b/include/libp2p/utils/linked_list.h new file mode 100644 index 0000000..4a79a89 --- /dev/null +++ b/include/libp2p/utils/linked_list.h @@ -0,0 +1,6 @@ +#pragma once + +struct Libp2pLinkedList { + void* item; + void* next; +}; diff --git a/test/Makefile b/test/Makefile index 52d6cde..90582c9 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../include -I. -I../../c-multihash/include +CFLAGS = -O0 -I../include -I. -I../../c-multihash/include -I../../c-multiaddr/include ifdef DEBUG CFLAGS += -g3 diff --git a/test/test_conn.h b/test/test_conn.h new file mode 100644 index 0000000..0d58315 --- /dev/null +++ b/test/test_conn.h @@ -0,0 +1,12 @@ +#include + +#include "libp2p/conn/dialer.h" + +int test_dialer_new() { + struct PrivateKey* private_key = NULL; + struct Dialer* dialer = libp2p_conn_dialer_new("ABC", private_key); + if (dialer == NULL) + return 0; + libp2p_conn_dialer_free(dialer); + return 1; +} diff --git a/test/testit.c b/test/testit.c index 2530019..a92a45d 100644 --- a/test/testit.c +++ b/test/testit.c @@ -8,6 +8,7 @@ #include "test_secio.h" #include "test_mbedtls.h" #include "test_multistream.h" +#include "test_conn.h" const char* names[] = { "test_public_der_to_private_der", @@ -34,7 +35,8 @@ const char* names[] = { "test_secio_handshake", "test_multistream_connect", "test_multistream_get_list", - "test_ephemeral_key_generate" + "test_ephemeral_key_generate", + "test_dialer_new" }; int (*funcs[])(void) = { @@ -63,6 +65,7 @@ int (*funcs[])(void) = { test_multistream_connect, test_multistream_get_list, test_ephemeral_key_generate, + test_dialer_new }; int testit(const char* name, int (*func)(void)) {