Initial implementation of the identify protocol.
This commit is contained in:
parent
9200e0f09c
commit
a91e840770
4 changed files with 144 additions and 0 deletions
3
Makefile
3
Makefile
|
@ -11,6 +11,7 @@ OBJS = \
|
||||||
db/*.o \
|
db/*.o \
|
||||||
thirdparty/mbedtls/*.o \
|
thirdparty/mbedtls/*.o \
|
||||||
hashmap/hashmap.o \
|
hashmap/hashmap.o \
|
||||||
|
identify/*.o \
|
||||||
net/*.o \
|
net/*.o \
|
||||||
os/*.o \
|
os/*.o \
|
||||||
peer/*.o \
|
peer/*.o \
|
||||||
|
@ -29,6 +30,7 @@ compile:
|
||||||
cd db; make all;
|
cd db; make all;
|
||||||
cd thirdparty; make all;
|
cd thirdparty; make all;
|
||||||
cd hashmap; make all;
|
cd hashmap; make all;
|
||||||
|
cd identify; make all;
|
||||||
cd net; make all;
|
cd net; make all;
|
||||||
cd os; make all;
|
cd os; make all;
|
||||||
cd peer; make all;
|
cd peer; make all;
|
||||||
|
@ -50,6 +52,7 @@ clean:
|
||||||
cd crypto; make clean;
|
cd crypto; make clean;
|
||||||
cd db; make clean;
|
cd db; make clean;
|
||||||
cd hashmap; make clean;
|
cd hashmap; make clean;
|
||||||
|
cd identify; make clean;
|
||||||
cd net; make clean;
|
cd net; make clean;
|
||||||
cd os; make clean;
|
cd os; make clean;
|
||||||
cd peer; make clean;
|
cd peer; make clean;
|
||||||
|
|
18
identify/Makefile
Normal file
18
identify/Makefile
Normal 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
94
identify/identify.c
Normal 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;
|
||||||
|
}
|
29
include/libp2p/identify/identify.h
Normal file
29
include/libp2p/identify/identify.h
Normal 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);
|
Loading…
Reference in a new issue