2017-02-15 17:04:10 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <netdb.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
|
|
|
#include "multiaddr/multiaddr.h"
|
|
|
|
#include "libp2p/net/p2pnet.h"
|
|
|
|
#include "libp2p/conn/connection.h"
|
|
|
|
#include "libp2p/conn/transport_dialer.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* An implementation of a tcp transport dialer
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
struct TcpIp {
|
|
|
|
char* ip;
|
|
|
|
int port;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TcpIp* libp2p_conn_parse_ip_multiaddress(struct MultiAddress* addr) {
|
|
|
|
struct TcpIp* out = (struct TcpIp*)malloc(sizeof(struct TcpIp));
|
|
|
|
char* address = malloc(strlen(addr->string) + 1);
|
|
|
|
strcpy(address, addr->string);
|
|
|
|
char* tok = strtok(address, "/");
|
|
|
|
int pos = 0;
|
|
|
|
while (tok != NULL) {
|
|
|
|
switch (pos) {
|
2017-02-16 23:49:17 +00:00
|
|
|
case 1: {
|
2017-02-15 17:04:10 +00:00
|
|
|
out->ip = malloc(strlen(tok) + 1);
|
|
|
|
strcpy(out->ip, tok);
|
|
|
|
break;
|
|
|
|
}
|
2017-02-16 23:49:17 +00:00
|
|
|
case 3: {
|
2017-02-15 17:04:10 +00:00
|
|
|
out->port = strtol(tok, NULL, 10);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tok = strtok(NULL, "/");
|
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
//TODO: do a better job of parsing the results
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
int libp2p_conn_tcp_can_handle(struct MultiAddress* addr) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-02-16 23:49:17 +00:00
|
|
|
int libp2p_conn_tcp_read(const struct Connection* connection, char** out, size_t* num_bytes) {
|
|
|
|
int buffer_size = 65535;
|
|
|
|
*out = (char*)malloc(buffer_size);
|
|
|
|
ssize_t bytes = socket_read(connection->socket_handle, *out, buffer_size, 0);
|
|
|
|
*num_bytes = bytes;
|
|
|
|
return bytes > 0;
|
|
|
|
}
|
2017-02-15 17:04:10 +00:00
|
|
|
|
2017-02-16 23:49:17 +00:00
|
|
|
int libp2p_conn_tcp_write(const struct Connection* connection, const char* in, size_t num_bytes) {
|
|
|
|
ssize_t bytes = socket_write(connection->socket_handle, in, num_bytes, 0);
|
|
|
|
return bytes == num_bytes;
|
|
|
|
}
|
2017-02-15 17:04:10 +00:00
|
|
|
|
|
|
|
struct Connection* libp2p_conn_tcp_dial(struct TransportDialer* transport_dialer, struct MultiAddress* addr) {
|
|
|
|
struct Connection* conn = (struct Connection*) malloc(sizeof(struct Connection*));
|
|
|
|
conn->socket_handle = socket_open4();
|
|
|
|
struct TcpIp* results = libp2p_conn_parse_ip_multiaddress(addr);
|
|
|
|
struct hostent* host = gethostbyname(results->ip);
|
|
|
|
struct in_addr** addr_list = (struct in_addr**)host->h_addr_list;
|
|
|
|
socket_connect4(conn->socket_handle, (*addr_list[0]).s_addr, results->port);
|
2017-02-16 23:49:17 +00:00
|
|
|
conn->read = libp2p_conn_tcp_read;
|
|
|
|
conn->write = libp2p_conn_tcp_write;
|
2017-02-15 17:04:10 +00:00
|
|
|
return conn;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct TransportDialer* libp2p_conn_tcp_transport_dialer_new(char* peer_id, struct PrivateKey* private_key) {
|
|
|
|
struct TransportDialer* out = libp2p_conn_transport_dialer_new(peer_id, private_key);
|
|
|
|
out->can_handle = libp2p_conn_tcp_can_handle;
|
|
|
|
out->dial = libp2p_conn_tcp_dial;
|
|
|
|
return out;
|
|
|
|
}
|