diff --git a/include/libp2p/peer/peer.h b/include/libp2p/peer/peer.h index 120f029..4c88e85 100644 --- a/include/libp2p/peer/peer.h +++ b/include/libp2p/peer/peer.h @@ -1,6 +1,7 @@ #pragma once #include "multiaddr/multiaddr.h" +#include "libp2p/net/stream.h" enum ConnectionType { // sender does not have a connection to the peer, and no extra information (default) @@ -18,6 +19,7 @@ struct Libp2pPeer { size_t id_size; // the length of id 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) + struct Stream *connection; // not protobuf'd, the current connection to the peer }; /** @@ -41,6 +43,14 @@ struct Libp2pPeer* libp2p_peer_new_from_data(const char* id, size_t id_size, con */ void libp2p_peer_free(struct Libp2pPeer* in); +/** + * Attempt to connect to the peer, setting connection_type correctly + * NOTE: If successful, this will set peer->connection to the stream + * @param peer the peer to connect to + * @returns true(1) on success, false(0) if we could not connect + */ +int libp2p_peer_connect(struct Libp2pPeer* peer); + /** * Make a copy of a peer * @param in what is to be copied diff --git a/include/libp2p/utils/logger.h b/include/libp2p/utils/logger.h index bcfa3d5..2b15a20 100644 --- a/include/libp2p/utils/logger.h +++ b/include/libp2p/utils/logger.h @@ -9,6 +9,23 @@ #define CURRENT_LOGLEVEL LOGLEVEL_DEBUG + +/*** + * Add a class to watch for logging messages + * @param str the class name to watch + */ +void libp2p_logger_add_class(const char* str); + +/** + * Initialize the logger. This should be done only once. + */ +void libp2p_logger_init(); + +/*** + * Checks to see if the logger has been initialized + */ +int libp2p_logger_initialized(); + /** * Log a message to the console * @param area the class it is coming from diff --git a/peer/peer.c b/peer/peer.c index 7384244..a2e28d1 100644 --- a/peer/peer.c +++ b/peer/peer.c @@ -4,6 +4,7 @@ #include "libp2p/utils/linked_list.h" #include "multiaddr/multiaddr.h" #include "protobuf.h" +#include "libp2p/net/multistream.h" /** * create a new Peer struct @@ -16,10 +17,37 @@ struct Libp2pPeer* libp2p_peer_new() { out->id_size = 0; out->addr_head = NULL; out->connection_type = CONNECTION_TYPE_NOT_CONNECTED; + out->connection = NULL; } return out; } +/** + * Attempt to connect to the peer, setting connection_type correctly + * NOTE: If successful, this will set peer->connection to the stream + * @param peer the peer to connect to + * @returns true(1) on success, false(0) if we could not connect + */ +int libp2p_peer_connect(struct Libp2pPeer* peer) { + // find an appropriate address + struct Libp2pLinkedList* current_address = peer->addr_head; + while (current_address != NULL && peer->connection_type != CONNECTION_TYPE_CONNECTED) { + struct MultiAddress *ma = (struct MultiAddress*)current_address->item; + if (multiaddress_is_ip(ma)) { + char* ip = NULL; + if (!multiaddress_get_ip_address(ma, &ip)) + continue; + int port = multiaddress_get_ip_port(ma); + peer->connection = libp2p_net_multistream_connect(ip, port); + if (peer->connection != NULL) { + peer->connection_type = CONNECTION_TYPE_CONNECTED; + } + free(ip); + } // is IP + } // trying to connect + return peer->connection_type == CONNECTION_TYPE_CONNECTED; +} + /** * Create a new peer struct with some data * @param id the id @@ -95,6 +123,7 @@ struct Libp2pPeer* libp2p_peer_copy(struct Libp2pPeer* in) { } current_in = current_in->next; } + out->connection = in->connection; } return out; } diff --git a/routing/dht_protocol.c b/routing/dht_protocol.c index 4d091a9..1d2d475 100644 --- a/routing/dht_protocol.c +++ b/routing/dht_protocol.c @@ -118,18 +118,37 @@ int libp2p_routing_dht_handle_get_providers(struct SessionContext* session, stru */ int libp2p_routing_dht_handle_add_provider(struct SessionContext* session, struct Libp2pMessage* message, struct Peerstore* peerstore, struct ProviderStore* providerstore, unsigned char** result_buffer, size_t* result_buffer_size) { + int retVal = 0; + struct Libp2pPeer *peer = NULL; + //TODO: verify peer signature if (message->record != NULL && message->record->author != NULL && message->record->author_size > 0 && message->key != NULL && message->key_size > 0) { - struct Libp2pPeer* peer = libp2p_peer_new(); + peer = libp2p_peer_new(); peer->id_size = message->record->author_size; peer->id = malloc(peer->id_size); + //TODO: Add addresses memcpy(peer->id, message->record->author, message->record->author_size); - int retVal = libp2p_peerstore_add_peer(peerstore, peer); + if (!libp2p_peerstore_add_peer(peerstore, peer)) + goto exit; + libp2p_peer_free(peer); - return retVal; + + if (retVal == 0) + goto exit; + + *result_buffer_size = libp2p_message_protobuf_encode_size(message); + *result_buffer = (unsigned char*)malloc(*result_buffer_size); + if (*result_buffer == NULL) + goto exit; + if (!libp2p_message_protobuf_encode(message, *result_buffer, *result_buffer_size, result_buffer_size)) + goto exit; } - return 0; + retVal = 1; + exit: + if (peer != NULL) + libp2p_peer_free(peer); + return retVal; } /** diff --git a/utils/logger.c b/utils/logger.c index 5051462..e84dac2 100644 --- a/utils/logger.c +++ b/utils/logger.c @@ -4,9 +4,43 @@ #include #include "libp2p/utils/logger.h" +#include "libp2p/utils/vector.h" -char* logger_classes[] = { "secio", "null" }; -int logger_classes_len = 2; +/** + * A class to handle logging + */ + +struct Libp2pVector* logger_classes = NULL; + +/** + * Initialize the logger. This should be done only once. + */ +void libp2p_logger_init() { + logger_classes = libp2p_utils_vector_new(1); + libp2p_logger_add_class("secio"); + libp2p_logger_add_class("null"); +} + +/*** + * Checks to see if the logger has been initialized + */ +int libp2p_logger_initialized() { + if (logger_classes == NULL) + return 0; + return 1; +} + +/*** + * Add a class to watch for logging messages + * @param str the class name to watch + */ +void libp2p_logger_add_class(const char* str) { + if (!libp2p_logger_initialized()) + libp2p_logger_init(); + char* ptr = malloc(strlen(str) + 1); + strcpy(ptr, str); + libp2p_utils_vector_add(logger_classes, ptr); +} /** * Log a message to the console @@ -16,10 +50,12 @@ int logger_classes_len = 2; * @param ... params */ void libp2p_logger_log(const char* area, int log_level, const char* format, ...) { + if (!libp2p_logger_initialized()) + libp2p_logger_init(); if (log_level <= CURRENT_LOGLEVEL) { int found = 0; - for (int i = 0; i < logger_classes_len; i++) { - if (strcmp(logger_classes[i], area) == 0) { + for (int i = 0; i < logger_classes->total; i++) { + if (strcmp(libp2p_utils_vector_get(logger_classes, i), area) == 0) { found = 1; break; } @@ -41,10 +77,12 @@ void libp2p_logger_log(const char* area, int log_level, const char* format, ...) * @param ... params */ void libp2p_logger_vlog(const char* area, int log_level, const char* format, va_list argptr) { + if (!libp2p_logger_initialized()) + libp2p_logger_init(); if (log_level <= CURRENT_LOGLEVEL) { int found = 0; - for (int i = 0; i < logger_classes_len; i++) { - if (strcmp(logger_classes[i], area) == 0) { + for (int i = 0; i < logger_classes->total; i++) { + if (strcmp(libp2p_utils_vector_get(logger_classes, i), area) == 0) { found = 1; break; }