Adding more compatibility fixes for standard ipfs
This commit is contained in:
parent
36061dc1da
commit
53f754af43
6 changed files with 115 additions and 7 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue