diff --git a/conn/Makefile b/conn/Makefile index c341f15..d68bc26 100644 --- a/conn/Makefile +++ b/conn/Makefile @@ -2,7 +2,7 @@ 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 +OBJS = dialer.o transport_dialer.o connection.o tcp_transport_dialer.o %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) diff --git a/conn/connection.c b/conn/connection.c index 4fc5d79..e91c7ad 100644 --- a/conn/connection.c +++ b/conn/connection.c @@ -16,7 +16,7 @@ struct Connection* libp2p_conn_connection_new(struct TransportDialer* transport_ void libp2p_conn_connection_free(struct Connection* connection) { if (connection != NULL) { - fclose(connection->socket_handle); + //close(connection->socket_handle); free(connection); } } diff --git a/conn/dialer.c b/conn/dialer.c index b842036..1fb2094 100644 --- a/conn/dialer.c +++ b/conn/dialer.c @@ -9,10 +9,13 @@ #include "libp2p/crypto/key.h" #include "libp2p/utils/linked_list.h" +struct TransportDialer* libp2p_conn_tcp_transport_dialer_new(); + /** * Create a Dialer with the specified local information */ struct Dialer* libp2p_conn_dialer_new(char* peer_id, struct PrivateKey* private_key) { + int success = 0; struct Dialer* dialer = (struct Dialer*)malloc(sizeof(struct Dialer)); if (dialer != NULL) { dialer->peer_id = malloc(strlen(peer_id) + 1); @@ -21,8 +24,9 @@ struct Dialer* libp2p_conn_dialer_new(char* peer_id, struct PrivateKey* private_ dialer->private_key = (struct PrivateKey*)malloc(sizeof(struct PrivateKey)); if (dialer->private_key != NULL) { libp2p_crypto_private_key_copy(private_key, dialer->private_key); - dialer->fallback_dialer = NULL; + //TODO: build transport dialers dialer->transport_dialers = NULL; + dialer->fallback_dialer = libp2p_conn_tcp_transport_dialer_new(peer_id, private_key); return dialer; } } @@ -32,7 +36,9 @@ struct Dialer* libp2p_conn_dialer_new(char* peer_id, struct PrivateKey* private_ } /** - * free resources from the Dialer + * Free resources from the Dialer + * NOTE: this frees the fallback dialer too (should we be doing this? + * @param in the Dialer struct to free */ void libp2p_conn_dialer_free(struct Dialer* in) { if (in != NULL) { @@ -47,6 +53,7 @@ void libp2p_conn_dialer_free(struct Dialer* in) { } if (in->fallback_dialer != NULL) libp2p_conn_transport_dialer_free((struct TransportDialer*)in->fallback_dialer); + free(in); } return; } diff --git a/conn/tcp_transport_dialer.c b/conn/tcp_transport_dialer.c new file mode 100644 index 0000000..9286459 --- /dev/null +++ b/conn/tcp_transport_dialer.c @@ -0,0 +1,66 @@ +#include +#include +#include + +#include "multiaddr/multiaddr.h" +#include "libp2p/net/p2pnet.h" +#include "libp2p/conn/connection.h" +#include "libp2p/conn/transport_dialer.h" + +/** + * An implementation of a tcp transport dialer + */ + + +struct TcpIp { + char* ip; + int port; +}; + +struct TcpIp* libp2p_conn_parse_ip_multiaddress(struct MultiAddress* addr) { + struct TcpIp* out = (struct TcpIp*)malloc(sizeof(struct TcpIp)); + char* address = malloc(strlen(addr->string) + 1); + strcpy(address, addr->string); + char* tok = strtok(address, "/"); + int pos = 0; + while (tok != NULL) { + switch (pos) { + case 2: { + out->ip = malloc(strlen(tok) + 1); + strcpy(out->ip, tok); + break; + } + case 4: { + out->port = strtol(tok, NULL, 10); + break; + } + } + tok = strtok(NULL, "/"); + pos++; + } + //TODO: do a better job of parsing the results + return out; +} + +int libp2p_conn_tcp_can_handle(struct MultiAddress* addr) { + return 1; +} + + + +struct Connection* libp2p_conn_tcp_dial(struct TransportDialer* transport_dialer, struct MultiAddress* addr) { + struct Connection* conn = (struct Connection*) malloc(sizeof(struct Connection*)); + conn->socket_handle = socket_open4(); + struct TcpIp* results = libp2p_conn_parse_ip_multiaddress(addr); + struct hostent* host = gethostbyname(results->ip); + struct in_addr** addr_list = (struct in_addr**)host->h_addr_list; + socket_connect4(conn->socket_handle, (*addr_list[0]).s_addr, results->port); + return conn; +} + +struct TransportDialer* libp2p_conn_tcp_transport_dialer_new(char* peer_id, struct PrivateKey* private_key) { + struct TransportDialer* out = libp2p_conn_transport_dialer_new(peer_id, private_key); + out->can_handle = libp2p_conn_tcp_can_handle; + out->dial = libp2p_conn_tcp_dial; + return out; +} diff --git a/conn/transport_dialer.c b/conn/transport_dialer.c index 7b8e3ed..2c59696 100644 --- a/conn/transport_dialer.c +++ b/conn/transport_dialer.c @@ -1,19 +1,15 @@ #include +#include "libp2p/crypto/key.h" #include "libp2p/conn/transport_dialer.h" -struct TransportDialer* libp2p_conn_transport_dialer_new(struct MultiAddress* multiaddr) { +struct TransportDialer* libp2p_conn_transport_dialer_new(char* peer_id, struct PrivateKey* private_key) { struct TransportDialer* out = (struct TransportDialer*)malloc(sizeof(struct TransportDialer)); if (out != NULL) { - out->multiaddr = (struct MultiAddress*)malloc(sizeof(struct MultiAddress)); - if (out->multiaddr == NULL) { - libp2p_conn_transport_dialer_free(out); - return NULL; - } - if (multiaddress_copy(multiaddr, out->multiaddr) == 0) { - libp2p_conn_transport_dialer_free(out); - return NULL; - } + out->peer_id = malloc(strlen(peer_id) + 1); + strcpy(out->peer_id, peer_id); + out->private_key = (struct PrivateKey*)malloc(sizeof(struct PrivateKey)); + libp2p_crypto_private_key_copy(private_key, out->private_key); } return out; } @@ -23,7 +19,12 @@ struct TransportDialer* libp2p_conn_transport_dialer_new(struct MultiAddress* mu * @param in the struct to be freed */ void libp2p_conn_transport_dialer_free(struct TransportDialer* in) { - free(in); + if (in != NULL) { + if (in->peer_id != NULL) + free(in->peer_id); + libp2p_crypto_private_key_free(in->private_key); + free(in); + } } /** @@ -33,6 +34,19 @@ void libp2p_conn_transport_dialer_free(struct TransportDialer* in) { * @returns a connection, or NULL if no appropriate dialer was found */ struct Connection* libp2p_conn_transport_dialer_get(struct Libp2pLinkedList* transport_dialers, struct MultiAddress* multiaddr) { - //TODO: implement this method + struct Libp2pLinkedList* current = transport_dialers; + struct TransportDialer* t_dialer = NULL; + while (current != NULL) { + t_dialer = (struct TransportDialer*)current->item; + if (t_dialer->can_handle(multiaddr)) + break; + current = current->next; + t_dialer = NULL; + } + + if (t_dialer != NULL) { + return t_dialer->dial(t_dialer, multiaddr); + } + return NULL; } diff --git a/include/libp2p/conn/connection.h b/include/libp2p/conn/connection.h index 49d32bf..d4da1c9 100644 --- a/include/libp2p/conn/connection.h +++ b/include/libp2p/conn/connection.h @@ -8,7 +8,7 @@ #include "multiaddr/multiaddr.h" struct Connection { - FILE* socket_handle; + int socket_handle; /** * Read from the stream * @param socket_handle the socket to read from diff --git a/include/libp2p/conn/transport_dialer.h b/include/libp2p/conn/transport_dialer.h index f8bb581..b75f5a1 100644 --- a/include/libp2p/conn/transport_dialer.h +++ b/include/libp2p/conn/transport_dialer.h @@ -4,10 +4,13 @@ #include "libp2p/utils/linked_list.h" struct TransportDialer { - struct MultiAddress* multiaddr; + char* peer_id; + struct PrivateKey* private_key; + int (*can_handle)(struct MultiAddress* multiaddr); + struct Connection* (*dial)(struct TransportDialer* transport_dialer, struct MultiAddress* multiaddr); }; -struct TransportDialer* libp2p_conn_transport_dialer_new(struct MultiAddress* multiaddr); +struct TransportDialer* libp2p_conn_transport_dialer_new(char* peer_id, struct PrivateKey* private_key); void libp2p_conn_transport_dialer_free(struct TransportDialer* in); struct Connection* libp2p_conn_transport_dialer_get(struct Libp2pLinkedList* transport_dialers, struct MultiAddress* multiaddr); diff --git a/test/test_conn.h b/test/test_conn.h index 64db0d9..2eb724e 100644 --- a/test/test_conn.h +++ b/test/test_conn.h @@ -16,7 +16,7 @@ int test_dialer_new() { int test_dialer_dial() { int retVal = 0; char* config_dir = "/home/parallels/.ipfs/config"; - char* destination_string = "/ip/192.210.179.217/tcp/4001"; + char* destination_string = "/ip4/192.210.179.217/tcp/4001/"; char* peer_id = NULL; struct PrivateKey* private_key = NULL; struct Dialer* dialer = NULL; @@ -56,6 +56,7 @@ int test_dialer_dial() { exit: if (result != NULL) free(result); + free(peer_id); multiaddress_free(destination_address); libp2p_conn_dialer_free(dialer); libp2p_crypto_private_key_free(private_key); diff --git a/test/test_helper.h b/test/test_helper.h index 1ac8431..c723e8a 100644 --- a/test/test_helper.h +++ b/test/test_helper.h @@ -39,6 +39,8 @@ struct PrivateKey* base64ToPrivateKey(char* base64) { libp2p_crypto_private_key_free(out); out = NULL; } + if (decode_base64 != NULL) + free(decode_base64); return out; }