diff --git a/include/libp2p/net/multistream.h b/include/libp2p/net/multistream.h index 57125ed..7babfc4 100644 --- a/include/libp2p/net/multistream.h +++ b/include/libp2p/net/multistream.h @@ -53,6 +53,6 @@ int libp2p_net_multistream_negotiate(struct Stream* stream); */ struct Libp2pMessage* libp2p_net_multistream_get_message(struct Stream* stream); -struct Stream* libp2p_net_multistream_stream_new(int socket_fd); +struct Stream* libp2p_net_multistream_stream_new(int socket_fd, const char* ip, int port); void libp2p_net_multistream_stream_free(struct Stream* stream); diff --git a/include/libp2p/net/stream.h b/include/libp2p/net/stream.h index fcf0e8c..c0a99b7 100644 --- a/include/libp2p/net/stream.h +++ b/include/libp2p/net/stream.h @@ -8,6 +8,7 @@ struct Stream { * A generic socket descriptor */ void* socket_descriptor; + struct MultiAddress *address; /** * Reads from the stream diff --git a/include/libp2p/utils/logger.h b/include/libp2p/utils/logger.h index 2b15a20..d145444 100644 --- a/include/libp2p/utils/logger.h +++ b/include/libp2p/utils/logger.h @@ -51,3 +51,11 @@ void libp2p_logger_debug(const char* area, const char* format, ...); */ void libp2p_logger_error(const char* area, const char* format, ...); +/** + * Log an info message to the console + * @param area the class it is coming from + * @param format the logging string + * @param ... params + */ +void libp2p_logger_info(const char* area, const char* format, ...); + diff --git a/net/Makefile b/net/Makefile index 5e9e63e..a0d0f47 100644 --- a/net/Makefile +++ b/net/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -Wall -I../include -I../../c-protobuf +CFLAGS = -O0 -Wall -I../include -I../../c-protobuf -I../../c-multiaddr/include ifdef DEBUG CFLAGS += -g3 diff --git a/net/multistream.c b/net/multistream.c index e0bd471..83a8079 100644 --- a/net/multistream.c +++ b/net/multistream.c @@ -10,6 +10,7 @@ #include "libp2p/secio/secio.h" #include "varint.h" #include "libp2p/net/multistream.h" +#include "multiaddr/multiaddr.h" /*** * An implementation of the libp2p multistream @@ -131,7 +132,7 @@ struct Stream* libp2p_net_multistream_connect(const char* hostname, int port) { // send the multistream handshake char* protocol_buffer = "/multistream/1.0.0\n"; - stream = libp2p_net_multistream_stream_new(socket); + stream = libp2p_net_multistream_stream_new(socket, hostname, port); if (stream == NULL) goto exit; @@ -221,11 +222,19 @@ void libp2p_net_multistream_stream_free(struct Stream* stream) { if (stream != NULL) { if (stream->socket_descriptor != NULL) free(stream->socket_descriptor); + if (stream->address != NULL) + multiaddress_free(stream->address); free(stream); } } -struct Stream* libp2p_net_multistream_stream_new(int socket_fd) { +/** + * Create a new MultiStream structure + * @param socket_fd the file descriptor + * @param ip the IP address + * @param port the port + */ +struct Stream* libp2p_net_multistream_stream_new(int socket_fd, const char* ip, int port) { struct Stream* out = (struct Stream*)malloc(sizeof(struct Stream)); if (out != NULL) { out->socket_descriptor = malloc(sizeof(int)); @@ -238,6 +247,9 @@ struct Stream* libp2p_net_multistream_stream_new(int socket_fd) { out->close = libp2p_net_multistream_close; out->read = libp2p_net_multistream_read; out->write = libp2p_net_multistream_write; + char str[strlen(ip) + 50]; + sprintf(str, "/ip4/%s/tcp/%d", ip, port); + out->address = multiaddress_new_from_string(str); } return out; } diff --git a/net/socket.c b/net/socket.c index 0d9dd11..79ceab1 100644 --- a/net/socket.c +++ b/net/socket.c @@ -9,12 +9,12 @@ #include "libp2p/net/p2pnet.h" -/* associate an IP address with an port to a socket. - * first param is the socket file description - * second is an array of four bytes IP address - * in binary format, this function return 0 on sucess - * or -1 on error setting errno apropriated. - */ +/** + * associate an IP address with an port to a socket. + * @param s the socket file descriptor + * @param ip an array of four bytes IP address in binary format + * @returns 0 on sucess or -1 on error setting errno apropriated. + **/ int socket_bind4(int s, uint32_t ip, uint16_t port) { struct sockaddr_in sa; @@ -27,7 +27,12 @@ int socket_bind4(int s, uint32_t ip, uint16_t port) return bind(s, (struct sockaddr *) &sa, sizeof sa); } -/* Same as socket_bind4(), but set SO_REUSEADDR before +/** + * Same as socket_bind4(), but set SO_REUSEADDR before + * @param s the socket file descriptor + * @param ip the ip address to use + * @param port the port to use + * @returns something... */ int socket_bind4_reuse(int s, uint32_t ip, uint16_t port) { @@ -54,16 +59,24 @@ int socket_accept4(int s, uint32_t *ip, uint16_t *port) return fd; } -/* retrieve local ip and port information from a socket. +/** + * retrieve local ip and port information from a socket. + * @param s the file descriptor + * @param ip the IP address + * @param port the port + * @returns 0 on success, -1 on error */ int socket_local4(int s, uint32_t *ip, uint16_t *port) { struct sockaddr_in sa; socklen_t dummy = sizeof sa; - if (getsockname(s, (struct sockaddr *) &sa, &dummy) == -1) return -1; + if (getsockname(s, (struct sockaddr *) &sa, &dummy) == -1) + return -1; + *ip = sa.sin_addr.s_addr; *port = ntohs(sa.sin_port); + return 0; } @@ -86,7 +99,12 @@ int socket_connect4(int s, uint32_t ip, uint16_t port) return connect(s, (struct sockaddr *) &sa, sizeof sa); } -/* bind and listen to a socket. +/** + * bind and listen to a socket. + * @param s socket file descriptor + * @param localip the ip address + * @param localport the port + * @returns the socket file descriptor */ int socket_listen(int s, uint32_t *localip, uint16_t *localport) { diff --git a/net/tcp.c b/net/tcp.c index 3206ceb..42b8b61 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -3,13 +3,17 @@ #include #include "libp2p/net/p2pnet.h" -/* Create a TCP socket. +/** + * Methods for tcp sockets + */ + +/** + * Create a TCP socket. + * @returns the socket descriptor returned by socket() */ int socket_tcp4(void) { int s; - s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (s == -1) return -1; return s; } diff --git a/peer/peerstore.c b/peer/peerstore.c index 36add87..d136f85 100644 --- a/peer/peerstore.c +++ b/peer/peerstore.c @@ -2,6 +2,7 @@ #include #include "libp2p/peer/peerstore.h" +#include "libp2p/utils/logger.h" struct PeerEntry* libp2p_peer_entry_new() { struct PeerEntry* out = (struct PeerEntry*)malloc(sizeof(struct PeerEntry)); @@ -95,6 +96,11 @@ int libp2p_peerstore_add_peer_entry(struct Peerstore* peerstore, struct PeerEntr * @returns true(1) on success, otherwise false */ int libp2p_peerstore_add_peer(struct Peerstore* peerstore, struct Libp2pPeer* peer) { + char peer_id[peer->id_size + 1]; + memcpy(peer_id, peer->id, peer->id_size); + peer_id[peer->id_size] = 0; + char* address = ((struct MultiAddress*)peer->addr_head->item)->string; + libp2p_logger_debug("peerstore", "Adding peer %s with address %s to peer store\n", peer_id, address); struct PeerEntry* peer_entry = libp2p_peer_entry_new(); if (peer_entry == NULL) { return 0; diff --git a/peer/providerstore.c b/peer/providerstore.c index cc2334c..5c776b2 100644 --- a/peer/providerstore.c +++ b/peer/providerstore.c @@ -2,6 +2,7 @@ #include #include "libp2p/utils/vector.h" +#include "libp2p/utils/logger.h" struct ProviderEntry { unsigned char* hash; @@ -43,6 +44,13 @@ void libp2p_providerstore_free(struct ProviderStore* in) { } int libp2p_providerstore_add(struct ProviderStore* store, unsigned char* hash, int hash_size, unsigned char* peer_id, int peer_id_size) { + char hash_str[hash_size + 1]; + memcpy(hash_str, hash, hash_size); + hash_str[hash_size] = 0; + char peer_str[peer_id_size + 1]; + memcpy(peer_str, peer_id, peer_id_size); + peer_str[peer_id_size] = 0; + libp2p_logger_debug("providerstore", "Adding hash %s to providerstore. It can be retrieved from %s", hash_str, peer_str); struct ProviderEntry* entry = (struct ProviderEntry*)malloc(sizeof(struct ProviderEntry)); entry->hash = malloc(hash_size); memcpy(entry->hash, hash, hash_size); diff --git a/routing/dht_protocol.c b/routing/dht_protocol.c index 0609e07..b37fb3b 100644 --- a/routing/dht_protocol.c +++ b/routing/dht_protocol.c @@ -107,6 +107,25 @@ int libp2p_routing_dht_handle_get_providers(struct SessionContext* session, stru return 1; } +/*** + * helper method to get ip multiaddress from peer's linked list + * @param head linked list of multiaddresses + * @returns the IP multiaddress in the list, or NULL if none found + */ +struct MultiAddress* libp2p_routing_dht_find_peer_ip_multiaddress(struct Libp2pLinkedList* head) { + struct MultiAddress* out = NULL; + struct Libp2pLinkedList* current = head; + while (current != NULL) { + out = (struct MultiAddress*)current->item; + if (multiaddress_is_ip(out)) + break; + current = current->next; + } + if (current == NULL) + out = NULL; + return out; +} + /*** * Remote peer has announced that he can provide a key * @param session session context @@ -130,12 +149,28 @@ int libp2p_routing_dht_handle_add_provider(struct SessionContext* session, struc && message->key != NULL && message->key_size > 0) */ struct Libp2pLinkedList* current = message->provider_peer_head; - while(current != NULL) { + // there should only be 1 when adding a provider + if (current != NULL) { struct Libp2pPeer* peer = (struct Libp2pPeer*)current->item; + struct MultiAddress *peer_ma = libp2p_routing_dht_find_peer_ip_multiaddress(peer->addr_head); + // add what we know to be the ip for this peer + char *ip; + char new_string[255]; + multiaddress_get_ip_address(session->default_stream->address, &ip); + int port = multiaddress_get_ip_port(peer_ma); + sprintf(new_string, "/ip4/%s/tcp/%d", ip, port); + struct MultiAddress* new_ma = multiaddress_new_from_string(new_string); + // set it as the first in the list + struct Libp2pLinkedList* new_head = libp2p_utils_linked_list_new(); + new_head->item = new_ma; + new_head->next = peer->addr_head; + peer->addr_head = new_head; + // now add the peer to the peerstore if (!libp2p_peerstore_add_peer(peerstore, peer)) goto exit; if (!libp2p_providerstore_add(providerstore, message->key, message->key_size, peer->id, peer->id_size)) goto exit; + current = current->next; } *result_buffer_size = libp2p_message_protobuf_encode_size(message); diff --git a/secio/secio.c b/secio/secio.c index 029c65b..ea98558 100644 --- a/secio/secio.c +++ b/secio/secio.c @@ -919,7 +919,7 @@ int libp2p_secio_handshake(struct SessionContext* local_session, struct RsaPriva } // set up the secure stream in the struct - local_session->secure_stream = libp2p_net_multistream_stream_new(*((int*)local_session->insecure_stream->socket_descriptor)); + local_session->secure_stream = local_session->insecure_stream; local_session->secure_stream->read = libp2p_secio_encrypted_read; local_session->secure_stream->write = libp2p_secio_encrypted_write; // set secure as default diff --git a/utils/logger.c b/utils/logger.c index 1876c0f..3ccee5c 100644 --- a/utils/logger.c +++ b/utils/logger.c @@ -119,3 +119,16 @@ void libp2p_logger_error(const char* area, const char* format, ...) { libp2p_logger_vlog(area, LOGLEVEL_ERROR, format, argptr); va_end(argptr); } + +/** + * Log an info message to the console + * @param area the class it is coming from + * @param format the logging string + * @param ... params + */ +void libp2p_logger_info(const char* area, const char* format, ...) { + va_list argptr; + va_start(argptr, format); + libp2p_logger_vlog(area, LOGLEVEL_INFO, format, argptr); + va_end(argptr); +}