diff options
Diffstat (limited to 'ecp/src')
-rw-r--r-- | ecp/src/Makefile | 2 | ||||
-rw-r--r-- | ecp/src/Makefile.posix | 2 | ||||
-rw-r--r-- | ecp/src/core.c | 102 | ||||
-rw-r--r-- | ecp/src/core.h | 12 | ||||
-rw-r--r-- | ecp/src/dir.c | 38 | ||||
-rw-r--r-- | ecp/src/dir.h | 15 | ||||
-rw-r--r-- | ecp/src/dir_srv.c | 82 | ||||
-rw-r--r-- | ecp/src/dir_srv.h | 7 | ||||
-rw-r--r-- | ecp/src/vconn/vconn.c | 4 |
9 files changed, 229 insertions, 35 deletions
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) { |