Finishing NodeIO
This commit is contained in:
parent
b6a94c7c11
commit
0d0c9bde53
8 changed files with 242 additions and 107 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "libp2p/crypto/key.h"
|
||||||
/***
|
/***
|
||||||
* Holds the details of communication between two hosts
|
* Holds the details of communication between two hosts
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "libp2p/net/stream.h"
|
#include "libp2p/net/stream.h"
|
||||||
|
#include "libp2p/conn/session.h"
|
||||||
|
|
||||||
int libp2p_nodeio_upgrade_stream(struct Stream* stream);
|
int libp2p_nodeio_upgrade_stream(struct SessionContext* context);
|
||||||
struct Node* libp2p_nodeio_get(struct Stream* stream, unsigned char* hash, int hash_length);
|
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);
|
||||||
|
|
32
include/libp2p/peer/providerstore.h
Normal file
32
include/libp2p/peer/providerstore.h
Normal 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);
|
|
@ -1,41 +1,26 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
#define VECTOR_INIT_CAPACITY 4
|
||||||
* A very simple vector implementation for unsigned chars
|
|
||||||
*/
|
//#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 {
|
struct Libp2pVector {
|
||||||
unsigned char* buffer;
|
void **items;
|
||||||
size_t buffer_size;
|
int capacity;
|
||||||
|
int total;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
struct Libp2pVector* libp2p_utils_vector_new(int initial_size);
|
||||||
* Create and destroy
|
int libp2p_utils_vector_total(struct Libp2pVector* in);
|
||||||
*/
|
//static void libp2p_utils_vector_resize(struct Libp2pVector *vector, int new_size);
|
||||||
struct Libp2pVector* libp2p_utils_vector_new();
|
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);
|
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);
|
|
||||||
|
|
|
@ -1,10 +1,49 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "libp2p/net/stream.h"
|
#include "libp2p/net/stream.h"
|
||||||
|
#include "libp2p/conn/session.h"
|
||||||
|
|
||||||
int libp2p_nodeio_upgrade_stream(struct Stream* stream) {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
return 0;
|
||||||
|
if (!context->default_stream->read(context, results, results_size))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Node* libp2p_nodeio_get(struct Stream* stream, unsigned char* hash, int hash_length) {
|
int libp2p_nodeio_handshake(struct SessionContext* context) {
|
||||||
return NULL;
|
char* protocol = "/nodeio/1.0.0\n";
|
||||||
|
return context->default_stream->write(context, (unsigned char*)protocol, strlen(protocol));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ CC = gcc
|
||||||
CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -I../../c-multiaddr/include -g3
|
CFLAGS = -O0 -I../include -I../../c-protobuf -I../../c-multihash/include -I../../c-multiaddr/include -g3
|
||||||
LFLAGS =
|
LFLAGS =
|
||||||
DEPS =
|
DEPS =
|
||||||
OBJS = peer.o peerstore.o
|
OBJS = peer.o peerstore.o providerstore.o
|
||||||
|
|
||||||
%.o: %.c $(DEPS)
|
%.o: %.c $(DEPS)
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
68
peer/providerstore.c
Normal file
68
peer/providerstore.c
Normal 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;
|
||||||
|
}
|
122
utils/vector.c
122
utils/vector.c
|
@ -1,78 +1,74 @@
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "libp2p/utils/vector.h"
|
#include "libp2p/utils/vector.h"
|
||||||
|
|
||||||
/**
|
struct Libp2pVector* libp2p_utils_vector_new(int initial_size)
|
||||||
* Allocate memory for a new Libp2pVector
|
{
|
||||||
* @returns a new Libp2pVector or NULL if it couldn't do it
|
struct Libp2pVector* v = (struct Libp2pVector*)malloc(sizeof(struct Libp2pVector));
|
||||||
*/
|
v->capacity = initial_size;
|
||||||
struct Libp2pVector* libp2p_utils_vector_new() {
|
v->total = 0;
|
||||||
struct Libp2pVector* out = (struct Libp2pVector*)malloc(sizeof(struct Libp2pVector));
|
v->items = malloc(sizeof(void *) * v->capacity);
|
||||||
if (out != NULL) {
|
return v;
|
||||||
out->buffer = NULL;
|
|
||||||
out->buffer_size = 0;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void libp2p_utils_vector_free(struct Libp2pVector* vector) {
|
int libp2p_utils_vector_total(struct Libp2pVector *v)
|
||||||
if (vector != NULL) {
|
{
|
||||||
if (vector->buffer != NULL)
|
return v->total;
|
||||||
free(vector->buffer);
|
}
|
||||||
vector->buffer_size = 0;
|
|
||||||
free(vector);
|
static void libp2p_utils_vector_resize(struct Libp2pVector *v, int capacity)
|
||||||
vector = NULL;
|
{
|
||||||
|
#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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void libp2p_utils_vector_add(struct Libp2pVector *v, void *item)
|
||||||
* Add bytes to vector
|
{
|
||||||
*/
|
if (v->capacity == v->total)
|
||||||
int libp2p_utils_vector_add(struct Libp2pVector* vector, unsigned char* in_bytes, size_t in_size) {
|
libp2p_utils_vector_resize(v, v->capacity * 2);
|
||||||
if (in_size > 0) {
|
v->items[v->total++] = item;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int libp2p_utils_vector_serialize(struct Libp2pVector* vector, unsigned char** out, size_t* out_size) {
|
void libp2p_utils_vector_set(struct Libp2pVector *v, int index, void *item)
|
||||||
// the first 4 bytes are the size, followed by the the byte array
|
{
|
||||||
*out_size = vector->buffer_size + 4;
|
if (index >= 0 && index < v->total)
|
||||||
*out = (unsigned char*)malloc(*out_size);
|
v->items[index] = item;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int libp2p_utils_vector_unserialize(unsigned char* in, struct Libp2pVector** out) {
|
void *libp2p_utils_vector_get(struct Libp2pVector *v, int index)
|
||||||
*out = (struct Libp2pVector*)malloc(sizeof(struct Libp2pVector));
|
{
|
||||||
if (*out == NULL)
|
if (index >= 0 && index < v->total)
|
||||||
return 0;
|
return v->items[index];
|
||||||
struct Libp2pVector* ptr = *out;
|
return NULL;
|
||||||
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_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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue