Adding more compatibility fixes for standard ipfs

This commit is contained in:
John Jones 2017-08-31 16:40:35 -05:00
parent 36061dc1da
commit 53f754af43
6 changed files with 115 additions and 7 deletions

View file

@ -14,6 +14,14 @@
* So in short, much of this will change. But for now, think of it as a Proof of Concept.
*/
/***
* The handler to handle calls to the protocol
* @param stream_context the context
* @returns the protocol handler
*/
struct Libp2pProtocolHandler* libp2p_net_multistream_build_protocol_handler(void* stream_context);
/**
* Read from a multistream socket
* @param socket_fd the socket file descriptor

View file

@ -35,4 +35,10 @@ struct Libp2pProtocolHandler {
int (*Shutdown)(void* protocol_context);
};
/**
* Allocate resources for a new Libp2pProtocolHandler
* @returns an allocated struct
*/
struct Libp2pProtocolHandler* libp2p_protocol_handler_new();
int libp2p_protocol_marshal(const uint8_t* incoming, size_t incoming_size, struct SessionContext* context, struct Libp2pVector* protocol_handlers);

View file

@ -32,3 +32,16 @@ int libp2p_secio_handshake(struct SessionContext* session, struct RsaPrivateKey*
* @returns true(1) on success, false(0) otherwise
*/
int libp2p_secio_initiate_handshake(struct SessionContext* session_context, struct RsaPrivateKey* private_key, struct Peerstore* peer_store);
/***
* Send the protocol string to the remote stream
* @param session the context
* @returns true(1) on success, false(0) otherwise
*/
int libp2p_secio_send_protocol(struct SessionContext* session);
/***
* Attempt to read the secio protocol as a reply from the remote
* @param session the context
* @returns true(1) if we received what we think we should have, false(0) otherwise
*/
int libp2p_secio_receive_protocol(struct SessionContext* session);

View file

@ -23,6 +23,43 @@ int multistream_default_timeout = 5;
* An implementation of the libp2p multistream
*/
int libp2p_net_multistream_can_handle(const uint8_t *incoming, const size_t incoming_size) {
char *protocol = "/multistream/1.0.0\n";
int protocol_size = strlen(protocol);
// is there a varint in front?
size_t num_bytes = 0;
varint_decode(incoming, incoming_size, &num_bytes);
if (incoming_size >= protocol_size - num_bytes) {
if (strncmp(protocol, (char*) &incoming[num_bytes], protocol_size) == 0)
return 1;
}
return 0;
}
int libp2p_net_multistream_handle_message(const uint8_t *incoming, size_t incoming_size, struct SessionContext* context, void* protocol_context) {
return 0;
}
int libp2p_net_multistream_shutdown(void* protocol_context) {
return 1;
}
/***
* The handler to handle calls to the protocol
* @param stream_context the context
* @returns the protocol handler
*/
struct Libp2pProtocolHandler* libp2p_net_multistream_build_protocol_handler(void* stream_context) {
struct Libp2pProtocolHandler *handler = libp2p_protocol_handler_new();
if (handler != NULL) {
handler->context = stream_context;
handler->CanHandle = libp2p_net_multistream_can_handle;
handler->HandleMessage = libp2p_net_multistream_handle_message;
handler->Shutdown = libp2p_net_multistream_shutdown;
}
return handler;
}
/***
* Close the Multistream interface
* NOTE: This also closes the socket

View file

@ -20,6 +20,21 @@ const struct Libp2pProtocolHandler* protocol_compare(const unsigned char* incomi
return NULL;
}
/**
* Allocate resources for a new Libp2pProtocolHandler
* @returns an allocated struct
*/
struct Libp2pProtocolHandler* libp2p_protocol_handler_new() {
struct Libp2pProtocolHandler* h = (struct Libp2pProtocolHandler*) malloc(sizeof(struct Libp2pProtocolHandler));
if (h != NULL) {
h->CanHandle = NULL;
h->HandleMessage = NULL;
h->Shutdown = NULL;
h->context = NULL;
}
return h;
}
/***
* Handle an incoming message
* @param incoming the incoming data

View file

@ -59,6 +59,9 @@ int libp2p_secio_can_handle(const uint8_t* incoming, size_t incoming_size) {
int libp2p_secio_handle_message(const uint8_t* incoming, size_t incoming_size, struct SessionContext* session_context, void* protocol_context) {
libp2p_logger_debug("secio", "Handling incoming secio message.\n");
struct SecioContext* ctx = (struct SecioContext*)protocol_context;
// send them the protocol
if (!libp2p_secio_send_protocol(session_context))
return -1;
int retVal = libp2p_secio_handshake(session_context, ctx->private_key, ctx->peer_store);
if (retVal)
return 0;
@ -79,13 +82,10 @@ int libp2p_secio_shutdown(void* context) {
* @returns true(1) on success, false(0) otherwise
*/
int libp2p_secio_initiate_handshake(struct SessionContext* session_context, struct RsaPrivateKey* private_key, struct Peerstore* peer_store) {
// send the protocol id first
const unsigned char* protocol = (unsigned char*)"/ipfs/secio/1.0.0\n";
int protocol_len = strlen((char*)protocol);
if (!session_context->default_stream->write(session_context, protocol, protocol_len))
return 0;
return libp2p_secio_handshake(session_context, private_key, peer_store);
if (libp2p_secio_send_protocol(session_context) && libp2p_secio_receive_protocol(session_context)) {
return libp2p_secio_handshake(session_context, private_key, peer_store);
}
return 0;
}
struct Libp2pProtocolHandler* libp2p_secio_build_protocol_handler(struct RsaPrivateKey* private_key, struct Peerstore* peer_store) {
@ -628,6 +628,35 @@ int libp2p_secio_unencrypted_read(struct SessionContext* session, unsigned char*
return buffer_size;
}
/***
* Send the protocol string to the remote stream
* @param session the context
* @returns true(1) on success, false(0) otherwise
*/
int libp2p_secio_send_protocol(struct SessionContext* session) {
char* protocol = "/secio/1.0.0\n";
int protocol_len = strlen(protocol);
return session->default_stream->write(session, (unsigned char *)protocol, protocol_len);
}
/***
* Attempt to read the secio protocol as a reply from the remote
* @param session the context
* @returns true(1) if we received what we think we should have, false(0) otherwise
*/
int libp2p_secio_receive_protocol(struct SessionContext* session) {
char* protocol = "/secio/1.0.0\n";
int numSecs = 30;
unsigned char* buffer = NULL;
size_t buffer_size = 0;
int retVal = session->default_stream->read(session, &buffer, &buffer_size, numSecs);
if (retVal == 0 || buffer != NULL) {
if (strncmp(protocol, (char*)buffer, strlen(protocol)) == 0)
return 1;
}
return 0;
}
/**
* Initialize state for the sha256 stream cipher
* @param session the SessionContext struct that contains the variables to initialize