c-ipfs/core/ping.c

125 lines
3.4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <pthread.h>
#include "libp2p/net/p2pnet.h"
#include "libp2p/net/multistream.h"
#include "libp2p/record/message.h"
#include "libp2p/secio/secio.h"
#include "libp2p/routing/dht_protocol.h"
#include "ipfs/repo/fsrepo/fs_repo.h"
#include "ipfs/repo/init.h"
#include "ipfs/core/ipfs_node.h"
#include "ipfs/routing/routing.h"
#include "ipfs/importer/resolver.h"
#include "multiaddr/multiaddr.h"
#define BUF_SIZE 4096
int ipfs_ping (int argc, char **argv)
{
int retVal = 0;
struct IpfsNode local_node;
struct Libp2pPeer* peer_to_ping = NULL;
char* id = NULL;
struct FSRepo* fs_repo = NULL;
char* repo_path = NULL;
struct timeval time1, time2;
int time_us;
// sanity check
local_node.peerstore = NULL;
local_node.providerstore = NULL;
if (argc < 3)
goto exit;
if (!ipfs_repo_get_directory(argc, argv, &repo_path)) {
fprintf(stderr, "Unable to open repo: %s\n", repo_path);
return 0;
}
// read the configuration
if (!ipfs_repo_fsrepo_new(NULL, NULL, &fs_repo))
goto exit;
// open the repository and read the file
if (!ipfs_repo_fsrepo_open(fs_repo))
goto exit;
local_node.identity = fs_repo->config->identity;
local_node.repo = fs_repo;
local_node.mode = MODE_ONLINE;
local_node.routing = ipfs_routing_new_online(&local_node, &fs_repo->config->identity->private_key);
local_node.peerstore = libp2p_peerstore_new(local_node.identity->peer);
local_node.providerstore = libp2p_providerstore_new(fs_repo->config->datastore, fs_repo->config->identity->peer);
if (local_node.routing->Bootstrap(local_node.routing) != 0)
goto exit;
if (strstr(argv[2], "Qm") == &argv[2][0]) {
// resolve the peer id
fprintf (stderr, "Looking up peer %s\n", argv[2]);
peer_to_ping = ipfs_resolver_find_peer(argv[2], &local_node);
} else {
// perhaps they passed an IP and port
if (argc >= 3) {
char* str = malloc(strlen(argv[2]) + strlen(argv[3]) + 100);
if (str == NULL) {
// memory issue
goto exit;
}
sprintf(str, "/ip4/%s/tcp/%s", argv[2], argv[3]);
peer_to_ping = libp2p_peer_new();
if (peer_to_ping) {
peer_to_ping->addr_head = libp2p_utils_linked_list_new();
peer_to_ping->addr_head->item = multiaddress_new_from_string(str);
peer_to_ping->id = str;
peer_to_ping->id_size = strlen(str);
}
}
//TODO: Error checking
}
if (peer_to_ping == NULL)
goto exit;
id = malloc(peer_to_ping->id_size + 1);
if (id) {
memcpy(id, peer_to_ping->id, peer_to_ping->id_size);
id[peer_to_ping->id_size] = 0;
fprintf (stderr, "PING %s.\n", id);
}
for (;;) {
gettimeofday(&time1, NULL);
if (!local_node.routing->Ping(local_node.routing, peer_to_ping)) {
fprintf(stderr, "Unable to ping %s\n", id);
goto exit;
}
gettimeofday(&time2, NULL);
// calculate microseconds
time_us = (time2.tv_sec - time1.tv_sec) * 1000000;
time_us += (time2.tv_usec - time1.tv_usec);
fprintf (stderr, "Pong received: time=%d.%03d ms\n", time_us / 1000, time_us % 1000);
if (time_us < 1000000) { // if the ping took less than a second...
sleep(1);
}
}
retVal = 1;
exit:
if (id != NULL)
free(id);
if (fs_repo != NULL)
ipfs_repo_fsrepo_free(fs_repo);
if (local_node.peerstore != NULL)
libp2p_peerstore_free(local_node.peerstore);
if (local_node.providerstore != NULL)
libp2p_providerstore_free(local_node.providerstore);
return retVal;
}