Dynamic bootstrap of kademlia peers

Will be using config file instead of hard coded bootstrap addresses
This commit is contained in:
John Jones 2017-03-24 16:50:02 -05:00
parent 158012858a
commit db0f62cee4
2 changed files with 41 additions and 15 deletions

View file

@ -1,9 +1,10 @@
#pragma once #pragma once
#include "libp2p/utils/vector.h"
#include "multiaddr/multiaddr.h" #include "multiaddr/multiaddr.h"
int start_kademlia(int sock, int family, char* peer_id, int timeout); int start_kademlia(int sock, int family, char* peer_id, int timeout, struct Libp2pVector* bootstrap_addresses);
int start_kademlia_multiaddress(struct MultiAddress* multiaddress, char* peer_id, int timeout); int start_kademlia_multiaddress(struct MultiAddress* multiaddress, char* peer_id, int timeout, struct Libp2pVector* bootstrap_addresses);
void stop_kademlia (void); void stop_kademlia (void);
void *kademlia_thread (void *ptr); void *kademlia_thread (void *ptr);

View file

@ -29,7 +29,6 @@ struct bs_struct {
char *ip; char *ip;
uint16_t port; uint16_t port;
} bootstrap_list[] = { } bootstrap_list[] = {
{ "192.210.179.217", 5001 }
}; };
pthread_t pth_kademlia, pth_announce; pthread_t pth_kademlia, pth_announce;
@ -166,19 +165,29 @@ static void callback(void *closure, int event, const unsigned char *info_hash, c
} }
} }
int start_kademlia_multiaddress(struct MultiAddress* address, char* peer_id, int timeout) { int start_kademlia_multiaddress(struct MultiAddress* address, char* peer_id, int timeout, struct Libp2pVector* bootstrap_addresses) {
int port = multiaddress_get_ip_port(address); int port = multiaddress_get_ip_port(address);
int family = multiaddress_get_ip_family(address); int family = multiaddress_get_ip_family(address);
int fd = socket(family, SOCK_STREAM, 0); int fd = socket(family, SOCK_DGRAM, 0);
if (fd < 0)
return 0;
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
serv_addr.sin_family = family; serv_addr.sin_family = family;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = port; serv_addr.sin_port = port;
bind (fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if (bind(fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) != 0)
return start_kademlia(fd, family, peer_id, timeout); return 0;
return start_kademlia(fd, family, peer_id, timeout, bootstrap_addresses);
} }
int start_kademlia(int net_fd, int family, char* peer_id, int timeout) /***
* Start the kademlia service
* @param net_fd the file descriptor of the address/socket already bound
* @param family ip4 or ip6
* @param peer_id the first 20 chars of the public PeerID in a null terminated string
* @param timeout seconds before a select() timeout
*/
int start_kademlia(int net_fd, int family, char* peer_id, int timeout, struct Libp2pVector* bootstrap_addresses)
{ {
int rc, i, len; int rc, i, len;
unsigned char id[sizeof hash]; unsigned char id[sizeof hash];
@ -186,26 +195,41 @@ int start_kademlia(int net_fd, int family, char* peer_id, int timeout)
dht_debug = stderr; dht_debug = stderr;
len = sizeof(bootstrap_list) / sizeof(bootstrap_list[0]); // array length len = bootstrap_addresses->total;
if (len > MAX_BOOTSTRAP_NODES) { if (len > MAX_BOOTSTRAP_NODES) {
len = MAX_BOOTSTRAP_NODES; // limit array length len = MAX_BOOTSTRAP_NODES; // limit array length
} }
memset(&sa, 0, sizeof sa); memset(&sa, 0, sizeof sa);
char* ip = NULL;
for (i = 0 ; i < len ; i++) { for (i = 0 ; i < len ; i++) {
if (family == AF_INET6 && inet_pton(AF_INET6, bootstrap_list[i].ip, &(sa.sin_addr.s_addr)) == 1) { struct MultiAddress* addr = (struct MultiAddress*)libp2p_utils_vector_get(bootstrap_addresses, i);
if (ip != NULL)
free(ip);
if (multiaddress_is_ip(addr)) {
multiaddress_get_ip_address(addr, &ip);
if (family == AF_INET6 && multiaddress_is_ip6(addr)) {
if (inet_pton(AF_INET6, ip, &(sa.sin_addr.s_addr)) == 1)
sa.sin_family = AF_INET6; sa.sin_family = AF_INET6;
} else if (inet_pton(AF_INET, bootstrap_list[i].ip, &(sa.sin_addr.s_addr)) == 1) { else
continue;
} else {
if (inet_pton(AF_INET , ip, &(sa.sin_addr.s_addr)) == 1)
sa.sin_family = AF_INET; sa.sin_family = AF_INET;
else
continue;
}
} else { } else {
continue; // not an ipv6 or ipv4? continue; // not an ipv6 or ipv4?
} }
sa.sin_port = htons (bootstrap_list[i].port); sa.sin_port = htons (multiaddress_get_ip_port(addr));
memcpy(&bootstrap_nodes[num_bootstrap_nodes++], &sa, sizeof(sa)); memcpy(&bootstrap_nodes[num_bootstrap_nodes++], &sa, sizeof(sa));
} }
if (ip != NULL)
free(ip);
dht_hash (id, sizeof(id), peer_id, strlen(peer_id), NULL, 0, NULL, 0); dht_hash (id, sizeof(id), peer_id, strlen(peer_id), NULL, 0, NULL, 0);
@ -299,6 +323,7 @@ void *kademlia_thread (void *ptr)
continue; continue;
} else { } else {
fprintf(stderr, "kademlia_thread:recvfrom failed with %d\n", errno); fprintf(stderr, "kademlia_thread:recvfrom failed with %d\n", errno);
continue;
} }
} }
buf[rc] = '\0'; buf[rc] = '\0';