summaryrefslogtreecommitdiff
path: root/ecp
diff options
context:
space:
mode:
Diffstat (limited to 'ecp')
-rwxr-xr-xecp/build.sh26
-rw-r--r--ecp/src/Makefile2
-rw-r--r--ecp/src/Makefile.posix2
-rw-r--r--ecp/src/core.c102
-rw-r--r--ecp/src/core.h12
-rw-r--r--ecp/src/dir.c38
-rw-r--r--ecp/src/dir.h15
-rw-r--r--ecp/src/dir_srv.c82
-rw-r--r--ecp/src/dir_srv.h7
-rw-r--r--ecp/src/vconn/vconn.c4
-rw-r--r--ecp/test/Makefile5
-rw-r--r--ecp/test/dir.c100
12 files changed, 354 insertions, 41 deletions
diff --git a/ecp/build.sh b/ecp/build.sh
index 0b205dd..7669db1 100755
--- a/ecp/build.sh
+++ b/ecp/build.sh
@@ -1,8 +1,24 @@
#!/bin/sh
-subdirs="src util test"
-
-for i in $subdirs; do
- (cd $i && make $1 && cd ..) || exit;
-done
+if [ -z $1 ]; then
+ ARG="all"
+else
+ ARG=$1
+fi
+cd src
+make clean
+if [ $ARG == "all" ]; then
+ make || exit
+ make install
+fi
+cd ../util
+make clean
+if [ $ARG == "all" ]; then
+ make || exit
+fi
+cd ../test
+make clean
+if [ $ARG == "all" ]; then
+ make
+fi
diff --git a/ecp/src/Makefile b/ecp/src/Makefile
index 9456a4b..991574a 100644
--- a/ecp/src/Makefile
+++ b/ecp/src/Makefile
@@ -1,7 +1,7 @@
include Makefile.platform
CFLAGS += $(PIC) -I.
-obj = core.o timer.o $(obj_rbuf)
+obj = core.o timer.o dir.o dir_srv.o $(obj_rbuf)
subdirs = crypto platform $(htable) $(vconn)
%.o: %.c
diff --git a/ecp/src/Makefile.posix b/ecp/src/Makefile.posix
index aed4d67..0c7e811 100644
--- a/ecp/src/Makefile.posix
+++ b/ecp/src/Makefile.posix
@@ -4,5 +4,5 @@ htable=htable
vconn=vconn
obj_rbuf=rbuf.o rbuf_send.o rbuf_recv.o msgq.o
-CFLAGS = -O3 -DECP_WITH_PTHREAD=1 -DECP_WITH_HTABLE=1 -DECP_WITH_RBUF=1 -DECP_WITH_MSGQ=1 -DECP_WITH_VCONN=1 -DECP_DEBUG=1
+CFLAGS = -O3 -DECP_WITH_PTHREAD=1 -DECP_WITH_HTABLE=1 -DECP_WITH_RBUF=1 -DECP_WITH_MSGQ=1 -DECP_WITH_VCONN=1 -DECP_WITH_DIRSRV -DECP_DEBUG=1
LDFLAGS = -lm -pthread \ No newline at end of file
diff --git a/ecp/src/core.c b/ecp/src/core.c
index a0f1bdb..23ed87b 100644
--- a/ecp/src/core.c
+++ b/ecp/src/core.c
@@ -204,6 +204,9 @@ int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) {
if (key) sock->key_perma = *key;
sock->handler[ECP_MTYPE_OPEN] = ecp_sock_handle_open;
sock->handler[ECP_MTYPE_KGET] = ecp_sock_handle_kget;
+#ifdef ECP_WITH_DIRSRV
+ sock->handler[ECP_MTYPE_DIR] = ecp_dir_handle_req;
+#endif
rv = ecp_dhkey_gen(sock->ctx, &sock->key[sock->key_curr]);
if (!rv) rv = ctable_create(&sock->conn, sock->ctx);
@@ -454,26 +457,6 @@ static int conn_shsec_set(ECPConnection *conn, unsigned char s_idx, unsigned cha
return ECP_OK;
}
-int ecp_conn_init(ECPConnection *conn, ECPNode *node) {
- ECPDHKey key;
- ECPContext *ctx = conn->sock->ctx;
- int rv;
-
- if (node == NULL) return ECP_ERR;
-
- conn->out = 1;
- conn->node = *node;
- rv = ecp_dhkey_gen(ctx, &key);
- if (!rv) rv = ctx->rng(conn->nonce, ECP_AEAD_SIZE_NONCE);
- if (!rv) rv = ctx->rng(&conn->seq_out, sizeof(conn->seq_out));
-
- if (!rv) rv = conn_dhkey_new_pair(conn, &key);
- if (!rv) rv = conn_dhkey_new_pub_local(conn, conn->key_curr);
- if (!rv) rv = ecp_conn_register(conn);
-
- return rv;
-}
-
int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) {
int i, rv;
@@ -545,11 +528,48 @@ void ecp_conn_unregister(ECPConnection *conn) {
#endif
}
+/* initializes outbound connection */
+int ecp_conn_set_remote(ECPConnection *conn, ECPNode *node) {
+ ECPDHKey key;
+ ECPContext *ctx = conn->sock->ctx;
+ int rv;
+
+ if (node == NULL) return ECP_ERR;
+
+ conn->out = 1;
+ conn->node = *node;
+ rv = ecp_dhkey_gen(ctx, &key);
+ if (!rv) rv = ctx->rng(conn->nonce, ECP_AEAD_SIZE_NONCE);
+ if (!rv) rv = ctx->rng(&conn->seq_out, sizeof(conn->seq_out));
+
+ if (!rv) rv = conn_dhkey_new_pair(conn, &key);
+ if (!rv) rv = conn_dhkey_new_pub_local(conn, conn->key_curr);
+ if (!rv) rv = ecp_conn_register(conn);
+
+ return rv;
+}
+
+int ecp_conn_get_dirlist(ECPConnection *conn, ECPNode *node) {
+ int rv;
+ ssize_t _rv;
+
+ rv = ecp_conn_set_remote(conn, node);
+ if (rv) return rv;
+
+ _rv = ecp_conn_send_dir(conn);
+ if (_rv < 0) {
+ ecp_conn_unregister(conn);
+ return _rv;
+ }
+
+ return ECP_OK;
+}
+
int ecp_conn_open(ECPConnection *conn, ECPNode *node) {
int rv;
ssize_t _rv;
- rv = ecp_conn_init(conn, node);
+ rv = ecp_conn_set_remote(conn, node);
if (rv) return rv;
_rv = ecp_conn_send_kget(conn);
@@ -647,6 +667,9 @@ int ecp_conn_handler_init(ECPConnHandler *handler) {
handler->msg[ECP_MTYPE_OPEN] = ecp_conn_handle_open;
handler->msg[ECP_MTYPE_KGET] = ecp_conn_handle_kget;
handler->msg[ECP_MTYPE_KPUT] = ecp_conn_handle_kput;
+#ifdef ECP_WITH_DIRSRV
+ handler->msg[ECP_MTYPE_DIR] = ecp_dir_handle_update;
+#endif
#ifdef ECP_WITH_RBUF
handler->msg[ECP_MTYPE_RBACK] = ecp_rbuf_handle_ack;
handler->msg[ECP_MTYPE_RBFLUSH] = ecp_rbuf_handle_flush;
@@ -780,6 +803,21 @@ static ssize_t _conn_send_kput(ECPConnection *conn, ECPTimerItem *ti) {
return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ), 0, ti);
}
+static ssize_t _conn_send_dir(ECPConnection *conn, ECPTimerItem *ti) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_DIR_REQ, conn)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_DIR_REQ, conn)];
+
+ packet.buffer = pkt_buf;
+ packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_DIR_REQ, conn);
+ payload.buffer = pld_buf;
+ payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_DIR_REQ, conn);
+
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_DIR_REQ);
+ return _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, NULL, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_DIR_REQ), 0, ti);
+}
+
ssize_t ecp_conn_send_open(ECPConnection *conn) {
return ecp_timer_send(conn, _conn_send_open, ECP_MTYPE_OPEN_REP, 3, 500);
}
@@ -792,6 +830,10 @@ ssize_t ecp_conn_send_kput(ECPConnection *conn) {
return ecp_timer_send(conn, _conn_send_kput, ECP_MTYPE_KPUT_REP, 3, 500);
}
+ssize_t ecp_conn_send_dir(ECPConnection *conn) {
+ return ecp_timer_send(conn, _conn_send_dir, ECP_MTYPE_DIR_REP, 3, 500);
+}
+
ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
int is_open;
@@ -1097,26 +1139,26 @@ int ecp_sock_handle_open(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *paren
}
int ecp_sock_handle_kget(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn) {
- ECPBuffer _packet;
- ECPBuffer _payload;
+ ECPBuffer packet;
+ ECPBuffer payload;
unsigned char pkt_buf[ECP_SIZE_PKT_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent)];
unsigned char pld_buf[ECP_SIZE_PLD_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent)];
unsigned char *buf;
int rv;
ssize_t _rv;
- _packet.buffer = pkt_buf;
- _packet.size = ECP_SIZE_PKT_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent);
- _payload.buffer = pld_buf;
- _payload.size = ECP_SIZE_PLD_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent);
+ packet.buffer = pkt_buf;
+ packet.size = ECP_SIZE_PKT_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent);
+ payload.buffer = pld_buf;
+ payload.size = ECP_SIZE_PLD_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent);
- ecp_pld_set_type(_payload.buffer, _payload.size, ECP_MTYPE_KGET_REP);
- buf = ecp_pld_get_buf(_payload.buffer, _payload.size);
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KGET_REP);
+ buf = ecp_pld_get_buf(payload.buffer, payload.size);
rv = ecp_sock_dhkey_get_curr(sock, buf, buf+1);
if (rv) return rv;
- _rv = ecp_pld_send_tr(sock, addr, parent, &_packet, pkt_meta, &_payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0);
+ _rv = ecp_pld_send_tr(sock, addr, parent, &packet, pkt_meta, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0);
if (_rv < 0) return _rv;
return ECP_OK;
diff --git a/ecp/src/core.h b/ecp/src/core.h
index bb96f26..24ea4ee 100644
--- a/ecp/src/core.h
+++ b/ecp/src/core.h
@@ -86,6 +86,8 @@
#define ECP_MTYPE_KGET_REP (ECP_MTYPE_KGET | ECP_MTYPE_FLAG_REP)
#define ECP_MTYPE_KPUT_REQ (ECP_MTYPE_KPUT)
#define ECP_MTYPE_KPUT_REP (ECP_MTYPE_KPUT | ECP_MTYPE_FLAG_REP)
+#define ECP_MTYPE_DIR_REQ (ECP_MTYPE_DIR)
+#define ECP_MTYPE_DIR_REP (ECP_MTYPE_DIR | ECP_MTYPE_FLAG_REP)
#define ECP_CONN_FLAG_REG 0x01
#define ECP_CONN_FLAG_OPEN 0x02
@@ -143,10 +145,12 @@ struct ECPSocket;
struct ECPConnection;
struct ECPSeqItem;
struct ECPPktMeta;
+struct ECPDirList;
#include "platform/transport.h"
#include "crypto/crypto.h"
#include "timer.h"
+#include "dir_srv.h"
#ifdef ECP_WITH_RBUF
#include "rbuf.h"
@@ -253,6 +257,10 @@ typedef struct ECPContext {
ecp_conn_alloc_t conn_alloc;
ecp_conn_free_t conn_free;
ECPConnHandler *handler[ECP_MAX_CTYPE];
+#ifdef ECP_WITH_DIRSRV
+ struct ECPDirList *dir_online;
+ struct ECPDirList *dir_shadow;
+#endif
} ECPContext;
typedef struct ECPSocket {
@@ -316,12 +324,13 @@ void ecp_sock_close(ECPSocket *sock);
int ecp_sock_dhkey_get_curr(ECPSocket *sock, unsigned char *idx, unsigned char *public);
int ecp_sock_dhkey_new(ECPSocket *sock);
-int ecp_conn_init(ECPConnection *conn, ECPNode *node);
int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype);
void ecp_conn_destroy(ECPConnection *conn);
int ecp_conn_register(ECPConnection *conn);
void ecp_conn_unregister(ECPConnection *conn);
+int ecp_conn_set_remote(ECPConnection *conn, ECPNode *node);
+int ecp_conn_get_dirlist(ECPConnection *conn, ECPNode *node);
int ecp_conn_open(ECPConnection *conn, ECPNode *node);
int ecp_conn_close(ECPConnection *conn, ecp_cts_t timeout);
int ecp_conn_reset(ECPConnection *conn);
@@ -334,6 +343,7 @@ int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned ch
ssize_t ecp_conn_send_open(ECPConnection *conn);
ssize_t ecp_conn_send_kget(ECPConnection *conn);
ssize_t ecp_conn_send_kput(ECPConnection *conn);
+ssize_t ecp_conn_send_dir(ECPConnection *conn);
ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b);
ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b);
diff --git a/ecp/src/dir.c b/ecp/src/dir.c
new file mode 100644
index 0000000..81f564e
--- /dev/null
+++ b/ecp/src/dir.c
@@ -0,0 +1,38 @@
+#include "core.h"
+#include "cr.h"
+
+#include "dir.h"
+
+void ecp_dir_parse_item(unsigned char *buf, ECPDirItem *item) {
+ ecp_cr_dh_pub_from_buf(&item->node.public, buf);
+ buf += ECP_ECDH_SIZE_KEY;
+
+ memcpy(&item->node.addr.host, buf, sizeof(item->node.addr));
+ buf += ECP_IPv4_ADDR_SIZE;
+
+ item->node.addr.port = \
+ (buf[0] << 8) | \
+ (buf[1]);
+ buf += sizeof(uint16_t);
+
+ item->capabilities = \
+ (buf[0] << 8) | \
+ (buf[1]);
+ buf += sizeof(uint16_t);
+}
+
+void ecp_dir_serialize_item(unsigned char *buf, ECPDirItem *item) {
+ ecp_cr_dh_pub_to_buf(buf, &item->node.public);
+ buf += ECP_ECDH_SIZE_KEY;
+
+ memcpy(buf, &item->node.addr.host, sizeof(item->node.addr));
+ buf += ECP_IPv4_ADDR_SIZE;
+
+ buf[0] = (item->node.addr.port & 0xFF00) >> 8;
+ buf[1] = (item->node.addr.port & 0x00FF);
+ buf += sizeof(uint16_t);
+
+ buf[0] = (item->capabilities & 0xFF00) >> 8;
+ buf[1] = (item->capabilities & 0x00FF);
+ buf += sizeof(uint16_t);
+}
diff --git a/ecp/src/dir.h b/ecp/src/dir.h
new file mode 100644
index 0000000..ae8daa9
--- /dev/null
+++ b/ecp/src/dir.h
@@ -0,0 +1,15 @@
+#define ECP_MAX_DIR_ITEM 30
+#define ECP_SIZE_DIR_ITEM 40
+
+typedef struct ECPDirItem {
+ ECPNode node;
+ uint16_t capabilities;
+} ECPDirItem;
+
+typedef struct ECPDirList {
+ ECPDirItem item[ECP_MAX_DIR_ITEM];
+ uint16_t count;
+} ECPDirList;
+
+void ecp_dir_parse_item(unsigned char *buf, ECPDirItem *item);
+void ecp_dir_serialize_item(unsigned char *buf, ECPDirItem *item);
diff --git a/ecp/src/dir_srv.c b/ecp/src/dir_srv.c
new file mode 100644
index 0000000..7513c4a
--- /dev/null
+++ b/ecp/src/dir_srv.c
@@ -0,0 +1,82 @@
+#include "core.h"
+#include "cr.h"
+
+#include "dir.h"
+
+#ifdef ECP_WITH_DIRSRV
+
+int ecp_dir_init(ECPContext *ctx, ECPDirList *dir_online, ECPDirList *dir_shadow) {
+ ctx->dir_online = dir_online;
+ ctx->dir_shadow = dir_shadow;
+
+ return ECP_OK;
+}
+
+int ecp_dir_update(ECPDirList *list, ECPDirItem *item) {
+ int i;
+
+ for (i=0; i<list->count; i++) {
+ if (memcmp(ecp_cr_dh_pub_get_buf(&list->item[i].node.public), ecp_cr_dh_pub_get_buf(&item->node.public), ECP_ECDH_SIZE_KEY) == 0) {
+ return ECP_OK;
+ }
+ }
+
+ if (list->count == ECP_MAX_DIR_ITEM) return ECP_ERR_SIZE;
+
+ list->item[list->count] = *item;
+ list->count++;
+
+ return ECP_OK;
+}
+
+ssize_t ecp_dir_handle_update(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
+ ECPContext *ctx = conn->sock->ctx;
+ ECPDirList *dir_shadow = ctx->dir_shadow;
+ ECPDirItem item;
+ size_t _size;
+
+ _size = size;
+ if (mtype == ECP_MTYPE_DIR_REQ) {
+ int rv;
+
+ while (_size >= ECP_SIZE_DIR_ITEM) {
+ ecp_dir_parse_item(msg, &item);
+
+ rv = ecp_dir_update(dir_shadow, &item);
+ if (rv) return rv;
+
+ msg += ECP_SIZE_DIR_ITEM;
+ _size -= ECP_SIZE_DIR_ITEM;
+ };
+ }
+
+ return size - _size;
+}
+
+int ecp_dir_handle_req(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn) {
+ ECPContext *ctx = sock->ctx;
+ ECPBuffer *packet = bufs->packet;
+ ECPBuffer *payload = bufs->payload;
+ ECPDirList *dir_online = ctx->dir_online;
+ ssize_t rv;
+ int i;
+
+ ecp_pld_set_type(payload->buffer, payload->size, ECP_MTYPE_DIR_REP);
+ msg = ecp_pld_get_buf(payload->buffer, payload->size);
+ msg_size = payload->size - (msg - payload->buffer);
+
+ for (i=0; i<dir_online->count; i++) {
+ if (msg_size < ECP_SIZE_DIR_ITEM) return ECP_ERR_SIZE;
+
+ ecp_dir_serialize_item(msg, &dir_online->item[i]);
+ msg += ECP_SIZE_DIR_ITEM;
+ msg_size -= ECP_SIZE_DIR_ITEM;
+ }
+
+ rv = ecp_pld_send_tr(sock, addr, parent, packet, pkt_meta, payload, ECP_SIZE_PLD(i * ECP_SIZE_DIR_ITEM, ECP_MTYPE_DIR_REP), 0);
+ if (rv < 0) return rv;
+
+ return ECP_OK;
+}
+
+#endif /* ECP_WITH_DIRSRV */ \ No newline at end of file
diff --git a/ecp/src/dir_srv.h b/ecp/src/dir_srv.h
new file mode 100644
index 0000000..cc2ebbe
--- /dev/null
+++ b/ecp/src/dir_srv.h
@@ -0,0 +1,7 @@
+#ifdef ECP_WITH_DIRSRV
+
+int ecp_dir_init(struct ECPContext *ctx, struct ECPDirList *dir_online, struct ECPDirList *dir_shadow);
+ssize_t ecp_dir_handle_update(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b);
+int ecp_dir_handle_req(struct ECPSocket *sock, struct ECPNetAddr *addr, struct ECPConnection *parent, unsigned char *msg, size_t msg_size, struct ECPPktMeta *pkt_meta, struct ECP2Buffer *bufs, struct ECPConnection **_conn);
+
+#endif /* ECP_WITH_DIRSRV */ \ No newline at end of file
diff --git a/ecp/src/vconn/vconn.c b/ecp/src/vconn/vconn.c
index 286a79a..56a2105 100644
--- a/ecp/src/vconn/vconn.c
+++ b/ecp/src/vconn/vconn.c
@@ -609,7 +609,7 @@ int ecp_vconn_init(ECPConnection *conn, ECPNode *conn_node, ECPVConnection vconn
ECPSocket *sock = conn->sock;
int i, rv;
- rv = ecp_conn_init(conn, conn_node);
+ rv = ecp_conn_set_remote(conn, conn_node);
if (rv) return rv;
conn->parent = (ECPConnection *)&vconn[size-1];
@@ -618,7 +618,7 @@ int ecp_vconn_init(ECPConnection *conn, ECPNode *conn_node, ECPVConnection vconn
rv = ecp_conn_create((ECPConnection *)&vconn[i], sock, ECP_CTYPE_VCONN);
if (rv) return rv;
- rv = ecp_conn_init((ECPConnection *)&vconn[i], &vconn_node[i]);
+ rv = ecp_conn_set_remote((ECPConnection *)&vconn[i], &vconn_node[i]);
if (rv) return rv;
if (i == 0) {
diff --git a/ecp/test/Makefile b/ecp/test/Makefile
index 863a3ef..84fdbe1 100644
--- a/ecp/test/Makefile
+++ b/ecp/test/Makefile
@@ -6,11 +6,14 @@ dep=../src/build-posix/*.a ../util/libecputil.a
%.o: %.c
$(CC) $(CFLAGS) -c $<
-all: basic client server echo frag stress vcs vc_server vc_client vc_client_t
+all: basic dir server echo frag stress vcs vc_server vc_client vc_client_t
basic: basic.o init.o $(dep)
$(CC) -o $@ $< init.o $(dep) $(LDFLAGS)
+dir: dir.o init.o $(dep)
+ $(CC) -DWITH_DIR_SERVER -o $@ $< init.o $(dep) $(LDFLAGS)
+
client: client.o init.o $(dep)
$(CC) -o $@ $< init.o $(dep) $(LDFLAGS)
diff --git a/ecp/test/dir.c b/ecp/test/dir.c
new file mode 100644
index 0000000..a4e94a3
--- /dev/null
+++ b/ecp/test/dir.c
@@ -0,0 +1,100 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "core.h"
+#include "cr.h"
+#include "dir.h"
+
+ECPContext ctx_s;
+ECPSocket sock_s;
+ECPDHKey key_perma_s;
+
+ECPContext ctx_c;
+ECPSocket sock_c;
+ECPDHKey key_perma_c;
+ECPConnHandler handler_c;
+
+ECPNode node;
+ECPConnection conn;
+
+static ECPDirList dir_online;
+static ECPDirList dir_shadow;
+
+#define CTYPE_TEST 0
+
+ssize_t handle_dir(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
+ ECPDirItem item;
+ size_t _size;
+
+ _size = size;
+ if (mtype == ECP_MTYPE_DIR_REP) {
+ int rv;
+
+ while (_size >= ECP_SIZE_DIR_ITEM) {
+ ecp_dir_parse_item(msg, &item);
+
+ printf("DIR: %s\n", (char *)ecp_cr_dh_pub_get_buf(&item.node.public));
+
+ msg += ECP_SIZE_DIR_ITEM;
+ _size -= ECP_SIZE_DIR_ITEM;
+ };
+ }
+
+ return size - _size;
+}
+
+int main(int argc, char *argv[]) {
+ int rv;
+
+ dir_online.count = 1;
+ strcpy((char *)ecp_cr_dh_pub_get_buf(&dir_online.item[0].node.public), "PERA");
+
+ rv = ecp_init(&ctx_s);
+ printf("ecp_init RV:%d\n", rv);
+
+ rv = ecp_dir_init(&ctx_s, &dir_online, &dir_shadow);
+ printf("ecp_dir_init RV:%d\n", rv);
+
+ rv = ecp_dhkey_gen(&ctx_s, &key_perma_s);
+ printf("ecp_dhkey_gen RV:%d\n", rv);
+
+ rv = ecp_sock_create(&sock_s, &ctx_s, &key_perma_s);
+ printf("ecp_sock_create RV:%d\n", rv);
+
+ rv = ecp_sock_open(&sock_s, "0.0.0.0:3000");
+ printf("ecp_sock_open RV:%d\n", rv);
+
+ rv = ecp_start_receiver(&sock_s);
+ printf("ecp_start_receiver RV:%d\n", rv);
+
+ rv = ecp_init(&ctx_c);
+ printf("ecp_init RV:%d\n", rv);
+
+ rv = ecp_conn_handler_init(&handler_c);
+ handler_c.msg[ECP_MTYPE_DIR] = handle_dir;
+ ctx_c.handler[CTYPE_TEST] = &handler_c;
+
+ rv = ecp_dhkey_gen(&ctx_c, &key_perma_c);
+ printf("ecp_dhkey_gen RV:%d\n", rv);
+
+ rv = ecp_sock_create(&sock_c, &ctx_c, &key_perma_c);
+ printf("ecp_sock_create RV:%d\n", rv);
+
+ rv = ecp_sock_open(&sock_c, NULL);
+ printf("ecp_sock_open RV:%d\n", rv);
+
+ rv = ecp_start_receiver(&sock_c);
+ printf("ecp_start_receiver RV:%d\n", rv);
+
+ rv = ecp_node_init(&node, &key_perma_s.public, "127.0.0.1:3000");
+ printf("ecp_node_init RV:%d\n", rv);
+
+ rv = ecp_conn_create(&conn, &sock_c, CTYPE_TEST);
+ printf("ecp_conn_create RV:%d\n", rv);
+
+ rv = ecp_conn_get_dirlist(&conn, &node);
+ printf("ecp_conn_get_dirlist RV:%d\n", rv);
+
+ while (1) sleep(1);
+} \ No newline at end of file