More dialer code

This commit is contained in:
John Jones 2017-02-13 17:41:31 -05:00
parent 81263fc1a2
commit 5c08094548
13 changed files with 231 additions and 33 deletions

View file

@ -2,7 +2,7 @@
#include "libp2p/conn/connection.h"
struct Connection* libp2p_conn_connection_open(struct TransportDialer* transport_dialer, struct maddr* multiaddress) {
struct Connection* libp2p_conn_connection_new(struct TransportDialer* transport_dialer, struct MultiAddress* multiaddress) {
struct Connection* out = NULL;
if (transport_dialer != NULL) {
@ -13,3 +13,11 @@ struct Connection* libp2p_conn_connection_open(struct TransportDialer* transport
}
return out;
}
void libp2p_conn_connection_free(struct Connection* connection) {
if (connection != NULL) {
fclose(connection->socket_handle);
free(connection);
}
}

View file

@ -15,12 +15,20 @@
struct Dialer* libp2p_conn_dialer_new(char* peer_id, struct PrivateKey* private_key) {
struct Dialer* dialer = (struct Dialer*)malloc(sizeof(struct Dialer));
if (dialer != NULL) {
dialer->peer_id = peer_id;
dialer->private_key = private_key;
dialer->peer_id = malloc(strlen(peer_id) + 1);
if (dialer->peer_id != NULL) {
strcpy(dialer->peer_id, peer_id);
dialer->private_key = (struct PrivateKey*)malloc(sizeof(struct PrivateKey));
if (dialer->private_key != NULL) {
libp2p_crypto_private_key_copy(private_key, dialer->private_key);
dialer->fallback_dialer = NULL;
dialer->transport_dialers = NULL;
}
return dialer;
}
}
}
libp2p_conn_dialer_free(dialer);
return NULL;
}
/**
@ -49,10 +57,10 @@ void libp2p_conn_dialer_free(struct Dialer* in) {
* @param muiltiaddress who to connect to
* @returns a Connection, or NULL
*/
struct Connection* libp2p_conn_dialer_get_connection(struct Dialer* dialer, struct maddr* multiaddress) {
struct Connection* libp2p_conn_dialer_get_connection(struct Dialer* dialer, struct MultiAddress* multiaddress) {
struct Connection* conn = libp2p_conn_transport_dialer_get(dialer->transport_dialers, multiaddress);
if (conn == NULL) {
conn = libp2p_conn_connection_open(dialer->fallback_dialer, multiaddress);
conn = libp2p_conn_connection_new(dialer->fallback_dialer, multiaddress);
}
return conn;
}

View file

@ -2,17 +2,18 @@
#include "libp2p/conn/transport_dialer.h"
struct TransportDialer* libp2p_conn_transport_dialer_new(struct maddr* multiaddr) {
struct TransportDialer* libp2p_conn_transport_dialer_new(struct MultiAddress* multiaddr) {
struct TransportDialer* out = (struct TransportDialer*)malloc(sizeof(struct TransportDialer));
if (out != NULL) {
out->multiaddr = (struct maddr*)malloc(sizeof(struct maddr));
out->multiaddr = (struct MultiAddress*)malloc(sizeof(struct MultiAddress));
if (out->multiaddr == NULL) {
free(out);
libp2p_conn_transport_dialer_free(out);
return NULL;
}
if (multiaddress_copy(multiaddr, out->multiaddr) == 0) {
libp2p_conn_transport_dialer_free(out);
return NULL;
}
out->multiaddr->bsize[0] = multiaddr->bsize[0];
memcpy(out->multiaddr->bytes, multiaddr->bytes, 400);
memcpy(out->multiaddr->string, multiaddr->string, 800);
}
return out;
}
@ -31,7 +32,7 @@ void libp2p_conn_transport_dialer_free(struct TransportDialer* in) {
* @param multiaddr the address
* @returns a connection, or NULL if no appropriate dialer was found
*/
struct Connection* libp2p_conn_transport_dialer_get(struct Libp2pLinkedList* transport_dialers, struct maddr* multiaddr) {
struct Connection* libp2p_conn_transport_dialer_get(struct Libp2pLinkedList* transport_dialers, struct MultiAddress* multiaddr) {
//TODO: implement this method
return NULL;
}

View file

@ -24,7 +24,7 @@ int libp2p_crypto_encoding_base64_encode(const unsigned char* input_data, size_t
* @param output_data the buffer to store the output
* @param max_output_length the length of the output buffer
* @param bytes_written the number of bytes written to output_data
* @returns a pointer to the decoded data
* @returns true(1) on success, otherwise 0
*/
int libp2p_crypto_encoding_base64_decode(const unsigned char* input_data, size_t input_length, unsigned char* output_data, size_t max_output_length, size_t* bytes_written) {
int retVal = mbedtls_base64_decode(output_data, max_output_length, bytes_written, input_data, input_length);

View file

@ -130,11 +130,25 @@ void libp2p_crypto_private_key_free(struct PrivateKey* in) {
}
}
int libp2p_crypto_private_key_protobuf_encode_size(struct PrivateKey* in) {
int libp2p_crypto_private_key_copy(const struct PrivateKey* source, struct PrivateKey* destination) {
if (source != NULL && destination != NULL) {
destination->type = source->type;
destination->data = (unsigned char*)malloc(source->data_size);
if (destination->data != NULL) {
memcpy(destination->data, source->data, source->data_size);
destination->data_size = source->data_size;
return 1;
}
libp2p_crypto_private_key_free(destination);
}
return 0;
}
size_t libp2p_crypto_private_key_protobuf_encode_size(const struct PrivateKey* in) {
return 22 + in->data_size;
}
int libp2p_crypto_private_key_protobuf_encode(struct PrivateKey* in, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written) {
int libp2p_crypto_private_key_protobuf_encode(const struct PrivateKey* in, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written) {
*bytes_written = 0;
size_t bytes_used;
// type (RSA vs ED25519)

View file

@ -1,3 +1,4 @@
#pragma once
/**
* Implements an interface to connect and talk to different nodes.
* A Dialer will connect, and return a Connection structure
@ -7,15 +8,15 @@
#include "multiaddr/multiaddr.h"
struct Connection {
int socket_handle;
FILE* socket_handle;
/**
* Read from the stream
* @param socket_handle the socket to read from
* @param in what was read in NOTE: this allocates memory
* @param in_size the number of bytes read in
* @returns 0 on success, otherwise an error code
* @returns number of bytes written or negative number on error
*/
int (*read)(int socket_handle, char** in, size_t* in_size);
int (*read)(const struct Connection* conn, char** in, size_t* in_size);
/**
* Write to the stream
* @param socket_handle the socket to write to
@ -23,7 +24,21 @@ struct Connection {
* @param out_size the number of bytes to write
* @returns 0 on success, otherwise an error code
*/
int (*write)(int socket_handle, char* out, size_t* out_size);
int (*write)(const struct Connection* conn, char* out, size_t out_size);
};
struct Connection* libp2p_conn_connection_open(struct TransportDialer* transport_dialer, struct maddr* multiaddress);
/**
* creates a new connection
* @param transport_dialer the TransportDialer to use
* @param multiaddress the destination
* @returns a connection that is ready to be read from / written to
*/
struct Connection* libp2p_conn_connection_new(struct TransportDialer* transport_dialer, struct MultiAddress* multiaddress);
/***
* close a connection and dispose of struct
* @param connection the resource to clean up
*/
void libp2p_conn_connection_free(struct Connection* connection);

View file

@ -6,6 +6,8 @@
#include "libp2p/crypto/key.h"
#include "multiaddr/multiaddr.h"
#include "libp2p/conn/connection.h"
#include "libp2p/conn/transport_dialer.h"
struct Dialer {
/**
@ -41,4 +43,4 @@ void libp2p_conn_dialer_free(struct Dialer* in);
* @param muiltiaddress who to connect to
* @returns a Connection, or NULL
*/
struct Connection* libp2p_conn_dialer_get_connection(struct Dialer* dialer, struct maddr* multiaddress);
struct Connection* libp2p_conn_dialer_get_connection(struct Dialer* dialer, struct MultiAddress* multiaddress);

View file

@ -4,10 +4,10 @@
#include "libp2p/utils/linked_list.h"
struct TransportDialer {
struct maddr* multiaddr;
struct MultiAddress* multiaddr;
};
struct TransportDialer* libp2p_conn_transport_dialer_new(struct maddr* multiaddr);
struct TransportDialer* libp2p_conn_transport_dialer_new(struct MultiAddress* multiaddr);
void libp2p_conn_transport_dialer_free(struct TransportDialer* in);
struct Connection* libp2p_conn_transport_dialer_get(struct Libp2pLinkedList* transport_dialers, struct maddr* multiaddr);
struct Connection* libp2p_conn_transport_dialer_get(struct Libp2pLinkedList* transport_dialers, struct MultiAddress* multiaddr);

View file

@ -23,6 +23,7 @@ void libp2p_crypto_public_key_free(struct PublicKey* in);
struct PrivateKey* libp2p_crypto_private_key_new();
void libp2p_crypto_private_key_free(struct PrivateKey* in);
int libp2p_crypto_private_key_copy(const struct PrivateKey* source, struct PrivateKey* destination);
/**
* Unmarshal a public key from a protobuf
@ -30,7 +31,10 @@ void libp2p_crypto_private_key_free(struct PrivateKey* in);
int libp2p_crypto_public_key_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct PublicKey** out);
size_t libp2p_crypto_public_key_protobuf_encode_size(const struct PublicKey* in);
int libp2p_crypto_public_key_protobuf_encode(const struct PublicKey* in, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written);
// private key
int libp2p_crypto_private_key_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct PrivateKey** out);
size_t libp2p_crypto_private_key_protobuf_encode_size(const struct PrivateKey* in);
int libp2p_crypto_private_key_protobuf_encode(const struct PrivateKey* in, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written);
/**
* convert a public key into a peer id

View file

@ -5,7 +5,7 @@ ifdef DEBUG
CFLAGS += -g3
endif
LFLAGS = -L../ -L../../c-multihash
LFLAGS = -L../ -L../../c-multihash -L../../c-multiaddr
DEPS = crypto/test_base58.h crypto/test_rsa.h test_mbedtls.h
OBJS = testit.o ../../c-protobuf/protobuf.o ../../c-protobuf/varint.o ../libp2p.a
@ -13,7 +13,7 @@ OBJS = testit.o ../../c-protobuf/protobuf.o ../../c-protobuf/varint.o ../libp2p.
$(CC) -c -o $@ $< $(CFLAGS)
testit_libp2p: $(OBJS) $(DEPS)
$(CC) -o $@ $(OBJS) $(LFLAGS) -lp2p -lm -lmultihash
$(CC) -o $@ $(OBJS) $(LFLAGS) -lp2p -lm -lmultihash -lmultiaddr
all_others:
cd ../crypto; make all;

View file

@ -1,12 +1,64 @@
#include <stdlib.h>
#include "libp2p/conn/dialer.h"
#include "test_helper.h"
int test_dialer_new() {
struct PrivateKey* private_key = NULL;
struct Dialer* dialer = libp2p_conn_dialer_new("ABC", private_key);
char* peer_id = "QmQSDGgxSVTkHmtT25rTzQtc5C1Yg8SpGK3BTws8YsJ4x3";
struct PrivateKey* private_key = libp2p_crypto_private_key_new();
struct Dialer* dialer = libp2p_conn_dialer_new(peer_id, private_key);
if (dialer == NULL)
return 0;
libp2p_conn_dialer_free(dialer);
return 1;
}
int test_dialer_dial() {
int retVal = 0;
char* config_dir = "/home/parallels/.ipfs/config";
char* destination_string = "/ip/192.210.179.217/tcp/4001";
char* peer_id = NULL;
struct PrivateKey* private_key = NULL;
struct Dialer* dialer = NULL;
struct MultiAddress* destination_address = NULL;
struct Connection* conn = NULL;
char* result = NULL;
size_t result_size = 0;
test_helper_get_id_from_config(config_dir, &private_key, &peer_id);
if (private_key == NULL)
goto exit;
dialer = libp2p_conn_dialer_new(peer_id, private_key);
if (dialer == NULL)
goto exit;
destination_address = multiaddress_new_from_string(destination_string);
if (destination_address == NULL)
goto exit;
// now try to dial
conn = libp2p_conn_dialer_get_connection(dialer, destination_address);
if (conn == NULL)
goto exit;
if (conn->write(conn, "ping", 4) == 0)
goto exit;
if (conn->read(conn, &result, &result_size) == 0)
goto exit;
if (result_size < 4 || strncmp(result, "pong", 4) != 0)
goto exit;
// clean up resources
retVal = 1;
exit:
if (result != NULL)
free(result);
multiaddress_free(destination_address);
libp2p_conn_dialer_free(dialer);
libp2p_crypto_private_key_free(private_key);
libp2p_conn_connection_free(conn);
return retVal;
}

92
test/test_helper.h Normal file
View file

@ -0,0 +1,92 @@
#include <stdlib.h>
#include <stdio.h>
#include "libp2p/crypto/key.h"
void read_file(char* path, char** contents) {
FILE* fd = fopen(path, "r");
fseek(fd, 0L, SEEK_END);
size_t num_bytes = ftell(fd);
rewind(fd);
*contents = malloc(num_bytes);
fread(*contents, 1, num_bytes, fd);
fclose(fd);
return;
}
struct PrivateKey* base64ToPrivateKey(char* base64) {
int retVal = 0;
size_t decode_base64_size = 0;
unsigned char* decode_base64 = NULL;
struct PrivateKey* out = NULL;
// 1) take the private key and turn it back into bytes (decode base 64)
decode_base64_size = libp2p_crypto_encoding_base64_decode_size(strlen(base64));
decode_base64 = (unsigned char*)malloc(decode_base64_size);
if (decode_base64 == NULL)
goto exit;
memset(decode_base64, 0, decode_base64_size);
if (!libp2p_crypto_encoding_base64_decode((unsigned char*)base64, strlen(base64), &decode_base64[0], decode_base64_size, &decode_base64_size))
goto exit;
if (!libp2p_crypto_private_key_protobuf_decode(decode_base64, decode_base64_size, &out))
goto exit;
retVal = 1;
exit:
if (retVal != 1) {
libp2p_crypto_private_key_free(out);
out = NULL;
}
return out;
}
int test_helper_get_id_from_config(char* path, struct PrivateKey** private_ptr, char** peer_ptr) {
int retVal = 0;
char* contents = NULL;
char* ptr = NULL;
char* end = NULL;
int length = 0;
read_file(path, &contents);
if (contents == NULL)
goto exit;
// peer id
ptr = strstr(contents, "PeerID");
if (ptr == NULL)
goto exit;
ptr = strstr(ptr, "Qm");
if (ptr == NULL)
goto exit;
end = strstr(ptr, "\"");
length = end - ptr;
*peer_ptr = malloc(length + 1);
if (*peer_ptr == NULL)
goto exit;
memcpy(*peer_ptr, ptr, length);
(*peer_ptr)[length] = 0;
// private key
ptr = strstr(contents, "PrivKey\":");
if (ptr == NULL)
goto exit;
ptr += 9;
ptr = strstr(ptr, "\"");
ptr++;
end = strstr(ptr, "\"");
end[0] = 0;
// turn the encoded private key into a struct
*private_ptr = base64ToPrivateKey(ptr);
retVal = 1;
exit:
if (contents != NULL)
free(contents);
return retVal;
}

View file

@ -36,7 +36,8 @@ const char* names[] = {
"test_multistream_connect",
"test_multistream_get_list",
"test_ephemeral_key_generate",
"test_dialer_new"
"test_dialer_new",
"test_dialer_dial"
};
int (*funcs[])(void) = {
@ -65,7 +66,8 @@ int (*funcs[])(void) = {
test_multistream_connect,
test_multistream_get_list,
test_ephemeral_key_generate,
test_dialer_new
test_dialer_new,
test_dialer_dial
};
int testit(const char* name, int (*func)(void)) {