Reading from stream now uses StreamMessage struct

This commit is contained in:
jmjatlanta 2017-10-23 09:01:03 -05:00
parent 0166a89d48
commit 6147769f4b
10 changed files with 191 additions and 127 deletions

View file

@ -27,6 +27,7 @@
<option id="gnu.c.compiler.option.include.paths.1688271638" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> <option id="gnu.c.compiler.option.include.paths.1688271638" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/c-multihash/include}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/c-multihash/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/c-libp2p/include}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/c-libp2p/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/c-multiaddr/include}&quot;"/>
</option> </option>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1284958161" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1284958161" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool> </tool>

View file

@ -129,6 +129,35 @@ int libp2p_stream_unlock(struct Stream* stream) {
return 0; return 0;
} }
/***
* Create a new StreamMessage struct
* @returns a StreamMessage struct
*/
struct StreamMessage* libp2p_stream_message_new() {
struct StreamMessage* out = (struct StreamMessage*) malloc(sizeof(struct StreamMessage));
if (out != NULL) {
out->data = NULL;
out->data_size = 0;
out->error_number = 0;
}
return out;
}
/**
* free resources of a StreamMessage struct
* @param msg the StreamMessage to free
*/
void libp2p_stream_message_free(struct StreamMessage* msg) {
if (msg != NULL) {
if (msg->data != NULL) {
free(msg->data);
msg->data = NULL;
}
free(msg);
msg = NULL;
}
}
/**** /****
* Make a copy of a SessionContext * Make a copy of a SessionContext
* @param original the original * @param original the original

View file

@ -44,12 +44,12 @@ int libp2p_net_multistream_receive_protocol(struct SessionContext* context);
/** /**
* Read from a multistream socket * Read from a multistream socket
* @param socket_fd the socket file descriptor * @param socket_fd the socket file descriptor
* @param data the data to send * @param data where to put the results
* @param data_length the length of the data
* @param timeout_secs number of seconds before read gives up. Will return 0 data length. * @param timeout_secs number of seconds before read gives up. Will return 0 data length.
* @returns the number of bytes written * @returns the number of bytes written
*/ */
int libp2p_net_multistream_read(void* stream_context, unsigned char** data, size_t* data_length, int timeout_secs); int libp2p_net_multistream_read(void* stream_context, struct StreamMessage** data, int timeout_secs);
/** /**
* Write to an open multistream host * Write to an open multistream host
* @param socket_fd the socket file descriptor * @param socket_fd the socket file descriptor

View file

@ -2,6 +2,29 @@
#include <pthread.h> #include <pthread.h>
/**
* Encapsulates a message that (was/will be) sent
* across a stream
*/
struct StreamMessage {
uint8_t* data;
size_t data_size;
int error_number;
};
/***
* Create a new StreamMessage struct
* @returns a StreamMessage struct
*/
struct StreamMessage* libp2p_stream_message_new();
/**
* free resources of a StreamMessage struct
* @param msg the StreamMessage to free
*/
void libp2p_stream_message_free(struct StreamMessage* msg);
/** /**
* An interface in front of various streams * An interface in front of various streams
*/ */
@ -16,12 +39,11 @@ struct Stream {
/** /**
* Reads from the stream * Reads from the stream
* @param stream the stream context (usually a SessionContext pointer) * @param stream the stream context (usually a SessionContext pointer)
* @param buffer where to put the results * @param message where to put the incoming message (will be allocated)
* @param bytes_read how many bytes were read
* @param timeout_secs number of seconds before a timeout * @param timeout_secs number of seconds before a timeout
* @returns true(1) on success, false(0) otherwise * @returns true(1) on success, false(0) otherwise
*/ */
int (*read)(void* stream_context, unsigned char** buffer, size_t* bytes_read, int timeout_secs); int (*read)(void* stream_context, struct StreamMessage** message, int timeout_secs);
/** /**
* Writes to a stream * Writes to a stream

View file

@ -60,9 +60,8 @@ int libp2p_net_multistream_send_protocol(struct SessionContext *context) {
*/ */
int libp2p_net_multistream_receive_protocol(struct SessionContext* context) { int libp2p_net_multistream_receive_protocol(struct SessionContext* context) {
char* protocol = "/multistream/1.0.0\n"; char* protocol = "/multistream/1.0.0\n";
uint8_t* results = NULL; struct StreamMessage* results = NULL;
size_t results_size = 0; if (!context->default_stream->read(context, &results, 30)) {
if (!context->default_stream->read(context, &results, &results_size, 30)) {
libp2p_logger_error("multistream", "receive_protocol: Unable to read results.\n"); libp2p_logger_error("multistream", "receive_protocol: Unable to read results.\n");
return 0; return 0;
} }
@ -82,21 +81,20 @@ int libp2p_net_multistream_handle_message(const uint8_t *incoming, size_t incomi
struct MultistreamContext* multistream_context = (struct MultistreamContext*) protocol_context; struct MultistreamContext* multistream_context = (struct MultistreamContext*) protocol_context;
// try to read from the network // try to read from the network
uint8_t *results = 0; struct StreamMessage* results = NULL;
size_t bytes_read = 0;
int retVal = 0; int retVal = 0;
int max_retries = 10; int max_retries = 10;
int numRetries = 0; int numRetries = 0;
// handle the call // handle the call
for(;;) { for(;;) {
// try to read for 5 seconds // try to read for 5 seconds
if (context->default_stream->read(context, &results, &bytes_read, 5)) { if (context->default_stream->read(context, &results, 5)) {
// we read something from the network. Process it. // we read something from the network. Process it.
// NOTE: If it is a multistream protocol that we are receiving, ignore it. // NOTE: If it is a multistream protocol that we are receiving, ignore it.
if (libp2p_net_multistream_can_handle(results, bytes_read)) if (libp2p_net_multistream_can_handle(results->data, results->data_size))
continue; continue;
numRetries = 0; numRetries = 0;
retVal = libp2p_protocol_marshal(results, bytes_read, context, multistream_context->handlers); retVal = libp2p_protocol_marshal(results->data, results->data_size, context, multistream_context->handlers);
if (results != NULL) if (results != NULL)
free(results); free(results);
// exit the loop on error (or if they ask us to no longer loop by returning 0) // exit the loop on error (or if they ask us to no longer loop by returning 0)
@ -244,7 +242,7 @@ int libp2p_net_multistream_write(void* stream_context, const unsigned char* data
* @param timeout_secs the seconds before a timeout * @param timeout_secs the seconds before a timeout
* @returns number of bytes received * @returns number of bytes received
*/ */
int libp2p_net_multistream_read(void* stream_context, unsigned char** results, size_t* results_size, int timeout_secs) { int libp2p_net_multistream_read(void* stream_context, struct StreamMessage** results, int timeout_secs) {
struct SessionContext* session_context = (struct SessionContext*)stream_context; struct SessionContext* session_context = (struct SessionContext*)stream_context;
struct Stream* stream = session_context->default_stream; struct Stream* stream = session_context->default_stream;
int bytes = 0; int bytes = 0;
@ -300,39 +298,52 @@ int libp2p_net_multistream_read(void* stream_context, unsigned char** results, s
return 0; return 0;
// parse the results, removing the leading size indicator // parse the results, removing the leading size indicator
*results = malloc(num_bytes_requested); *results = libp2p_stream_message_new();
if (*results == NULL) struct StreamMessage* rslts = *results;
if (rslts == NULL)
return 0; return 0;
memcpy(*results, buffer, num_bytes_requested); rslts->data_size = num_bytes_requested;
*results_size = num_bytes_requested; rslts->data = (uint8_t*) malloc(num_bytes_requested);
if (rslts->data == NULL) {
libp2p_stream_message_free(rslts);
return 0;
}
memcpy(rslts->data, buffer, num_bytes_requested);
session_context->last_comm_epoch = os_utils_gmtime(); session_context->last_comm_epoch = os_utils_gmtime();
} else { // use secio instead of raw read/writes } else { // use secio instead of raw read/writes
unsigned char* read_from_stream; struct StreamMessage* read_from_stream;
size_t size_read_from_stream; if (session_context->default_stream->read(session_context, &read_from_stream, timeout_secs) == 0) {
if (session_context->default_stream->read(session_context, &read_from_stream, &size_read_from_stream, timeout_secs) == 0) {
return 0; return 0;
} }
// pull out num_bytes_requested // pull out num_bytes_requested
num_bytes_requested = varint_decode(read_from_stream, size_read_from_stream, &left); num_bytes_requested = varint_decode(read_from_stream->data, read_from_stream->data_size, &left);
memcpy(buffer, read_from_stream, size_read_from_stream); memcpy(buffer, read_from_stream->data, read_from_stream->data_size);
free(read_from_stream); buffer_size = read_from_stream->data_size;
buffer_size = size_read_from_stream; libp2p_stream_message_free(read_from_stream);
read_from_stream = NULL;
while (num_bytes_requested > buffer_size - left) { while (num_bytes_requested > buffer_size - left) {
// need to read more into buffer // need to read more into buffer
if (session_context->default_stream->read(session_context, &read_from_stream, &size_read_from_stream, timeout_secs) == 0) { if (session_context->default_stream->read(session_context, &read_from_stream, timeout_secs) == 0) {
return 0; return 0;
} }
memcpy(&buffer[buffer_size], read_from_stream, size_read_from_stream); memcpy(&buffer[buffer_size], read_from_stream->data, read_from_stream->data_size);
free(read_from_stream); buffer_size += read_from_stream->data_size;
buffer_size += size_read_from_stream; libp2p_stream_message_free(read_from_stream);
} }
*results = malloc(num_bytes_requested); *results = libp2p_stream_message_new();
*results_size = num_bytes_requested; struct StreamMessage* rslts = *results;
if (*results == NULL) { if (rslts == NULL) {
libp2p_logger_error("multistream", "Unable to allocate %lu bytes of memory.", num_bytes_requested); libp2p_logger_error("multistream", "Unable to allocate %lu bytes of memory.", num_bytes_requested);
return 0; return 0;
} }
memcpy(*results, &buffer[left], num_bytes_requested); rslts->data_size = num_bytes_requested;
rslts->data = (uint8_t*) malloc(num_bytes_requested);
if (rslts->data == NULL) {
libp2p_stream_message_free(rslts);
libp2p_logger_error("multistream", "Unable to allocate %lu bytes of memory.", num_bytes_requested);
return 0;
}
memcpy(rslts->data, &buffer[left], num_bytes_requested);
session_context->last_comm_epoch = os_utils_gmtime(); session_context->last_comm_epoch = os_utils_gmtime();
} }
@ -359,8 +370,7 @@ struct Stream* libp2p_net_multistream_connect(const char* hostname, int port) {
*/ */
struct Stream* libp2p_net_multistream_connect_with_timeout(const char* hostname, int port, int timeout_secs) { struct Stream* libp2p_net_multistream_connect_with_timeout(const char* hostname, int port, int timeout_secs) {
int retVal = -1, return_result = -1, socket = -1; int retVal = -1, return_result = -1, socket = -1;
unsigned char* results = NULL; struct StreamMessage* results = NULL;
size_t results_size;
struct Stream* stream = NULL; struct Stream* stream = NULL;
uint32_t ip = hostname_to_ip(hostname); uint32_t ip = hostname_to_ip(hostname);
@ -381,8 +391,8 @@ struct Stream* libp2p_net_multistream_connect_with_timeout(const char* hostname,
session.default_stream = stream; session.default_stream = stream;
// try to receive the protocol id // try to receive the protocol id
return_result = libp2p_net_multistream_read(&session, &results, &results_size, timeout_secs); return_result = libp2p_net_multistream_read(&session, &results, timeout_secs);
if (return_result == 0 || results_size < 1 || !libp2p_net_multistream_can_handle(results, results_size)) { if (results == NULL || return_result == 0 || results->data_size < 1 || !libp2p_net_multistream_can_handle(results->data, results->data_size)) {
libp2p_logger_error("multistream", "Attempted to receive the multistream protocol header, but received %s.\n", results); libp2p_logger_error("multistream", "Attempted to receive the multistream protocol header, but received %s.\n", results);
goto exit; goto exit;
} }
@ -418,15 +428,14 @@ struct Stream* libp2p_net_multistream_connect_with_timeout(const char* hostname,
*/ */
int libp2p_net_multistream_negotiate(struct SessionContext* session) { int libp2p_net_multistream_negotiate(struct SessionContext* session) {
const char* protocolID = "/multistream/1.0.0\n"; const char* protocolID = "/multistream/1.0.0\n";
unsigned char* results = NULL; struct StreamMessage* results = NULL;
size_t results_length = 0;
int retVal = 0; int retVal = 0;
// send the protocol id // send the protocol id
if (!libp2p_net_multistream_write(session, (unsigned char*)protocolID, strlen(protocolID))) if (!libp2p_net_multistream_write(session, (unsigned char*)protocolID, strlen(protocolID)))
goto exit; goto exit;
// expect the same back // expect the same back
libp2p_net_multistream_read(session, &results, &results_length, multistream_default_timeout); libp2p_net_multistream_read(session, &results, multistream_default_timeout);
if (results_length == 0) if (results == NULL || results->data_size == 0)
goto exit; goto exit;
if (strncmp((char*)results, protocolID, strlen(protocolID)) != 0) if (strncmp((char*)results, protocolID, strlen(protocolID)) != 0)
goto exit; goto exit;

View file

@ -82,30 +82,27 @@ int libp2p_routing_dht_protobuf_message(struct KademliaMessage* message, unsigne
int libp2p_routing_dht_upgrade_stream(struct SessionContext* context) { int libp2p_routing_dht_upgrade_stream(struct SessionContext* context) {
int retVal = 0; int retVal = 0;
char* protocol = "/ipfs/kad/1.0.0\n"; char* protocol = "/ipfs/kad/1.0.0\n";
unsigned char* results = NULL; struct StreamMessage* results = NULL;
size_t results_size = 0;
if (!context->default_stream->write(context, (unsigned char*)protocol, strlen(protocol))) { if (!context->default_stream->write(context, (unsigned char*)protocol, strlen(protocol))) {
libp2p_logger_error("dht_protocol", "Unable to write to stream during upgrade attempt.\n"); libp2p_logger_error("dht_protocol", "Unable to write to stream during upgrade attempt.\n");
goto exit; goto exit;
} }
if (!context->default_stream->read(context, &results, &results_size, 5)) { if (!context->default_stream->read(context, &results, 5)) {
libp2p_logger_error("dht_protocol", "Unable to read from stream during upgrade attempt.\n"); libp2p_logger_error("dht_protocol", "Unable to read from stream during upgrade attempt.\n");
goto exit; goto exit;
} }
if (results_size != strlen(protocol)) { if (results == NULL || results->data_size != strlen(protocol)) {
libp2p_logger_error("dht_protocol", "Expected response size incorrect during upgrade attempt.\n"); libp2p_logger_error("dht_protocol", "Expected response size incorrect during upgrade attempt.\n");
goto exit; goto exit;
} }
if (strncmp((char*)results, protocol, results_size) != 0) { if (strncmp((char*)results->data, protocol, results->data_size) != 0) {
libp2p_logger_error("dht_protocol", "Expected %s but received %s.\n", protocol, results); libp2p_logger_error("dht_protocol", "Expected %s but received %s.\n", protocol, results);
goto exit; goto exit;
} }
retVal = 1; retVal = 1;
exit: exit:
if (results != NULL) { libp2p_stream_message_free(results);
free(results);
results = NULL; results = NULL;
}
return retVal; return retVal;
} }
@ -443,16 +440,17 @@ int libp2p_routing_dht_handle_find_node(struct SessionContext* session, struct K
* @returns true(1) on success, otherwise false(0) * @returns true(1) on success, otherwise false(0)
*/ */
int libp2p_routing_dht_handle_message(struct SessionContext* session, struct Peerstore* peerstore, struct ProviderStore* providerstore) { int libp2p_routing_dht_handle_message(struct SessionContext* session, struct Peerstore* peerstore, struct ProviderStore* providerstore) {
unsigned char* buffer = NULL, *result_buffer = NULL; unsigned char *result_buffer = NULL;
size_t buffer_size = 0, result_buffer_size = 0; struct StreamMessage* buffer = NULL;
size_t result_buffer_size = 0;
int retVal = 0; int retVal = 0;
struct KademliaMessage* message = NULL; struct KademliaMessage* message = NULL;
// read from stream // read from stream
if (!session->default_stream->read(session, &buffer, &buffer_size, 5)) if (!session->default_stream->read(session, &buffer, 5))
goto exit; goto exit;
// unprotobuf // unprotobuf
if (!libp2p_message_protobuf_decode(buffer, buffer_size, &message)) if (!libp2p_message_protobuf_decode(buffer->data, buffer->data_size, &message))
goto exit; goto exit;
// handle message // handle message
@ -486,8 +484,7 @@ int libp2p_routing_dht_handle_message(struct SessionContext* session, struct Pee
} }
retVal = 1; retVal = 1;
exit: exit:
if (buffer != NULL) libp2p_stream_message_free(buffer);
free(buffer);
if (result_buffer != NULL) if (result_buffer != NULL)
free(result_buffer); free(result_buffer);
if (message != NULL) if (message != NULL)
@ -503,20 +500,20 @@ int libp2p_routing_dht_handle_message(struct SessionContext* session, struct Pee
* @returns true(1) on success, false(0) otherwise * @returns true(1) on success, false(0) otherwise
*/ */
int libp2p_routing_dht_receive_message(struct SessionContext* sessionContext, struct KademliaMessage** result) { int libp2p_routing_dht_receive_message(struct SessionContext* sessionContext, struct KademliaMessage** result) {
uint8_t* results = NULL; struct StreamMessage* results = NULL;
size_t results_size = 0;
if (!sessionContext->default_stream->read(sessionContext, &results, &results_size, 5)) { if (!sessionContext->default_stream->read(sessionContext, &results, 5)) {
libp2p_logger_error("online", "Attempted to read from Kademlia stream, but could not.\n"); libp2p_logger_error("online", "Attempted to read from Kademlia stream, but could not.\n");
goto exit; goto exit;
} }
// see if we can unprotobuf // see if we can unprotobuf
if (!libp2p_message_protobuf_decode(results, results_size, result)) { if (!libp2p_message_protobuf_decode(results->data, results->data_size, result)) {
libp2p_logger_error("online", "Received kademlia response, but cannot decode it.\n"); libp2p_logger_error("online", "Received kademlia response, but cannot decode it.\n");
goto exit; goto exit;
} }
exit: exit:
libp2p_stream_message_free(results);
return result != NULL; return result != NULL;
} }

View file

@ -659,25 +659,22 @@ int libp2p_secio_send_protocol(struct SessionContext* session) {
int libp2p_secio_receive_protocol(struct SessionContext* session) { int libp2p_secio_receive_protocol(struct SessionContext* session) {
char* protocol = "/secio/1.0.0\n"; char* protocol = "/secio/1.0.0\n";
int numSecs = 30; int numSecs = 30;
unsigned char* buffer = NULL; int retVal = 0;
size_t buffer_size = 0; struct StreamMessage* buffer = NULL;
int retVal = session->default_stream->read(session, &buffer, &buffer_size, numSecs); session->default_stream->read(session, &buffer, numSecs);
if (retVal == 0 || buffer != NULL) {
if (buffer == NULL) { if (buffer == NULL) {
libp2p_logger_error("secio", "Expected the secio protocol header, but received NULL.\n"); libp2p_logger_error("secio", "Expected the secio protocol header, but received NULL.\n");
} else { } else {
if (strncmp(protocol, (char*)buffer, strlen(protocol)) == 0) { // see if they sent the correct response
free(buffer); if (strncmp(protocol, (char*)buffer->data, strlen(protocol)) == 0) {
return 1; retVal = 1;
} }
else { else {
libp2p_logger_error("secio", "Expected the secio protocol header, but received %s.\n", buffer); libp2p_logger_error("secio", "Expected the secio protocol header, but received %s.\n", buffer);
} }
} }
} libp2p_stream_message_free(buffer);
if (buffer != NULL) return retVal;
free(buffer);
return 0;
} }
/** /**
@ -782,9 +779,8 @@ int libp2p_secio_encrypted_write(void* stream_context, const unsigned char* byte
* @param outgoing_size the amount of memory allocated for the results * @param outgoing_size the amount of memory allocated for the results
* @returns number of unencrypted bytes * @returns number of unencrypted bytes
*/ */
int libp2p_secio_decrypt(struct SessionContext* session, const unsigned char* incoming, size_t incoming_size, unsigned char** outgoing, size_t* outgoing_size) { int libp2p_secio_decrypt(struct SessionContext* session, const unsigned char* incoming, size_t incoming_size, struct StreamMessage** outgoing) {
size_t data_section_size = incoming_size - 32; size_t data_section_size = incoming_size - 32;
*outgoing_size = 0;
unsigned char* buffer; unsigned char* buffer;
// verify MAC // verify MAC
@ -802,9 +798,13 @@ int libp2p_secio_decrypt(struct SessionContext* session, const unsigned char* in
// MAC verification failed // MAC verification failed
libp2p_logger_error("secio", "libp2p_secio_decrypt: MAC verification failed.\n"); libp2p_logger_error("secio", "libp2p_secio_decrypt: MAC verification failed.\n");
// copy the raw bytes into outgoing for further analysis // copy the raw bytes into outgoing for further analysis
*outgoing = (unsigned char*)malloc(incoming_size); *outgoing = libp2p_stream_message_new();
*outgoing_size = incoming_size; struct StreamMessage* message = *outgoing;
memcpy(*outgoing, incoming, incoming_size); if (message != NULL) {
message->data_size = incoming_size;
message->data = (uint8_t*) malloc(incoming_size);
memcpy(message->data, incoming, incoming_size);
}
return 0; return 0;
} }
@ -824,22 +824,28 @@ int libp2p_secio_decrypt(struct SessionContext* session, const unsigned char* in
} }
mbedtls_aes_free(&cipher_ctx); mbedtls_aes_free(&cipher_ctx);
*outgoing = malloc(data_section_size); *outgoing = libp2p_stream_message_new();
*outgoing_size = data_section_size; struct StreamMessage* message = *outgoing;
memcpy(*outgoing, buffer, data_section_size); message->data_size = data_section_size;
message->data = (uint8_t*) malloc(data_section_size);
if (message->data == NULL) {
libp2p_stream_message_free(message);
*outgoing = NULL;
return 0;
}
memcpy(message->data, buffer, data_section_size);
free(buffer); free(buffer);
return *outgoing_size; return message->data_size;
} }
/** /**
* Read from an encrypted stream * Read from an encrypted stream
* @param session the session parameters * @param session the session parameters
* @param bytes where the bytes will be stored * @param bytes where the bytes will be stored
* @param num_bytes the number of bytes read from the stream
* @returns the number of bytes read * @returns the number of bytes read
*/ */
int libp2p_secio_encrypted_read(void* stream_context, unsigned char** bytes, size_t* num_bytes, int timeout_secs) { int libp2p_secio_encrypted_read(void* stream_context, struct StreamMessage** bytes, int timeout_secs) {
int retVal = 0; int retVal = 0;
struct SessionContext* session = (struct SessionContext*)stream_context; struct SessionContext* session = (struct SessionContext*)stream_context;
// reader uses the remote cipher and mac // reader uses the remote cipher and mac
@ -850,7 +856,7 @@ int libp2p_secio_encrypted_read(void* stream_context, unsigned char** bytes, siz
libp2p_logger_error("secio", "Unencrypted_read returned false.\n"); libp2p_logger_error("secio", "Unencrypted_read returned false.\n");
goto exit; goto exit;
} }
retVal = libp2p_secio_decrypt(session, incoming, incoming_size, bytes, num_bytes); retVal = libp2p_secio_decrypt(session, incoming, incoming_size, bytes);
if (!retVal) if (!retVal)
libp2p_logger_error("secio", "Decrypting incoming stream returned false.\n"); libp2p_logger_error("secio", "Decrypting incoming stream returned false.\n");
exit: exit:
@ -871,6 +877,7 @@ int libp2p_secio_encrypted_read(void* stream_context, unsigned char** bytes, siz
int libp2p_secio_handshake(struct SessionContext* local_session, const struct RsaPrivateKey* private_key, struct Peerstore* peerstore) { int libp2p_secio_handshake(struct SessionContext* local_session, const struct RsaPrivateKey* private_key, struct Peerstore* peerstore) {
int retVal = 0; int retVal = 0;
size_t results_size = 0, bytes_written = 0; size_t results_size = 0, bytes_written = 0;
struct StreamMessage* stream_message = NULL;
unsigned char* propose_in_bytes = NULL; // the remote protobuf unsigned char* propose_in_bytes = NULL; // the remote protobuf
size_t propose_in_size = 0; size_t propose_in_size = 0;
unsigned char* propose_out_bytes = NULL; // the local protobuf unsigned char* propose_out_bytes = NULL; // the local protobuf
@ -1172,16 +1179,16 @@ int libp2p_secio_handshake(struct SessionContext* local_session, const struct Rs
// receive our nonce to verify encryption works // receive our nonce to verify encryption works
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Receiving our nonce\n"); libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Receiving our nonce\n");
results = NULL; results = NULL;
int bytes_read = libp2p_secio_encrypted_read(local_session, &results, &results_size, 10); int bytes_read = libp2p_secio_encrypted_read(local_session, &stream_message, 10);
if (bytes_read <= 0) { if (bytes_read <= 0 || stream_message == NULL) {
libp2p_logger_error("secio", "Encrypted read returned %d\n", bytes_read); libp2p_logger_error("secio", "Encrypted read returned %d\n", bytes_read);
goto exit; goto exit;
} }
if (results_size != 16) { if (stream_message->data_size != 16) {
libp2p_logger_error("secio", "Results_size should be 16 but was %d\n", results_size); libp2p_logger_error("secio", "Results_size should be 16 but was %d\n", stream_message->data_size);
goto exit; goto exit;
} }
if (libp2p_secio_bytes_compare(results, (unsigned char*)local_session->local_nonce, 16) != 0) { if (libp2p_secio_bytes_compare(stream_message->data, (unsigned char*)local_session->local_nonce, 16) != 0) {
libp2p_logger_error("secio", "Bytes of nonce did not match\n"); libp2p_logger_error("secio", "Bytes of nonce did not match\n");
goto exit; goto exit;
} }
@ -1221,10 +1228,9 @@ int libp2p_secio_handshake(struct SessionContext* local_session, const struct Rs
libp2p_secio_propose_free(propose_out); libp2p_secio_propose_free(propose_out);
libp2p_secio_propose_free(propose_in); libp2p_secio_propose_free(propose_in);
libp2p_stream_message_free(stream_message);
if (retVal == 1) { if (retVal != 1) {
//libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Handshake success!\n");
} else {
libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Handshake returning false\n"); libp2p_logger_log("secio", LOGLEVEL_DEBUG, "Handshake returning false\n");
} }
return retVal; return retVal;

View file

@ -30,8 +30,7 @@ int test_multistream_connect() {
int test_multistream_get_list() { int test_multistream_get_list() {
int retVal = 0; int retVal = 0;
unsigned char* response; struct StreamMessage* response;
size_t response_size;
char* filtered = NULL; char* filtered = NULL;
struct SessionContext session; struct SessionContext session;
@ -47,13 +46,13 @@ int test_multistream_get_list() {
goto exit; goto exit;
// retrieve response // retrieve response
retVal = libp2p_net_multistream_read(&session, &response, &response_size, 5); retVal = libp2p_net_multistream_read(&session, &response, 5);
if (retVal <= 0) if (retVal <= 0)
goto exit; goto exit;
filtered = malloc(response_size + 1); filtered = malloc(response->data_size + 1);
strncpy(filtered, (char*)response, response_size); strncpy(filtered, (char*)response->data, response->data_size);
filtered[response_size] = 0; filtered[response->data_size] = 0;
fprintf(stdout, "Response from multistream ls: %s", (char*)filtered); fprintf(stdout, "Response from multistream ls: %s", (char*)filtered);
@ -64,8 +63,7 @@ int test_multistream_get_list() {
session.insecure_stream->close(&session); session.insecure_stream->close(&session);
libp2p_net_multistream_stream_free(session.insecure_stream); libp2p_net_multistream_stream_free(session.insecure_stream);
} }
if (response != NULL) libp2p_stream_message_free(response);
free(response);
if (filtered != NULL) if (filtered != NULL)
free(filtered); free(filtered);

View file

@ -159,17 +159,16 @@ int test_secio_handshake() {
} }
// retrieve the response // retrieve the response
unsigned char* results; struct StreamMessage* results;
size_t results_size; if (libp2p_net_multistream_read(secure_session, &results, 30) == 0) {
if (libp2p_net_multistream_read(secure_session, &results, &results_size, 30) == 0) {
fprintf(stdout, "Unable to read ls results from multistream\n"); fprintf(stdout, "Unable to read ls results from multistream\n");
free(results); free(results);
goto exit; goto exit;
} }
fprintf(stdout, "Results of ls (%d bytes long):\n%s\n", (int)results_size, results); fprintf(stdout, "Results of ls (%d bytes long):\n%s\n", (int)results->data_size, results->data);
free(results); libp2p_stream_message_free(results);
results = NULL; results = NULL;
// try to yamux // try to yamux
char* yamux_string = "/yamux/1.0.0\n"; char* yamux_string = "/yamux/1.0.0\n";
@ -177,14 +176,14 @@ int test_secio_handshake() {
libp2p_logger_error("test_secio", "Unable to send yamux protocol request\n"); libp2p_logger_error("test_secio", "Unable to send yamux protocol request\n");
goto exit; goto exit;
} }
if (!libp2p_net_multistream_read(secure_session, &results, &results_size, 30)) { if (!libp2p_net_multistream_read(secure_session, &results, 30)) {
libp2p_logger_error("test_secio", "Unable to read reply to yamux request.\n"); libp2p_logger_error("test_secio", "Unable to read reply to yamux request.\n");
goto exit; goto exit;
} }
fprintf(stdout, "Results of yamux request: %s\n", results); fprintf(stdout, "Results of yamux request: %s\n", results->data);
free(results); libp2p_stream_message_free(results);
results = NULL; results = NULL;
retVal = 1; retVal = 1;
@ -496,17 +495,16 @@ int test_secio_handshake_go() {
} }
// retrieve the response // retrieve the response
unsigned char* results; struct StreamMessage* results;
size_t results_size; if (libp2p_net_multistream_read(secure_session, &results, 30) == 0) {
if (libp2p_net_multistream_read(secure_session, &results, &results_size, 30) == 0) {
fprintf(stdout, "Unable to read ls results from multistream\n"); fprintf(stdout, "Unable to read ls results from multistream\n");
free(results); free(results);
goto exit; goto exit;
} }
fprintf(stdout, "Results of ls: %.*s", (int)results_size, results); fprintf(stdout, "Results of ls: %.*s", (int)results->data_size, results->data);
free(results); libp2p_stream_message_free(results);
results = NULL; results = NULL;
retVal = 1; retVal = 1;

View file

@ -71,18 +71,22 @@ int yamux_send_protocol(struct SessionContext* context) {
*/ */
int yamux_receive_protocol(struct SessionContext* context) { int yamux_receive_protocol(struct SessionContext* context) {
char* protocol = "/yamux/1.0.0\n"; char* protocol = "/yamux/1.0.0\n";
uint8_t* results = NULL; struct StreamMessage* results = NULL;
size_t results_size = 0; int retVal = 0;
if (!context->default_stream->read(context, &results, &results_size, 30)) {
if (!context->default_stream->read(context, &results, 30)) {
libp2p_logger_error("yamux", "receive_protocol: Unable to read results.\n"); libp2p_logger_error("yamux", "receive_protocol: Unable to read results.\n");
return 0; goto exit;
} }
// the first byte is the size, so skip it // the first byte is the size, so skip it
char* ptr = strstr((char*)&results[1], protocol); char* ptr = strstr((char*)&results->data[1], protocol);
if (ptr == NULL || ptr - (char*)results > 1) { if (ptr == NULL || ptr - (char*)results->data > 1) {
return 0; goto exit;
} }
return 1; retVal = 1;
exit:
libp2p_stream_message_free(results);
return retVal;
} }
/*** /***