Finishing NodeIO

yamux
John Jones 2017-03-19 14:39:48 -05:00
parent b6a94c7c11
commit 0d0c9bde53
8 changed files with 242 additions and 107 deletions

View File

@ -1,3 +1,6 @@
#pragma once
#include "libp2p/crypto/key.h"
/***
* Holds the details of communication between two hosts
*/

View File

@ -1,6 +1,18 @@
#pragma once
#include "libp2p/net/stream.h"
#include "libp2p/conn/session.h"
int libp2p_nodeio_upgrade_stream(struct Stream* stream);
struct Node* libp2p_nodeio_get(struct Stream* stream, unsigned char* hash, int hash_length);
int libp2p_nodeio_upgrade_stream(struct SessionContext* context);
int libp2p_nodeio_handshake(struct SessionContext* context);
int libp2p_nodeio_handle(struct SessionContext* context);
/**
* Called by requestor to get a protobuf'd node from a hash
* @param context the session context
* @param hash the hash
* @param hash_size the length of the hash
* @param results where to put the buffer
* @param results_size the size of the results
* @returns true(1) on success, otherwise false(0)
*/
int libp2p_nodeio_get(struct SessionContext* context, unsigned char* hash, int hash_size, unsigned char** results, size_t* results_length);

View File

@ -0,0 +1,32 @@
#pragma once
struct ProviderEntry {
unsigned char* hash;
int hash_size;
unsigned char* peer_id;
int peer_id_size;
};
struct ProviderStore {
struct Libp2pVector* provider_entries;
};
/***
* Stores hashes, and peers where you can possibly get them
*/
/**
* Create a new ProviderStore
* @returns a ProviderStore struct
*/
struct ProviderStore* libp2p_providerstore_new();
/***
* Clean resources used by a ProviderStore
* @param in the ProviderStore to clean up
*/
void libp2p_providerstore_free(struct ProviderStore* in);
void libp2p_providerstore_add(struct ProviderStore* store, unsigned char* hash, int hash_size, unsigned char* peer_id, int peer_id_size);
int libp2p_providerstore_get(struct ProviderStore* store, unsigned char* hash, int hash_size, unsigned char** peer_id, int *peer_id_size);

View File

@ -1,41 +1,26 @@
#pragma once
/***
* A very simple vector implementation for unsigned chars
*/
#define VECTOR_INIT_CAPACITY 4
//#define VECTOR_INIT(vec) vector vec; vector_init(&vec)
//#define VECTOR_ADD(vec, item) vector_add(&vec, (void *) item)
//#define VECTOR_SET(vec, id, item) vector_set(&vec, id, (void *) item)
//#define VECTOR_GET(vec, type, id) (type) vector_get(&vec, id)
//#define VECTOR_DELETE(vec, id) vector_delete(&vec, id)
//#define VECTOR_TOTAL(vec) vector_total(&vec)
//#define VECTOR_FREE(vec) vector_free(&vec)
/**
* The struct
*/
struct Libp2pVector {
unsigned char* buffer;
size_t buffer_size;
void **items;
int capacity;
int total;
};
/**
* Create and destroy
*/
struct Libp2pVector* libp2p_utils_vector_new();
void libp2p_utils_vector_free(struct Libp2pVector* vector);
/**
* Add bytes to vector
*/
int libp2p_utils_vector_add(struct Libp2pVector* vector, unsigned char* in_bytes, size_t in_size);
/**
* serialize the vector into a byte array that has a 4 byte prefix of the size
* @param vector the vector to serialize
* @param out a pointer to the byte array that will be filled
* @param out_size the number of bytes written
* @returns true(1) on success, otherwise false
*/
int libp2p_utils_vector_serialize(struct Libp2pVector* vector, unsigned char** out, size_t* out_size);
/**
* turn a byte array into a Libp2pVector
* @param in the bytes that were previously serialized
* @param out the new Libp2pVector
* @returns true(1) on success, otherwise false(0)
*/
int libp2p_utils_vector_unserialize(unsigned char* in, struct Libp2pVector** out);
struct Libp2pVector* libp2p_utils_vector_new(int initial_size);
int libp2p_utils_vector_total(struct Libp2pVector* in);
//static void libp2p_utils_vector_resize(struct Libp2pVector *vector, int new_size);
void libp2p_utils_vector_add(struct Libp2pVector *vector, void * value);
void libp2p_utils_vector_set(struct Libp2pVector *vector, int pos, void *value);
void *libp2p_utils_vector_get(struct Libp2pVector *vector, int);
void libp2p_utils_vector_delete(struct Libp2pVector *vector, int pos);
void libp2p_utils_vector_free(struct Libp2pVector *vector);

View File

@ -1,10 +1,49 @@
#include <stdlib.h>
#include <string.h>
#include "libp2p/net/stream.h"
#include "libp2p/conn/session.h"
int libp2p_nodeio_upgrade_stream(struct Stream* stream) {
return 0;
int libp2p_nodeio_upgrade_stream(struct SessionContext* context) {
int retVal = 0;
char* protocol = "/nodeio/1.0.0\n";
unsigned char* results = NULL;
size_t results_size = 0;
if (!context->default_stream->write(context, (unsigned char*)protocol, strlen(protocol)))
goto exit;
if (!context->default_stream->read(context, &results, &results_size))
goto exit;
if (results_size != strlen(protocol))
goto exit;
if (strncmp((char*)results, protocol, results_size) != 0)
goto exit;
retVal = 1;
exit:
if (results != NULL) {
free(results);
results = NULL;
}
return retVal;
}
struct Node* libp2p_nodeio_get(struct Stream* stream, unsigned char* hash, int hash_length) {
return NULL;
/**
* Called by requestor to get a protobuf'd node from a hash
* @param context the session context
* @param hash the hash
* @param hash_size the length of the hash
* @param results where to put the buffer
* @param results_size the size of the results
* @returns true(1) on success, otherwise false(0)
*/
int libp2p_nodeio_get(struct SessionContext* context, unsigned char* hash, int hash_length, unsigned char** results, size_t* results_size) {
if (!context->default_stream->write(context, hash, hash_length))
return 0;
if (!context->default_stream->read(context, results, results_size))
return 0;
return 1;
}
int libp2p_nodeio_handshake(struct SessionContext* context) {
char* protocol = "/nodeio/1.0.0\n";
return context->default_stream->write(context, (unsigned char*)protocol, strlen(protocol));
}

View File

@ -2,7 +2,7 @@ CC = gcc
CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -I../../c-multiaddr/include -g3
LFLAGS =
DEPS =
OBJS = peer.o peerstore.o
OBJS = peer.o peerstore.o providerstore.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)

68
peer/providerstore.c Normal file
View File

@ -0,0 +1,68 @@
#include <stdlib.h>
#include <string.h>
#include "libp2p/utils/vector.h"
struct ProviderEntry {
unsigned char* hash;
int hash_size;
unsigned char* peer_id;
int peer_id_size;
};
struct ProviderStore {
struct Libp2pVector* provider_entries;
};
/***
* Stores hashes, and peers where you can possibly get them
*/
/**
* Create a new ProviderStore
* @returns a ProviderStore struct
*/
struct ProviderStore* libp2p_providerstore_new() {
struct ProviderStore* out = (struct ProviderStore*)malloc(sizeof(struct ProviderStore));
if (out != NULL) {
out->provider_entries = libp2p_utils_vector_new(4);
}
return out;
}
/***
* Clean resources used by a ProviderStore
* @param in the ProviderStore to clean up
*/
void libp2p_providerstore_free(struct ProviderStore* in) {
if (in != NULL) {
libp2p_utils_vector_free(in->provider_entries);
free(in);
in = NULL;
}
}
void libp2p_providerstore_add(struct ProviderStore* store, unsigned char* hash, int hash_size, unsigned char* peer_id, int peer_id_size) {
struct ProviderEntry* entry = (struct ProviderEntry*)malloc(sizeof(struct ProviderEntry));
entry->hash = malloc(hash_size);
memcpy(entry->hash, hash, hash_size);
entry->hash_size = hash_size;
entry->peer_id = malloc(peer_id_size);
memcpy(entry->peer_id, peer_id, peer_id_size);
entry->peer_id_size = peer_id_size;
libp2p_utils_vector_add(store->provider_entries, entry);
}
int libp2p_providerstore_get(struct ProviderStore* store, unsigned char* hash, int hash_size, unsigned char** peer_id, int *peer_id_size) {
struct ProviderEntry* current = NULL;
for (int i = 0; i < store->provider_entries->total; i++) {
current = (struct ProviderEntry*)libp2p_utils_vector_get(store->provider_entries, i);
if (current->hash_size == hash_size && memcmp(current->hash, hash, hash_size) == 0) {
*peer_id = malloc(current->peer_id_size);
memcpy(*peer_id, current->peer_id, current->peer_id_size);
*peer_id_size = current->peer_id_size;
return 1;
}
}
return 0;
}

View File

@ -1,78 +1,74 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libp2p/utils/vector.h"
/**
* Allocate memory for a new Libp2pVector
* @returns a new Libp2pVector or NULL if it couldn't do it
*/
struct Libp2pVector* libp2p_utils_vector_new() {
struct Libp2pVector* out = (struct Libp2pVector*)malloc(sizeof(struct Libp2pVector));
if (out != NULL) {
out->buffer = NULL;
out->buffer_size = 0;
}
return out;
struct Libp2pVector* libp2p_utils_vector_new(int initial_size)
{
struct Libp2pVector* v = (struct Libp2pVector*)malloc(sizeof(struct Libp2pVector));
v->capacity = initial_size;
v->total = 0;
v->items = malloc(sizeof(void *) * v->capacity);
return v;
}
void libp2p_utils_vector_free(struct Libp2pVector* vector) {
if (vector != NULL) {
if (vector->buffer != NULL)
free(vector->buffer);
vector->buffer_size = 0;
free(vector);
vector = NULL;
}
int libp2p_utils_vector_total(struct Libp2pVector *v)
{
return v->total;
}
/**
* Add bytes to vector
*/
int libp2p_utils_vector_add(struct Libp2pVector* vector, unsigned char* in_bytes, size_t in_size) {
if (in_size > 0) {
if (vector->buffer == NULL) {
vector->buffer = (unsigned char*)malloc(in_size);
if (vector->buffer == NULL)
return 0;
memcpy(vector->buffer, in_bytes, in_size);
} else {
vector->buffer = (unsigned char*)realloc(vector->buffer, in_size + vector->buffer_size);
if (vector->buffer == NULL)
return 0;
memcpy(&vector->buffer[vector->buffer_size], in_bytes, in_size);
vector->buffer_size += in_size;
}
}
return 1;
static void libp2p_utils_vector_resize(struct Libp2pVector *v, int capacity)
{
#ifdef DEBUG_ON
printf("vector_resize: %d to %d\n", v->capacity, capacity);
#endif
void **items = realloc(v->items, sizeof(void *) * capacity);
if (items) {
v->items = items;
v->capacity = capacity;
}
}
int libp2p_utils_vector_serialize(struct Libp2pVector* vector, unsigned char** out, size_t* out_size) {
// the first 4 bytes are the size, followed by the the byte array
*out_size = vector->buffer_size + 4;
*out = (unsigned char*)malloc(*out_size);
if (*out == NULL)
return 0;
unsigned char* ptr = *out;
ptr[0] = (vector->buffer_size >> 24) & 0xFF;
ptr[1] = (vector->buffer_size >> 16) & 0xFF;
ptr[2] = (vector->buffer_size >> 8) & 0xFF;
ptr[3] = vector->buffer_size & 0xFF;
memcpy(&ptr[4], vector->buffer, vector->buffer_size);
return 1;
void libp2p_utils_vector_add(struct Libp2pVector *v, void *item)
{
if (v->capacity == v->total)
libp2p_utils_vector_resize(v, v->capacity * 2);
v->items[v->total++] = item;
}
int libp2p_utils_vector_unserialize(unsigned char* in, struct Libp2pVector** out) {
*out = (struct Libp2pVector*)malloc(sizeof(struct Libp2pVector));
if (*out == NULL)
return 0;
struct Libp2pVector* ptr = *out;
ptr->buffer_size = in[0] | (in[1] << 8) | (in[2] << 16) | (in[3] << 24);
ptr->buffer = (unsigned char*)malloc(ptr->buffer_size);
if (ptr->buffer == NULL) {
free (*out);
return 0;
}
memcpy(ptr->buffer, &in[4], ptr->buffer_size);
return 1;
void libp2p_utils_vector_set(struct Libp2pVector *v, int index, void *item)
{
if (index >= 0 && index < v->total)
v->items[index] = item;
}
void *libp2p_utils_vector_get(struct Libp2pVector *v, int index)
{
if (index >= 0 && index < v->total)
return v->items[index];
return NULL;
}
void libp2p_utils_vector_delete(struct Libp2pVector *v, int index)
{
if (index < 0 || index >= v->total)
return;
v->items[index] = NULL;
for (int i = 0; i < v->total - 1; i++) {
v->items[i] = v->items[i + 1];
v->items[i + 1] = NULL;
}
v->total--;
if (v->total > 0 && v->total == v->capacity / 4)
libp2p_utils_vector_resize(v, v->capacity / 2);
}
void libp2p_utils_vector_free(struct Libp2pVector *v)
{
free(v->items);
}