Initial implementation of the identify protocol.

This commit is contained in:
Jose Marcial Vieira Bisneto 2017-11-03 03:26:43 -03:00
parent 9200e0f09c
commit a91e840770
No known key found for this signature in database
GPG key ID: 103E935E7E6E831E
4 changed files with 144 additions and 0 deletions

View file

@ -11,6 +11,7 @@ OBJS = \
db/*.o \
thirdparty/mbedtls/*.o \
hashmap/hashmap.o \
identify/*.o \
net/*.o \
os/*.o \
peer/*.o \
@ -29,6 +30,7 @@ compile:
cd db; make all;
cd thirdparty; make all;
cd hashmap; make all;
cd identify; make all;
cd net; make all;
cd os; make all;
cd peer; make all;
@ -50,6 +52,7 @@ clean:
cd crypto; make clean;
cd db; make clean;
cd hashmap; make clean;
cd identify; make clean;
cd net; make clean;
cd os; make clean;
cd peer; make clean;

18
identify/Makefile Normal file
View file

@ -0,0 +1,18 @@
CC = gcc
CFLAGS = -O0 -Wall -Werror -I../include -I../../c-protobuf -std=c11
ifdef DEBUG
CFLAGS += -g3
endif
LFLAGS =
DEPS =
OBJS = identify.o
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)
all: $(OBJS)
clean:
rm -f *.o

94
identify/identify.c Normal file
View file

@ -0,0 +1,94 @@
#include <string.h>
#include "varint.h"
#include "libp2p/net/protocol.h"
#include "libp2p/net/protocol.h"
#include "libp2p/utils/vector.h"
#include "libp2p/net/stream.h"
#include "libp2p/conn/session.h"
#include "libp2p/identify/identify.h"
#include "libp2p/utils/logger.h"
/**
* Determines if this protocol can handle the incoming message
* @param incoming the incoming data
* @param incoming_size the size of the incoming data buffer
* @returns true(1) if it can handle this message, false(0) if not
*/
int libp2p_identify_can_handle(const struct StreamMessage* msg) {
const char *protocol = "/ipfs/id/1.0.0\n";
int protocol_size = strlen(protocol);
// is there a varint in front?
size_t num_bytes = 0;
if (msg->data[0] != protocol[0] && msg->data[1] != protocol[1]) {
varint_decode(msg->data, msg->data_size, &num_bytes);
}
if (msg->data_size >= protocol_size - num_bytes) {
if (strncmp(protocol, (char*) &msg->data[num_bytes], protocol_size) == 0)
return 1;
}
return 0;
}
/***
* Send the identify header out the default stream
* @param context the context
* @returns true(1) on success, false(0) otherwise
*/
int libp2p_identify_send_protocol(struct SessionContext *context) {
char *protocol = "/ipfs/id/1.0.0\n";
struct StreamMessage msg;
msg.data = (uint8_t*) protocol;
msg.data_size = strlen(protocol);
if (!context->default_stream->write(context, &msg)) {
libp2p_logger_error("identify", "send_protocol: Unable to send identify protocol header.\n");
return 0;
}
return 1;
}
/***
* Check to see if the reply is the identify header we expect
* NOTE: if we initiate the connection, we should expect the same back
* @param context the SessionContext
* @returns true(1) on success, false(0) otherwise
*/
int libp2p_identify_receive_protocol(struct SessionContext* context) {
const char *protocol = "/ipfs/id/1.0.0\n";
struct StreamMessage* results = NULL;
if (!context->default_stream->read(context, &results, 30)) {
libp2p_logger_error("identify", "receive_protocol: Unable to read results.\n");
return 0;
}
// the first byte is the size, so skip it
char* ptr = strstr((char*)&results[1], protocol);
if (ptr == NULL || ptr - (char*)results > 1) {
return 0;
}
return 1;
}
int libp2p_identify_handle_message(const struct StreamMessage* msg, struct SessionContext* context, void* protocol_context) {
//TODO: Implement
return 0;
}
/**
* Shutting down. Clean up any memory allocations
* @param protocol_context the context
* @returns true(1)
*/
int libp2p_identify_shutdown(void* protocol_context) {
return 0;
}
struct Libp2pProtocolHandler* libp2p_identify_build_protocol_handler(struct Libp2pVector* handlers) {
struct Libp2pProtocolHandler* handler = libp2p_protocol_handler_new();
if (handler != NULL) {
handler->context = handlers;
handler->CanHandle = libp2p_identify_can_handle;
handler->HandleMessage = libp2p_identify_handle_message;
handler->Shutdown = libp2p_identify_shutdown;
}
return handler;
}

View file

@ -0,0 +1,29 @@
#pragma once
typedef struct {
// publicKey is this node's public key (which also gives its node.ID)
// - 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.
char *PublicKey;
// listenAddrs are the multiaddrs the sender node listens for open connections on
char **ListenAddrs;
// protocols are the services this node is running
char **Protocols;
// oservedAddr is the multiaddr of the remote endpoint that the sender node perceives
// this is useful information to convey to the other side, as it helps the remote endpoint
// determine whether its connection to the local peer goes through NAT.
char *ObservedAddr;
// protocolVersion determines compatibility between peers
char *ProtocolVersion;
// agentVersion is like a UserAgent string in browsers, or client version in bittorrent
// includes the client name and client.
char *AgentVersion;
char *XXX_unrecognized;
} Identify;
int libp2p_identify_can_handle(const struct StreamMessage* msg);
int libp2p_identify_send_protocol(struct SessionContext *context);
int libp2p_identify_receive_protocol(struct SessionContext* context);
int libp2p_identify_handle_message(const struct StreamMessage* msg, struct SessionContext* context, void* protocol_context);
int libp2p_identify_shutdown(void* protocol_context);
struct Libp2pProtocolHandler* libp2p_identify_build_protocol_handler(struct Libp2pVector* handlers);