Changes to Identity protocol

master
John Jones 2017-11-30 15:27:28 -05:00
parent e67d626000
commit 4218876198
3 changed files with 68 additions and 40 deletions

View File

@ -11,6 +11,8 @@
#include "libp2p/identify/identify.h" #include "libp2p/identify/identify.h"
#include "libp2p/utils/logger.h" #include "libp2p/utils/logger.h"
/** /**
* Determines if this protocol can handle the incoming message * Determines if this protocol can handle the incoming message
* @param incoming the incoming data * @param incoming the incoming data
@ -39,11 +41,20 @@ int libp2p_identify_can_handle(const struct StreamMessage* msg) {
* @param context the context * @param context the context
* @returns true(1) on success, false(0) otherwise * @returns true(1) on success, false(0) otherwise
*/ */
int libp2p_identify_send_protocol(struct Stream *stream) { int libp2p_identify_send_protocol(struct Stream *stream, Identify* identify) {
size_t max_buffer_size = 6000;
uint8_t buffer[max_buffer_size];
char *protocol = "/ipfs/id/1.0.0\n"; char *protocol = "/ipfs/id/1.0.0\n";
int protocol_len = strlen(protocol);
// throw the protocol into the buffer
memcpy(&buffer[0], protocol, protocol_len);
if (!libp2p_identify_protobuf_encode(identify, &buffer[protocol_len], max_buffer_size-protocol_len, &max_buffer_size)) {
libp2p_logger_error("identify", "Unable to protobuf the identity.\n");
return 0;
}
struct StreamMessage msg; struct StreamMessage msg;
msg.data = (uint8_t*) protocol; msg.data_size = protocol_len + max_buffer_size;
msg.data_size = strlen(protocol); msg.data = buffer;
if (!stream->write(stream->stream_context, &msg)) { if (!stream->write(stream->stream_context, &msg)) {
libp2p_logger_error("identify", "send_protocol: Unable to send identify protocol header.\n"); libp2p_logger_error("identify", "send_protocol: Unable to send identify protocol header.\n");
return 0; return 0;
@ -175,39 +186,51 @@ int libp2p_identify_protobuf_encode(const Identify* in, unsigned char* buffer, s
int i, retVal = 0; int i, retVal = 0;
// field 1 // field 1
retVal = protobuf_encode_string(1, WIRETYPE_LENGTH_DELIMITED, in->PublicKey, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used); if (in->PublicKey != NULL) {
if (retVal == 0) retVal = protobuf_encode_length_delimited(1, WIRETYPE_LENGTH_DELIMITED, in->PublicKey, in->PublicKeyLength, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
return 0;
*bytes_written += bytes_used;
// field 2
for (i = 0 ; in->ListenAddrs[i] ; i++) {
retVal = protobuf_encode_string(2, WIRETYPE_LENGTH_DELIMITED, in->ListenAddrs[i], &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
if (retVal == 0) if (retVal == 0)
return 0; return 0;
*bytes_written += bytes_used; *bytes_written += bytes_used;
} }
// field 2
if (in->ListenAddrs != NULL) {
for (i = 0 ; in->ListenAddrs[i] ; i++) {
retVal = protobuf_encode_string(2, WIRETYPE_LENGTH_DELIMITED, in->ListenAddrs[i], &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
if (retVal == 0)
return 0;
*bytes_written += bytes_used;
}
}
// field 3 // field 3
for (i = 0 ; in->Protocols[i] ; i++) { if (in->Protocols != NULL) {
retVal = protobuf_encode_string(3, WIRETYPE_LENGTH_DELIMITED, in->Protocols[i], &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used); for (i = 0 ; in->Protocols[i] ; i++) {
retVal = protobuf_encode_string(3, WIRETYPE_LENGTH_DELIMITED, in->Protocols[i], &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
if (retVal == 0)
return 0;
*bytes_written += bytes_used;
}
}
// field 4
if (in->ObservedAddr != NULL) {
retVal = protobuf_encode_string(4, WIRETYPE_LENGTH_DELIMITED, in->ObservedAddr, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
if (retVal == 0) if (retVal == 0)
return 0; return 0;
*bytes_written += bytes_used; *bytes_written += bytes_used;
} }
// field 4
retVal = protobuf_encode_string(4, WIRETYPE_LENGTH_DELIMITED, in->ObservedAddr, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
if (retVal == 0)
return 0;
*bytes_written += bytes_used;
// field 5 // field 5
retVal = protobuf_encode_string(5, WIRETYPE_LENGTH_DELIMITED, in->ProtocolVersion, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used); if (in->ProtocolVersion != NULL) {
if (retVal == 0) retVal = protobuf_encode_string(5, WIRETYPE_LENGTH_DELIMITED, in->ProtocolVersion, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
return 0; if (retVal == 0)
*bytes_written += bytes_used; return 0;
*bytes_written += bytes_used;
}
// field 6 // field 6
retVal = protobuf_encode_string(6, WIRETYPE_LENGTH_DELIMITED, in->AgentVersion, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used); if (in->AgentVersion != NULL) {
if (retVal == 0) retVal = protobuf_encode_string(6, WIRETYPE_LENGTH_DELIMITED, in->AgentVersion, &buffer[*bytes_written], max_buffer_size - *bytes_written, &bytes_used);
return 0; if (retVal == 0)
*bytes_written += bytes_used; return 0;
*bytes_written += bytes_used;
}
return 1; return 1;
} }
@ -310,7 +333,8 @@ exit:
int libp2p_identify_handle_message(const struct StreamMessage* msg, struct Stream* stream, void* protocol_context) { int libp2p_identify_handle_message(const struct StreamMessage* msg, struct Stream* stream, void* protocol_context) {
// attempt to create a new Identify connection with them. // attempt to create a new Identify connection with them.
// send the protocol id back, and set up the channel // send the protocol id back, and set up the channel
struct Stream* new_stream = libp2p_identify_stream_new(stream); Identify* identify = (Identify*)protocol_context;
struct Stream* new_stream = libp2p_identify_stream_new(stream, identify);
if (new_stream == NULL) if (new_stream == NULL)
return -1; return -1;
return stream->handle_upgrade(stream, new_stream); return stream->handle_upgrade(stream, new_stream);
@ -328,10 +352,13 @@ int libp2p_identify_shutdown(void* protocol_context) {
return 1; return 1;
} }
struct Libp2pProtocolHandler* libp2p_identify_build_protocol_handler(struct Libp2pVector* handlers) { struct Libp2pProtocolHandler* libp2p_identify_build_protocol_handler(char* public_key, int public_key_length) {
struct Libp2pProtocolHandler* handler = libp2p_protocol_handler_new(); struct Libp2pProtocolHandler* handler = libp2p_protocol_handler_new();
if (handler != NULL) { if (handler != NULL) {
handler->context = NULL; Identify* identify = libp2p_identify_new();
identify->PublicKey = public_key;
identify->PublicKeyLength = public_key_length;
handler->context = identify;
handler->CanHandle = libp2p_identify_can_handle; handler->CanHandle = libp2p_identify_can_handle;
handler->HandleMessage = libp2p_identify_handle_message; handler->HandleMessage = libp2p_identify_handle_message;
handler->Shutdown = libp2p_identify_shutdown; handler->Shutdown = libp2p_identify_shutdown;
@ -360,7 +387,7 @@ int libp2p_identify_close(struct Stream* stream) {
* @param parent_stream the parent stream * @param parent_stream the parent stream
* @returns a new Stream that can talk "identify" * @returns a new Stream that can talk "identify"
*/ */
struct Stream* libp2p_identify_stream_new(struct Stream* parent_stream) { struct Stream* libp2p_identify_stream_new(struct Stream* parent_stream, Identify* identify) {
if (parent_stream == NULL) if (parent_stream == NULL)
return NULL; return NULL;
struct Stream* out = libp2p_stream_new(); struct Stream* out = libp2p_stream_new();
@ -375,10 +402,10 @@ struct Stream* libp2p_identify_stream_new(struct Stream* parent_stream) {
ctx->stream = out; ctx->stream = out;
out->stream_context = ctx; out->stream_context = ctx;
out->close = libp2p_identify_close; out->close = libp2p_identify_close;
out->negotiate = libp2p_identify_stream_new; out->negotiate = NULL;
out->bytes_waiting = NULL; out->bytes_waiting = NULL;
// do we expect a reply? // do we expect a reply?
if (!libp2p_identify_send_protocol(parent_stream) /* || !libp2p_identify_receive_protocol(parent_stream) */) { if (!libp2p_identify_send_protocol(parent_stream, identify) /* || !libp2p_identify_receive_protocol(parent_stream) */) {
libp2p_stream_free(out); libp2p_stream_free(out);
free(ctx); free(ctx);
return NULL; return NULL;
@ -415,8 +442,8 @@ struct Stream* libp2p_identify_stream_new_with_multistream(struct Stream* parent
ctx->stream = out; ctx->stream = out;
out->stream_context = ctx; out->stream_context = ctx;
out->close = libp2p_identify_close; out->close = libp2p_identify_close;
out->negotiate = libp2p_identify_stream_new_with_multistream; out->negotiate = NULL;
if (!libp2p_identify_send_protocol(parent_stream) || !libp2p_identify_receive_protocol(parent_stream)) { if (!libp2p_identify_send_protocol(parent_stream, NULL) || !libp2p_identify_receive_protocol(parent_stream)) {
libp2p_stream_free(out); libp2p_stream_free(out);
free(ctx); free(ctx);
return NULL; return NULL;

View File

@ -10,6 +10,7 @@ typedef struct {
// - may not need to be sent, as secure channel implies it has been sent. // - may not need to be sent, as secure channel implies it has been sent.
// - then again, if we change / disable secure channel, may still want it. // - then again, if we change / disable secure channel, may still want it.
char *PublicKey; char *PublicKey;
int PublicKeyLength;
// listenAddrs are the multiaddrs the sender node listens for open connections on // listenAddrs are the multiaddrs the sender node listens for open connections on
char **ListenAddrs; char **ListenAddrs;
// protocols are the services this node is running // protocols are the services this node is running
@ -32,7 +33,7 @@ struct IdentifyContext {
}; };
int libp2p_identify_can_handle(const struct StreamMessage* msg); int libp2p_identify_can_handle(const struct StreamMessage* msg);
int libp2p_identify_send_protocol(struct Stream* stream); int libp2p_identify_send_protocol(struct Stream* stream, Identify* identify);
int libp2p_identify_receive_protocol(struct Stream* stream); int libp2p_identify_receive_protocol(struct Stream* stream);
Identify* libp2p_identify_new(); Identify* libp2p_identify_new();
void libp2p_identify_free(Identify* in); void libp2p_identify_free(Identify* in);
@ -42,7 +43,7 @@ int libp2p_identify_protobuf_encode(const Identify* in, unsigned char* buffer, s
int libp2p_identify_protobuf_decode(const unsigned char* in, size_t in_size, Identify** out); int libp2p_identify_protobuf_decode(const unsigned char* in, size_t in_size, Identify** out);
int libp2p_identify_handle_message(const struct StreamMessage* msg, struct Stream* stream, void* protocol_context); int libp2p_identify_handle_message(const struct StreamMessage* msg, struct Stream* stream, void* protocol_context);
int libp2p_identify_shutdown(void* protocol_context); int libp2p_identify_shutdown(void* protocol_context);
struct Libp2pProtocolHandler* libp2p_identify_build_protocol_handler(struct Libp2pVector* handlers); struct Libp2pProtocolHandler* libp2p_identify_build_protocol_handler(char* public_key, int publicKeyLength);
/*** /***
* Create a new stream that negotiates the identify protocol * Create a new stream that negotiates the identify protocol
@ -54,5 +55,5 @@ struct Libp2pProtocolHandler* libp2p_identify_build_protocol_handler(struct Libp
* @param parent_stream the parent stream * @param parent_stream the parent stream
* @returns a new Stream that can talk "identify" * @returns a new Stream that can talk "identify"
*/ */
struct Stream* libp2p_identify_stream_new(struct Stream* parent_stream); struct Stream* libp2p_identify_stream_new(struct Stream* parent_stream, Identify* identify);

View File

@ -132,7 +132,7 @@ int test_yamux_identify() {
mock_stream->read = mock_yamux_read_protocol; mock_stream->read = mock_yamux_read_protocol;
// protocol handlers // protocol handlers
struct Libp2pVector* protocol_handlers = libp2p_utils_vector_new(1); struct Libp2pVector* protocol_handlers = libp2p_utils_vector_new(1);
struct Libp2pProtocolHandler* handler = libp2p_identify_build_protocol_handler(protocol_handlers); struct Libp2pProtocolHandler* handler = libp2p_identify_build_protocol_handler("ABC", 3);
libp2p_utils_vector_add(protocol_handlers, handler); libp2p_utils_vector_add(protocol_handlers, handler);
// yamux // yamux
struct Stream* yamux_stream = libp2p_yamux_stream_new(mock_stream, 0, protocol_handlers); struct Stream* yamux_stream = libp2p_yamux_stream_new(mock_stream, 0, protocol_handlers);
@ -140,7 +140,7 @@ int test_yamux_identify() {
goto exit; goto exit;
// Now add in another protocol // Now add in another protocol
mock_stream->read = mock_identify_read_protocol; mock_stream->read = mock_identify_read_protocol;
if (!libp2p_yamux_stream_add(yamux_stream->stream_context, libp2p_identify_stream_new(yamux_stream))) { if (!libp2p_yamux_stream_add(yamux_stream->stream_context, libp2p_identify_stream_new(yamux_stream, handler->context))) {
goto exit; goto exit;
} }
// tear down // tear down
@ -199,7 +199,7 @@ int test_yamux_incoming_protocol_request() {
// setup // setup
// build the protocol handler that can handle yamux, multistream, and identify protocol // build the protocol handler that can handle yamux, multistream, and identify protocol
struct Libp2pVector* protocol_handlers = libp2p_utils_vector_new(1); struct Libp2pVector* protocol_handlers = libp2p_utils_vector_new(1);
struct Libp2pProtocolHandler* handler = libp2p_identify_build_protocol_handler(protocol_handlers); struct Libp2pProtocolHandler* handler = libp2p_identify_build_protocol_handler("ABC", 3);
libp2p_utils_vector_add(protocol_handlers, handler); libp2p_utils_vector_add(protocol_handlers, handler);
handler = libp2p_yamux_build_protocol_handler(protocol_handlers); handler = libp2p_yamux_build_protocol_handler(protocol_handlers);
libp2p_utils_vector_add(protocol_handlers, handler); libp2p_utils_vector_add(protocol_handlers, handler);
@ -273,7 +273,7 @@ int test_yamux_identity_frame() {
// setup // setup
// build the protocol handler that can handle yamux and identify protocol // build the protocol handler that can handle yamux and identify protocol
struct Libp2pVector* protocol_handlers = libp2p_utils_vector_new(1); struct Libp2pVector* protocol_handlers = libp2p_utils_vector_new(1);
struct Libp2pProtocolHandler* handler = libp2p_identify_build_protocol_handler(protocol_handlers); struct Libp2pProtocolHandler* handler = libp2p_identify_build_protocol_handler("ABC", 3);
libp2p_utils_vector_add(protocol_handlers, handler); libp2p_utils_vector_add(protocol_handlers, handler);
handler = libp2p_yamux_build_protocol_handler(protocol_handlers); handler = libp2p_yamux_build_protocol_handler(protocol_handlers);
libp2p_utils_vector_add(protocol_handlers, handler); libp2p_utils_vector_add(protocol_handlers, handler);