diff --git a/.cproject b/.cproject index a60437a..c5f1416 100644 --- a/.cproject +++ b/.cproject @@ -21,16 +21,20 @@ + @@ -42,6 +46,10 @@ + diff --git a/core/null.c b/core/null.c index 3b3efa4..bfc3768 100644 --- a/core/null.c +++ b/core/null.c @@ -5,6 +5,8 @@ #include #include #include "libp2p/net/p2pnet.h" +#include "libp2p/record/message.h" +#include "libp2p/net/multistream.h" #include "ipfs/core/daemon.h" #define BUF_SIZE 4096 @@ -12,8 +14,8 @@ void *ipfs_null_connection (void *ptr) { struct null_connection_params *connection_param; - char b[BUF_SIZE]; - int len; + //char b[BUF_SIZE]; + //int len; connection_param = (struct null_connection_params*) ptr; @@ -21,6 +23,13 @@ void *ipfs_null_connection (void *ptr) fprintf(stderr, "Connection %d, count %d\n", connection_param->socket, *(connection_param->count)); for(;;) { + if (libp2p_net_multistream_negotiate(connection_param->socket)) { + // we negotiated, now find out what they want + libp2p_net_multistream_handle_message(connection_param->socket); + } else { + break; + } + /* len = socket_read(connection_param->socket, b, sizeof(b)-1, 0); if (len > 0) { while (b[len-1] == '\r' || b[len-1] == '\n') len--; @@ -32,6 +41,7 @@ void *ipfs_null_connection (void *ptr) } else if(len < 0) { break; } + */ } close (connection_param->socket); // close socket. diff --git a/core/ping.c b/core/ping.c index b915e27..c970ddc 100644 --- a/core/ping.c +++ b/core/ping.c @@ -5,11 +5,54 @@ #include #include #include "libp2p/net/p2pnet.h" +#include "libp2p/net/multistream.h" +#include "libp2p/record/message.h" #define BUF_SIZE 4096 int ipfs_ping (int argc, char **argv) { + char* results = NULL; + size_t results_size = 0; + //TODO: handle multiaddress + + // the way using multistream + //TODO: Error checking + char* ip = argv[2]; + int port = atoi(argv[3]); + int socket_fd = libp2p_net_multistream_connect(ip, port); + if (socket_fd < 0) { + fprintf(stderr, "Unable to connect to %s on port %s", ip, argv[3]); + } + + // prepare the PING message + struct Libp2pMessage* msg = libp2p_message_new(); + msg->message_type = MESSAGE_TYPE_PING; + + size_t protobuf_size = libp2p_message_protobuf_encode_size(msg); + unsigned char protobuf[protobuf_size]; + libp2p_message_protobuf_encode(msg, &protobuf[0], protobuf_size, &protobuf_size); + libp2p_net_multistream_send(socket_fd, protobuf, protobuf_size); + libp2p_net_multistream_receive(socket_fd, &results, &results_size); + + if (results_size != protobuf_size) { + fprintf(stderr, "PING unsuccessful. Original size: %lu, returned size: %lu\n", protobuf_size, results_size); + return 0; + } + if (memcmp(results, protobuf, protobuf_size) != 0) { + fprintf(stderr, "PING unsuccessful. Results do not match.\n"); + return 0; + } + + if (msg != NULL) + libp2p_message_free(msg); + + fprintf(stdout, "Ping of %s:%s successful.\n", ip, argv[3]); + + return 0; + + // the old way + /* int socketfd, i, count=10, tcount = 0; uint32_t ipv4; uint16_t port; @@ -60,4 +103,5 @@ int ipfs_ping (int argc, char **argv) fprintf(stderr, "Average latency: %.2fms\n", total / tcount); return 0; + */ } diff --git a/test/Makefile b/test/Makefile index d173ebe..151534b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/ -I../../c-protobuf -g3 -Wall +CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include -I../../c-protobuf -g3 -Wall LFLAGS = -L../../c-libp2p -L../../c-multihash -L../../c-multiaddr -lp2p -lm -lmultihash -lmultiaddr -lpthread DEPS = cmd/ipfs/test_init.h repo/test_repo_bootstrap_peers.h repo/test_repo_config.h repo/test_repo_identity.h cid/test_cid.h OBJS = testit.o test_helper.o \ diff --git a/test/core/test_ping.h b/test/core/test_ping.h new file mode 100644 index 0000000..3eeba91 --- /dev/null +++ b/test/core/test_ping.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#include "../test_helper.h" +#include "multiaddr/multiaddr.h" +#include "libp2p/peer/peerstore.h" +#include "libp2p/peer/peer.h" +#include "libp2p/record/message.h" +#include "ipfs/core/daemon.h" +#include "ipfs/core/ipfs_node.h" +#include "ipfs/repo/fsrepo/fs_repo.h" +#include "libp2p/conn/dialer.h" + +/** + * Testing connectivity with other nodes + */ + +int test_ping() { + int retVal = 0; + struct FSRepo* fs_repo = NULL; + struct Libp2pMessage* message = NULL; + struct IpfsNode local_node; + struct Libp2pPeer* remote_peer = NULL; + struct Dialer* dialer = NULL; + struct Connection* conn = NULL; + unsigned char* protobuf = NULL; + size_t protobuf_size = 0; + unsigned char* response = NULL; + size_t response_size = 0; + + // act like this is a normal node + drop_build_and_open_repo("/tmp/.ipfs", &fs_repo); + + // create a new IpfsNode + local_node.mode = MODE_ONLINE; + local_node.peerstore = libp2p_peerstore_new(); + local_node.repo = fs_repo; + local_node.identity = fs_repo->config->identity; + + // build the ping message + message = libp2p_message_new(); + message->message_type = MESSAGE_TYPE_PING; + protobuf_size = libp2p_message_protobuf_encode_size(message); + protobuf = (unsigned char*)malloc(protobuf_size); + libp2p_message_protobuf_encode(message, protobuf, protobuf_size, &protobuf_size); + libp2p_message_free(message); + message = NULL; + // ping a known node with a ping record + // create the connection + remote_peer = libp2p_peer_new(); + remote_peer->id = "QmdMZoaL4azVzEPHYVH6imn3iPYYv6L1fLcH7Vd1aLbfSD"; + remote_peer->id_size = strlen(remote_peer->id); + remote_peer->addr_head = libp2p_utils_linked_list_new(); + remote_peer->addr_head->item = multiaddress_new_from_string("/ip4/192.168.43.234/tcp/4001/"); + + // connect using a dialer + dialer = libp2p_conn_dialer_new(fs_repo->config->identity->peer_id, libp2p_crypto_rsa_to_private_key(&fs_repo->config->identity->private_key)); + conn = libp2p_conn_dialer_get_connection(dialer, remote_peer->addr_head->item); + + //TODO: Dialer should know the protocol + + // send the record + conn->write(conn, (char*)protobuf, protobuf_size); + conn->read(conn, (char**)&response, &response_size); + libp2p_message_protobuf_decode(response, response_size, &message); + // verify the response + if (message->message_type != MESSAGE_TYPE_PING) + goto exit; + + // clean up + retVal = 1; + exit: + ipfs_repo_fsrepo_free(fs_repo); + return retVal; +} diff --git a/test/testit.c b/test/testit.c index 8f8b2c5..b3667f8 100644 --- a/test/testit.c +++ b/test/testit.c @@ -13,6 +13,7 @@ #include "storage/test_datastore.h" #include "storage/test_blocks.h" #include "storage/test_unixfs.h" +#include "core/test_ping.h" int testit(const char* name, int (*func)(void)) { printf("Testing %s...\n", name); @@ -55,7 +56,8 @@ const char* names[] = { "test_merkledag_add_node_with_links", "test_resolver_get", "test_unixfs_encode_decode", - "test_unixfs_encode_smallfile" + "test_unixfs_encode_smallfile", + "test_ping" }; int (*funcs[])(void) = { @@ -89,7 +91,8 @@ int (*funcs[])(void) = { test_merkledag_add_node_with_links, test_resolver_get, test_unixfs_encode_decode, - test_unixfs_encode_smallfile + test_unixfs_encode_smallfile, + test_ping }; /**