summaryrefslogtreecommitdiff
path: root/ecp
diff options
context:
space:
mode:
Diffstat (limited to 'ecp')
-rw-r--r--ecp/server/Makefile16
-rw-r--r--ecp/server/dir.c551
-rw-r--r--ecp/server/dir.h35
-rw-r--r--ecp/server/ht.c34
-rw-r--r--ecp/server/ht.h7
-rw-r--r--ecp/server/server.c204
-rw-r--r--ecp/server/server.h15
-rw-r--r--ecp/server/vlink.c321
-rw-r--r--ecp/server/vlink.h17
-rw-r--r--ecp/src/ecp/common.mk21
-rw-r--r--ecp/src/ecp/core.c963
-rw-r--r--ecp/src/ecp/core.h149
-rw-r--r--ecp/src/ecp/crypto/crypto.c4
-rw-r--r--ecp/src/ecp/dir/Makefile4
-rw-r--r--ecp/src/ecp/dir/dir.c157
-rw-r--r--ecp/src/ecp/dir/dir.h26
-rw-r--r--ecp/src/ecp/dir/dir_srv.c143
-rw-r--r--ecp/src/ecp/dir/dir_srv.h23
-rw-r--r--ecp/src/ecp/ext.h25
-rw-r--r--ecp/src/ecp/ext/Makefile14
-rw-r--r--ecp/src/ecp/ext/frag.c126
-rw-r--r--ecp/src/ecp/ext/frag.h7
-rw-r--r--ecp/src/ecp/ext/msgq.c19
-rw-r--r--ecp/src/ecp/ext/msgq.h3
-rw-r--r--ecp/src/ecp/ext/rbuf.c52
-rw-r--r--ecp/src/ecp/ext/rbuf.h16
-rw-r--r--ecp/src/ecp/ext/rbuf_ext.c (renamed from ecp/src/ecp/ext/ext.c)46
-rw-r--r--ecp/src/ecp/ext/rbuf_recv.c33
-rw-r--r--ecp/src/ecp/ext/rbuf_send.c17
-rw-r--r--ecp/src/ecp/ht.h11
-rwxr-xr-xecp/src/ecp/htable/hashtable.c61
-rwxr-xr-xecp/src/ecp/htable/hashtable.h9
-rw-r--r--ecp/src/ecp/htable/htable.c30
-rw-r--r--ecp/src/ecp/timer.c6
-rw-r--r--ecp/src/ecp/tm.h3
-rw-r--r--ecp/src/ecp/tr.h2
-rw-r--r--ecp/src/ecp/vconn/vconn.c337
-rw-r--r--ecp/src/ecp/vconn/vconn.h36
-rw-r--r--ecp/src/platform/fe310/time.c10
-rw-r--r--ecp/src/platform/fe310/transport.c6
-rw-r--r--ecp/src/platform/posix/features.mk3
-rw-r--r--ecp/src/platform/posix/time.c11
-rw-r--r--ecp/src/platform/posix/transport.c17
-rw-r--r--ecp/test/Makefile14
-rw-r--r--ecp/test/basic.c23
-rw-r--r--ecp/test/client.c15
-rw-r--r--ecp/test/init.c19
-rw-r--r--ecp/test/init.h1
-rw-r--r--ecp/test/init_vconn.c55
-rw-r--r--ecp/test/init_vconn.h1
-rw-r--r--ecp/test/server.c12
-rw-r--r--ecp/test/stress.c256
-rw-r--r--ecp/test/vc_client.c37
-rw-r--r--ecp/test/vc_client_t.c118
-rw-r--r--ecp/test/vc_common.c127
-rw-r--r--ecp/test/vc_common.h2
-rw-r--r--ecp/test/vc_inb.c124
-rw-r--r--ecp/test/vc_outb.c128
-rw-r--r--ecp/test/vc_server.c44
-rw-r--r--ecp/test/vcs.c25
-rw-r--r--ecp/util/mknode.c9
-rw-r--r--ecp/util/util.c2
62 files changed, 2945 insertions, 1657 deletions
diff --git a/ecp/server/Makefile b/ecp/server/Makefile
new file mode 100644
index 0000000..2105e9f
--- /dev/null
+++ b/ecp/server/Makefile
@@ -0,0 +1,16 @@
+src_dir = ../src
+include $(src_dir)/ecp/common.mk
+CFLAGS += -Wno-int-to-void-pointer-cast
+
+obj = server.o dir.o vlink.o ht.o
+dep = ../build-posix/*.a
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $<
+
+ecp_server: $(obj)
+ $(CC) -o $@ $(obj) $(dep) $(LDFLAGS)
+
+clean:
+ rm -f *.o
+ rm -f ecp_server
diff --git a/ecp/server/dir.c b/ecp/server/dir.c
new file mode 100644
index 0000000..0066bac
--- /dev/null
+++ b/ecp/server/dir.c
@@ -0,0 +1,551 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <ecp/core.h>
+#include <ecp/dir/dir.h>
+#include <ecp/ht.h>
+#include <ecp/tm.h>
+
+#include "server.h"
+#include "vlink.h"
+#include "dir.h"
+#include "ht.h"
+
+static ecp_ht_table_t *dir_shadow = NULL;
+static pthread_rwlock_t dir_shadow_rwlock;
+static pthread_rwlock_t dir_online_rwlock;
+static pthread_t dir_announce_thd;
+
+static DirList dir_online;
+
+static SRVConfig *srv_config;
+
+ssize_t dir_send_ann(ECPConnection *conn) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF(sizeof(uint16_t), ECP_MTYPE_DIR_ANN, conn)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(sizeof(uint16_t), ECP_MTYPE_DIR_ANN, conn)];
+ unsigned char *msg;
+
+ packet.buffer = pkt_buf;
+ packet.size = sizeof(pkt_buf);
+ payload.buffer = pld_buf;
+ payload.size = sizeof(pld_buf);
+
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_DIR_ANN);
+ msg = ecp_pld_get_msg(payload.buffer, payload.size);
+ msg[0] = srv_config->capabilities >> 8;
+ msg[1] = srv_config->capabilities;
+
+ return ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(sizeof(uint16_t), ECP_MTYPE_DIR_ANN), 0);
+}
+
+ssize_t dir_send_shadow(ECPConnection *conn) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_MAX_PKT];
+ unsigned char pld_buf[ECP_MAX_PLD];
+ unsigned char *msg;
+
+ struct hashtable_itr itr;
+ DirNode *node;
+ uint16_t count;
+ ecp_sts_t access_ts;
+ size_t msg_size;
+
+ packet.buffer = pkt_buf;
+ packet.size = ECP_MAX_PKT;
+ payload.buffer = pld_buf;
+ payload.size = ECP_MAX_PLD;
+
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_DIR_SHADOW);
+ msg = ecp_pld_get_msg(payload.buffer, payload.size);
+ msg_size = 0;
+
+ pthread_rwlock_rdlock(&dir_shadow_rwlock);
+
+ count = ecp_ht_count(dir_shadow);
+ msg[0] = count >> 8;
+ msg[1] = count;
+ msg += sizeof(uint16_t);
+ msg_size += sizeof(uint16_t);
+
+ if (count > 0) {
+ size_t rv;
+ int _rv;
+
+ ecp_ht_itr_create(&itr, dir_shadow);
+ do {
+ node = ecp_ht_itr_value(&itr);
+
+ pthread_mutex_lock(&node->mutex);
+ access_ts = node->access_ts;
+ pthread_mutex_unlock(&node->mutex);
+
+ rv = ecp_dir_item_serialize(&node->dir_item, msg);
+ msg += rv;
+ msg_size += rv;
+
+ msg[0] = access_ts >> 24;
+ msg[1] = access_ts >> 16;
+ msg[2] = access_ts >> 8;
+ msg[3] = access_ts;
+ msg += sizeof(uint32_t);
+ msg_size += sizeof(uint32_t);
+
+ _rv = ecp_ht_itr_advance(&itr);
+ } while (_rv == ECP_OK);
+ }
+
+ pthread_rwlock_unlock(&dir_shadow_rwlock);
+
+ return ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(msg_size, ECP_MTYPE_DIR_SHADOW), 0);
+}
+
+ssize_t dir_send_online(ECPConnection *conn) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_MAX_PKT];
+ unsigned char pld_buf[ECP_MAX_PLD];
+ unsigned char *msg;
+ size_t msg_size;
+
+ packet.buffer = pkt_buf;
+ packet.size = ECP_MAX_PKT;
+ payload.buffer = pld_buf;
+ payload.size = ECP_MAX_PLD;
+
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_DIR_REP);
+ msg = ecp_pld_get_msg(payload.buffer, payload.size);
+
+ pthread_rwlock_rdlock(&dir_online_rwlock);
+
+ msg[0] = dir_online.count >> 8;
+ msg[1] = dir_online.count;
+ msg += sizeof(uint16_t);
+ msg_size = sizeof(uint16_t) + dir_online.count * ECP_SIZE_DIR_ITEM;
+ memcpy(msg, dir_online.msg, dir_online.count * ECP_SIZE_DIR_ITEM);
+
+ pthread_rwlock_unlock(&dir_online_rwlock);
+
+ return ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(msg_size, ECP_MTYPE_DIR_REP), 0);
+}
+
+ssize_t dir_handle_ann(ECPConnection *conn, unsigned char *msg, size_t msg_size) {
+ ECPDirItem dir_item;
+ int is_new;
+ uint16_t capabilities;
+ ecp_sts_t now;
+ ssize_t rsize;
+ ssize_t rv;
+
+ rsize = sizeof(uint16_t);
+ if (msg_size < rsize) return ECP_ERR_SIZE;
+
+ capabilities = \
+ ((uint16_t)msg[0] << 8) | \
+ ((uint16_t)msg[1]);
+
+ memset(&dir_item, 0, sizeof(ECPDirItem));
+ dir_item.node = conn->remote;
+ dir_item.capabilities = capabilities;
+
+ now = ecp_tm_get_s();
+ is_new = dir_process_item(&dir_item, now);
+ if (is_new) vlink_new_node(conn->sock, &dir_item);
+
+ rv = dir_send_shadow(conn);
+ if (rv < 0) return rv;
+
+ return rsize;
+}
+
+ssize_t dir_handle_req(ECPConnection *conn, unsigned char *msg, size_t msg_size) {
+ ssize_t rv;
+
+ rv = dir_send_online(conn);
+ if (rv < 0) return rv;
+
+ return 0;
+}
+
+ssize_t dir_handle_shadow(ECPConnection *conn, unsigned char *msg, size_t msg_size) {
+ ecp_sts_t now;
+ uint16_t count;
+ size_t rsize;
+ int i;
+
+ if (msg_size < sizeof(uint16_t)) return ECP_ERR_SIZE;
+
+ count = \
+ ((uint16_t)msg[0] << 8) | \
+ ((uint16_t)msg[1]);
+
+ rsize = sizeof(uint16_t) + count * (ECP_SIZE_DIR_ITEM + sizeof(uint32_t));
+ if (msg_size < rsize) return ECP_ERR_SIZE;
+
+ msg += sizeof(uint16_t);
+
+ now = ecp_tm_get_s();
+ for (i=0; i<count; i++) {
+ ECPDirItem dir_item;
+ ecp_sts_t access_ts;
+ size_t rv;
+
+ rv = ecp_dir_item_parse(&dir_item, msg);
+ msg += rv;
+
+ access_ts = \
+ ((uint32_t)msg[0] << 24) | \
+ ((uint32_t)msg[1] << 16) | \
+ ((uint32_t)msg[2] << 8) | \
+ ((uint32_t)msg[3]);
+ msg += sizeof(uint32_t);
+
+ if (ECP_STS_LT(now, access_ts) || (now - access_ts < (NODE_EXP_TIME / 2))) {
+ int is_new;
+
+ is_new = dir_process_item(&dir_item, access_ts);
+ if (is_new) vlink_new_node(conn->sock, &dir_item);
+ }
+ }
+
+ return rsize;
+}
+
+ssize_t dir_handle_msg(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b) {
+ switch (mtype) {
+ case ECP_MTYPE_DIR_REQ: {
+ if (ecp_conn_is_outb(conn)) return ECP_ERR;
+ return dir_handle_req(conn, msg, msg_size);
+ }
+
+ case ECP_MTYPE_DIR_ANN: {
+ if (ecp_conn_is_outb(conn)) return ECP_ERR;
+ if (!conn->remote.key_perma.valid) return ECP_ERR_VBOX;
+ return dir_handle_ann(conn, msg, msg_size);
+ }
+
+ case ECP_MTYPE_DIR_SHADOW: {
+ if (ecp_conn_is_inb(conn)) return ECP_ERR;
+ return dir_handle_shadow(conn, msg, msg_size);
+ }
+
+ default:
+ return ECP_ERR_MTYPE;
+ }
+}
+
+int dir_handle_open(ECPConnection *conn, ECP2Buffer *bufs) {
+ ssize_t rv;
+
+ if (ecp_conn_is_inb(conn)) return ECP_OK;
+
+ rv = dir_send_ann(conn);
+ if (rv < 0) return rv;
+
+ return ECP_OK;
+}
+
+void dir_online_switch(void) {
+ struct hashtable_itr itr;
+ DirNode *node;
+ unsigned char *msg;
+
+ pthread_rwlock_rdlock(&dir_shadow_rwlock);
+ pthread_rwlock_wrlock(&dir_online_rwlock);
+
+ msg = dir_online.msg;
+ dir_online.count = ecp_ht_count(dir_shadow);
+
+ if (dir_online.count > 0) {
+ size_t _rv;
+ int rv;
+
+ ecp_ht_itr_create(&itr, dir_shadow);
+ do {
+ node = ecp_ht_itr_value(&itr);
+
+ _rv = ecp_dir_item_serialize(&node->dir_item, msg);
+ msg += _rv;
+
+ rv = ecp_ht_itr_advance(&itr);
+ } while (rv == ECP_OK);
+ }
+
+ pthread_rwlock_unlock(&dir_online_rwlock);
+ pthread_rwlock_unlock(&dir_shadow_rwlock);
+}
+
+int dir_process_item(ECPDirItem *dir_item, ecp_sts_t access_ts) {
+ DirNode *node;
+ int is_new = 0;
+ int rv = ECP_OK;
+
+ pthread_rwlock_rdlock(&dir_shadow_rwlock);
+
+ node = ht_search_item(dir_shadow, dir_item);
+ if (node) {
+ pthread_mutex_lock(&node->mutex);
+ if (!node->zombie) node->access_ts = access_ts;
+ pthread_mutex_unlock(&node->mutex);
+
+ pthread_rwlock_unlock(&dir_shadow_rwlock);
+ } else {
+ pthread_rwlock_unlock(&dir_shadow_rwlock);
+
+ LOG(LOG_DEBUG, "dir new node\n");
+
+ node = dir_create_node(dir_item, access_ts);
+ if (node == NULL) rv = ECP_ERR_ALLOC;
+
+ if (!rv) {
+ pthread_rwlock_wrlock(&dir_shadow_rwlock);
+ if (ecp_ht_count(dir_shadow) > MAX_DIR_ITEM) rv = ECP_ERR_FULL;
+ if (!rv) {
+ if (ht_search_node(dir_shadow, node) == NULL) {
+ rv = ht_insert_node(dir_shadow, node);
+ } else {
+ rv = ECP_ERR_DUP;
+ }
+ }
+ pthread_rwlock_unlock(&dir_shadow_rwlock);
+ }
+
+ if (!rv) {
+ is_new = 1;
+ /* always switch */
+ dir_online_switch();
+ } else {
+ if (node) dir_destroy_node(node);
+ LOG(LOG_ERR, "dir create node err:%d\n", rv);
+ }
+ }
+
+ return is_new;
+}
+
+DirNode *dir_create_node(ECPDirItem *dir_item, ecp_sts_t access_ts) {
+ DirNode *node;
+ int rv;
+
+ node = malloc(sizeof(DirNode));
+ if (node == NULL) return NULL;
+
+ memset(node, 0, sizeof(DirNode));
+
+ rv = pthread_mutex_init(&node->mutex, NULL);
+ if (rv) {
+ free(node);
+ return NULL;
+ }
+
+ node->dir_item = *dir_item;
+ node->access_ts = access_ts;
+
+ return node;
+}
+
+void dir_destroy_node(DirNode *node) {
+ pthread_mutex_destroy(&node->mutex);
+ free(node);
+}
+
+int dir_open_conn(ECPSocket *sock, ECPNode *node) {
+ ECPConnection *conn;
+ int rv;
+
+ conn = malloc(sizeof(ECPConnection));
+ if (conn == NULL) return ECP_ERR_ALLOC;
+
+ ecp_dir_conn_init(conn, sock);
+ ecp_conn_set_flags(conn, ECP_CONN_FLAG_GC | ECP_CONN_FLAG_VBOX);
+ rv = ecp_conn_try_open(conn, node);
+ return rv;
+}
+
+DirNode *dir_search_conn(ECPConnection *conn) {
+ DirNode *node;
+ DirNode *ret = NULL;
+
+ pthread_rwlock_rdlock(&dir_shadow_rwlock);
+
+ node = ht_search_conn(dir_shadow, conn);
+ if (node) {
+ pthread_mutex_lock(&node->mutex);
+ if (!node->zombie) {
+ node->refcount++;
+ ret = node;
+ } else {
+ ret = NULL;
+ }
+ pthread_mutex_unlock(&node->mutex);
+ }
+
+ pthread_rwlock_unlock(&dir_shadow_rwlock);
+
+ return ret;
+}
+
+void dir_announce(ECPSocket *sock) {
+ static DirNode *expire_node[MAX_EXPIRE_CNT];
+ static int expire_node_z[MAX_EXPIRE_CNT];
+ static int expire_cnt;
+
+ struct hashtable_itr itr;
+ ecp_sts_t now;
+ DirNode *node;
+ DirNode *node_next;
+ DirNode *announce_node[MAX_ANNOUNCE_CNT];
+ int announce_cnt;
+ int refcount;
+ int i;
+ int rv;
+
+ now = ecp_tm_get_s();
+ node_next = NULL;
+ do {
+ announce_cnt = 0;
+ pthread_rwlock_rdlock(&dir_shadow_rwlock);
+
+ if (ecp_ht_count(dir_shadow) > 0) {
+ ecp_ht_itr_create(&itr, dir_shadow);
+ if (node_next) {
+ rv = ecp_ht_itr_search(&itr, node_next);
+ if (rv) {
+ LOG(LOG_ERR, "dir ann itr search err:%d\n", rv);
+ break;
+ }
+ node_next = NULL;
+ }
+ do {
+ node = ecp_ht_itr_value(&itr);
+ rv = ecp_ht_itr_advance(&itr);
+
+ pthread_mutex_lock(&node->mutex);
+ if (ECP_STS_LT(node->access_ts, now) && (now - node->access_ts > NODE_EXP_TIME)) {
+ node->zombie = 1;
+ pthread_mutex_unlock(&node->mutex);
+
+ if (expire_cnt < MAX_EXPIRE_CNT) {
+ expire_node[expire_cnt] = node;
+ expire_node_z[expire_cnt] = 1;
+ expire_cnt++;
+ }
+ } else {
+ pthread_mutex_unlock(&node->mutex);
+
+ if ((node->dir_item.capabilities & ECP_DIR_CAP_DIR) && (memcmp(node->dir_item.node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) != 0)) {
+ announce_node[announce_cnt] = node;
+ announce_cnt++;
+
+ if (announce_cnt == MAX_ANNOUNCE_CNT) {
+ if (!rv) {
+ node_next = ecp_ht_itr_key(&itr);
+ } else {
+ node_next = NULL;
+ }
+ break;
+ }
+ }
+ }
+ } while (rv == ECP_OK);
+ }
+
+ pthread_rwlock_unlock(&dir_shadow_rwlock);
+
+ if (expire_cnt) {
+ pthread_rwlock_wrlock(&dir_shadow_rwlock);
+ for (i=0; i<expire_cnt; i++) {
+ if (expire_node_z[i]) {
+ expire_node_z[i] = 0;
+ ht_remove_node(dir_shadow, expire_node[i]);
+ LOG(LOG_DEBUG, "dir remove node\n");
+ }
+ }
+ pthread_rwlock_unlock(&dir_shadow_rwlock);
+ }
+
+ for (i=0; i<announce_cnt; i++) {
+ rv = dir_open_conn(sock, &announce_node[i]->dir_item.node);
+ if (rv) LOG(LOG_ERR, "dir open connection err:%d\n", rv);
+ }
+
+ i = expire_cnt - 1;
+ while (i >= 0) {
+ node = expire_node[i];
+
+ pthread_mutex_lock(&node->mutex);
+ refcount = node->refcount;
+ pthread_mutex_unlock(&node->mutex);
+
+ if (refcount == 0) {
+ int j = i;
+
+ expire_cnt--;
+ while (j < expire_cnt) {
+ expire_node[j] = expire_node[j+1];
+ j++;
+ }
+ expire_node[j] = NULL;
+ dir_destroy_node(node);
+ }
+ i--;
+ }
+ } while (node_next);
+}
+
+static void *_dir_announce(void *arg) {
+ ECPSocket *sock = arg;
+
+ while (1) {
+ LOG(LOG_DEBUG, "dir announce...\n");
+ dir_announce(sock);
+ sleep(10);
+ }
+
+ return NULL;
+}
+
+int dir_start_announce(ECPSocket *sock) {
+ int rv;
+
+ rv = pthread_create(&dir_announce_thd, NULL, _dir_announce, sock);
+ if (rv) return ECP_ERR;
+ return ECP_OK;
+}
+
+int dir_init(ECPContext *ctx) {
+ ECPConnHandler *handler;
+ int rv;
+
+ srv_config = srv_get_config();
+
+ handler = malloc(sizeof(ECPConnHandler));
+ if (handler == NULL) return ECP_ERR_ALLOC;
+
+ ecp_conn_handler_init(handler, dir_handle_msg, dir_handle_open, NULL, NULL);
+ rv = ecp_ctx_set_handler(ctx, ECP_CTYPE_DIR, handler);
+ if (rv) return rv;
+
+ rv = pthread_rwlock_init(&dir_shadow_rwlock, NULL);
+ if (rv) {
+ return ECP_ERR;
+ }
+
+ rv = pthread_rwlock_init(&dir_online_rwlock, NULL);
+ if (rv) {
+ pthread_rwlock_destroy(&dir_shadow_rwlock);
+ return ECP_ERR;
+ }
+
+ dir_shadow = ecp_ht_create_keys();
+ if (dir_shadow == NULL) {
+ pthread_rwlock_destroy(&dir_shadow_rwlock);
+ pthread_rwlock_destroy(&dir_online_rwlock);
+ return ECP_ERR_ALLOC;
+ }
+
+ return ECP_OK;
+}
diff --git a/ecp/server/dir.h b/ecp/server/dir.h
new file mode 100644
index 0000000..cbc0c87
--- /dev/null
+++ b/ecp/server/dir.h
@@ -0,0 +1,35 @@
+#define MAX_DIR_ITEM 30
+#define MAX_EXPIRE_CNT 100
+#define MAX_ANNOUNCE_CNT 100
+
+#define NODE_EXP_TIME 86400
+
+typedef struct DirNode {
+ ECPDirItem dir_item;
+ int refcount;
+ int zombie;
+ ecp_sts_t access_ts;
+ pthread_mutex_t mutex;
+} DirNode;
+
+typedef struct DirList {
+ unsigned char msg[ECP_MAX_PLD];
+ uint16_t count;
+} DirList;
+
+ssize_t dir_send_ann(ECPConnection *conn);
+ssize_t dir_send_shadow(ECPConnection *conn);
+ssize_t dir_send_online(ECPConnection *conn);
+ssize_t dir_handle_ann(ECPConnection *conn, unsigned char *msg, size_t msg_size);
+ssize_t dir_handle_req(ECPConnection *conn, unsigned char *msg, size_t msg_size);
+ssize_t dir_handle_shadow(ECPConnection *conn, unsigned char *msg, size_t msg_size);
+ssize_t dir_handle_msg(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b);
+int dir_handle_open(ECPConnection *conn, ECP2Buffer *bufs);
+int dir_process_item(ECPDirItem *dir_item, ecp_sts_t access_ts);
+DirNode *dir_create_node(ECPDirItem *dir_item, ecp_sts_t access_ts);
+void dir_destroy_node(DirNode *node);
+int dir_open_conn(ECPSocket *sock, ECPNode *node);
+DirNode *dir_search_conn(ECPConnection *conn);
+void dir_announce(ECPSocket *sock);
+int dir_start_announce(ECPSocket *sock);
+int dir_init(ECPContext *ctx);
diff --git a/ecp/server/ht.c b/ecp/server/ht.c
new file mode 100644
index 0000000..0daf8d5
--- /dev/null
+++ b/ecp/server/ht.c
@@ -0,0 +1,34 @@
+#include <ecp/core.h>
+#include <ecp/dir/dir.h>
+#include <ecp/ht.h>
+
+#include "dir.h"
+#include "ht.h"
+
+int ht_insert_node(ecp_ht_table_t *table, DirNode *node) {
+ return ecp_ht_insert(table, &node->dir_item.node.key_perma.public, node);
+}
+
+void ht_remove_node(ecp_ht_table_t *table, DirNode *node) {
+ ecp_ht_remove(table, &node->dir_item.node.key_perma.public);
+}
+
+void *ht_search_node(ecp_ht_table_t *table, DirNode *node) {
+ return ecp_ht_search(table, &node->dir_item.node.key_perma.public);
+}
+
+int ht_insert_conn(ecp_ht_table_t *table, ECPConnection *conn) {
+ return ecp_ht_insert(table, &conn->remote.key_perma.public, conn);
+}
+
+void ht_remove_conn(ecp_ht_table_t *table, ECPConnection *conn) {
+ ecp_ht_remove(table, &conn->remote.key_perma.public);
+}
+
+void *ht_search_conn(ecp_ht_table_t *table, ECPConnection *conn) {
+ return ecp_ht_search(table, &conn->remote.key_perma.public);
+}
+
+void *ht_search_item(ecp_ht_table_t *table, ECPDirItem *dir_item) {
+ return ecp_ht_search(table, &dir_item->node.key_perma.public);
+}
diff --git a/ecp/server/ht.h b/ecp/server/ht.h
new file mode 100644
index 0000000..cba4691
--- /dev/null
+++ b/ecp/server/ht.h
@@ -0,0 +1,7 @@
+int ht_insert_node(ecp_ht_table_t *table, DirNode *node);
+void ht_remove_node(ecp_ht_table_t *table, DirNode *node);
+void *ht_search_node(ecp_ht_table_t *table, DirNode *node);
+int ht_insert_conn(ecp_ht_table_t *table, ECPConnection *conn);
+void ht_remove_conn(ecp_ht_table_t *table, ECPConnection *conn);
+void *ht_search_conn(ecp_ht_table_t *table, ECPConnection *conn);
+void *ht_search_item(ecp_ht_table_t *table, ECPDirItem *dir_item); \ No newline at end of file
diff --git a/ecp/server/server.c b/ecp/server/server.c
new file mode 100644
index 0000000..bbe7c4e
--- /dev/null
+++ b/ecp/server/server.c
@@ -0,0 +1,204 @@
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <ecp/core.h>
+#include <ecp/dir/dir.h>
+#include <ecp/vconn/vconn.h>
+
+#include "dir.h"
+#include "vlink.h"
+#include "ht.h"
+
+#include "server.h"
+
+static SRVConfig srv_config;
+
+SRVConfig *srv_get_config(void) {
+ return &srv_config;
+}
+
+static void usage(char *arg) {
+ fprintf(stderr, "Usage: %s <capabilities> <priv> <addr> [ <pub> <addr> ]\n", arg);
+ exit(1);
+}
+
+static void handle_err(ECPConnection *conn, unsigned char mtype, int err) {
+ if (conn->type == ECP_CTYPE_VLINK) vlink_handle_err(conn, mtype, err);
+ LOG(LOG_ERR, "handle error ctype:%d mtype:%d err:%d\n", conn->type, mtype, err);
+}
+
+static ECPConnection *conn_new(ECPSocket *sock, unsigned char type) {
+ ECPConnection *conn = NULL;
+
+ switch (type) {
+ case ECP_CTYPE_VCONN: {
+ ECPVConnInb *_conn;
+
+ _conn = malloc(sizeof(ECPVConnInb));
+ if (_conn) {
+ ecp_vconn_init_inb(_conn, sock);
+ conn = &_conn->b;
+ }
+ break;
+ }
+
+ case ECP_CTYPE_VLINK: {
+ conn = malloc(sizeof(ECPConnection));
+ if (conn) ecp_vlink_init(conn, sock);
+ break;
+ }
+
+ default: {
+ conn = malloc(sizeof(ECPConnection));
+ if (conn) ecp_conn_init(conn, sock, type);
+ break;
+ }
+ }
+
+ return conn;
+}
+
+static void conn_free(ECPConnection *conn) {
+ free(conn);
+}
+
+int ecp_init(ECPContext *ctx, ECPConnHandler *vconn_handler, ECPConnHandler *vlink_handler) {
+ int rv;
+
+ rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free);
+ if (rv) return rv;
+
+ rv = ecp_vconn_handler_init(ctx, vconn_handler);
+ if (rv) return rv;
+
+ rv = ecp_vlink_handler_init(ctx, vlink_handler);
+ if (rv) return rv;
+
+ return ECP_OK;
+}
+
+int main(int argc, char *argv[]) {
+ ecp_tr_addr_t addr;
+ ECPContext ctx;
+ ECPSocket sock;
+ ECPConnHandler vconn_handler;
+ ECPConnHandler vlink_handler;
+ char *endptr;
+ int fd;
+ int rv;
+
+ if ((argc < 4) || (argc > 6)) usage(argv[0]);
+
+ srv_config.capabilities = (uint16_t)strtol(argv[1], &endptr, 16);
+ if (endptr[0] != '\0') {
+ fprintf(stderr, "Bad capabilities\n");
+ exit(1);
+ }
+
+ if ((fd = open(argv[2], O_RDONLY)) < 0) {
+ fprintf(stderr, "Unable to open %s\n", argv[2]);
+ exit(1);
+ }
+ if (read(fd, &srv_config.key_perma.public, sizeof(ecp_ecdh_public_t)) != sizeof(ecp_ecdh_public_t)) {
+ close(fd);
+ fprintf(stderr, "Unable to read public key from %s\n", argv[2]);
+ exit(1);
+ }
+ if (read(fd, &srv_config.key_perma.private, sizeof(ecp_ecdh_private_t)) != sizeof(ecp_ecdh_private_t)) {
+ close(fd);
+ fprintf(stderr, "Unable to read private key from %s\n", argv[2]);
+ exit(1);
+ }
+ close(fd);
+ srv_config.key_perma.valid = 1;
+
+ rv = ecp_init(&ctx, &vconn_handler, &vlink_handler);
+ if (rv) {
+ fprintf(stderr, "ecp_init RV:%d\n", rv);
+ exit(1);
+ }
+ rv = ecp_sock_create(&sock, &ctx, &srv_config.key_perma);
+ if (rv) {
+ fprintf(stderr, "ecp_sock_create RV:%d\n", rv);
+ exit(1);
+ }
+
+
+ rv = ecp_addr_init(&addr, argv[3]);
+ if (rv) {
+ fprintf(stderr, "ecp_addr_init RV:%d\n", rv);
+ exit(1);
+ }
+
+ rv = ecp_sock_open(&sock, &addr);
+ if (rv) {
+ fprintf(stderr, "ecp_sock_open RV:%d\n", rv);
+ exit(1);
+ }
+
+ rv = dir_init(&ctx);
+ if (rv) {
+ fprintf(stderr, "dir_init RV:%d\n", rv);
+ exit(1);
+ }
+
+ rv = vlink_init(&ctx);
+ if (rv) {
+ fprintf(stderr, "vlink_init RV:%d\n", rv);
+ exit(1);
+ }
+
+ rv = dir_start_announce(&sock);
+ if (rv) {
+ fprintf(stderr, "dir_start_announce RV:%d\n", rv);
+ exit(1);
+ }
+
+ rv = vlink_start_open(&sock);
+ if (rv) {
+ fprintf(stderr, "vlink_start_open RV:%d\n", rv);
+ exit(1);
+ }
+
+ rv = vlink_start_keyx();
+ if (rv) {
+ fprintf(stderr, "vlink_start_keyx RV:%d\n", rv);
+ exit(1);
+ }
+
+ if (argc == 6) {
+ ECPNode node;
+ ecp_ecdh_public_t node_pub;
+ ecp_tr_addr_t node_addr;
+
+ if ((fd = open(argv[4], O_RDONLY)) < 0) {
+ fprintf(stderr, "Unable to open %s\n", argv[4]);
+ exit(1);
+ }
+ if (read(fd, &node_pub, sizeof(ecp_ecdh_public_t)) != sizeof(ecp_ecdh_public_t)) {
+ close(fd);
+ fprintf(stderr, "Unable to read public key from %s\n", argv[4]);
+ exit(1);
+ }
+ close(fd);
+
+ int rv;
+
+ ecp_node_init(&node, &node_pub, NULL);
+ rv = ecp_node_set_addr(&node, argv[5]);
+ if (rv) {
+ fprintf(stderr, "ecp_node_set_addr RV:%d\n", rv);
+ exit(1);
+ }
+
+ rv = dir_open_conn(&sock, &node);
+ if (rv) {
+ fprintf(stderr, "dir_open_conn RV:%d\n", rv);
+ exit(1);
+ }
+ }
+
+ ecp_receiver(&sock);
+} \ No newline at end of file
diff --git a/ecp/server/server.h b/ecp/server/server.h
new file mode 100644
index 0000000..ff8e444
--- /dev/null
+++ b/ecp/server/server.h
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+#define LOG_DEBUG 1
+#define LOG_INFO 2
+#define LOG_ERR 3
+
+#define LOG_LEVEL LOG_DEBUG
+#define LOG(l, ...) (l >= LOG_LEVEL ? fprintf(stderr, __VA_ARGS__) : 0 )
+
+typedef struct SRVConfig {
+ ECPDHKey key_perma;
+ uint16_t capabilities;
+} SRVConfig;
+
+SRVConfig *srv_get_config(void);
diff --git a/ecp/server/vlink.c b/ecp/server/vlink.c
new file mode 100644
index 0000000..e98dacc
--- /dev/null
+++ b/ecp/server/vlink.c
@@ -0,0 +1,321 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <ecp/core.h>
+#include <ecp/dir/dir.h>
+#include <ecp/vconn/vconn.h>
+#include <ecp/ht.h>
+#include <ecp/tm.h>
+
+#include "server.h"
+#include "dir.h"
+#include "ht.h"
+
+#include "vlink.h"
+
+static ecp_ht_table_t *vlink_conn = NULL;
+static ecp_ht_table_t *vlink_node = NULL;
+static pthread_mutex_t vlink_conn_mutex;
+static pthread_mutex_t vlink_node_mutex;
+static pthread_t vlink_open_thd;
+static pthread_t vlink_keyx_thd;
+
+static SRVConfig *srv_config;
+
+void vlink_handle_err(ECPConnection *conn, unsigned char mtype, int err) {
+ switch (mtype) {
+ case ECP_MTYPE_OPEN_REP: {
+ if (err == ECP_ERR_TIMEOUT) {
+ int rv;
+
+ rv = vlink_insert_node(conn);
+ if (rv) LOG(LOG_ERR, "vlink insert node err:%d\n", rv);
+ }
+ ecp_conn_close(conn);
+ break;
+ }
+ }
+}
+
+int vlink_handle_open(ECPConnection *conn, ECP2Buffer *bufs) {
+ int rv;
+
+ rv = ecp_vlink_handle_open(conn, bufs);
+ if (rv) return rv;
+
+ if (ecp_conn_is_inb(conn)) return ECP_OK;
+
+ pthread_mutex_lock(&vlink_conn_mutex);
+ rv = ht_insert_conn(vlink_conn, conn);
+ pthread_mutex_unlock(&vlink_conn_mutex);
+
+ if (rv) {
+ ecp_vlink_handle_close(conn);
+ return rv;
+ }
+
+ return ECP_OK;
+}
+
+void vlink_handle_close(ECPConnection *conn) {
+ int rv;
+
+ ecp_vlink_handle_close(conn);
+
+ if (ecp_conn_is_inb(conn)) return;
+
+ rv = vlink_insert_node(conn);
+ if (rv) LOG(LOG_ERR, "vlink insert node err:%d\n", rv);
+}
+
+int vlink_open_conn(ECPSocket *sock, ECPNode *node) {
+ ECPConnection *conn;
+ int rv;
+
+ conn = malloc(sizeof(ECPConnection));
+ if (conn == NULL) return ECP_ERR_ALLOC;
+
+ ecp_vlink_init(conn, sock);
+ rv = ecp_conn_open(conn, node);
+ return rv;
+}
+
+void vlink_new_node(ECPSocket *sock, ECPDirItem *dir_item) {
+ if ((dir_item->capabilities & ECP_DIR_CAP_VCONN) && (memcmp(&dir_item->node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) < 0)) {
+ int rv;
+
+ LOG(LOG_DEBUG, "vlink open connection\n");
+ rv = vlink_open_conn(sock, &dir_item->node);
+ if (rv) LOG(LOG_ERR, "vlink open connection err:%d\n", rv);
+ }
+}
+
+int vlink_insert_node(ECPConnection *conn) {
+ DirNode *node;
+ int rv = ECP_OK;
+
+ node = dir_search_conn(conn);
+ if (node) {
+ pthread_mutex_lock(&vlink_node_mutex);
+ rv = ht_insert_node(vlink_node, node);
+ pthread_mutex_unlock(&vlink_node_mutex);
+
+ if (rv) {
+ pthread_mutex_lock(&node->mutex);
+ node->refcount--;
+ pthread_mutex_unlock(&node->mutex);
+ }
+ }
+
+ return rv;
+}
+
+void vlink_open(ECPSocket *sock) {
+ struct hashtable_itr itr;
+ DirNode *node;
+ DirNode *node_next;
+ DirNode *open_node[MAX_OPEN_CNT];
+ int open_cnt;
+ int i;
+ int rv;
+
+ node_next = NULL;
+ do {
+ open_cnt = 0;
+ pthread_mutex_lock(&vlink_node_mutex);
+
+ if (ecp_ht_count(vlink_node) > 0) {
+ ecp_ht_itr_create(&itr, vlink_node);
+ if (node_next) {
+ rv = ecp_ht_itr_search(&itr, node_next);
+ if (rv) {
+ LOG(LOG_ERR, "vlink open itr search err:%d\n", rv);
+ break;
+ }
+ node_next = NULL;
+ }
+ do {
+ node = ecp_ht_itr_value(&itr);
+ rv = ecp_ht_itr_remove(&itr);
+
+ open_node[open_cnt] = node;
+ open_cnt++;
+ if (open_cnt == MAX_OPEN_CNT) {
+ if (!rv) {
+ node_next = ecp_ht_itr_key(&itr);
+ } else {
+ node_next = NULL;
+ }
+ }
+ } while (rv == ECP_OK);
+ }
+
+ pthread_mutex_unlock(&vlink_node_mutex);
+
+ for (i=0; i<open_cnt; i++) {
+ pthread_mutex_lock(&open_node[i]->mutex);
+
+ if (open_node[i]->zombie) {
+ open_node[i]->refcount--;
+
+ pthread_mutex_unlock(&open_node[i]->mutex);
+ } else {
+ pthread_mutex_unlock(&open_node[i]->mutex);
+
+ LOG(LOG_DEBUG, "vlink open connection\n");
+ rv = vlink_open_conn(sock, &open_node[i]->dir_item.node);
+ if (rv) LOG(LOG_ERR, "vlink open connection err:%d\n", rv);
+ }
+ }
+ } while (node_next);
+}
+
+void vlink_keyx(void) {
+ struct hashtable_itr itr;
+ ecp_sts_t now;
+ ECPConnection *conn;
+ ECPConnection *keyx_next;
+ ECPConnection *keyx_conn[MAX_KEYX_CNT];
+ int keyx_conn_z[MAX_KEYX_CNT];
+ int keyx_cnt;
+ int is_zombie;
+ int i;
+ int rv;
+
+ now = ecp_tm_get_s();
+ keyx_next = NULL;
+ do {
+ keyx_cnt = 0;
+ pthread_mutex_lock(&vlink_conn_mutex);
+
+ if (ecp_ht_count(vlink_conn) > 0) {
+ ecp_ht_itr_create(&itr, vlink_conn);
+ if (keyx_next) {
+ rv = ecp_ht_itr_search(&itr, keyx_next);
+ if (rv) {
+ LOG(LOG_ERR, "vlink keyx itr search err:%d\n", rv);
+ break;
+ }
+ keyx_next = NULL;
+ }
+ do {
+ conn = ecp_ht_itr_value(&itr);
+
+ is_zombie = ecp_conn_is_zombie(conn, now, CONN_EXP_TIME);
+ if (is_zombie) {
+ rv = ecp_ht_itr_remove(&itr);
+ } else {
+ rv = ecp_ht_itr_advance(&itr);
+ }
+
+ keyx_conn[keyx_cnt] = conn;
+ keyx_conn_z[keyx_cnt] = is_zombie;
+ keyx_cnt++;
+
+ if (keyx_cnt == MAX_KEYX_CNT) {
+ if (!rv) {
+ keyx_next = ecp_ht_itr_key(&itr);
+ } else {
+ keyx_next = NULL;
+ }
+ }
+ } while (rv == ECP_OK);
+ }
+
+ pthread_mutex_unlock(&vlink_conn_mutex);
+
+ for (i=0; i<keyx_cnt; i++) {
+ if (keyx_conn_z[i]) {
+ LOG(LOG_DEBUG, "vlink close connection\n");
+ ecp_conn_close(keyx_conn[i]);
+ } else {
+ ssize_t _rv;
+
+ LOG(LOG_DEBUG, "vlink send keyx\n");
+ _rv = ecp_send_keyx_req(keyx_conn[i], 1);
+ if (_rv < 0) LOG(LOG_ERR, "vlink send keyx err:%ld\n", _rv);
+ }
+ }
+ } while (keyx_next);
+}
+
+static void *_vlink_open(void *arg) {
+ ECPSocket *sock = arg;
+
+ while (1) {
+ LOG(LOG_DEBUG, "vlink open...\n");
+ vlink_open(sock);
+ sleep(10);
+ }
+
+ return NULL;
+}
+
+static void *_vlink_keyx(void *arg) {
+ while (1) {
+ LOG(LOG_DEBUG, "vlink keyx...\n");
+ vlink_keyx();
+ sleep(10);
+ }
+
+ return NULL;
+}
+
+int vlink_start_open(ECPSocket *sock) {
+ int rv;
+
+ rv = pthread_create(&vlink_open_thd, NULL, _vlink_open, sock);
+ if (rv) return ECP_ERR;
+ return ECP_OK;
+}
+
+int vlink_start_keyx(void) {
+ int rv;
+
+ rv = pthread_create(&vlink_keyx_thd, NULL, _vlink_keyx, NULL);
+ if (rv) return ECP_ERR;
+ return ECP_OK;
+}
+
+int vlink_init(ECPContext *ctx) {
+ ECPConnHandler *handler;
+ int rv;
+
+ srv_config = srv_get_config();
+
+ handler = ecp_ctx_get_handler(ctx, ECP_CTYPE_VLINK);
+ if (handler == NULL) return ECP_ERR;
+
+ handler->handle_open = vlink_handle_open;
+ handler->handle_close = vlink_handle_close;
+
+ rv = pthread_mutex_init(&vlink_conn_mutex, NULL);
+ if (rv) {
+ return ECP_ERR;
+ }
+
+ rv = pthread_mutex_init(&vlink_node_mutex, NULL);
+ if (rv) {
+ pthread_mutex_destroy(&vlink_conn_mutex);
+ return ECP_ERR;
+ }
+
+ rv = ECP_OK;
+ vlink_conn = ecp_ht_create_keys();
+ if (vlink_conn == NULL) rv = ECP_ERR_ALLOC;
+ if (!rv) {
+ vlink_node = ecp_ht_create_keys();
+ if (vlink_node == NULL) rv = ECP_ERR_ALLOC;
+ }
+
+ if (rv) {
+ pthread_mutex_destroy(&vlink_node_mutex);
+ pthread_mutex_destroy(&vlink_conn_mutex);
+ if (vlink_node) ecp_ht_destroy(vlink_node);
+ if (vlink_conn) ecp_ht_destroy(vlink_conn);
+ return rv;
+ }
+
+ return ECP_OK;
+}
diff --git a/ecp/server/vlink.h b/ecp/server/vlink.h
new file mode 100644
index 0000000..78af6b1
--- /dev/null
+++ b/ecp/server/vlink.h
@@ -0,0 +1,17 @@
+#define MAX_KEYX_CNT 100
+#define MAX_OPEN_CNT 100
+
+#define CONN_EXP_TIME 22
+
+void vlink_handle_err(ECPConnection *conn, unsigned char mtype, int err);
+int vlink_handle_open(ECPConnection *conn, ECP2Buffer *bufs);
+void vlink_handle_close(ECPConnection *conn);
+int vlink_open_conn(ECPSocket *sock, ECPNode *node);
+void vlink_new_node(ECPSocket *sock, ECPDirItem *item);
+int vlink_insert_node(ECPConnection *conn);
+
+void vlink_keyx(void);
+void vlink_open(ECPSocket *sock);
+int vlink_start_open(ECPSocket *sock);
+int vlink_start_keyx(void);
+int vlink_init(ECPContext *ctx);
diff --git a/ecp/src/ecp/common.mk b/ecp/src/ecp/common.mk
index a07b5c5..9380130 100644
--- a/ecp/src/ecp/common.mk
+++ b/ecp/src/ecp/common.mk
@@ -7,11 +7,7 @@ platform_dir = $(abspath $(src_dir)/platform/$(platform))
include $(platform_dir)/platform.mk
include $(platform_dir)/features.mk
-CFLAGS += -I$(src_dir)/ecp -I$(ssl_dir)/include -I$(platform_dir)
-
-ifeq ($(with_dirsrv),yes)
-with_dir = yes
-endif
+CFLAGS += -I$(src_dir) -I$(platform_dir) -I$(ssl_dir)/include
ifeq ($(with_pthread),yes)
CFLAGS += -DECP_WITH_PTHREAD=1
@@ -27,24 +23,29 @@ CFLAGS += -DECP_WITH_VCONN=1
subdirs += vconn
endif
+ifeq ($(with_frag),yes)
+CFLAGS += -DECP_WITH_FRAG=1
+ext_subdir = yes
+endif
+
ifeq ($(with_rbuf),yes)
CFLAGS += -DECP_WITH_RBUF=1
-subdirs += ext
+ext_subdir = yes
endif
ifeq ($(with_msgq),yes)
CFLAGS += -DECP_WITH_MSGQ=1
endif
+ifdef ext_subdir
+subdirs += ext
+endif
+
ifeq ($(with_dir),yes)
CFLAGS += -DECP_WITH_DIR=1
subdirs += dir
endif
-ifeq ($(with_dirsrv),yes)
-CFLAGS += -DECP_WITH_DIRSRV=1
-endif
-
ifeq ($(with_debug),yes)
CFLAGS += -DECP_DEBUG=1
endif
diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c
index 3d4342d..9585388 100644
--- a/ecp/src/ecp/core.c
+++ b/ecp/src/ecp/core.c
@@ -12,10 +12,6 @@
#include "vconn/vconn.h"
#endif
-#ifdef ECP_WITH_DIR
-#include "dir/dir.h"
-#endif
-
#include "cr.h"
#include "tr.h"
#include "tm.h"
@@ -34,13 +30,12 @@ int ecp_dhkey_gen(ECPDHKey *key) {
return ECP_OK;
}
-int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_dir_handler_t handle_dir, ecp_conn_alloc_t conn_alloc, ecp_conn_free_t conn_free) {
+int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free) {
int rv;
memset(ctx, 0, sizeof(ECPContext));
ctx->handle_err = handle_err;
- ctx->handle_dir = handle_dir;
- ctx->conn_alloc = conn_alloc;
+ ctx->conn_new = conn_new;
ctx->conn_free = conn_free;
rv = ecp_tr_init(ctx);
@@ -52,14 +47,44 @@ int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_dir_handler_
return ECP_OK;
}
-int ecp_ctx_set_handler(ECPContext *ctx, ECPConnHandler *handler, unsigned char ctype) {
- if (ctype >= ECP_MAX_CTYPE) return ECP_ERR_CTYPE;
+int ecp_ctx_set_handler(ECPContext *ctx, unsigned char ctype, ECPConnHandler *handler) {
+ unsigned char _ctype = ctype & ECP_CTYPE_MASK;
- ctx->handler[ctype] = handler;
+ if (ctype & ECP_CTYPE_FLAG_SYS) {
+ if (_ctype >= ECP_MAX_CTYPE_SYS) return ECP_ERR_CTYPE;
+ ctx->handler_sys[_ctype] = handler;
+ } else {
+ if (_ctype >= ECP_MAX_CTYPE) return ECP_ERR_CTYPE;
+ ctx->handler[_ctype] = handler;
+ }
return ECP_OK;
}
-int ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, void *addr) {
+ECPConnHandler *ecp_ctx_get_handler(ECPContext *ctx, unsigned char ctype) {
+ unsigned char _ctype = ctype & ECP_CTYPE_MASK;
+
+ if (ctype & ECP_CTYPE_FLAG_SYS) {
+ if (_ctype >= ECP_MAX_CTYPE_SYS) return NULL;
+ return ctx->handler_sys[_ctype];
+ } else {
+ if (_ctype >= ECP_MAX_CTYPE) return NULL;
+ return ctx->handler[_ctype];
+ }
+ return NULL;
+}
+
+int ecp_addr_init(ecp_tr_addr_t *addr, void *addr_s) {
+ int rv = ECP_OK;
+
+ memset(addr, 0, sizeof(ecp_tr_addr_t));
+ if (addr_s) {
+ rv = ecp_tr_addr_set(addr, addr_s);
+ }
+
+ return rv;
+}
+
+void ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr) {
memset(node, 0, sizeof(ECPNode));
if (public) {
@@ -70,13 +95,8 @@ int ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, void *addr) {
}
if (addr) {
- int rv;
-
- rv = ecp_tr_addr_set(&node->addr, addr);
- if (rv) return ECP_ERR_NET_ADDR;
+ node->addr = *addr;
}
-
- return ECP_OK;
}
void ecp_node_set_pub(ECPNode *node, ecp_ecdh_public_t *public) {
@@ -106,7 +126,7 @@ static int conn_table_create(ECPConnTable *conn_table) {
return ECP_ERR;
}
- rv = pthread_mutex_init(&conn_table->mutex_inb, NULL);
+ rv = pthread_mutex_init(&conn_table->mutex_gc, NULL);
if (rv) {
pthread_mutex_destroy(&conn_table->mutex);
return ECP_ERR;
@@ -120,8 +140,8 @@ static int conn_table_create(ECPConnTable *conn_table) {
if (conn_table->keys == NULL) rv = ECP_ERR_ALLOC;
if (!rv) {
- conn_table->keys_inb = ecp_ht_create_keys();
- if (conn_table->keys_inb == NULL) rv = ECP_ERR_ALLOC;
+ conn_table->keys_gc = ecp_ht_create_keys();
+ if (conn_table->keys_gc == NULL) rv = ECP_ERR_ALLOC;
}
if (!rv) {
@@ -131,11 +151,11 @@ static int conn_table_create(ECPConnTable *conn_table) {
if (rv) {
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_destroy(&conn_table->mutex_inb);
+ pthread_mutex_destroy(&conn_table->mutex_gc);
pthread_mutex_destroy(&conn_table->mutex);
#endif
if (conn_table->addrs) ecp_ht_destroy(conn_table->addrs);
- if (conn_table->keys_inb) ecp_ht_destroy(conn_table->keys_inb);
+ if (conn_table->keys_gc) ecp_ht_destroy(conn_table->keys_gc);
if (conn_table->keys) ecp_ht_destroy(conn_table->keys);
}
#endif
@@ -145,12 +165,12 @@ static int conn_table_create(ECPConnTable *conn_table) {
static void conn_table_destroy(ECPConnTable *conn_table) {
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_destroy(&conn_table->mutex_inb);
+ pthread_mutex_destroy(&conn_table->mutex_gc);
pthread_mutex_destroy(&conn_table->mutex);
#endif
#ifdef ECP_WITH_HTABLE
ecp_ht_destroy(conn_table->addrs);
- ecp_ht_destroy(conn_table->keys_inb);
+ ecp_ht_destroy(conn_table->keys_gc);
ecp_ht_destroy(conn_table->keys);
#endif
}
@@ -162,7 +182,7 @@ static int conn_table_insert(ECPConnection *conn) {
int i, rv = ECP_OK;
if (ecp_conn_is_outb(conn)) {
- if (ecp_conn_is_root(conn) && !ecp_conn_is_open(conn)) {
+ if (ecp_conn_is_root(conn) && !_ecp_conn_is_open(conn)) {
rv = ecp_ht_insert(sock->conn_table.addrs, &conn->remote.addr, conn);
if (rv) return rv;
}
@@ -178,8 +198,8 @@ static int conn_table_insert(ECPConnection *conn) {
ecp_ht_remove(sock->conn_table.keys, &conn->key[j].public);
}
}
- if (ecp_conn_is_root(conn) && !ecp_conn_is_open(conn)) {
- ecp_ht_remove(sock->conn_table.addrs, &conn->remote.addr);
+ if (ecp_conn_is_root(conn) && !_ecp_conn_is_open(conn)) {
+ ecp_ht_remove_kv(sock->conn_table.addrs, &conn->remote.addr, conn);
}
return rv;
}
@@ -214,16 +234,12 @@ static int conn_table_insert(ECPConnection *conn) {
return ECP_OK;
}
-static int conn_table_insert_inb(ECPConnection *conn) {
+static int conn_table_insert_gc(ECPConnection *conn) {
ECPSocket *sock = conn->sock;
int rv = ECP_OK;
#ifdef ECP_WITH_HTABLE
- unsigned char idx;
-
- idx = conn->rkey_curr % ECP_MAX_NODE_KEY;
-
- rv = ecp_ht_insert(sock->conn_table.keys_inb, &conn->rkey[idx].public, conn);
+ rv = ecp_ht_insert(sock->conn_table.keys_gc, &conn->remote.key_perma.public, conn);
#endif
return rv;
@@ -241,8 +257,8 @@ static void conn_table_remove(ECPConnection *conn) {
ecp_ht_remove(sock->conn_table.keys, &conn->key[i].public);
}
}
- if (ecp_conn_is_root(conn) && !ecp_conn_is_open(conn)) {
- ecp_ht_remove(sock->conn_table.addrs, &conn->remote.addr);
+ if (ecp_conn_is_root(conn) && !_ecp_conn_is_open(conn)) {
+ ecp_ht_remove_kv(sock->conn_table.addrs, &conn->remote.addr, conn);
}
} else {
for (i=0; i<ECP_MAX_NODE_KEY; i++) {
@@ -273,126 +289,168 @@ static void conn_table_remove_addr(ECPConnection *conn) {
ECPSocket *sock = conn->sock;
#ifdef ECP_WITH_HTABLE
- ecp_ht_remove(sock->conn_table.addrs, &conn->remote.addr);
+ ecp_ht_remove_kv(sock->conn_table.addrs, &conn->remote.addr, conn);
#endif
}
-static ECPConnection *conn_table_search(ECPSocket *sock, unsigned char c_idx, ecp_ecdh_public_t *c_public, ecp_tr_addr_t *addr, ECPConnection *parent) {
-#ifdef ECP_WITH_VCONN
- if ((c_public == NULL) && parent) {
- return parent->next;
- }
-#endif
-
+static ECPConnection *conn_table_search_pub(ECPSocket *sock, unsigned char c_idx, ecp_ecdh_public_t *c_public) {
#ifdef ECP_WITH_HTABLE
+ return ecp_ht_search(sock->conn_table.keys, c_public);
+#else /* ECP_WITH_HTABLE */
+ ECPConnection *conn = NULL;
+ int i;
- if (c_public) {
- return ecp_ht_search(sock->conn_table.keys, c_public);
- } else if (addr) {
- return ecp_ht_search(sock->conn_table.addrs, addr);
- } else {
- return NULL;
+ for (i=0; i<sock->conn_table.size; i++) {
+ conn = sock->conn_table.arr[i];
+ if (ecp_conn_is_outb(conn)) {
+ if (c_idx >= ECP_MAX_CONN_KEY) continue;
+
+ if (conn->key[c_idx].valid && ecp_ecdh_pub_eq(c_public, &conn->key[c_idx].public)) {
+ return conn;
+ }
+ } else {
+ unsigned char _c_idx;
+
+ if (c_idx & ~ECP_ECDH_IDX_MASK) continue;
+
+ _c_idx = c_idx % ECP_MAX_NODE_KEY;
+ if (conn->rkey[_c_idx].valid && ecp_ecdh_pub_eq(c_public, &conn->rkey[_c_idx].public)) {
+ return conn;
+ }
+ }
}
+ return NULL;
+#endif /* ECP_WITH_HTABLE */
+}
+static ECPConnection *conn_table_search_addr(ECPSocket *sock, ecp_tr_addr_t *addr) {
+#ifdef ECP_WITH_HTABLE
+ return ecp_ht_search(sock->conn_table.addrs, addr);
#else /* ECP_WITH_HTABLE */
ECPConnection *conn = NULL;
int i;
- if (c_public) {
- for (i=0; i<sock->conn_table.size; i++) {
- conn = sock->conn_table.arr[i];
- if (ecp_conn_is_outb(conn)) {
- if (c_idx >= ECP_MAX_CONN_KEY) continue;
+ for (i=0; i<sock->conn_table.size; i++) {
+ conn = sock->conn_table.arr[i];
+ if (ecp_conn_is_root(conn) && ecp_conn_is_outb(conn) && ecp_tr_addr_eq(&conn->remote.addr, addr)) {
+ return conn;
+ }
+ }
- if (conn->key[c_idx].valid && ecp_ecdh_pub_eq(c_public, &conn->key[c_idx].public)) {
- return conn;
- }
- } else {
- unsigned char _c_idx;
+ return NULL;
+#endif /* ECP_WITH_HTABLE */
+}
- if (c_idx & ~ECP_ECDH_IDX_MASK) continue;
+static ECPConnection *conn_table_search_addr_next(ECPSocket *sock, ecp_tr_addr_t *addr, ECPConnection *_conn) {
+#ifdef ECP_WITH_HTABLE
+ return ecp_ht_search_next(sock->conn_table.addrs, addr, _conn);
+#else /* ECP_WITH_HTABLE */
+ ECPConnection *conn = NULL;
+ int i, f;
- _c_idx = c_idx % ECP_MAX_NODE_KEY;
- if (conn->rkey[_c_idx].valid && ecp_ecdh_pub_eq(c_public, &conn->rkey[_c_idx].public)) {
- return conn;
- }
- }
- }
- } else if (addr) {
- for (i=0; i<sock->conn_table.size; i++) {
- conn = sock->conn_table.arr[i];
+ f = 0;
+ for (i=0; i<sock->conn_table.size; i++) {
+ conn = sock->conn_table.arr[i];
+ if (f)
if (ecp_conn_is_root(conn) && ecp_conn_is_outb(conn) && ecp_tr_addr_eq(&conn->remote.addr, addr)) {
return conn;
}
+ } else if (conn == _conn) {
+ f = 1;
}
}
return NULL;
-
#endif /* ECP_WITH_HTABLE */
}
-static void conn_table_expire_inb(ECPSocket *sock, ecp_sts_t to) {
+static ECPConnection *conn_table_search(ECPSocket *sock, unsigned char c_idx, ecp_ecdh_public_t *c_public, ecp_tr_addr_t *addr, ECPConnection *parent) {
+#ifdef ECP_WITH_VCONN
+ if ((c_public == NULL) && parent) {
+ if ((parent->type == ECP_CTYPE_VCONN) && ecp_conn_is_outb(parent)) {
+ ECPVConnOutb *_parent = (ECPVConnOutb *)parent;
+
+ return _parent->next;
+ }
+ return NULL;
+ }
+#endif
+
+ if (c_public) {
+ return conn_table_search_pub(sock, c_idx, c_public);
+ } else if (addr) {
+ return conn_table_search_addr(sock, addr);
+ }
+
+ return NULL;
+}
+
+static void conn_table_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t conn_expired) {
ECPConnection *conn;
ECPConnection *to_remove[ECP_MAX_EXP];
- int i, remove_cnt;
- ecp_sts_t access_ts, now = ecp_tm_get_tick();
+ int i, remove_cnt, expired;
+ ecp_sts_t now = ecp_tm_get_s();
#ifdef ECP_WITH_HTABLE
struct hashtable_itr itr;
void *remove_next;
int rv = ECP_OK;
+
remove_next = NULL;
do {
+ ecp_ht_table_t *keys_gc = sock->conn_table.keys_gc;
remove_cnt = 0;
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&sock->conn_table.mutex_inb);
+ pthread_mutex_lock(&sock->conn_table.mutex_gc);
#endif
- ecp_ht_itr_create(&itr, sock->conn_table.keys_inb);
- if (remove_next) {
- ecp_ht_itr_search(&itr, remove_next);
- remove_next = NULL;
- }
- do {
- conn = ecp_ht_itr_value(&itr);
- if (conn) {
+ if (ecp_ht_count(keys_gc) > 0) {
+ ecp_ht_itr_create(&itr, keys_gc);
+ if (remove_next) {
+ ecp_ht_itr_search(&itr, remove_next);
+ remove_next = NULL;
+ }
+ do {
+ conn = ecp_ht_itr_value(&itr);
+
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&conn->mutex);
#endif
- access_ts = conn->access_ts;
+ expired = conn_expired(conn, now, to);
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&conn->mutex);
#endif
- if (now - access_ts > to) {
+ if (expired) {
+ rv = ecp_ht_itr_remove(&itr);
+
to_remove[remove_cnt] = conn;
remove_cnt++;
- rv = ecp_ht_itr_remove(&itr);
if (remove_cnt == ECP_MAX_EXP) {
- if (!rv) remove_next = ecp_ht_itr_key(&itr);
+ if (!rv) {
+ remove_next = ecp_ht_itr_key(&itr);
+ } else {
+ remove_next = NULL;
+ }
break;
}
} else {
rv = ecp_ht_itr_advance(&itr);
}
- } else {
- rv = ECP_ITR_END;
- }
- } while (rv == ECP_OK);
+ } while (rv == ECP_OK);
+ }
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&sock->conn_table.mutex_inb);
+ pthread_mutex_unlock(&sock->conn_table.mutex_gc);
#endif
for (i=0; i<remove_cnt; i++) {
_ecp_conn_close(to_remove[i]);
}
-
} while (remove_next);
#else /* ECP_WITH_HTABLE */
@@ -406,18 +464,18 @@ static void conn_table_expire_inb(ECPSocket *sock, ecp_sts_t to) {
for (i=0; i<sock->conn_table.size; i++) {
conn = sock->conn_table.arr[i];
- if (ecp_conn_is_inb(conn)) {
+ if (ecp_conn_is_gc(conn)) {
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&conn->mutex);
#endif
- access_ts = conn->access_ts;
+ expired = conn_expired(conn, now, to);
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&conn->mutex);
#endif
- if (now - access_ts > to) {
+ if (expired) {
to_remove[remove_cnt] = conn;
remove_cnt++;
if (remove_cnt == ECP_MAX_EXP) break;
@@ -492,7 +550,7 @@ void ecp_sock_destroy(ECPSocket *sock) {
#endif
}
-int ecp_sock_open(ECPSocket *sock, void *myaddr) {
+int ecp_sock_open(ECPSocket *sock, ecp_tr_addr_t *myaddr) {
return ecp_tr_open(sock, myaddr);
}
@@ -606,11 +664,20 @@ void ecp_sock_get_nonce(ECPSocket *sock, ecp_nonce_t *nonce) {
#endif
}
+static int _conn_expired_inb(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to) {
+ if (ecp_conn_is_inb(conn) && _ecp_conn_expired(conn, now, to)) return 1;
+ return 0;
+}
+
+void ecp_sock_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t conn_expired) {
+ conn_table_expire(sock, to, conn_expired);
+}
+
int ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to) {
int rv;
rv = ecp_sock_minkey_new(sock);
- if (!rv) conn_table_expire_inb(sock, to);
+ if (!rv) conn_table_expire(sock, to, _conn_expired_inb);
return rv;
}
@@ -664,7 +731,7 @@ static int conn_dhkey_new(ECPConnection *conn, unsigned char idx, ECPDHKey *key)
if (idx >= ECP_MAX_CONN_KEY) return ECP_ERR_ECDH_IDX;
#ifdef ECP_WITH_HTABLE
- if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn) && conn->key[idx].valid) {
+ if (ecp_conn_is_outb(conn) && _ecp_conn_is_reg(conn) && conn->key[idx].valid) {
ecp_ht_remove(sock->conn_table.keys, &conn->key[idx].public);
}
#endif
@@ -672,7 +739,7 @@ static int conn_dhkey_new(ECPConnection *conn, unsigned char idx, ECPDHKey *key)
conn->key[idx] = *key;
#ifdef ECP_WITH_HTABLE
- if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn)) {
+ if (ecp_conn_is_outb(conn) && _ecp_conn_is_reg(conn)) {
int rv;
rv = ecp_ht_insert(sock->conn_table.keys, &conn->key[idx].public, conn);
@@ -689,7 +756,7 @@ static void conn_dhkey_del(ECPConnection *conn, unsigned char idx) {
if (idx >= ECP_MAX_CONN_KEY) return;
#ifdef ECP_WITH_HTABLE
- if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn) && conn->key[idx].valid) {
+ if (ecp_conn_is_outb(conn) && _ecp_conn_is_reg(conn) && conn->key[idx].valid) {
ecp_ht_remove(sock->conn_table.keys, &conn->key[idx].public);
}
#endif
@@ -723,7 +790,7 @@ static ECPDHPub *conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx) {
}
/* node will send public key */
-static void conn_dhkey_get_pub(ECPConnection *conn, unsigned char idx) {
+static void conn_dhkey_send_pub(ECPConnection *conn, unsigned char idx) {
unsigned char _idx;
int i;
@@ -754,10 +821,10 @@ static int conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_p
_idx = idx % ECP_MAX_NODE_KEY;
key = &conn->rkey[_idx];
- if (key->valid && (memcmp(public, &key->public, sizeof(key->public)) == 0)) return ECP_ERR_ECDH_KEY_DUP;
+ if (key->valid && (memcmp(public, &key->public, sizeof(key->public)) == 0)) return ECP_ERR_DUP;
#ifdef ECP_WITH_HTABLE
- if (ecp_conn_is_inb(conn) && ecp_conn_is_reg(conn) && (key->valid)) {
+ if (ecp_conn_is_inb(conn) && _ecp_conn_is_reg(conn) && (key->valid)) {
ecp_ht_remove(sock->conn_table.keys, &key->public);
}
#endif
@@ -766,7 +833,7 @@ static int conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_p
key->valid = 1;
#ifdef ECP_WITH_HTABLE
- if (ecp_conn_is_inb(conn) && ecp_conn_is_reg(conn)) {
+ if (ecp_conn_is_inb(conn) && _ecp_conn_is_reg(conn)) {
int rv;
rv = ecp_ht_insert(sock->conn_table.keys, &key->public, conn);
@@ -847,24 +914,11 @@ static int conn_shkey_set(ECPConnection *conn, unsigned char s_idx, unsigned cha
return ECP_OK;
}
-int ecp_conn_alloc(ECPSocket *sock, unsigned char ctype, ECPConnection **_conn) {
+ECPConnection *ecp_conn_new_inb(ECPSocket *sock, unsigned char ctype) {
ECPContext *ctx = sock->ctx;
- ECPConnection *conn;
- int rv;
- if (ctx->conn_alloc == NULL) return ECP_ERR_ALLOC;
-
- conn = ctx->conn_alloc(sock, ctype);
- if (conn == NULL) return ECP_ERR_ALLOC;
-
- *_conn = conn;
- return ECP_OK;
-}
-
-void ecp_conn_free(ECPConnection *conn) {
- ECPContext *ctx = conn->sock->ctx;
-
- if (ctx->conn_free) ctx->conn_free(conn);
+ if (ctx->conn_new) return ctx->conn_new(sock, ctype);
+ return NULL;
}
void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) {
@@ -878,138 +932,146 @@ void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) {
conn->key_next = ECP_ECDH_IDX_INV;
conn->rkey_curr = ECP_ECDH_IDX_INV;
arc4random_buf(&conn->nonce_out, sizeof(conn->nonce_out));
+ conn->access_ts = ecp_tm_get_s();
}
-void ecp_conn_reinit(ECPConnection *conn) {
- conn->flags = 0;
+int ecp_conn_reset(ECPConnection *conn) {
+ if (conn->flags) return ECP_ERR;
+
+ conn->key_curr = ECP_ECDH_IDX_INV;
conn->key_next = ECP_ECDH_IDX_INV;
conn->rkey_curr = ECP_ECDH_IDX_INV;
memset(&conn->key, 0, sizeof(conn->key));
memset(&conn->rkey, 0, sizeof(conn->rkey));
memset(&conn->shkey, 0, sizeof(conn->shkey));
arc4random_buf(&conn->nonce_out, sizeof(conn->nonce_out));
+ conn->nonce_in = 0;
+ conn->nonce_map = 0;
+
+ return ECP_OK;
}
-int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) {
+int ecp_conn_create(ECPConnection *conn, ECPConnection *parent) {
int rv;
+#ifdef ECP_WITH_VCONN
+ unsigned short pcount;
- ecp_conn_init(conn, sock, ctype);
+ pcount = parent ? parent->pcount + 1 : 0;
+ if (pcount > ECP_MAX_PARENT) return ECP_ERR_MAX_PARENT;
+#endif
#ifdef ECP_WITH_PTHREAD
rv = pthread_mutex_init(&conn->mutex, NULL);
if (rv) return ECP_ERR;
#endif
- return ECP_OK;
-}
-
-int ecp_conn_create_inb(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) {
- int rv;
-
- rv = ecp_conn_create(conn, sock, ctype);
- if (rv) return rv;
-
- ecp_conn_set_inb(conn);
-
-#ifdef ECP_WITH_VCONN
- if (conn->parent) {
- ecp_conn_refcount_inc(conn->parent);
- }
+ rv = ecp_ext_conn_create(conn);
+ if (rv) {
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_destroy(&conn->mutex);
#endif
- return ECP_OK;
-}
-
-void ecp_conn_destroy(ECPConnection *conn) {
-#ifdef ECP_WITH_VCONN
- if (ecp_conn_is_inb(conn) && conn->parent) {
- ecp_conn_refcount_dec(conn->parent);
+ return ECP_ERR;
}
-#endif
- ecp_ext_conn_destroy(conn);
+#ifdef ECP_WITH_VCONN
+ if (parent) {
+ conn->parent = parent;
+ conn->pcount = pcount;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_destroy(&conn->mutex);
+ ecp_conn_refcount_inc(parent);
+ }
#endif
-}
-
-void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags) {
- flags &= flags & ECP_CONN_FLAG_MASK;
- conn->flags_im |= flags;
-}
-
-void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags) {
- flags &= flags & ECP_CONN_FLAG_MASK;
- conn->flags_im &= ~flags;
-}
-
-void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key) {
- conn->remote.key_perma = *key;
-}
-void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr) {
- conn->remote.addr = *addr;
+ return ECP_OK;
}
-int ecp_conn_init_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *remote_key, ecp_aead_key_t *shkey) {
+int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *remote_key, ecp_aead_key_t *shkey) {
ECPSocket *sock = conn->sock;
- unsigned short pcount;
int rv;
-#ifdef ECP_WITH_VCONN
- pcount = (parent ? parent->pcount + 1 : 0);
- if (pcount > ECP_MAX_PARENT) return ECP_ERR_MAX_PARENT;
-#endif
-
if (ecp_conn_has_vbox(conn) && ((remote_key == NULL) || !remote_key->valid)) return ECP_ERR_VBOX;
+ ecp_conn_set_inb(conn);
+
rv = conn_dhkey_set_pub(conn, c_idx, public);
if (rv) return rv;
rv = conn_shkey_set(conn, s_idx, c_idx, shkey);
if (rv) return rv;
-#ifdef ECP_WITH_VCONN
- conn->parent = parent;
- conn->pcount = pcount;
-#endif
-
+ ecp_conn_set_flags(conn, ECP_CONN_FLAG_GC);
conn->refcount = 1;
conn->key_curr = s_idx;
conn->rkey_curr = c_idx;
- if (remote_key && remote_key->valid) conn->remote.key_perma = *remote_key;
+ if (remote_key && remote_key->valid) {
+ conn->remote.key_perma = *remote_key;
+ } else {
+ ECPDHPub *key_perma = &conn->remote.key_perma;
+ memcpy(&key_perma->public, public, sizeof(key_perma->public));
+ }
- return ECP_OK;
+ rv = ecp_conn_create(conn, parent);
+ return rv;
+}
+
+int ecp_conn_create_outb(ECPConnection *conn, ECPConnection *parent, ECPNode *node) {
+ int rv;
+
+ ecp_conn_set_outb(conn);
+
+ conn->refcount = 1;
+ if (node) conn->remote = *node;
+
+ rv = ecp_conn_reset_outb(conn);
+ if (rv) return rv;
+
+ rv = ecp_conn_create(conn, parent);
+ return rv;
}
-int ecp_conn_init_outb(ECPConnection *conn, ECPNode *node) {
+int ecp_conn_reset_outb(ECPConnection *conn) {
ECPDHKey key;
- unsigned char key_curr;
int rv;
- if (conn->key_curr == ECP_ECDH_IDX_INV) {
- key_curr = 0;
- } else {
- key_curr = (conn->key_curr + 1) % ECP_MAX_CONN_KEY;
- }
+ conn->key_curr = 0;
+
rv = ecp_dhkey_gen(&key);
if (rv) return rv;
- rv = conn_dhkey_new(conn, key_curr, &key);
+ rv = conn_dhkey_new(conn, conn->key_curr, &key);
if (rv) return rv;
- if (node) conn->remote = *node;
- conn->key_curr = key_curr;
-
return ECP_OK;
}
+void ecp_conn_destroy(ECPConnection *conn) {
+#ifdef ECP_WITH_VCONN
+ if (conn->parent) {
+ ecp_conn_refcount_dec(conn->parent);
+ }
+#endif
+
+ ecp_ext_conn_destroy(conn);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_destroy(&conn->mutex);
+#endif
+
+ ecp_conn_free(conn);
+}
+
+void ecp_conn_free(ECPConnection *conn) {
+ ECPContext *ctx = conn->sock->ctx;
+
+ if (ctx->conn_free) ctx->conn_free(conn);
+}
+
int ecp_conn_insert(ECPConnection *conn) {
ECPSocket *sock = conn->sock;
int rv;
- ecp_conn_set_reg(conn);
+ _ecp_conn_set_reg(conn);
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&sock->conn_table.mutex);
@@ -1021,25 +1083,23 @@ int ecp_conn_insert(ECPConnection *conn) {
pthread_mutex_unlock(&sock->conn_table.mutex);
#endif
- if (rv) ecp_conn_clr_reg(conn);
+ if (rv) _ecp_conn_clr_reg(conn);
return rv;
}
-int ecp_conn_insert_inb(ECPConnection *conn) {
+int ecp_conn_insert_gc(ECPConnection *conn) {
ECPSocket *sock = conn->sock;
int rv;
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&sock->conn_table.mutex_inb);
- pthread_mutex_lock(&conn->mutex);
+ pthread_mutex_lock(&sock->conn_table.mutex_gc);
#endif
- rv = conn_table_insert_inb(conn);
+ rv = conn_table_insert_gc(conn);
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
- pthread_mutex_unlock(&sock->conn_table.mutex_inb);
+ pthread_mutex_unlock(&sock->conn_table.mutex_gc);
#endif
return rv;
@@ -1053,9 +1113,9 @@ void ecp_conn_remove(ECPConnection *conn, unsigned short *refcount) {
pthread_mutex_lock(&conn->mutex);
#endif
- if (ecp_conn_is_reg(conn)) {
+ if (_ecp_conn_is_reg(conn)) {
conn_table_remove(conn);
- ecp_conn_clr_reg(conn);
+ _ecp_conn_clr_reg(conn);
}
if (refcount) *refcount = conn->refcount;
@@ -1082,57 +1142,64 @@ void ecp_conn_remove_addr(ECPConnection *conn) {
}
-int ecp_conn_open(ECPConnection *conn, ECPNode *node) {
+int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, ECPNode *node, int retry) {
int rv;
ssize_t _rv;
- rv = ecp_conn_init_outb(conn, node);
+ rv = ecp_conn_create_outb(conn, parent, node);
if (rv) return rv;
rv = ecp_conn_insert(conn);
- if (rv) return rv;
+ if (rv) {
+ ecp_conn_destroy(conn);
+ return rv;
+ }
- _rv = ecp_send_init_req(conn);
+ if (ecp_conn_is_gc(conn)) {
+ rv = ecp_conn_insert_gc(conn);
+ if (rv) {
+ ecp_conn_refcount_dec(conn);
+ _ecp_conn_close(conn);
+ return rv;
+ }
+ }
+
+ _rv = ecp_send_init_req(conn, retry);
if (_rv < 0) {
- ecp_timer_remove(conn);
- ecp_conn_remove(conn, NULL);
+ ecp_conn_refcount_dec(conn);
+ ecp_conn_close(conn);
return _rv;
}
+ ecp_conn_refcount_dec(conn);
+
return ECP_OK;
}
-int ecp_conn_reset(ECPConnection *conn) {
- unsigned short refcount = 0;
- int i;
+int ecp_conn_open(ECPConnection *conn, ECPNode *node) {
int rv;
- /* timer holds one reference to this connection */
- ecp_conn_remove(conn, &refcount);
- if (refcount > 1) return ECP_ERR_BUSY;
-
- ecp_conn_reinit(conn);
- if (rv) return rv;
-
- rv = ecp_conn_init_outb(conn, NULL);
- if (rv) return rv;
+ rv = _ecp_conn_open(conn, NULL, node, 1);
+ return rv;
+}
- rv = ecp_conn_insert(conn);
- if (rv) return rv;
+int ecp_conn_try_open(ECPConnection *conn, ECPNode *node) {
+ int rv;
- return ECP_OK;
+ rv = _ecp_conn_open(conn, NULL, node, 0);
+ return rv;
}
static void conn_close(ECPConnection *conn) {
- if (ecp_conn_is_open(conn)) {
+ if (_ecp_conn_is_open(conn)) {
ecp_close_handler_t handler;
- ecp_conn_clr_open(conn);
+ _ecp_conn_clr_open(conn);
handler = ecp_get_close_handler(conn);
if (handler) handler(conn);
+ ecp_ext_conn_close(conn);
}
ecp_conn_destroy(conn);
- if (ecp_conn_is_inb(conn)) ecp_conn_free(conn);
}
int _ecp_conn_close(ECPConnection *conn) {
@@ -1147,8 +1214,49 @@ int _ecp_conn_close(ECPConnection *conn) {
}
int ecp_conn_close(ECPConnection *conn) {
- if (ecp_conn_is_inb(conn)) return ECP_ERR;
- return _ecp_conn_close(conn);
+ int rv;
+
+ if (ecp_conn_is_gc(conn)) {
+ ecp_conn_mark_closed(conn);
+ rv = ECP_OK;
+ } else {
+ rv = _ecp_conn_close(conn);
+ }
+
+ return rv;
+}
+
+void ecp_conn_mark_closed(ECPConnection *conn) {
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&conn->mutex);
+#endif
+
+ _ecp_conn_set_closed(conn);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&conn->mutex);
+#endif
+}
+
+int _ecp_conn_expired(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to) {
+ if (_ecp_conn_is_closed(conn) || (ECP_STS_LT(conn->access_ts, now) && (now - conn->access_ts > to))) return 1;
+ return 0;
+}
+
+int ecp_conn_is_zombie(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to) {
+ int z = 0;
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&conn->mutex);
+#endif
+
+ z = _ecp_conn_expired(conn, now, to);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&conn->mutex);
+#endif
+
+ return z;
}
void ecp_conn_refcount_inc(ECPConnection *conn) {
@@ -1173,7 +1281,7 @@ void ecp_conn_refcount_dec(ECPConnection *conn) {
conn->refcount--;
refcount = conn->refcount;
- is_reg = ecp_conn_is_reg(conn);
+ is_reg = _ecp_conn_is_reg(conn);
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&conn->mutex);
@@ -1182,6 +1290,24 @@ void ecp_conn_refcount_dec(ECPConnection *conn) {
if (!is_reg && (refcount == 0)) conn_close(conn);
}
+void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags) {
+ flags &= ECP_CONN_FLAG_MASK;
+ conn->flags_im |= flags;
+}
+
+void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags) {
+ flags &= ECP_CONN_FLAG_MASK;
+ conn->flags_im &= ~flags;
+}
+
+void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key) {
+ conn->remote.key_perma = *key;
+}
+
+void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr) {
+ conn->remote.addr = *addr;
+}
+
int ecp_conn_dhkey_new(ECPConnection *conn) {
ECPSocket *sock = conn->sock;
ECPDHKey new_key;
@@ -1208,13 +1334,9 @@ int ecp_conn_dhkey_new(ECPConnection *conn) {
pthread_mutex_unlock(&conn->mutex);
if (ecp_conn_is_outb(conn)) pthread_mutex_unlock(&sock->conn_table.mutex);
#endif
- if (idx == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX;
- if (rv) return rv;
-
- _rv = ecp_send_keyx_req(conn);
- if (_rv < 0) return _rv;
- return ECP_OK;
+ if (idx == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX;
+ return rv;
}
int ecp_conn_dhkey_get(ECPConnection *conn, unsigned char idx, ECPDHKey *key) {
@@ -1274,7 +1396,6 @@ int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_pub
#ifdef ECP_WITH_PTHREAD
if (will_send) pthread_mutex_lock(&conn->mutex);
#endif
-
} else {
ECPDHKey *key;
@@ -1282,7 +1403,7 @@ int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_pub
pthread_mutex_lock(&conn->mutex);
#endif
- if (will_send) {
+ if (will_send && (conn->key_next != ECP_ECDH_IDX_INV)) {
_idx = conn->key_next;
} else {
_idx = conn->key_curr;
@@ -1296,7 +1417,7 @@ int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_pub
if (!rv) memcpy(public, &key->public, sizeof(key->public));
}
- if (!rv && will_send) conn_dhkey_get_pub(conn, _idx);
+ if (!rv && will_send) conn_dhkey_send_pub(conn, _idx);
#ifdef ECP_WITH_PTHREAD
if (will_send || ecp_conn_is_outb(conn)) pthread_mutex_unlock(&conn->mutex);
@@ -1324,7 +1445,7 @@ int ecp_conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_publ
if (ecp_conn_is_inb(conn)) pthread_mutex_unlock(&sock->conn_table.mutex);
#endif
- if (rv == ECP_ERR_ECDH_KEY_DUP) rv = ECP_OK;
+ if (rv == ECP_ERR_DUP) rv = ECP_OK;
return rv;
}
@@ -1344,7 +1465,7 @@ void ecp_conn_dhkey_set_curr(ECPConnection *conn) {
#endif
}
-void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_open_send_t send_open) {
+void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_send_open_t send_open) {
memset(handler, 0, sizeof(ECPConnHandler));
handler->handle_msg = handle_msg;
handler->handle_open = handle_open;
@@ -1356,87 +1477,56 @@ ecp_msg_handler_t ecp_get_msg_handler(ECPConnection *conn) {
ECPContext *ctx = conn->sock->ctx;
unsigned char ctype;
- ctype = conn->type;
+ ctype = conn->type & ECP_CTYPE_MASK;
if (ecp_conn_is_sys(conn)) {
- switch (ctype) {
-#ifdef ECP_WITH_DIR
- case ECP_CTYPE_DIR:
- return ecp_dir_handle_msg;
-#endif
-
-#ifdef ECP_WITH_VCONN
- case ECP_CTYPE_VCONN:
- case ECP_CTYPE_VLINK:
- return ecp_vconn_handle_msg;
-#endif
-
- default:
- return NULL;
- }
+ if (ctype >= ECP_MAX_CTYPE_SYS) return NULL;
+ return ctx->handler_sys[ctype] ? ctx->handler_sys[ctype]->handle_msg : NULL;
+ } else {
+ if (ctype >= ECP_MAX_CTYPE) return NULL;
+ return ctx->handler[ctype] ? ctx->handler[ctype]->handle_msg : NULL;
}
-
- if (ctype >= ECP_MAX_CTYPE) return NULL;
- return ctx->handler[ctype] ? ctx->handler[ctype]->handle_msg : NULL;
}
ecp_open_handler_t ecp_get_open_handler(ECPConnection *conn) {
ECPContext *ctx = conn->sock->ctx;
unsigned char ctype;
- ctype = conn->type;
+ ctype = conn->type & ECP_CTYPE_MASK;
if (ecp_conn_is_sys(conn)) {
- switch (ctype) {
-#ifdef ECP_WITH_DIR
- case ECP_CTYPE_DIR:
- return ecp_dir_handle_open;
-#endif
-
-#ifdef ECP_WITH_VCONN
- case ECP_CTYPE_VCONN:
- case ECP_CTYPE_VLINK:
- return ecp_vconn_handle_open;
-#endif
-
- default:
- return NULL;
- }
+ if (ctype >= ECP_MAX_CTYPE_SYS) return NULL;
+ return ctx->handler_sys[ctype] ? ctx->handler_sys[ctype]->handle_open : NULL;
+ } else {
+ if (ctype >= ECP_MAX_CTYPE) return NULL;
+ return ctx->handler[ctype] ? ctx->handler[ctype]->handle_open : NULL;
}
-
- if (ctype >= ECP_MAX_CTYPE) return NULL;
- return ctx->handler[ctype] ? ctx->handler[ctype]->handle_open : NULL;
}
ecp_close_handler_t ecp_get_close_handler(ECPConnection *conn) {
ECPContext *ctx = conn->sock->ctx;
unsigned char ctype;
- ctype = conn->type;
+ ctype = conn->type & ECP_CTYPE_MASK;
if (ecp_conn_is_sys(conn)) {
- switch (ctype) {
-#ifdef ECP_WITH_DIR
- case ECP_CTYPE_DIR:
- return NULL;
-#endif
-
-#ifdef ECP_WITH_VCONN
- case ECP_CTYPE_VCONN:
- case ECP_CTYPE_VLINK:
- return ecp_vconn_handle_close;
-#endif
-
- default:
- return NULL;
- }
+ if (ctype >= ECP_MAX_CTYPE_SYS) return NULL;
+ return ctx->handler_sys[ctype] ? ctx->handler_sys[ctype]->handle_close : NULL;
+ } else {
+ if (ctype >= ECP_MAX_CTYPE) return NULL;
+ return ctx->handler[ctype] ? ctx->handler[ctype]->handle_close : NULL;
}
-
- if (ctype >= ECP_MAX_CTYPE) return NULL;
- return ctx->handler[ctype] ? ctx->handler[ctype]->handle_close : NULL;
}
-ecp_dir_handler_t ecp_get_dir_handler(ECPConnection *conn) {
+ecp_send_open_t ecp_get_send_open_f(ECPConnection *conn) {
ECPContext *ctx = conn->sock->ctx;
+ unsigned char ctype;
- return ctx->handle_dir;
+ ctype = conn->type & ECP_CTYPE_MASK;
+ if (ecp_conn_is_sys(conn)) {
+ if (ctype >= ECP_MAX_CTYPE_SYS) return NULL;
+ return ctx->handler_sys[ctype] ? ctx->handler_sys[ctype]->send_open : NULL;
+ } else {
+ if (ctype >= ECP_MAX_CTYPE) return NULL;
+ return ctx->handler[ctype] ? ctx->handler[ctype]->send_open : NULL;
+ }
}
void ecp_err_handle(ECPConnection *conn, unsigned char mtype, int err) {
@@ -1454,6 +1544,7 @@ static ssize_t _send_ireq(ECPConnection *conn, ECPTimerItem *ti) {
ECPBuffer payload;
unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_INIT_REQ, conn)];
unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_INIT_REQ, conn)];
+ ssize_t rv;
packet.buffer = pkt_buf;
packet.size = sizeof(pkt_buf);
@@ -1462,29 +1553,50 @@ static ssize_t _send_ireq(ECPConnection *conn, ECPTimerItem *ti) {
ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_INIT_REQ);
- return _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, NULL, NULL, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_INIT_REQ), 0, ti);
+ rv = _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, NULL, NULL, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_INIT_REQ), 0, ti);
+ return rv;
}
static ssize_t _retry_ireq(ECPConnection *conn, ECPTimerItem *ti) {
+ unsigned short refcount = 0;
int rv;
+ /* timer holds one reference to this connection */
+ ecp_conn_remove(conn, &refcount);
+ if (refcount > 1) return ECP_ERR_BUSY;
+
rv = ecp_conn_reset(conn);
if (rv) return rv;
+ rv = ecp_conn_reset_outb(conn);
+ if (rv) return rv;
+
+ rv = ecp_conn_insert(conn);
+ if (rv) return rv;
+
return _send_ireq(conn, ti);
}
-ssize_t ecp_send_init_req(ECPConnection *conn) {
- ECPTimerItem ti;
+ssize_t ecp_send_init_req(ECPConnection *conn, int retry) {
+ ssize_t rv;
+
+ if (retry) {
+ ECPTimerItem ti;
- ecp_timer_item_init(&ti, conn, ECP_MTYPE_OPEN_REP, _retry_ireq, ECP_SEND_TRIES-1, ECP_SEND_TIMEOUT);
+ ecp_timer_item_init(&ti, conn, ECP_MTYPE_OPEN_REP, _retry_ireq, ECP_SEND_TRIES-1, ECP_SEND_TIMEOUT);
+
+ rv = _send_ireq(conn, &ti);
+ } else {
+ rv = _send_ireq(conn, NULL);
+ }
- return _send_ireq(conn, &ti);
+ return rv;
}
-ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey) {
+ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey, ECP2Buffer *bufs) {
ssize_t rv;
+ ecp_tr_release(bufs->packet, 1);
rv = ecp_send_init_rep(sock, parent, addr, c_idx, public_buf, shkey);
if (rv < 0) return rv;
@@ -1531,9 +1643,8 @@ ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t
return rv;
}
-ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size) {
- ecp_open_send_t send_open_f;
- unsigned char ctype;
+ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
+ ecp_send_open_t send_open_f;
unsigned char *cookie;
ssize_t rv;
int _rv;
@@ -1543,29 +1654,11 @@ ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_
_rv = ecp_conn_dhkey_set_pub(conn, msg[0], (ecp_ecdh_public_t *)(msg+1));
if (_rv) return _rv;
- ctype = conn->type;
- send_open_f = NULL;
cookie = msg+1+ECP_SIZE_ECDH_PUB;
- if (ecp_conn_is_sys(conn)) {
- switch (ctype) {
-#ifdef ECP_WITH_VCONN
- case ECP_CTYPE_VCONN:
- case ECP_CTYPE_VLINK:
- send_open_f = ecp_vconn_send_open_req;
- break;
-#endif
-
- default:
- break;
- }
- } else {
- ECPContext *ctx = conn->sock->ctx;
-
- if (ctype >= ECP_MAX_CTYPE) return ECP_ERR_CTYPE;
- send_open_f = ctx->handler[ctype] ? ctx->handler[ctype]->send_open : NULL;
- }
+ send_open_f = ecp_get_send_open_f(conn);
if (send_open_f == NULL) send_open_f = ecp_send_open_req;
+ ecp_tr_release(bufs->packet, 1);
rv = send_open_f(conn, cookie);
if (rv < 0) return rv;
@@ -1684,17 +1777,27 @@ ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned cha
remote_key.valid = 1;
}
- _rv = ecp_conn_alloc(sock, ctype, &conn);
+ conn = ecp_conn_new_inb(sock, ctype);
+ if (conn == NULL) return ECP_ERR_ALLOC;
+
+ _rv = ecp_conn_create_inb(conn, parent, s_idx, c_idx, (ecp_ecdh_public_t *)public_buf, remote_key.valid ? &remote_key : NULL, shkey);
if (_rv) return _rv;
- _rv = ecp_conn_init_inb(conn, parent, s_idx, c_idx, (ecp_ecdh_public_t *)public_buf, remote_key.valid ? &remote_key : NULL, shkey);
- if (!_rv) _rv = ecp_conn_insert(conn);
+ _rv = ecp_conn_insert(conn);
if (_rv) {
ecp_conn_destroy(conn);
- ecp_conn_free(conn);
return _rv;
}
+ if (ecp_conn_is_gc(conn)) {
+ _rv = ecp_conn_insert_gc(conn);
+ if (_rv) {
+ ecp_conn_refcount_dec(conn);
+ _ecp_conn_close(conn);
+ return _rv;
+ }
+ }
+
*_conn = conn;
/* handle_open will be called later from msg handler */
@@ -1718,77 +1821,75 @@ ssize_t ecp_send_open_rep(ECPConnection *conn) {
return rv;
}
-ssize_t ecp_handle_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
- size_t rsize;
- ecp_open_handler_t handler;
- int rv = ECP_OK;
+ssize_t ecp_check_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size) {
+ int is_open;
+ ssize_t rv;
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&conn->mutex);
+#endif
+
+ is_open = _ecp_conn_is_open(conn);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&conn->mutex);
+#endif
+
+ if (is_open) return ECP_ERR;
if (mtype == ECP_MTYPE_OPEN_REQ) {
if (ecp_conn_is_outb(conn)) return ECP_ERR;
- rsize = 2;
- if (msg_size < rsize) return ECP_ERR_SIZE;
+ rv = 2;
+ if (msg_size < rv) return ECP_ERR_SIZE;
- if (msg[1]) rsize += ECP_SIZE_VBOX;
- if (msg_size < rsize) return ECP_ERR_SIZE;
+ if (msg[1]) rv += ECP_SIZE_VBOX;
+ if (msg_size < rv) return ECP_ERR_SIZE;
} else {
if (ecp_conn_is_inb(conn)) return ECP_ERR;
- rsize = 0;
+ rv = 0;
}
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&conn->mutex);
-#endif
-
- if (ecp_conn_is_open(conn)) rv = ECP_ERR;
- if (!rv) rv = ecp_ext_conn_open(conn);
- if (!rv) ecp_conn_set_open(conn);
+ return rv;
+}
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
-#endif
+int ecp_handle_open(ECPConnection *conn, ECP2Buffer *bufs) {
+ ecp_open_handler_t handler;
+ int rv = ECP_OK;
+ rv = ecp_ext_conn_open(conn);
if (rv) return rv;
handler = ecp_get_open_handler(conn);
- if (handler) rv = handler(conn, bufs);
- if (rv) {
+ if (handler) {
+ rv = handler(conn, bufs);
+ if (rv) {
+ ecp_ext_conn_close(conn);
+ return rv;
+ }
+ }
+
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&conn->mutex);
+ pthread_mutex_lock(&conn->mutex);
#endif
- ecp_conn_clr_open(conn);
+ _ecp_conn_set_open(conn);
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
+ pthread_mutex_unlock(&conn->mutex);
#endif
- if (ecp_conn_is_inb(conn)) _ecp_conn_close(conn);
- return rv;
- }
-
if (ecp_conn_is_inb(conn)) {
- ssize_t _rv;
-
ecp_tr_release(bufs->packet, 1);
-
- _rv = ecp_send_open_rep(conn);
- if (_rv < 0) {
- _ecp_conn_close(conn);
- return _rv;
- }
- rv = ecp_conn_insert_inb(conn);
- if (rv) {
- _ecp_conn_close(conn);
- return rv;
- }
+ ecp_send_open_rep(conn);
} else if (ecp_conn_is_root(conn)) {
ecp_conn_remove_addr(conn);
}
- return rsize;
+
+ return ECP_OK;
}
-static ssize_t _send_keyx_req(ECPConnection *conn, ECPTimerItem *ti) {
+static ssize_t _send_kxreq(ECPConnection *conn, ECPTimerItem *ti) {
ECPBuffer packet;
ECPBuffer payload;
unsigned char pkt_buf[ECP_SIZE_PKT_BUF(1+ECP_SIZE_ECDH_PUB, ECP_MTYPE_KEYX_REQ, conn)];
@@ -1812,8 +1913,16 @@ static ssize_t _send_keyx_req(ECPConnection *conn, ECPTimerItem *ti) {
return rv;
}
-ssize_t ecp_send_keyx_req(ECPConnection *conn) {
- return ecp_timer_send(conn, _send_keyx_req, ECP_MTYPE_KEYX_REP, ECP_SEND_TRIES, ECP_SEND_TIMEOUT);
+ssize_t ecp_send_keyx_req(ECPConnection *conn, int retry) {
+ ssize_t rv;
+
+ if (retry) {
+ rv = ecp_timer_send(conn, _send_kxreq, ECP_MTYPE_KEYX_REP, ECP_SEND_TRIES, ECP_SEND_TIMEOUT);
+ } else {
+ rv = _send_kxreq(conn, NULL);
+ }
+
+ return rv;
}
ssize_t ecp_send_keyx_rep(ECPConnection *conn) {
@@ -1857,7 +1966,6 @@ ssize_t ecp_handle_keyx(ECPConnection *conn, unsigned char mtype, unsigned char
if (ecp_conn_is_outb(conn)) return ECP_ERR;
ecp_tr_release(bufs->packet, 1);
-
rv = ecp_send_keyx_rep(conn);
if (rv < 0) return rv;
}
@@ -1870,7 +1978,7 @@ ssize_t ecp_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype,
switch (mtype) {
case ECP_MTYPE_OPEN_REQ:
case ECP_MTYPE_OPEN_REP:
- return ecp_handle_open(conn, mtype, msg, msg_size, bufs);
+ return ecp_check_open(conn, mtype, msg, msg_size);
case ECP_MTYPE_KEYX_REQ:
case ECP_MTYPE_KEYX_REP:
@@ -1901,17 +2009,20 @@ ssize_t ecp_pld_handle_one(ECPConnection *conn, ecp_seq_t seq, unsigned char *pa
_rv = ecp_pld_get_type(payload, pld_size, &mtype);
if (_rv) return _rv;
- ecp_timer_pop(conn, mtype);
-
msg = ecp_pld_get_msg(payload, pld_size);
if (msg == NULL) return ECP_ERR;
hdr_size = msg - payload;
msg_size = pld_size - hdr_size;
rv = ecp_msg_handle(conn, seq, mtype, msg, msg_size, bufs);
- if (rv < 0) return rv;
+ ecp_timer_pop(conn, mtype);
+ if (rv < 0) {
+ ecp_err_handle(conn, mtype, rv);
+ return rv;
+ }
rv += hdr_size;
+
if (rv > pld_size) return ECP_ERR_SIZE;
return rv;
}
@@ -1920,7 +2031,7 @@ ssize_t ecp_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payloa
size_t pld_size = _pld_size;
ssize_t rv;
- rv = ecp_ext_pld_handle(conn, seq, payload, pld_size, bufs);
+ rv = ecp_ext_pld_handle_one(conn, seq, payload, pld_size, bufs);
if (rv < 0) return rv;
payload += rv;
@@ -1938,7 +2049,7 @@ ssize_t ecp_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payloa
return _pld_size;
}
-ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t _pkt_size, ECPConnection **_conn, unsigned char **_payload, ecp_seq_t *_seq) {
+ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t _pkt_size, ECPConnection **_conn, unsigned char **_payload, ecp_seq_t *_seq, int *is_open_msg) {
ECPConnection *conn = NULL;
unsigned char idx;
unsigned char s_idx;
@@ -1962,6 +2073,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr,
*_conn = NULL;
*_payload = NULL;
*_seq = 0;
+ *is_open_msg = 0;
packet = bufs->packet->buffer;
idx = packet[ECP_SIZE_PROTO];
@@ -1984,7 +2096,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr,
if (conn) {
is_inb = ecp_conn_is_inb(conn);
- is_open = ecp_conn_is_open(conn);
+ is_open = _ecp_conn_is_open(conn);
if (!is_open && !is_inb && (idx == ECP_ECDH_IDX_INV)) {
nonce_buf = packet+ECP_SIZE_PROTO+1;
@@ -2083,6 +2195,44 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr,
payload = bufs->payload->buffer;
rv = ecp_aead_dec(payload, bufs->payload->size, packet, pkt_size, &shkey, &nonce_pkt, is_inb ? ECP_NTYPE_INB : ECP_NTYPE_OUTB);
+
+ /* init reply collision */
+ if ((rv == ECP_ERR_DECRYPT) && conn && !is_open && !is_inb && (idx == ECP_ECDH_IDX_INV)) {
+ ECPConnection *_conn = conn;
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&sock->conn_table.mutex);
+#endif
+
+ conn = conn_table_search_addr(sock, addr);
+
+ while (conn && (rv == ECP_ERR_DECRYPT)) {
+ if (conn != _conn) {
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&conn->mutex);
+#endif
+
+ _rv = conn_shkey_get(conn, s_idx, c_idx, &shkey);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&conn->mutex);
+#endif
+
+ if (_rv) rv = _rv;
+ if (rv == ECP_ERR_DECRYPT) rv = ecp_aead_dec(payload, bufs->payload->size, packet, pkt_size, &shkey, &nonce_pkt, ECP_NTYPE_OUTB);
+ }
+ if (rv == ECP_ERR_DECRYPT) conn = conn_table_search_addr_next(sock, addr, conn);
+ }
+
+ if (rv < 0) conn = NULL;
+ if (conn) ecp_conn_refcount_inc(conn);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&sock->conn_table.mutex);
+#endif
+
+ ecp_conn_refcount_dec(_conn);
+ }
if (rv < 0) goto unpack_err;
pld_size = rv;
@@ -2108,11 +2258,8 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr,
case ECP_MTYPE_INIT_REQ: {
unsigned char _public_buf[ECP_SIZE_ECDH_PUB];
- /* we should release incoming packet before sending reply packet */
memcpy(_public_buf, public_buf, sizeof(_public_buf));
- ecp_tr_release(bufs->packet, 1);
-
- rv = ecp_handle_init_req(sock, parent, addr, c_idx, _public_buf, &shkey);
+ rv = ecp_handle_init_req(sock, parent, addr, c_idx, _public_buf, &shkey, bufs);
if (rv < 0) return rv;
rv += hdr_size;
@@ -2126,7 +2273,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr,
/* pass to payload handler */
nonce_in = nonce_pkt;
nonce_map = ECP_ACK_FULL;
- is_open = 1;
+ *is_open_msg = 1;
rv = 0;
break;
}
@@ -2158,10 +2305,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr,
switch (mtype) {
case ECP_MTYPE_INIT_REP: {
- /* we should release incoming packet before sending reply packet */
- ecp_tr_release(bufs->packet, 1);
-
- rv = ecp_handle_init_rep(conn, msg, msg_size);
+ rv = ecp_handle_init_rep(conn, msg, msg_size, bufs);
if (rv < 0) goto unpack_err;
rv += hdr_size;
@@ -2172,7 +2316,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr,
/* pass to payload handler */
nonce_in = nonce_pkt;
nonce_map = ECP_ACK_FULL;
- is_open = 1;
+ *is_open_msg = 1;
rv = 0;
break;
}
@@ -2187,16 +2331,16 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr,
}
if (conn) {
- if (is_open) {
+ if (is_open || *is_open_msg) {
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&conn->mutex);
#endif
conn->nonce_in = nonce_in;
conn->nonce_map = nonce_map;
- if (is_inb) {
- conn->access_ts = ecp_tm_get_tick();
- if (addr) conn->remote.addr = *addr;
+ conn->access_ts = ecp_tm_get_s();
+ if (is_inb && addr) {
+ conn->remote.addr = *addr;
}
#ifdef ECP_WITH_PTHREAD
@@ -2219,13 +2363,14 @@ unpack_err:
}
ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t pkt_size) {
- ECPConnection *conn = NULL;
+ ECPConnection *conn;
unsigned char *payload;
+ int is_open_msg;
ecp_seq_t seq;
size_t pld_size;
ssize_t rv;
- rv = ecp_unpack(sock, parent, addr, bufs, pkt_size, &conn, &payload, &seq);
+ rv = ecp_unpack(sock, parent, addr, bufs, pkt_size, &conn, &payload, &seq, &is_open_msg);
if (rv < 0) return rv;
pld_size = pkt_size - rv;
@@ -2235,7 +2380,7 @@ ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *ad
}
if (pld_size) {
- rv = ecp_ext_pld_store(conn, seq, payload, pld_size, bufs);
+ rv = ecp_ext_pld_handle(conn, seq, payload, pld_size, bufs);
if (rv < 0) goto pkt_handle_fin;
payload += rv;
@@ -2250,6 +2395,16 @@ ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *ad
pld_size -= rv;
}
+ if (is_open_msg) {
+ int _rv;
+
+ _rv = ecp_handle_open(conn, bufs);
+ if (_rv) {
+ rv = _rv;
+ goto pkt_handle_fin;
+ }
+ }
+
rv = pkt_size - pld_size;
pkt_handle_fin:
@@ -2483,8 +2638,8 @@ int ecp_pld_get_frag(unsigned char *pld, size_t pld_size, unsigned char *frag_cn
*frag_cnt = pld[1];
*frag_tot = pld[2];
*frag_size = \
- (pld[3] << 8) | \
- (pld[4]);
+ ((uint16_t)pld[3] << 8) | \
+ ((uint16_t)pld[4]);
return ECP_OK;
}
diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h
index 4b47bcb..9be0dc0 100644
--- a/ecp/src/ecp/core.h
+++ b/ecp/src/ecp/core.h
@@ -15,18 +15,18 @@
#define ECP_ERR_ALLOC -3
#define ECP_ERR_SIZE -4
#define ECP_ERR_BUSY -5
-#define ECP_ERR_EMPTY -6
-#define ECP_ERR_FULL -7
-#define ECP_ERR_MTYPE -8
-#define ECP_ERR_CTYPE -9
-#define ECP_ERR_HANDLER -10
-#define ECP_ERR_COOKIE -11
-
-#define ECP_ERR_NET_ADDR -12
-#define ECP_ERR_MAX_PARENT -13
-#define ECP_ERR_NEXT -14
-
-#define ECP_ERR_ECDH_KEY_DUP -21
+#define ECP_ERR_DUP -6
+#define ECP_ERR_EMPTY -7
+#define ECP_ERR_FULL -8
+#define ECP_ERR_MTYPE -9
+#define ECP_ERR_CTYPE -10
+#define ECP_ERR_HANDLER -11
+#define ECP_ERR_COOKIE -12
+
+#define ECP_ERR_NET_ADDR -13
+#define ECP_ERR_MAX_PARENT -14
+#define ECP_ERR_NEXT -15
+
#define ECP_ERR_ECDH_IDX -22
#define ECP_ERR_ENCRYPT -26
#define ECP_ERR_DECRYPT -27
@@ -43,6 +43,7 @@
#define ECP_MAX_CONN_KEY 2
#define ECP_MAX_NODE_KEY 2
#define ECP_MAX_CTYPE 8
+#define ECP_MAX_CTYPE_SYS 3
#define ECP_MAX_MTYPE 16
#define ECP_MAX_PARENT 3
#define ECP_MAX_SEQ_FWD 1024
@@ -121,31 +122,37 @@
#define ECP_CONN_FLAG_INB 0x80
#define ECP_CONN_FLAG_VBOX 0x01
#define ECP_CONN_FLAG_RBUF 0x02
+#define ECP_CONN_FLAG_GC 0x04
#define ECP_CONN_FLAG_MASK 0x7F
/* mutable flags */
-#define ECP_CONN_FLAG_REG 0x04
-#define ECP_CONN_FLAG_OPEN 0x08
+#define ECP_CONN_FLAG_REG 0x01
+#define ECP_CONN_FLAG_OPEN 0x02
+#define ECP_CONN_FLAG_CLOSED 0x04
#define ECP_SEND_FLAG_REPLY 0x01
#define ECP_SEND_FLAG_MORE 0x02
#define ecp_conn_has_vbox(conn) ((conn)->flags_im & ECP_CONN_FLAG_VBOX)
#define ecp_conn_has_rbuf(conn) ((conn)->flags_im & ECP_CONN_FLAG_RBUF)
+#define ecp_conn_is_gc(conn) ((conn)->flags_im & ECP_CONN_FLAG_GC)
#define ecp_conn_is_inb(conn) ((conn)->flags_im & ECP_CONN_FLAG_INB)
#define ecp_conn_is_outb(conn) (!((conn)->flags_im & ECP_CONN_FLAG_INB))
-#define ecp_conn_is_reg(conn) ((conn)->flags & ECP_CONN_FLAG_REG)
-#define ecp_conn_is_open(conn) ((conn)->flags & ECP_CONN_FLAG_OPEN)
#define ecp_conn_is_sys(conn) ((conn)->type & ECP_CTYPE_FLAG_SYS)
+#define _ecp_conn_is_reg(conn) ((conn)->flags & ECP_CONN_FLAG_REG)
+#define _ecp_conn_is_open(conn) ((conn)->flags & ECP_CONN_FLAG_OPEN)
+#define _ecp_conn_is_closed(conn) ((conn)->flags & ECP_CONN_FLAG_CLOSED)
#define ecp_conn_set_inb(conn) ((conn)->flags_im |= ECP_CONN_FLAG_INB)
#define ecp_conn_set_outb(conn) ((conn)->flags_im &= ~ECP_CONN_FLAG_INB)
-#define ecp_conn_set_reg(conn) ((conn)->flags |= ECP_CONN_FLAG_REG)
-#define ecp_conn_set_open(conn) ((conn)->flags |= ECP_CONN_FLAG_OPEN)
+#define _ecp_conn_set_reg(conn) ((conn)->flags |= ECP_CONN_FLAG_REG)
+#define _ecp_conn_set_open(conn) ((conn)->flags |= ECP_CONN_FLAG_OPEN)
+#define _ecp_conn_set_closed(conn) ((conn)->flags |= ECP_CONN_FLAG_CLOSED)
-#define ecp_conn_clr_reg(conn) ((conn)->flags &= ~ECP_CONN_FLAG_REG)
-#define ecp_conn_clr_open(conn) ((conn)->flags &= ~ECP_CONN_FLAG_OPEN)
+#define _ecp_conn_clr_reg(conn) ((conn)->flags &= ~ECP_CONN_FLAG_REG)
+#define _ecp_conn_clr_open(conn) ((conn)->flags &= ~ECP_CONN_FLAG_OPEN)
+#define _ecp_conn_clr_closed(conn) ((conn)->flags &= ~ECP_CONN_FLAG_CLOSED)
typedef uint32_t ecp_ack_t;
#define ECP_SIZE_ACKB (sizeof(ecp_ack_t)*8)
@@ -174,9 +181,8 @@ typedef uint64_t ecp_nonce_t;
struct ECP2Buffer;
struct ECPSocket;
struct ECPConnection;
-
-#ifdef ECP_WITH_DIRSRV
-struct ECPDirList;
+#ifdef ECP_WITH_FRAG
+struct ECPFragIter;
#endif
#ifdef ECP_WITH_HTABLE
@@ -186,15 +192,16 @@ struct ECPDirList;
#include "transport.h"
#include "timer.h"
+typedef int (*ecp_conn_expired_t) (struct ECPConnection *conn, ecp_sts_t now, ecp_sts_t to);
+
typedef void (*ecp_err_handler_t) (struct ECPConnection *conn, unsigned char mtype, int err);
-typedef ssize_t (*ecp_dir_handler_t) (struct ECPConnection *conn, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b);
-typedef struct ECPConnection * (*ecp_conn_alloc_t) (struct ECPSocket *sock, unsigned char type);
+typedef struct ECPConnection * (*ecp_conn_new_t) (struct ECPSocket *sock, unsigned char type);
typedef void (*ecp_conn_free_t) (struct ECPConnection *conn);
typedef ssize_t (*ecp_msg_handler_t) (struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b);
typedef int (*ecp_open_handler_t) (struct ECPConnection *conn, struct ECP2Buffer *b);
typedef void (*ecp_close_handler_t) (struct ECPConnection *conn);
-typedef ssize_t (*ecp_open_send_t) (struct ECPConnection *conn, unsigned char *cookie);
+typedef ssize_t (*ecp_send_open_t) (struct ECPConnection *conn, unsigned char *cookie);
typedef struct ECPBuffer {
unsigned char *buffer;
@@ -241,24 +248,21 @@ typedef struct ECPConnHandler {
ecp_msg_handler_t handle_msg;
ecp_open_handler_t handle_open;
ecp_close_handler_t handle_close;
- ecp_open_send_t send_open;
+ ecp_send_open_t send_open;
} ECPConnHandler;
typedef struct ECPContext {
ecp_err_handler_t handle_err;
- ecp_dir_handler_t handle_dir;
- ecp_conn_alloc_t conn_alloc;
+ ecp_conn_new_t conn_new; /* inbound connections only */
ecp_conn_free_t conn_free;
ECPConnHandler *handler[ECP_MAX_CTYPE];
-#ifdef ECP_WITH_DIRSRV
- struct ECPDirSrv *dir_srv;
-#endif
+ ECPConnHandler *handler_sys[ECP_MAX_CTYPE_SYS];
} ECPContext;
typedef struct ECPConnTable {
#ifdef ECP_WITH_HTABLE
ecp_ht_table_t *keys;
- ecp_ht_table_t *keys_inb;
+ ecp_ht_table_t *keys_gc;
ecp_ht_table_t *addrs;
#else
struct ECPConnection *arr[ECP_MAX_SOCK_CONN];
@@ -266,7 +270,7 @@ typedef struct ECPConnTable {
#endif
#ifdef ECP_WITH_PTHREAD
pthread_mutex_t mutex;
- pthread_mutex_t mutex_inb;
+ pthread_mutex_t mutex_gc;
#endif
} ECPConnTable;
@@ -304,70 +308,79 @@ typedef struct ECPConnection {
unsigned char rkey_curr;
ECPDHShkey shkey[ECP_MAX_NODE_KEY][ECP_MAX_NODE_KEY];
ecp_sts_t access_ts;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_t mutex;
-#endif
+ void *param;
#ifdef ECP_WITH_VCONN
struct ECPConnection *parent;
- struct ECPConnection *next;
unsigned short pcount;
#endif
+#ifdef ECP_WITH_FRAG
+ struct ECPFragIter *iter;
+#endif
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_t mutex;
+#endif
} ECPConnection;
int ecp_dhkey_gen(ECPDHKey *key);
-int ecp_init(ECPContext *ctx);
-int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_dir_handler_t handle_dir, ecp_conn_alloc_t conn_alloc, ecp_conn_free_t conn_free);
-int ecp_ctx_set_handler(ECPContext *ctx, ECPConnHandler *handler, unsigned char ctype);
+int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free);
+int ecp_ctx_set_handler(ECPContext *ctx, unsigned char ctype, ECPConnHandler *handler);
+ECPConnHandler *ecp_ctx_get_handler(ECPContext *ctx, unsigned char ctype);
+
+int ecp_addr_init(ecp_tr_addr_t *addr, void *addr_s);
-int ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, void *addr);
+void ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr);
void ecp_node_set_pub(ECPNode *node, ecp_ecdh_public_t *public);
int ecp_node_set_addr(ECPNode *node, void *addr);
int ecp_sock_init(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key);
int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key);
void ecp_sock_destroy(ECPSocket *sock);
-int ecp_sock_open(ECPSocket *sock, void *myaddr);
+int ecp_sock_open(ECPSocket *sock, ecp_tr_addr_t *myaddr);
void ecp_sock_close(ECPSocket *sock);
int ecp_sock_minkey_new(ECPSocket *sock);
int ecp_sock_dhkey_new(ECPSocket *sock);
int ecp_sock_dhkey_get(ECPSocket *sock, unsigned char idx, ECPDHKey *key);
int ecp_sock_dhkey_get_pub(ECPSocket *sock, unsigned char *idx, ecp_ecdh_public_t *public);
void ecp_sock_get_nonce(ECPSocket *sock, ecp_nonce_t *nonce);
+
+void ecp_sock_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t conn_expired);
int ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to);
int ecp_cookie_gen(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf);
int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf);
-int ecp_conn_alloc(ECPSocket *sock, unsigned char ctype, ECPConnection **_conn);
-void ecp_conn_free(ECPConnection *conn);
-
+ECPConnection *ecp_conn_new_inb(ECPSocket *sock, unsigned char ctype);
void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype);
-void ecp_conn_reinit(ECPConnection *conn);
-int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype);
-int ecp_conn_create_inb(ECPConnection *conn, ECPSocket *sock, unsigned char ctype);
+int ecp_conn_reset(ECPConnection *conn);
+int ecp_conn_create(ECPConnection *conn, ECPConnection *parent);
+int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *remote_key, ecp_aead_key_t *shkey);
+int ecp_conn_create_outb(ECPConnection *conn, ECPConnection *parent, ECPNode *node);
+int ecp_conn_reset_outb(ECPConnection *conn);
void ecp_conn_destroy(ECPConnection *conn);
-
-void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags);
-void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags);
-void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key);
-void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr);
-
-int ecp_conn_init_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *remote_key, ecp_aead_key_t *shkey);
-int ecp_conn_init_outb(ECPConnection *conn, ECPNode *node);
+void ecp_conn_free(ECPConnection *conn);
int ecp_conn_insert(ECPConnection *conn);
-int ecp_conn_insert_inb(ECPConnection *conn);
+int ecp_conn_insert_gc(ECPConnection *conn);
void ecp_conn_remove(ECPConnection *conn, unsigned short *refcount);
void ecp_conn_remove_addr(ECPConnection *conn);
+int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, ECPNode *node, int retry);
int ecp_conn_open(ECPConnection *conn, ECPNode *node);
-int ecp_conn_reset(ECPConnection *conn);
+int ecp_conn_try_open(ECPConnection *conn, ECPNode *node);
int _ecp_conn_close(ECPConnection *conn);
int ecp_conn_close(ECPConnection *conn);
+void ecp_conn_mark_closed(ECPConnection *conn);
+int _ecp_conn_expired(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to);
+int ecp_conn_is_zombie(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to);
void ecp_conn_refcount_inc(ECPConnection *conn);
void ecp_conn_refcount_dec(ECPConnection *conn);
+void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags);
+void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags);
+void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key);
+void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr);
+
int ecp_conn_dhkey_new(ECPConnection *conn);
int ecp_conn_dhkey_get(ECPConnection *conn, unsigned char idx, ECPDHKey *key);
int ecp_conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx, ECPDHPub *key);
@@ -375,24 +388,26 @@ int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_pub
int ecp_conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_public_t *public);
void ecp_conn_dhkey_set_curr(ECPConnection *conn);
-void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_open_send_t send_open);
+void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_send_open_t send_open);
ecp_msg_handler_t ecp_get_msg_handler(ECPConnection *conn);
ecp_open_handler_t ecp_get_open_handler(ECPConnection *conn);
ecp_close_handler_t ecp_get_close_handler(ECPConnection *conn);
-ecp_dir_handler_t ecp_get_dir_handler(ECPConnection *conn);
+ecp_send_open_t ecp_get_send_open_f(ECPConnection *conn);
void ecp_err_handle(ECPConnection *conn, unsigned char mtype, int err);
-ssize_t ecp_send_init_req(ECPConnection *conn);
-ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey);
+ssize_t ecp_send_init_req(ECPConnection *conn, int retry);
+ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey, ECP2Buffer *bufs);
ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey);
-ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size);
+ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs);
+
ssize_t ecp_write_open_req(ECPConnection *conn, ECPBuffer *payload);
ssize_t ecp_send_open_req(ECPConnection *conn, unsigned char *cookie);
ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, unsigned char *public_buf, unsigned char *msg, size_t msg_size, ecp_aead_key_t *shkey, ECPConnection **_conn);
ssize_t ecp_send_open_rep(ECPConnection *conn);
-ssize_t ecp_handle_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs);
+ssize_t ecp_check_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size);
+int ecp_handle_open(ECPConnection *conn, ECP2Buffer *bufs);
-ssize_t ecp_send_keyx_req(ECPConnection *conn);
+ssize_t ecp_send_keyx_req(ECPConnection *conn, int retry);
ssize_t ecp_send_keyx_rep(ECPConnection *conn);
ssize_t ecp_handle_keyx(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs);
@@ -400,7 +415,7 @@ ssize_t ecp_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype,
ssize_t ecp_pld_handle_one(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs);
ssize_t ecp_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t _pld_size, ECP2Buffer *bufs);
-ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t _pkt_size, ECPConnection **_conn, unsigned char **_payload, ecp_seq_t *_seq);
+ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t _pkt_size, ECPConnection **_conn, unsigned char **_payload, ecp_seq_t *_seq, int *is_open_msg);
ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t pkt_size);
ssize_t ecp_pkt_send(ECPSocket *sock, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ecp_tr_addr_t *addr);
diff --git a/ecp/src/ecp/crypto/crypto.c b/ecp/src/ecp/crypto/crypto.c
index 6841e9d..ba013fa 100644
--- a/ecp/src/ecp/crypto/crypto.c
+++ b/ecp/src/ecp/crypto/crypto.c
@@ -1,8 +1,8 @@
#include <stdlib.h>
#include <string.h>
-#include <core.h>
-#include <cr.h>
+#include <ecp/core.h>
+#include <ecp/cr.h>
#include <openssl/curve25519.h>
diff --git a/ecp/src/ecp/dir/Makefile b/ecp/src/ecp/dir/Makefile
index 9283144..a002b65 100644
--- a/ecp/src/ecp/dir/Makefile
+++ b/ecp/src/ecp/dir/Makefile
@@ -2,10 +2,6 @@ include ../common.mk
obj = dir.o
-ifeq ($(with_dirsrv),yes)
-obj += dir_srv.o
-endif
-
%.o: %.c
$(CC) $(CFLAGS) -c $<
diff --git a/ecp/src/ecp/dir/dir.c b/ecp/src/ecp/dir/dir.c
index 72097c7..d826e24 100644
--- a/ecp/src/ecp/dir/dir.c
+++ b/ecp/src/ecp/dir/dir.c
@@ -1,131 +1,72 @@
#include <stdlib.h>
#include <string.h>
-#include <core.h>
-#include <cr.h>
+#include <ecp/core.h>
+#include <ecp/cr.h>
#include "dir.h"
-#include "dir_srv.h"
-static int dir_update(ECPDirList *list, ECPDirItem *item) {
- int i;
-
- for (i=0; i<list->count; i++) {
- if (memcmp(&list->item[i].node.key_perma.public, &item->node.key_perma.public, sizeof(item->node.key_perma.public)) == 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_parse(ECPDirList *list, unsigned char *buf, size_t buf_size) {
- ECPDirItem item;
- size_t rsize;
- uint16_t count;
- int i;
- int rv;
-
- if (buf_size < sizeof(uint16_t)) return ECP_ERR_SIZE;
-
- count = \
- (buf[0] << 8) | \
- (buf[1]);
-
- rsize = sizeof(uint16_t) + count * ECP_SIZE_DIR_ITEM;
- if (buf_size < rsize) return ECP_ERR_SIZE;
-
- buf += sizeof(uint16_t);
- for (i=0; i<count; i++) {
- ecp_dir_item_parse(&item, buf);
-
- rv = dir_update(list, &item);
- if (rv) return rv;
-
- buf += ECP_SIZE_DIR_ITEM;
- }
-
- return rsize;
-}
-
-ssize_t ecp_dir_serialize(ECPDirList *list, unsigned char *buf, size_t buf_size) {
- size_t rsize;
- int i;
-
- rsize = sizeof(uint16_t) + list->count * ECP_SIZE_DIR_ITEM;
- if (buf_size < rsize) return ECP_ERR_SIZE;
-
- buf[0] = (list->count & 0xFF00) >> 8;
- buf[1] = (list->count & 0x00FF);
- buf += sizeof(uint16_t);
- for (i=0; i<list->count; i++) {
- ecp_dir_item_serialize(&list->item[i], buf);
- buf += ECP_SIZE_DIR_ITEM;
- }
-
- return rsize;
-}
-
-void ecp_dir_item_parse(ECPDirItem *item, unsigned char *buf) {
+size_t ecp_dir_item_parse(ECPDirItem *item, unsigned char *buf) {
ECPDHPub *key;
ecp_tr_addr_t *addr;
+ size_t rsize = 0;
+
+ memset(item, 0, sizeof(ECPDirItem));
key = &item->node.key_perma;
addr = &item->node.addr;
+ key->valid = 1;
memcpy(&key->public, buf, sizeof(key->public));
buf += sizeof(key->public);
+ rsize += sizeof(key->public);
memcpy(&addr->host, buf, sizeof(addr->host));
buf += sizeof(addr->host);
+ rsize += sizeof(addr->host);
addr->port = \
- (buf[0] << 8) | \
- (buf[1]);
+ ((uint16_t)buf[0] << 8) | \
+ ((uint16_t)buf[1]);
buf += sizeof(uint16_t);
+ rsize += sizeof(uint16_t);
item->capabilities = \
- (buf[0] << 8) | \
- (buf[1]);
+ ((uint16_t)buf[0] << 8) | \
+ ((uint16_t)buf[1]);
buf += sizeof(uint16_t);
+ rsize += sizeof(uint16_t);
+
+ return rsize;
}
-void ecp_dir_item_serialize(ECPDirItem *item, unsigned char *buf) {
+size_t ecp_dir_item_serialize(ECPDirItem *item, unsigned char *buf) {
ECPDHPub *key;
ecp_tr_addr_t *addr;
+ size_t rsize = 0;
key = &item->node.key_perma;
addr = &item->node.addr;
memcpy(buf, &key->public, sizeof(key->public));
buf += sizeof(key->public);
+ rsize += sizeof(key->public);
memcpy(buf, &addr->host, sizeof(addr->host));
buf += sizeof(addr->host);
+ rsize += sizeof(addr->host);
- buf[0] = (addr->port & 0xFF00) >> 8;
- buf[1] = (addr->port & 0x00FF);
+ buf[0] = addr->port >> 8;
+ buf[1] = addr->port;
buf += sizeof(uint16_t);
+ rsize += sizeof(uint16_t);
- buf[0] = (item->capabilities & 0xFF00) >> 8;
- buf[1] = (item->capabilities & 0x00FF);
+ buf[0] = item->capabilities >> 8;
+ buf[1] = item->capabilities;
buf += sizeof(uint16_t);
-}
-
-ssize_t ecp_dir_handle(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
- ecp_dir_handler_t handler;
+ rsize += sizeof(uint16_t);
- handler = ecp_get_dir_handler(conn);
- if (handler) {
- return handler(conn, msg, msg_size, b);
- } else {
- return ECP_ERR_HANDLER;
- }
+ return rsize;
}
int ecp_dir_handle_open(ECPConnection *conn, ECP2Buffer *b) {
@@ -133,41 +74,12 @@ int ecp_dir_handle_open(ECPConnection *conn, ECP2Buffer *b) {
if (ecp_conn_is_inb(conn)) return ECP_OK;
-#ifdef ECP_WITH_DIRSRV
- rv = ecp_dir_send_upd(conn);
-#else
rv = ecp_dir_send_req(conn);
-#endif
if (rv < 0) return rv;
return ECP_OK;
}
-ssize_t ecp_dir_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
- switch (mtype) {
-#ifdef ECP_WITH_DIRSRV
- case ECP_MTYPE_DIR_UPD: {
- return ecp_dir_handle_upd(conn, msg, msg_size);
- }
-
- case ECP_MTYPE_DIR_REQ: {
- return ecp_dir_handle_req(conn, msg, msg_size);
- }
-#endif
-
- case ECP_MTYPE_DIR_REP: {
-#ifdef ECP_WITH_DIRSRV
- return ecp_dir_handle_rep(conn, msg, msg_size);
-#else
- return ecp_dir_handle(conn, msg, msg_size, b);
-#endif
- }
-
- default:
- return ECP_ERR_MTYPE;
- }
-}
-
static ssize_t _dir_send_req(ECPConnection *conn, ECPTimerItem *ti) {
ECPBuffer packet;
ECPBuffer payload;
@@ -187,15 +99,6 @@ ssize_t ecp_dir_send_req(ECPConnection *conn) {
return ecp_timer_send(conn, _dir_send_req, ECP_MTYPE_DIR_REP, ECP_SEND_TRIES, ECP_SEND_TIMEOUT);
}
-int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ECPNode *node) {
- int rv;
- ssize_t _rv;
-
- rv = ecp_conn_create(conn, sock, ECP_CTYPE_DIR);
- if (rv) return rv;
-
- rv = ecp_conn_open(conn, node);
- if (rv) return rv;
-
- return ECP_OK;
+void ecp_dir_conn_init(ECPConnection *conn, ECPSocket *sock) {
+ ecp_conn_init(conn, sock, ECP_CTYPE_DIR);
}
diff --git a/ecp/src/ecp/dir/dir.h b/ecp/src/ecp/dir/dir.h
index e9f8e1e..b28f801 100644
--- a/ecp/src/ecp/dir/dir.h
+++ b/ecp/src/ecp/dir/dir.h
@@ -1,32 +1,24 @@
-#define ECP_MAX_DIR_ITEM 30
#define ECP_SIZE_DIR_ITEM 40
#define ECP_MTYPE_DIR_UPD 0x00
#define ECP_MTYPE_DIR_REQ 0x01
-#define ECP_MTYPE_DIR_REP 0x02
+#define ECP_MTYPE_DIR_ANN 0x02
+#define ECP_MTYPE_DIR_REP 0x03
+#define ECP_MTYPE_DIR_SHADOW 0x04
#define ECP_CTYPE_DIR (0x00 | ECP_CTYPE_FLAG_SYS)
+#define ECP_DIR_CAP_DIR 0x01
+#define ECP_DIR_CAP_VCONN 0x02
+
typedef struct ECPDirItem {
ECPNode node;
uint16_t capabilities;
} ECPDirItem;
-typedef struct ECPDirList {
- ECPDirItem item[ECP_MAX_DIR_ITEM];
- uint16_t count;
-} ECPDirList;
-
-ssize_t ecp_dir_parse(ECPDirList *list, unsigned char *buf, size_t buf_size);
-ssize_t ecp_dir_serialize(ECPDirList *list, unsigned char *buf, size_t buf_size);
-
-void ecp_dir_item_parse(ECPDirItem *item, unsigned char *buf);
-void ecp_dir_item_serialize(ECPDirItem *item, unsigned char *buf);
-
-ssize_t ecp_dir_handle(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *b);
+size_t ecp_dir_item_parse(ECPDirItem *item, unsigned char *buf);
+size_t ecp_dir_item_serialize(ECPDirItem *item, unsigned char *buf);
int ecp_dir_handle_open(ECPConnection *conn, ECP2Buffer *b);
-ssize_t ecp_dir_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b);
-
ssize_t ecp_dir_send_req(ECPConnection *conn);
-int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ECPNode *node); \ No newline at end of file
+void ecp_dir_conn_init(ECPConnection *conn, ECPSocket *sock); \ No newline at end of file
diff --git a/ecp/src/ecp/dir/dir_srv.c b/ecp/src/ecp/dir/dir_srv.c
deleted file mode 100644
index cbaafc5..0000000
--- a/ecp/src/ecp/dir/dir_srv.c
+++ /dev/null
@@ -1,143 +0,0 @@
-#include <stdlib.h>
-
-#include <core.h>
-#include <cr.h>
-
-#include "dir.h"
-#include "dir_srv.h"
-
-int ecp_dir_create(ECPContext *ctx, ECPDirSrv *dir_srv, ECPDirList *dir_online, ECPDirList *dir_shadow) {
- int rv;
-
-#ifdef ECP_WITH_PTHREAD
- rv = pthread_mutex_init(&dir_srv->online.mutex, NULL);
- if (rv) return ECP_ERR;
-
- rv = pthread_mutex_init(&dir_srv->shadow.mutex, NULL);
- if (rv) {
- pthread_mutex_destroy(&dir_srv->online.mutex);
- return ECP_ERR;
- }
-#endif
-
- dir_srv->online.list = dir_online;
- dir_srv->shadow.list = dir_shadow;
- ctx->dir_srv = dir_srv;
-
- return ECP_OK;
-}
-
-void ecp_dir_destroy(ECPContext *ctx) {
- ECPDirSrv *dir_srv = ctx->dir_srv;
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_destroy(&dir_srv->shadow.mutex);
- pthread_mutex_destroy(&dir_srv->online.mutex);
-#endif
-
-}
-
-ssize_t ecp_dir_send_list(ECPConnection *conn, unsigned char mtype, ECPDirTable *dir_table) {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_MAX_PKT];
- unsigned char pld_buf[ECP_MAX_PLD];
- unsigned char *msg;
- size_t hdr_size;
- size_t msg_size;
- ssize_t rv;
-
- packet.buffer = pkt_buf;
- packet.size = ECP_MAX_PKT;
- payload.buffer = pld_buf;
- payload.size = ECP_MAX_PLD;
-
- ecp_pld_set_type(payload.buffer, payload.size, mtype);
- msg = ecp_pld_get_msg(payload.buffer, payload.size);
- hdr_size = msg - payload.buffer;
- msg_size = payload.size - hdr_size;
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&dir_table->mutex);
-#endif
-
- rv = ecp_dir_serialize(dir_table->list, msg, msg_size);
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&dir_table->mutex);
-#endif
-
- if (rv < 0) return rv;
-
- rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(rv, mtype), 0);
- return rv;
-}
-
-ssize_t ecp_dir_send_upd(ECPConnection *conn) {
- ECPDirSrv *dir_srv = conn->sock->ctx->dir_srv;
- ECPDirTable *dir_table = &dir_srv->shadow;
- ssize_t rv;
-
- rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_UPD, dir_table);
- return rv;
-}
-
-ssize_t ecp_dir_handle_upd(ECPConnection *conn, unsigned char *msg, size_t msg_size) {
- ECPDirSrv *dir_srv = conn->sock->ctx->dir_srv;
- ECPDirTable *dir_table = &dir_srv->shadow;
- ssize_t rsize;
- ssize_t rv;
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&dir_table->mutex);
-#endif
-
- rsize = ecp_dir_parse(dir_table->list, msg, msg_size);
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&dir_table->mutex);
-#endif
-
- if (rsize < 0) return rsize;
-
- rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_REP, dir_table);
- if (rv < 0) return rv;
-
- return rsize;
-}
-
-ssize_t ecp_dir_handle_req(ECPConnection *conn, unsigned char *msg, size_t msg_size) {
- ssize_t rv;
-
- rv = ecp_dir_send_rep(conn);
- if (rv < 0) return rv;
-
- return 0;
-}
-
-ssize_t ecp_dir_send_rep(ECPConnection *conn) {
- ECPDirSrv *dir_srv = conn->sock->ctx->dir_srv;
- ECPDirTable *dir_table = &dir_srv->online;
- ssize_t rv;
-
- rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_REP, dir_table);
- return rv;
-}
-
-ssize_t ecp_dir_handle_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size) {
- ECPDirSrv *dir_srv = conn->sock->ctx->dir_srv;
- ECPDirTable *dir_table = &dir_srv->shadow;
- ssize_t rv;
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&dir_table->mutex);
-#endif
-
- rv = ecp_dir_parse(dir_table->list, msg, msg_size);
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&dir_table->mutex);
-#endif
-
- return rv;
-}
diff --git a/ecp/src/ecp/dir/dir_srv.h b/ecp/src/ecp/dir/dir_srv.h
deleted file mode 100644
index 5e107df..0000000
--- a/ecp/src/ecp/dir/dir_srv.h
+++ /dev/null
@@ -1,23 +0,0 @@
-typedef struct ECPDirTable {
- ECPDirList *list;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_t mutex;
-#endif
-} ECPDirTable;
-
-typedef struct ECPDirSrv {
- ECPDirTable online;
- ECPDirTable shadow;
-} ECPDirSrv;
-
-int ecp_dir_create(ECPContext *ctx, ECPDirSrv *dir_srv, ECPDirList *dir_online, ECPDirList *dir_shadow);
-void ecp_dir_destroy(ECPContext *ctx);
-ssize_t ecp_dir_send_list(ECPConnection *conn, unsigned char mtype, ECPDirTable *list);
-
-ssize_t ecp_dir_send_upd(ECPConnection *conn);
-ssize_t ecp_dir_handle_upd(ECPConnection *conn, unsigned char *msg, size_t msg_size);
-
-ssize_t ecp_dir_handle_req(ECPConnection *conn, unsigned char *msg, size_t msg_size);
-
-ssize_t ecp_dir_send_rep(ECPConnection *conn);
-ssize_t ecp_dir_handle_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size);
diff --git a/ecp/src/ecp/ext.h b/ecp/src/ecp/ext.h
index 4c91000..d661329 100644
--- a/ecp/src/ecp/ext.h
+++ b/ecp/src/ecp/ext.h
@@ -1,23 +1,36 @@
+#ifdef ECP_WITH_FRAG
+
+ssize_t ecp_ext_pld_handle_one(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs);
+ssize_t ecp_ext_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload);
+
+#else
+
+#define ecp_ext_pld_handle_one(c,s,p,sz,b) (0)
+#define ecp_ext_msg_send(c,t,m,sz,p1,p2) (0)
+
+#endif
+
#ifdef ECP_WITH_RBUF
int ecp_ext_err_handle(ECPConnection *conn, unsigned char mtype, int err);
-int ecp_ext_conn_open(ECPConnection *conn);
+int ecp_ext_conn_create(ECPConnection *conn);
void ecp_ext_conn_destroy(ECPConnection *conn);
+int ecp_ext_conn_open(ECPConnection *conn);
+void ecp_ext_conn_close(ECPConnection *conn);
+
ssize_t ecp_ext_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs);
-ssize_t ecp_ext_pld_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs);
ssize_t ecp_ext_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs);
ssize_t ecp_ext_pld_send(ECPConnection *conn, ECPBuffer *payload, size_t pld_size, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ecp_tr_addr_t *addr);
-ssize_t ecp_ext_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload);
#else
#define ecp_ext_err_handle(c,t,e) (ECP_PASS)
-#define ecp_ext_conn_open(c) (ECP_OK)
+#define ecp_ext_conn_create(c) (0)
#define ecp_ext_conn_destroy(c) ;
+#define ecp_ext_conn_open(c) (ECP_OK)
+#define ecp_ext_conn_close(c) ;
#define ecp_ext_msg_handle(c,s,t,m,sz,b) (0)
-#define ecp_ext_pld_store(c,s,p,sz,b) (0)
#define ecp_ext_pld_handle(c,s,p,sz,b) (0)
#define ecp_ext_pld_send(c,p1,sz1,p2,sz2,f,t,a) (0)
-#define ecp_ext_msg_send(c,t,m,sz,p1,p2) (0)
#endif
diff --git a/ecp/src/ecp/ext/Makefile b/ecp/src/ecp/ext/Makefile
index 0e61e83..b20258f 100644
--- a/ecp/src/ecp/ext/Makefile
+++ b/ecp/src/ecp/ext/Makefile
@@ -1,6 +1,18 @@
include ../common.mk
-obj = ext.o frag.o rbuf.o rbuf_send.o rbuf_recv.o msgq.o
+obj =
+
+ifeq ($(with_frag),yes)
+obj += frag.o
+endif
+
+ifeq ($(with_rbuf),yes)
+obj += rbuf.o rbuf_send.o rbuf_recv.o rbuf_ext.o
+endif
+
+ifeq ($(with_msgq),yes)
+obj += msgq.o
+endif
%.o: %.c
diff --git a/ecp/src/ecp/ext/frag.c b/ecp/src/ecp/ext/frag.c
index 58941ba..8795470 100644
--- a/ecp/src/ecp/ext/frag.c
+++ b/ecp/src/ecp/ext/frag.c
@@ -1,12 +1,11 @@
#include <stdlib.h>
#include <string.h>
-#include <core.h>
+#include <ecp/core.h>
-#include "rbuf.h"
#include "frag.h"
-int ecp_frag_iter_init(ECPRBConn *conn, ECPFragIter *iter, unsigned char *buffer, size_t buf_size) {
+int ecp_frag_iter_init(ECPConnection *conn, ECPFragIter *iter, unsigned char *buffer, size_t buf_size) {
memset(iter, 0, sizeof(ECPFragIter));
iter->buffer = buffer;
iter->buf_size = buf_size;
@@ -15,17 +14,64 @@ int ecp_frag_iter_init(ECPRBConn *conn, ECPFragIter *iter, unsigned char *buffer
return ECP_OK;
}
-ECPFragIter *ecp_frag_iter_get(ECPRBConn *conn) {
- return conn->iter;
-}
-
void ecp_frag_iter_reset(ECPFragIter *iter) {
iter->seq = 0;
iter->frag_cnt = 0;
iter->pld_size = 0;
}
-ssize_t ecp_msg_frag(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload) {
+ssize_t ecp_pld_defrag(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *payload, size_t pld_size) {
+ ECPFragIter *iter = conn->iter;
+ unsigned char *msg;
+ unsigned char frag_cnt, frag_tot;
+ uint16_t frag_size;
+ size_t hdr_size, msg_size;
+ size_t buf_offset;
+ int rv;
+
+ rv = ecp_pld_get_frag(payload, pld_size, &frag_cnt, &frag_tot, &frag_size);
+ if (rv) return ECP_ERR;
+
+ msg = ecp_pld_get_msg(payload, pld_size);
+ if (msg == NULL) return ECP_ERR;
+ hdr_size = msg - payload;
+
+ msg_size = pld_size - hdr_size;
+ if (msg_size == 0) return ECP_ERR;
+
+ if (iter->pld_size && (iter->seq + frag_cnt != seq)) ecp_frag_iter_reset(iter);
+
+ if (iter->pld_size == 0) {
+ iter->seq = seq - frag_cnt;
+ iter->frag_cnt = 0;
+ }
+
+ mtype &= ~ECP_MTYPE_FLAG_FRAG;
+ buf_offset = ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype) + frag_size * frag_cnt;
+ if (buf_offset + msg_size > iter->buf_size) return ECP_ERR_SIZE;
+ memcpy(iter->buffer + buf_offset, msg, msg_size);
+
+ if (frag_cnt == 0) {
+ if (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype) > iter->buf_size) return ECP_ERR_SIZE;
+
+ iter->buffer[0] = mtype;
+ if (ECP_SIZE_MT_FLAG(mtype)) {
+ memcpy(iter->buffer + ECP_SIZE_MTYPE, payload + ECP_SIZE_MTYPE, ECP_SIZE_MT_FLAG(mtype));
+ }
+ msg_size += ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype);
+ }
+
+ iter->frag_cnt++;
+ iter->pld_size += msg_size;
+ if (iter->frag_cnt == frag_tot) {
+ ecp_pld_handle_one(conn, iter->seq, iter->buffer, iter->pld_size, NULL);
+ ecp_frag_iter_reset(iter);
+ }
+
+ return pld_size;
+}
+
+ssize_t ecp_msg_send_wfrag(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload) {
unsigned char *msg_buf;
unsigned char *pld_buf;
size_t pld_size;
@@ -72,58 +118,26 @@ ssize_t ecp_msg_frag(ECPConnection *conn, unsigned char mtype, unsigned char *ms
return msg_size;
}
-ssize_t ecp_pld_defrag(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *payload, size_t pld_size) {
- ECPRBConn *_conn = NULL;
- ECPFragIter *iter = NULL;
- unsigned char *msg;
- unsigned char frag_cnt, frag_tot;
- uint16_t frag_size;
- size_t hdr_size, msg_size;
- size_t buf_offset;
- int rv;
-
- _conn = ecp_rbuf_get_rbconn(conn);
- if (_conn) iter = ecp_frag_iter_get(_conn);
- if (iter == NULL) ECP_ERR;
-
- rv = ecp_pld_get_frag(payload, pld_size, &frag_cnt, &frag_tot, &frag_size);
- if (rv) return ECP_ERR;
-
- msg = ecp_pld_get_msg(payload, pld_size);
- if (msg == NULL) return ECP_ERR;
- hdr_size = msg - payload;
-
- msg_size = pld_size - hdr_size;
- if (msg_size == 0) return ECP_ERR;
-
- if (iter->pld_size && (iter->seq + frag_cnt != seq)) ecp_frag_iter_reset(iter);
-
- if (iter->pld_size == 0) {
- iter->seq = seq - frag_cnt;
- iter->frag_cnt = 0;
- }
-
- mtype &= ~ECP_MTYPE_FLAG_FRAG;
- buf_offset = ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype) + frag_size * frag_cnt;
- if (buf_offset + msg_size > iter->buf_size) return ECP_ERR_SIZE;
- memcpy(iter->buffer + buf_offset, msg, msg_size);
+ssize_t ecp_ext_pld_handle_one(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs) {
+ if (conn->iter) {
+ unsigned char mtype;
+ int rv;
- if (frag_cnt == 0) {
- if (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype) > iter->buf_size) return ECP_ERR_SIZE;
+ rv = ecp_pld_get_type(payload, pld_size, &mtype);
+ if (rv) return rv;
- iter->buffer[0] = mtype;
- if (ECP_SIZE_MT_FLAG(mtype)) {
- memcpy(iter->buffer + ECP_SIZE_MTYPE, payload + ECP_SIZE_MTYPE, ECP_SIZE_MT_FLAG(mtype));
+ if (mtype & ECP_MTYPE_FLAG_FRAG) {
+ return ecp_pld_defrag(conn, seq, mtype, payload, pld_size);
}
- msg_size += ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype);
}
- iter->frag_cnt++;
- iter->pld_size += msg_size;
- if (iter->frag_cnt == frag_tot) {
- ecp_pld_handle_one(conn, iter->seq, iter->buffer, iter->pld_size, NULL);
- ecp_frag_iter_reset(iter);
- }
+ return 0;
+}
- return pld_size;
+ssize_t ecp_ext_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload) {
+ if (ECP_SIZE_PKT_BUF(msg_size, mtype, conn) > ECP_MAX_PKT) {
+ return ecp_msg_send_wfrag(conn, mtype, msg, msg_size, packet, payload);
+ } else {
+ return 0;
+ }
}
diff --git a/ecp/src/ecp/ext/frag.h b/ecp/src/ecp/ext/frag.h
index 1400c1d..2bf35d1 100644
--- a/ecp/src/ecp/ext/frag.h
+++ b/ecp/src/ecp/ext/frag.h
@@ -6,8 +6,7 @@ typedef struct ECPFragIter {
size_t pld_size;
} ECPFragIter;
-int ecp_frag_iter_init(ECPRBConn *conn, ECPFragIter *iter, unsigned char *buffer, size_t buf_size);
-ECPFragIter *ecp_frag_iter_get(ECPRBConn *conn);
+int ecp_frag_iter_init(ECPConnection *conn, ECPFragIter *iter, unsigned char *buffer, size_t buf_size);
void ecp_frag_iter_reset(ECPFragIter *iter);
-ssize_t ecp_msg_frag(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload);
-ssize_t ecp_pld_defrag(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *payload, size_t pld_size); \ No newline at end of file
+ssize_t ecp_pld_defrag(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *payload, size_t pld_size);
+ssize_t ecp_msg_send_wfrag(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload);
diff --git a/ecp/src/ecp/ext/msgq.c b/ecp/src/ecp/ext/msgq.c
index e383b03..7172e51 100644
--- a/ecp/src/ecp/ext/msgq.c
+++ b/ecp/src/ecp/ext/msgq.c
@@ -2,7 +2,7 @@
#include <stdlib.h>
#include <string.h>
-#include <core.h>
+#include <ecp/core.h>
#include "rbuf.h"
#include "msgq.h"
@@ -21,13 +21,15 @@ static struct timespec *abstime_ts(struct timespec *ts, ecp_sts_t msec) {
return ts;
}
-int ecp_msgq_create(ECPRBConn *conn, ECPMsgQ *msgq) {
- int i;
- int rv;
+void ecp_msgq_init(ECPRBConn *conn, ECPMsgQ *msgq) {
+ memset(msgq, 0, sizeof(ECPMsgQ));
- if (conn->recv == NULL) return ECP_ERR;
+ conn->recv->msgq = msgq;
+}
- memset(msgq, 0, sizeof(ECPMsgQ));
+int ecp_msgq_create(ECPRBConn *conn) {
+ ECPMsgQ *msgq = conn->recv->msgq;
+ int i, rv;
for (i=0; i<ECP_MSGQ_MAX_MTYPE; i++) {
rv = pthread_cond_init(&msgq->cond[i], NULL);
@@ -40,7 +42,6 @@ int ecp_msgq_create(ECPRBConn *conn, ECPMsgQ *msgq) {
return ECP_ERR;
}
}
- conn->recv->msgq = msgq;
return ECP_OK;
}
@@ -52,8 +53,6 @@ void ecp_msgq_destroy(ECPRBConn *conn) {
for (i=0; i<ECP_MSGQ_MAX_MTYPE; i++) {
pthread_cond_destroy(&msgq->cond[i]);
}
-
- conn->recv->msgq = NULL;
}
void ecp_msgq_start(ECPRBConn *conn, ecp_seq_t seq) {
@@ -117,6 +116,8 @@ ssize_t ecp_msgq_pop(ECPRBConn *conn, unsigned char mtype, unsigned char *msg, s
msg_size = pld_size - hdr_size;
rbuf->arr.pld[idx].flags &= ~ECP_RBUF_FLAG_IN_MSGQ;
+ // if (rbuf->arr.pld[idx].flags == 0);
+
msgq->idx_r[mtype]++;
if (msgq->seq_start == seq) {
int i;
diff --git a/ecp/src/ecp/ext/msgq.h b/ecp/src/ecp/ext/msgq.h
index dddb6e7..669a5af 100644
--- a/ecp/src/ecp/ext/msgq.h
+++ b/ecp/src/ecp/ext/msgq.h
@@ -11,7 +11,8 @@ typedef struct ECPMsgQ {
pthread_cond_t cond[ECP_MSGQ_MAX_MTYPE];
} ECPMsgQ;
-int ecp_msgq_create(ECPRBConn *conn, ECPMsgQ *msgq);
+void ecp_msgq_init(ECPRBConn *conn, ECPMsgQ *msgq);
+int ecp_msgq_create(ECPRBConn *conn);
void ecp_msgq_destroy(ECPRBConn *conn);
void ecp_msgq_start(ECPRBConn *conn, ecp_seq_t seq);
int ecp_msgq_push(ECPRBConn *conn, ecp_seq_t seq, unsigned char mtype);
diff --git a/ecp/src/ecp/ext/rbuf.c b/ecp/src/ecp/ext/rbuf.c
index 70ee0d2..e1fab7b 100644
--- a/ecp/src/ecp/ext/rbuf.c
+++ b/ecp/src/ecp/ext/rbuf.c
@@ -1,6 +1,6 @@
#include <stdlib.h>
-#include <core.h>
+#include <ecp/core.h>
#include "rbuf.h"
@@ -28,41 +28,35 @@ int _ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq, unsigned short *idx) {
return ECP_OK;
}
-void ecp_rbuf_conn_init(ECPRBConn *conn) {
+void ecp_rbuf_init(ECPRBConn *conn) {
ECPConnection *_conn = ecp_rbuf_get_conn(conn);
ecp_conn_set_flags(_conn, ECP_CONN_FLAG_RBUF);
conn->send = NULL;
conn->recv = NULL;
- conn->iter = NULL;
}
-int ecp_rbuf_conn_create(ECPRBConn *conn, ECPSocket *sock, unsigned char type) {
- ECPConnection *_conn = ecp_rbuf_get_conn(conn);
+int ecp_rbuf_create(ECPRBConn *conn) {
int rv;
- rv = ecp_conn_create(_conn, sock, type);
- if (rv) return rv;
-
- ecp_rbuf_conn_init(conn);
- return ECP_OK;
-}
-
-int ecp_rbuf_conn_create_inb(ECPRBConn *conn, ECPSocket *sock, unsigned char type) {
- ECPConnection *_conn = ecp_rbuf_get_conn(conn);
- int rv;
-
- rv = ecp_conn_create_inb(_conn, sock, type);
- if (rv) return rv;
+ if (conn->send) {
+ rv = ecp_rbsend_create(conn);
+ if (rv) return rv;
+ }
+ if (conn->recv) {
+ rv = ecp_rbrecv_create(conn);
+ if (rv) {
+ if (conn->send) ecp_rbsend_destroy(conn);
+ return rv;
+ }
+ }
- ecp_rbuf_conn_init(conn);
return ECP_OK;
}
void ecp_rbuf_destroy(ECPRBConn *conn) {
if (conn->send) ecp_rbsend_destroy(conn);
if (conn->recv) ecp_rbrecv_destroy(conn);
- conn->iter = NULL;
}
void ecp_rbuf_start(ECPRBConn *conn) {
@@ -71,14 +65,32 @@ void ecp_rbuf_start(ECPRBConn *conn) {
if (conn->send) {
ecp_seq_t seq_out;
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&_conn->mutex);
+#endif
+
seq_out = (ecp_seq_t)(_conn->nonce_out);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&_conn->mutex);
+#endif
+
ecp_rbsend_start(conn, seq_out);
}
if (conn->recv) {
ecp_seq_t seq_in;
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&_conn->mutex);
+#endif
+
seq_in = (ecp_seq_t)(_conn->nonce_in);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&_conn->mutex);
+#endif
+
ecp_rbrecv_start(conn, seq_in);
}
}
diff --git a/ecp/src/ecp/ext/rbuf.h b/ecp/src/ecp/ext/rbuf.h
index 36ff963..bf6e6df 100644
--- a/ecp/src/ecp/ext/rbuf.h
+++ b/ecp/src/ecp/ext/rbuf.h
@@ -87,16 +87,14 @@ typedef struct ECPRBConn {
ECPConnection b;
ECPRBRecv *recv;
ECPRBSend *send;
- struct ECPFragIter *iter;
} ECPRBConn;
ECPRBConn *ecp_rbuf_get_rbconn(ECPConnection *conn);
ECPConnection *ecp_rbuf_get_conn(ECPRBConn *conn);
void _ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq);
int _ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq, unsigned short *idx);
-void ecp_rbuf_conn_init(ECPRBConn *conn);
-int ecp_rbuf_conn_create(ECPRBConn *conn, ECPSocket *sock, unsigned char type);
-int ecp_rbuf_conn_create_inb(ECPRBConn *conn, ECPSocket *sock, unsigned char type);
+void ecp_rbuf_init(ECPRBConn *conn);
+int ecp_rbuf_create(ECPRBConn *conn);
void ecp_rbuf_destroy(ECPRBConn *conn);
void ecp_rbuf_start(ECPRBConn *conn);
ssize_t ecp_rbuf_msg_handle(ECPRBConn *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs);
@@ -105,19 +103,23 @@ int ecp_rbuf_err_handle(ECPRBConn *conn, unsigned char mtype, int err);
/* send */
ssize_t ecp_rbuf_send_flush(ECPRBConn *conn);
ssize_t ecp_rbuf_handle_ack(ECPRBConn *conn, unsigned char *msg, size_t msg_size);
-int ecp_rbsend_create(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigned short pkt_size);
+void ecp_rbsend_init(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigned short pkt_size);
+int ecp_rbsend_create(ECPRBConn *conn);
void ecp_rbsend_destroy(ECPRBConn *conn);
void ecp_rbsend_start(ECPRBConn *conn, ecp_seq_t seq);
int ecp_rbuf_set_wsize(ECPRBConn *conn, ecp_win_t size);
int ecp_rbuf_flush(ECPRBConn *conn);
ssize_t ecp_rbuf_pld_send(ECPRBConn *conn, ECPBuffer *payload, size_t pld_size, ECPBuffer *packet, size_t pkt_size, ECPTimerItem *ti);
+/* recv */
ssize_t ecp_rbuf_handle_nop(ECPRBConn *conn, unsigned char *msg, size_t msg_size);
ssize_t ecp_rbuf_handle_flush(ECPRBConn *conn);
-void ecp_rbuf_handle_timer(ECPRBConn *conn) ;
-int ecp_rbrecv_create(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsigned short pld_size);
+void ecp_rbuf_handle_timer(ECPRBConn *conn);
+void ecp_rbrecv_init(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsigned short pld_size);
+int ecp_rbrecv_create(ECPRBConn *conn);
void ecp_rbrecv_destroy(ECPRBConn *conn);
void ecp_rbrecv_start(ECPRBConn *conn, ecp_seq_t seq);
+
int ecp_rbuf_set_hole(ECPRBConn *conn, unsigned short hole_max);
int ecp_rbuf_set_delay(ECPRBConn *conn, ecp_sts_t delay);
ssize_t ecp_rbuf_store(ECPRBConn *conn, ecp_seq_t seq, unsigned char *pld, size_t pld_size);
diff --git a/ecp/src/ecp/ext/ext.c b/ecp/src/ecp/ext/rbuf_ext.c
index d407e80..67b6a8d 100644
--- a/ecp/src/ecp/ext/ext.c
+++ b/ecp/src/ecp/ext/rbuf_ext.c
@@ -1,10 +1,9 @@
#include <stdlib.h>
-#include <core.h>
-#include <ext.h>
+#include <ecp/core.h>
+#include <ecp/ext.h>
#include "rbuf.h"
-#include "frag.h"
int ecp_ext_err_handle(ECPConnection *conn, unsigned char mtype, int err) {
ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn);
@@ -13,44 +12,41 @@ int ecp_ext_err_handle(ECPConnection *conn, unsigned char mtype, int err) {
return ECP_PASS;
}
-int ecp_ext_conn_open(ECPConnection *conn) {
+int ecp_ext_conn_create(ECPConnection *conn) {
ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn);
+ int rv = ECP_OK;
- if (_conn) ecp_rbuf_start(_conn);
- return ECP_OK;
+ if (_conn) rv = ecp_rbuf_create(_conn);
+ return rv;
}
void ecp_ext_conn_destroy(ECPConnection *conn) {
ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn);
+
if (_conn) ecp_rbuf_destroy(_conn);
}
-ssize_t ecp_ext_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
+int ecp_ext_conn_open(ECPConnection *conn) {
ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn);
- if (_conn) return ecp_rbuf_msg_handle(_conn, seq, mtype, msg, msg_size, bufs);
- return 0;
+ if (_conn) ecp_rbuf_start(_conn);
+ return ECP_OK;
}
-ssize_t ecp_ext_pld_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs) {
+void ecp_ext_conn_close(ECPConnection *conn) {}
+
+ssize_t ecp_ext_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn);
- if (_conn && _conn->recv) return ecp_rbuf_store(_conn, seq, payload, pld_size);
+ if (_conn) return ecp_rbuf_msg_handle(_conn, seq, mtype, msg, msg_size, bufs);
return 0;
}
ssize_t ecp_ext_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs) {
- unsigned char mtype;
- int rv;
-
- rv = ecp_pld_get_type(payload, pld_size, &mtype);
- if (rv) return rv;
+ ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn);
- if (mtype & ECP_MTYPE_FLAG_FRAG) {
- return ecp_pld_defrag(conn, seq, mtype, payload, pld_size);
- } else {
- return 0;
- }
+ if (_conn && _conn->recv) return ecp_rbuf_store(_conn, seq, payload, pld_size);
+ return 0;
}
ssize_t ecp_ext_pld_send(ECPConnection *conn, ECPBuffer *payload, size_t pld_size, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ecp_tr_addr_t *addr) {
@@ -59,11 +55,3 @@ ssize_t ecp_ext_pld_send(ECPConnection *conn, ECPBuffer *payload, size_t pld_siz
if (_conn && _conn->send) return ecp_rbuf_pld_send(_conn, payload, pld_size, packet, pkt_size, ti);
return 0;
}
-
-ssize_t ecp_ext_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload) {
- if (ECP_SIZE_PKT_BUF(msg_size, mtype, conn) > ECP_MAX_PKT) {
- return ecp_msg_frag(conn, mtype, msg, msg_size, packet, payload);
- } else {
- return 0;
- }
-}
diff --git a/ecp/src/ecp/ext/rbuf_recv.c b/ecp/src/ecp/ext/rbuf_recv.c
index de25cb6..b981e3f 100644
--- a/ecp/src/ecp/ext/rbuf_recv.c
+++ b/ecp/src/ecp/ext/rbuf_recv.c
@@ -1,8 +1,8 @@
#include <stdlib.h>
#include <string.h>
-#include <core.h>
-#include <tm.h>
+#include <ecp/core.h>
+#include <ecp/tm.h>
#include "rbuf.h"
@@ -89,7 +89,7 @@ static void msg_flush(ECPRBConn *conn) {
rv = ecp_pld_get_pts(rbuf->arr.pld[idx].buf, rbuf->arr.pld[idx].size, &msg_pts);
if (!rv && buf->deliver_delay) {
- ecp_sts_t now = ecp_tm_get_tick();
+ ecp_sts_t now = ecp_tm_get_ms();
msg_pts += buf->deliver_delay;
if (ECP_PTS_LT(now, msg_pts)) {
@@ -122,6 +122,7 @@ static void msg_flush(ECPRBConn *conn) {
rbuf->arr.pld[idx].flags &= ~ECP_RBUF_FLAG_SKIP;
}
rbuf->arr.pld[idx].flags &= ~ECP_RBUF_FLAG_IN_RBUF;
+ // if (rbuf->arr.pld[idx].flags == 0);
} else {
if (buf->flags & ECP_RBUF_FLAG_RELIABLE) break;
if (!ECP_SEQ_LT(seq, rbuf->seq_max - buf->hole_max)) break;
@@ -274,9 +275,8 @@ void ecp_rbuf_handle_timer(ECPRBConn *conn) {
#endif
}
-int ecp_rbrecv_create(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsigned short pld_size) {
+void ecp_rbrecv_init(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsigned short pld_size) {
ECPRBuffer *rbuf = &buf->rbuf;
- int rv;
memset(buf, 0, sizeof(ECPRBRecv));
memset(pld, 0, sizeof(ECPRBPayload) * pld_size);
@@ -286,12 +286,31 @@ int ecp_rbrecv_create(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsign
rbuf->arr.pld = pld;
rbuf->arr_size = pld_size;
+ conn->recv = buf;
+}
+
+int ecp_rbrecv_create(ECPRBConn *conn) {
+ ECPRBRecv *buf = conn->recv;
+ int rv;
+
#ifdef ECP_WITH_PTHREAD
rv = pthread_mutex_init(&buf->mutex, NULL);
if (rv) return ECP_ERR;
#endif
- conn->recv = buf;
+#ifdef ECP_WITH_MSGQ
+ if (buf->msgq) {
+ rv = ecp_msgq_create(conn);
+ if (rv) {
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_destroy(&buf->mutex);
+#endif
+
+ return ECP_ERR;
+ }
+ }
+#endif
+
return ECP_OK;
}
@@ -305,8 +324,6 @@ void ecp_rbrecv_destroy(ECPRBConn *conn) {
#ifdef ECP_WITH_MSGQ
if (buf->msgq) ecp_msgq_destroy(conn);
#endif
-
- conn->recv = NULL;
}
void ecp_rbrecv_start(ECPRBConn *conn, ecp_seq_t seq) {
diff --git a/ecp/src/ecp/ext/rbuf_send.c b/ecp/src/ecp/ext/rbuf_send.c
index d3d2f04..40d526c 100644
--- a/ecp/src/ecp/ext/rbuf_send.c
+++ b/ecp/src/ecp/ext/rbuf_send.c
@@ -1,7 +1,7 @@
#include <stdlib.h>
#include <string.h>
-#include <core.h>
+#include <ecp/core.h>
#include "rbuf.h"
@@ -43,6 +43,7 @@ static void cc_flush(ECPRBConn *conn, unsigned char flags) {
}
if (!(buf->flags & ECP_RBUF_FLAG_RELIABLE)) {
rbuf->arr.pkt[idx].flags = 0;
+ // if (rbuf->arr.pkt[idx].flags == 0);
}
buf->seq_cc++;
idx = ECP_RBUF_IDX_MASK(idx + 1, rbuf->arr_size);
@@ -209,6 +210,7 @@ ssize_t ecp_rbuf_handle_ack(ECPRBConn *conn, unsigned char *msg, size_t msg_size
idx = rbuf->idx_start;
for (i=0; i<msg_cnt; i++) {
rbuf->arr.pkt[idx].flags = 0;
+ // if (rbuf->arr.pkt[idx].flags == 0);
idx = ECP_RBUF_IDX_MASK(idx + 1, rbuf->arr_size);
}
rbuf->seq_start = seq_start;
@@ -237,9 +239,8 @@ handle_ack_fin:
return rsize;
}
-int ecp_rbsend_create(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigned short pkt_size) {
+void ecp_rbsend_init(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigned short pkt_size) {
ECPRBuffer *rbuf = &buf->rbuf;
- int rv;
memset(buf, 0, sizeof(ECPRBRecv));
memset(pkt, 0, sizeof(ECPRBPacket) * pkt_size);
@@ -247,12 +248,18 @@ int ecp_rbsend_create(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigne
rbuf->arr.pkt = pkt;
rbuf->arr_size = pkt_size;
+ conn->send = buf;
+}
+
+int ecp_rbsend_create(ECPRBConn *conn) {
+ ECPRBSend *buf = conn->send;
+ int rv;
+
#ifdef ECP_WITH_PTHREAD
rv = pthread_mutex_init(&buf->mutex, NULL);
if (rv) return ECP_ERR;
#endif
- conn->send = buf;
return ECP_OK;
}
@@ -262,8 +269,6 @@ void ecp_rbsend_destroy(ECPRBConn *conn) {
#ifdef ECP_WITH_PTHREAD
pthread_mutex_destroy(&buf->mutex);
#endif
-
- conn->send = NULL;
}
void ecp_rbsend_start(ECPRBConn *conn, ecp_seq_t seq) {
diff --git a/ecp/src/ecp/ht.h b/ecp/src/ecp/ht.h
index 31ca698..805fbda 100644
--- a/ecp/src/ecp/ht.h
+++ b/ecp/src/ecp/ht.h
@@ -2,13 +2,16 @@ ecp_ht_table_t *ecp_ht_create_keys(void);
ecp_ht_table_t *ecp_ht_create_addrs(void);
void ecp_ht_destroy(ecp_ht_table_t *h);
-int ecp_ht_insert(ecp_ht_table_t *h, void *k, ECPConnection *v);
-ECPConnection *ecp_ht_remove(ecp_ht_table_t *h, void *k);
-ECPConnection *ecp_ht_search(ecp_ht_table_t *h, void *k);
+int ecp_ht_insert(ecp_ht_table_t *h, void *k, void *v);
+void *ecp_ht_remove(ecp_ht_table_t *h, void *k);
+void *ecp_ht_remove_kv(ecp_ht_table_t *h, void *k, void *v);
+void *ecp_ht_search(ecp_ht_table_t *h, void *k);
+void *ecp_ht_search_next(ecp_ht_table_t *h, void *k, void *v);
+unsigned int ecp_ht_count(ecp_ht_table_t *h);
void ecp_ht_itr_create(ecp_ht_itr_t *i, ecp_ht_table_t *h);
int ecp_ht_itr_advance(ecp_ht_itr_t *i);
int ecp_ht_itr_remove(ecp_ht_itr_t *i);
int ecp_ht_itr_search(ecp_ht_itr_t *i, void *k);
void *ecp_ht_itr_key(ecp_ht_itr_t *i);
-ECPConnection *ecp_ht_itr_value(ecp_ht_itr_t *i);
+void *ecp_ht_itr_value(ecp_ht_itr_t *i);
diff --git a/ecp/src/ecp/htable/hashtable.c b/ecp/src/ecp/htable/hashtable.c
index 4a48edb..13ed68c 100755
--- a/ecp/src/ecp/htable/hashtable.c
+++ b/ecp/src/ecp/htable/hashtable.c
@@ -212,6 +212,32 @@ hashtable_search(struct hashtable *h, void *k)
}
/*****************************************************************************/
+void * /* returns value associated with key k after value v */
+hashtable_search_next(struct hashtable *h, void *k, void *v)
+{
+ struct entry *e;
+ unsigned int hashvalue, index, f;
+ hashvalue = hashtable_hash(h,k);
+ index = indexFor(h->tablelength,hashvalue);
+ f = 0;
+ e = h->table[index];
+ while (NULL != e)
+ {
+ if (f)
+ {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
+ }
+ else if (v == e->v)
+ {
+ f = 1;
+ }
+ e = e->next;
+ }
+ return NULL;
+}
+
+/*****************************************************************************/
void * /* returns value associated with key */
hashtable_remove(struct hashtable *h, void *k)
{
@@ -228,6 +254,17 @@ hashtable_remove(struct hashtable *h, void *k)
return v;
}
+void * /* returns value associated with key */
+hashtable_remove_kv(struct hashtable *h, void *k, void *v)
+{
+ struct entry *e;
+ e = hashtable_remove_kv_static(h,k,v);
+ if (NULL == e) return NULL;
+ freekey(e->k);
+ free(e);
+ return v;
+}
+
struct entry * /* returns hash table entry associated with key */
hashtable_remove_static(struct hashtable *h, void *k)
{
@@ -253,6 +290,30 @@ hashtable_remove_static(struct hashtable *h, void *k)
return NULL;
}
+struct entry * /* returns hash table entry associated with key k and value v */
+hashtable_remove_kv_static(struct hashtable *h, void *k, void *v)
+{
+ struct entry *e;
+ struct entry **pE;
+ unsigned int hashvalue, index;
+ hashvalue = hashtable_hash(h,k);
+ index = indexFor(h->tablelength,hashvalue);
+ pE = &(h->table[index]);
+ e = *pE;
+ while (NULL != e)
+ {
+ if (v == e->v)
+ {
+ *pE = e->next;
+ h->entrycount--;
+ return e;
+ }
+ pE = &(e->next);
+ e = e->next;
+ }
+ return NULL;
+}
+
/*****************************************************************************/
/* destroy */
void
diff --git a/ecp/src/ecp/htable/hashtable.h b/ecp/src/ecp/htable/hashtable.h
index 8faeafc..a5b3ab8 100755
--- a/ecp/src/ecp/htable/hashtable.h
+++ b/ecp/src/ecp/htable/hashtable.h
@@ -150,6 +150,9 @@ int fnname (struct hashtable *h, keytype *k, valuetype *v) \
void *
hashtable_search(struct hashtable *h, void *k);
+void *
+hashtable_search_next(struct hashtable *h, void *k, void *v);
+
#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
valuetype * fnname (struct hashtable *h, keytype *k) \
{ \
@@ -168,9 +171,15 @@ valuetype * fnname (struct hashtable *h, keytype *k) \
void * /* returns value */
hashtable_remove(struct hashtable *h, void *k);
+void * /* returns value v */
+hashtable_remove_kv(struct hashtable *h, void *k, void *v);
+
struct entry * /* returns hash table entry */
hashtable_remove_static(struct hashtable *h, void *k);
+struct entry * /* returns hash table entry */
+hashtable_remove_kv_static(struct hashtable *h, void *k, void *v);
+
#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
valuetype * fnname (struct hashtable *h, keytype *k) \
{ \
diff --git a/ecp/src/ecp/htable/htable.c b/ecp/src/ecp/htable/htable.c
index c0efebb..c22d2ab 100644
--- a/ecp/src/ecp/htable/htable.c
+++ b/ecp/src/ecp/htable/htable.c
@@ -1,9 +1,9 @@
#include <stdlib.h>
-#include <core.h>
-#include <cr.h>
-#include <tr.h>
-#include <ht.h>
+#include <ecp/core.h>
+#include <ecp/cr.h>
+#include <ecp/tr.h>
+#include <ecp/ht.h>
ecp_ht_table_t *ecp_ht_create_keys(void) {
return hashtable_create(1000, (unsigned int (*)(void *))ecp_ecdh_pub_hash, (int (*)(void *, void *))ecp_ecdh_pub_eq);
@@ -17,7 +17,7 @@ void ecp_ht_destroy(ecp_ht_table_t *h) {
hashtable_destroy(h, 0);
}
-int ecp_ht_insert(ecp_ht_table_t *h, void *k, ECPConnection *v) {
+int ecp_ht_insert(ecp_ht_table_t *h, void *k, void *v) {
int rv;
rv = hashtable_insert(h, k, v);
@@ -25,14 +25,26 @@ int ecp_ht_insert(ecp_ht_table_t *h, void *k, ECPConnection *v) {
return ECP_OK;
}
-ECPConnection *ecp_ht_remove(ecp_ht_table_t *h, void *k) {
+void *ecp_ht_remove(ecp_ht_table_t *h, void *k) {
return hashtable_remove(h, k);
}
-ECPConnection *ecp_ht_search(ecp_ht_table_t *h, void *k) {
+void *ecp_ht_remove_kv(ecp_ht_table_t *h, void *k, void *v) {
+ return hashtable_remove_kv(h, k, v);
+}
+
+void *ecp_ht_search(ecp_ht_table_t *h, void *k) {
return hashtable_search(h, k);
}
+void *ecp_ht_search_next(ecp_ht_table_t *h, void *k, void *v) {
+ return hashtable_search_next(h, k, v);
+}
+
+unsigned int ecp_ht_count(ecp_ht_table_t *h) {
+ return hashtable_count(h);
+}
+
void ecp_ht_itr_create(ecp_ht_itr_t *i, ecp_ht_table_t *h) {
hashtable_iterator(i, h);
}
@@ -42,7 +54,7 @@ int ecp_ht_itr_advance(ecp_ht_itr_t *i) {
rv = hashtable_iterator_advance(i);
if (rv == 0) return ECP_ITR_END;
- return rv;
+ return ECP_OK;
}
int ecp_ht_itr_remove(ecp_ht_itr_t *i) {
@@ -65,6 +77,6 @@ void *ecp_ht_itr_key(ecp_ht_itr_t *i) {
return hashtable_iterator_key(i);
}
-ECPConnection *ecp_ht_itr_value(ecp_ht_itr_t *i) {
+void *ecp_ht_itr_value(ecp_ht_itr_t *i) {
return hashtable_iterator_value(i);
}
diff --git a/ecp/src/ecp/timer.c b/ecp/src/ecp/timer.c
index fb0f62a..38df398 100644
--- a/ecp/src/ecp/timer.c
+++ b/ecp/src/ecp/timer.c
@@ -37,13 +37,13 @@ int ecp_timer_push(ECPTimerItem *ti) {
ECPConnection *conn = ti->conn;
ECPTimer *timer = &conn->sock->timer;
- ti->abstime = ecp_tm_get_tick() + ti->timeout;
+ ti->abstime = ecp_tm_get_ms() + ti->timeout;
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&timer->mutex);
pthread_mutex_lock(&conn->mutex);
#endif
- is_reg = ecp_conn_is_reg(conn);
+ is_reg = _ecp_conn_is_reg(conn);
if (is_reg) conn->refcount++;
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&conn->mutex);
@@ -137,7 +137,7 @@ ecp_sts_t ecp_timer_exe(ECPSocket *sock) {
ECPTimer *timer = &sock->timer;
ECPTimerItem to_exec[ECP_MAX_TIMER];
int to_exec_size = 0;
- ecp_sts_t now = ecp_tm_get_tick();
+ ecp_sts_t now = ecp_tm_get_ms();
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&timer->mutex);
diff --git a/ecp/src/ecp/tm.h b/ecp/src/ecp/tm.h
index 033a031..45e5784 100644
--- a/ecp/src/ecp/tm.h
+++ b/ecp/src/ecp/tm.h
@@ -1,4 +1,5 @@
int ecp_tm_init(ECPContext *ctx);
-ecp_sts_t ecp_tm_get_tick(void);
+ecp_sts_t ecp_tm_get_s(void);
+ecp_sts_t ecp_tm_get_ms(void);
void ecp_tm_sleep(ecp_sts_t msec);
void ecp_tm_timer_set(ecp_sts_t next);
diff --git a/ecp/src/ecp/tr.h b/ecp/src/ecp/tr.h
index 263577c..6c99f15 100644
--- a/ecp/src/ecp/tr.h
+++ b/ecp/src/ecp/tr.h
@@ -2,7 +2,7 @@ int ecp_tr_init(ECPContext *ctx);
unsigned int ecp_tr_addr_hash(ecp_tr_addr_t *addr);
int ecp_tr_addr_eq(ecp_tr_addr_t *addr1, ecp_tr_addr_t *addr2);
int ecp_tr_addr_set(ecp_tr_addr_t *addr, void *addr_s);
-int ecp_tr_open(ECPSocket *sock, void *addr_s);
+int ecp_tr_open(ECPSocket *sock, ecp_tr_addr_t *addr);
void ecp_tr_close(ECPSocket *sock);
ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t pkt_size, ecp_tr_addr_t *addr, unsigned char flags);
ssize_t ecp_tr_recv(ECPSocket *sock, ECPBuffer *packet, ecp_tr_addr_t *addr, int timeout);
diff --git a/ecp/src/ecp/vconn/vconn.c b/ecp/src/ecp/vconn/vconn.c
index 3d4dd29..f52b2f5 100644
--- a/ecp/src/ecp/vconn/vconn.c
+++ b/ecp/src/ecp/vconn/vconn.c
@@ -1,11 +1,11 @@
#include <stdlib.h>
#include <string.h>
-#include <core.h>
-#include <tr.h>
+#include <ecp/core.h>
+#include <ecp/tr.h>
#ifdef ECP_WITH_HTABLE
-#include <ht.h>
+#include <ecp/ht.h>
#endif
#include "vconn.h"
@@ -13,9 +13,9 @@
#ifdef ECP_WITH_HTABLE
-static int insert_key_next(ECPConnection *conn, unsigned char c_idx, ecp_ecdh_public_t *public) {
+static int insert_key_next(ECPVConnInb *vconn, unsigned char c_idx, ecp_ecdh_public_t *public) {
+ ECPConnection *conn = &vconn->b;
ECPSocket *sock = conn->sock;
- ECPVConn *_conn = (ECPVConn *)conn;
ECPDHPub *key = NULL;
int rv = ECP_OK;
@@ -25,11 +25,11 @@ static int insert_key_next(ECPConnection *conn, unsigned char c_idx, ecp_ecdh_pu
pthread_mutex_lock(&conn->mutex);
#endif
- if (c_idx != _conn->key_next_curr) {
+ if (c_idx != vconn->key_next_curr) {
unsigned char _c_idx;
_c_idx = c_idx % ECP_MAX_NODE_KEY;
- key = &_conn->key_next[_c_idx];
+ key = &vconn->key_next[_c_idx];
if (key->valid && (memcmp(public, &key->public, sizeof(key->public)) == 0)) {
key = NULL;
@@ -54,7 +54,7 @@ static int insert_key_next(ECPConnection *conn, unsigned char c_idx, ecp_ecdh_pu
rv = ecp_ht_insert(sock->conn_table.keys, &key->public, conn);
if (!rv) {
key->valid = 1;
- _conn->key_next_curr = c_idx;
+ vconn->key_next_curr = c_idx;
}
#ifdef ECP_WITH_PTHREAD
@@ -67,23 +67,37 @@ static int insert_key_next(ECPConnection *conn, unsigned char c_idx, ecp_ecdh_pu
}
static ssize_t handle_next(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
+ ECPVConnInb *vconn = (ECPVConnInb *)conn;
ECPSocket *sock = conn->sock;
+ int is_open;
if (msg_size < ECP_SIZE_ECDH_PUB) return ECP_ERR_SIZE;
if (ecp_conn_is_outb(conn)) return ECP_ERR;
#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&conn->mutex);
+#endif
+
+ is_open = _ecp_conn_is_open(conn);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&conn->mutex);
+#endif
+
+ if (is_open) return ECP_ERR_NEXT;
+
+#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&sock->conn_table.mutex);
#endif
- conn->next = ecp_ht_search(sock->conn_table.keys, (ecp_ecdh_public_t *)msg);
- if (conn->next) ecp_conn_refcount_inc(conn->next);
+ vconn->next = ecp_ht_search(sock->conn_table.keys, (ecp_ecdh_public_t *)msg);
+ if (vconn->next) ecp_conn_refcount_inc(vconn->next);
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&sock->conn_table.mutex);
#endif
- if (conn->next == NULL) return ECP_ERR_NEXT;
+ if (vconn->next == NULL) return ECP_ERR_NEXT;
return ECP_SIZE_ECDH_PUB;
}
@@ -105,13 +119,15 @@ static ssize_t handle_relay(ECPConnection *conn, unsigned char *msg, size_t msg_
switch (conn->type) {
/* forward message */
case ECP_CTYPE_VCONN: {
+ ECPVConnInb *vconn = (ECPVConnInb *)conn;
+
if (ecp_conn_is_outb(conn)) return ECP_ERR;
- conn_next = conn->next;
+ conn_next = vconn->next;
if (conn_next) {
_idx = (idx & 0x0F);
- _rv = insert_key_next(conn, _idx, (ecp_ecdh_public_t *)(msg+ECP_SIZE_PROTO+1));
+ _rv = insert_key_next(vconn, _idx, (ecp_ecdh_public_t *)(msg+ECP_SIZE_PROTO+1));
if (_rv) return _rv;
}
@@ -167,6 +183,7 @@ static ssize_t handle_relay(ECPConnection *conn, unsigned char *msg, size_t msg_
static ssize_t handle_exec(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
ECPBuffer *packet;
+ ssize_t rv;
if (bufs == NULL) return ECP_ERR;
@@ -174,7 +191,8 @@ static ssize_t handle_exec(ECPConnection *conn, unsigned char *msg, size_t msg_s
if (packet->size < msg_size) return ECP_ERR_SIZE;
memcpy(packet->buffer, msg, msg_size);
- return ecp_pkt_handle(conn->sock, conn, NULL, bufs, msg_size);
+ rv = ecp_pkt_handle(conn->sock, conn, NULL, bufs, msg_size);
+ return rv;
}
ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *payload, ECPBuffer *packet, size_t pkt_size, ecp_tr_addr_t *addr) {
@@ -197,70 +215,77 @@ ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *payload, ECPBuffer
return rv;
}
-static int vconn_create(ECPConnection vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPSocket *sock) {
+void ecp_vconn_init(ECPVConnOutb vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPSocket *sock) {
ECPDHPub key;
- int i, j;
- int rv;
+ int i;
key.valid = 1;
for (i=0; i<vconn_size; i++) {
- rv = ecp_conn_create(&vconn[i], sock, ECP_CTYPE_VCONN);
- if (rv) {
- for (j=0; j<i; j++) {
- ecp_conn_destroy(&vconn[j]);
- }
- return rv;
- }
memcpy(&key.public, &keys[i], sizeof(keys[i]));
- ecp_conn_set_remote_key(&vconn[i], &key);
+ ecp_conn_init(&vconn[i].b, sock, ECP_CTYPE_VCONN);
+ ecp_conn_set_remote_key(&vconn[i].b, &key);
+ if (i < vconn_size - 1) {
+ vconn[i].next = &vconn[i + 1].b;
+ } else {
+ vconn[i].next = NULL;
+ }
}
-
- return ECP_OK;
}
-int ecp_vconn_create(ECPConnection vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPConnection *conn) {
- ECPConnection *_conn;
- unsigned short pcount;
- int rv;
+#ifdef ECP_WITH_HTABLE
- _conn = conn;
- pcount = vconn_size;
+void ecp_vconn_init_inb(ECPVConnInb *vconn, ECPSocket *sock) {
+ ECPConnection *conn = &vconn->b;
- if (pcount > ECP_MAX_PARENT) return ECP_ERR_MAX_PARENT;
+ ecp_conn_init(conn, sock, ECP_CTYPE_VCONN);
+ vconn->next = NULL;
+ memset(vconn->key_next, 0, sizeof(vconn->key_next));
+ vconn->key_next_curr = ECP_ECDH_IDX_INV;
+}
- rv = vconn_create(vconn, keys, vconn_size, conn->sock);
- if (rv) return rv;
+#endif /* ECP_WITH_HTABLE */
- while (pcount) {
- _conn->parent = &vconn[pcount-1];
- _conn->parent->next = _conn;
- _conn->pcount = pcount;
+int ecp_vconn_open(ECPVConnOutb *vconn, ECPConnection *conn, ECPNode *node) {
+ ECPVConnOutb *_vconn;
+ int rv;
- _conn = _conn->parent;
- pcount--;
+ _vconn = vconn;
+ while (_vconn->next) {
+ _vconn = (ECPVConnOutb *)_vconn->next;
}
- return ECP_OK;
+ _vconn->next = conn;
+ if (node) {
+ ecp_conn_set_remote_key(conn, &node->key_perma);
+ ecp_conn_set_remote_addr(&vconn->b, &node->addr);
+ }
+
+ rv = _ecp_conn_open(&vconn->b, NULL, NULL, 1);
+ return rv;
}
-#ifdef ECP_WITH_HTABLE
+int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs) {
+ int rv = ECP_OK;
-int ecp_vconn_create_inb(ECPVConn *conn, ECPSocket *sock) {
- ECPConnection *_conn = &conn->b;
- int rv;
+ if (ecp_conn_is_outb(conn)) {
+ ECPVConnOutb *vconn = (ECPVConnOutb *)conn;
- rv = ecp_conn_create_inb(_conn, sock, ECP_CTYPE_VCONN);
- if (rv) return rv;
+ if (vconn->next == NULL) return ECP_ERR;
- memset(conn->key_next, 0, sizeof(conn->key_next));
- conn->key_next_curr = ECP_ECDH_IDX_INV;
+ /* we should release incoming packet before sending next open packet */
+ ecp_tr_release(bufs->packet, 1);
+ rv = _ecp_conn_open(vconn->next, conn, NULL, 1);
+ if (rv) rv = ECP_ERR_NEXT;
+ }
- return ECP_OK;
+ return rv;
}
-void ecp_vconn_destroy(ECPConnection *conn) {
+#ifdef ECP_WITH_HTABLE
+
+void ecp_vconn_handle_close(ECPConnection *conn) {
+ ECPVConnInb *vconn = (ECPVConnInb *)conn;
ECPSocket *sock = conn->sock;
- ECPVConn *_conn = (ECPVConn *)conn;
int i;
if (ecp_conn_is_outb(conn)) return;
@@ -272,7 +297,7 @@ void ecp_vconn_destroy(ECPConnection *conn) {
for (i=0; i<ECP_MAX_NODE_KEY; i++) {
ECPDHPub *key;
- key = &_conn->key_next[i];
+ key = &vconn->key_next[i];
if (key->valid) {
ecp_ht_remove(sock->conn_table.keys, &key->public);
}
@@ -282,77 +307,82 @@ void ecp_vconn_destroy(ECPConnection *conn) {
pthread_mutex_unlock(&sock->conn_table.mutex);
#endif
- if (conn->next) ecp_conn_refcount_dec(conn->next);
+ if (vconn->next) ecp_conn_refcount_dec(vconn->next);
}
#endif /* ECP_WITH_HTABLE */
-int ecp_vconn_open(ECPConnection *conn, ECPNode *node) {
- ECPConnection *vconn0;
- int rv;
+ssize_t ecp_vconn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
+ ssize_t rv;
- vconn0 = conn;
- while (vconn0->parent) {
- vconn0 = vconn0->parent;
- }
+ switch (mtype) {
+#ifdef ECP_WITH_HTABLE
+ case ECP_MTYPE_NEXT:
+ rv = handle_next(conn, msg, msg_size, bufs);
+ break;
- if (node) {
- ecp_conn_set_remote_key(conn, &node->key_perma);
- ecp_conn_set_remote_addr(vconn0, &node->addr);
+ case ECP_MTYPE_RELAY:
+ rv = handle_relay(conn, msg, msg_size, bufs);
+ break;
+#endif
+
+ case ECP_MTYPE_EXEC:
+ rv = handle_exec(conn, msg, msg_size, bufs);
+ break;
+
+ default:
+ rv = ECP_ERR_MTYPE;
+ break;
}
- rv = ecp_conn_open(vconn0, NULL);
return rv;
}
-static int vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs) {
- int rv = ECP_OK;
+ssize_t ecp_vconn_send_open_req(ECPConnection *conn, unsigned char *cookie) {
+ ECPVConnOutb *vconn = (ECPVConnOutb *)conn;
+ ECPDHPub key_next;
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ, conn)+ECP_SIZE_COOKIE+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ, conn)+ECP_SIZE_COOKIE+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT)];
+ unsigned char *msg;
+ unsigned char *_pld_buf;
+ size_t _pld_size;
+ ssize_t rv;
+ int _rv;
- if (ecp_conn_is_outb(conn) && conn->next) {
- ecp_tr_release(bufs->packet, 1);
- rv = ecp_conn_open(conn->next, NULL);
- if (rv) ecp_err_handle(conn->next, ECP_MTYPE_INIT_REQ, rv);
- }
+ if (vconn->next == NULL) return ECP_ERR_NEXT;
- return rv;;
-}
+ _rv = ecp_conn_dhkey_get_remote(vconn->next, ECP_ECDH_IDX_PERMA, &key_next);
+ if (_rv) return _rv;
-int ecp_vlink_create(ECPConnection *conn, ECPSocket *sock) {
- int rv;
+ packet.buffer = pkt_buf;
+ packet.size = sizeof(pkt_buf);
+ payload.buffer = pld_buf;
+ payload.size = sizeof(pld_buf);
- rv = ecp_conn_create(conn, sock, ECP_CTYPE_VLINK);
- if (!rv) ecp_conn_set_flags(conn, ECP_CONN_FLAG_VBOX);
- return rv;
-}
+ rv = ecp_write_open_req(conn, &payload);
+ if (rv < 0) return rv;
-#ifdef ECP_WITH_HTABLE
+ _pld_buf = payload.buffer + rv;
+ _pld_size = payload.size - rv;
-int ecp_vlink_create_inb(ECPConnection *conn, ECPSocket *sock) {
- int rv;
+ ecp_pld_set_type(_pld_buf, _pld_size, ECP_MTYPE_NEXT);
+ msg = ecp_pld_get_msg(_pld_buf, _pld_size);
+ memcpy(msg, &key_next.public, ECP_SIZE_ECDH_PUB);
- rv = ecp_conn_create_inb(conn, sock, ECP_CTYPE_VLINK);
- if (!rv) ecp_conn_set_flags(conn, ECP_CONN_FLAG_VBOX);
+ rv = ecp_pld_send_wcookie(conn, &packet, &payload, rv+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT), 0, cookie);
return rv;
}
-void ecp_vlink_destroy(ECPConnection *conn) {
- ECPSocket *sock = conn->sock;
- ECPDHPub *key = &conn->remote.key_perma;
-
- if (key->valid) {
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&sock->conn_table.mutex);
-#endif
-
- ecp_ht_remove(sock->conn_table.keys, &key->public);
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&sock->conn_table.mutex);
-#endif
- }
+void ecp_vlink_init(ECPConnection *conn, ECPSocket *sock) {
+ ecp_conn_init(conn, sock, ECP_CTYPE_VLINK);
+ ecp_conn_set_flags(conn, ECP_CONN_FLAG_VBOX);
}
-static int vlink_handle_open(ECPConnection *conn) {
+#ifdef ECP_WITH_HTABLE
+
+int ecp_vlink_handle_open(ECPConnection *conn, ECP2Buffer *bufs) {
ECPSocket *sock = conn->sock;
ECPDHPub *key;
int rv = ECP_OK;
@@ -393,55 +423,30 @@ static int vlink_handle_open(ECPConnection *conn) {
return rv;
}
-#endif /* ECP_WITH_HTABLE */
-
-int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs) {
- int rv;
-
- switch (conn->type) {
- case ECP_CTYPE_VCONN:
- rv = vconn_handle_open(conn, bufs);
- break;
+void ecp_vlink_handle_close(ECPConnection *conn) {
+ ECPSocket *sock = conn->sock;
+ ECPDHPub *key = &conn->remote.key_perma;
- case ECP_CTYPE_VLINK:
-#ifdef ECP_WITH_HTABLE
- rv = vlink_handle_open(conn);
-#else
- rv = ECP_OK;
+ if (key->valid) {
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&sock->conn_table.mutex);
#endif
- break;
-
- default:
- rv = ECP_ERR_CTYPE;
- break;
- }
-
- return rv;
-}
-void ecp_vconn_handle_close(ECPConnection *conn) {
- switch (conn->type) {
-#ifdef ECP_WITH_HTABLE
- case ECP_CTYPE_VCONN:
- ecp_vconn_destroy(conn);
- break;
+ ecp_ht_remove(sock->conn_table.keys, &key->public);
- case ECP_CTYPE_VLINK:
- ecp_vlink_destroy(conn);
- break;
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&sock->conn_table.mutex);
#endif
}
}
-ssize_t ecp_vconn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
+#endif /* ECP_WITH_HTABLE */
+
+ssize_t ecp_vlink_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
ssize_t rv;
switch (mtype) {
#ifdef ECP_WITH_HTABLE
- case ECP_MTYPE_NEXT:
- rv = handle_next(conn, msg, msg_size, bufs);
- break;
-
case ECP_MTYPE_RELAY:
rv = handle_relay(conn, msg, msg_size, bufs);
break;
@@ -459,42 +464,18 @@ ssize_t ecp_vconn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char m
return rv;
}
-ssize_t ecp_vconn_send_open_req(ECPConnection *conn, unsigned char *cookie) {
- if (conn->type == ECP_CTYPE_VCONN) {
- ECPDHPub key_next;
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ, conn)+ECP_SIZE_COOKIE+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ, conn)+ECP_SIZE_COOKIE+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT)];
- unsigned char *msg;
- unsigned char *_pld_buf;
- size_t _pld_size;
- ssize_t rv;
- int _rv;
-
- if (conn->next == NULL) return ECP_ERR_NEXT;
-
- _rv = ecp_conn_dhkey_get_remote(conn->next, ECP_ECDH_IDX_PERMA, &key_next);
- if (_rv) return _rv;
-
- packet.buffer = pkt_buf;
- packet.size = sizeof(pkt_buf);
- payload.buffer = pld_buf;
- payload.size = sizeof(pld_buf);
-
- rv = ecp_write_open_req(conn, &payload);
- if (rv < 0) return rv;
-
- _pld_buf = payload.buffer + rv;
- _pld_size = payload.size - rv;
-
- ecp_pld_set_type(_pld_buf, _pld_size, ECP_MTYPE_NEXT);
- msg = ecp_pld_get_msg(_pld_buf, _pld_size);
- memcpy(msg, &key_next.public, ECP_SIZE_ECDH_PUB);
-
- rv = ecp_pld_send_wcookie(conn, &packet, &payload, rv+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT), 0, cookie);
- return rv;
- } else {
- return ecp_send_open_req(conn, cookie);
- }
+int ecp_vconn_handler_init(ECPContext *ctx, ECPConnHandler *vconn_handler) {
+ int rv;
+
+ ecp_conn_handler_init(vconn_handler, ecp_vconn_handle_msg, ecp_vconn_handle_open, ecp_vconn_handle_close, ecp_vconn_send_open_req);
+ rv = ecp_ctx_set_handler(ctx, ECP_CTYPE_VCONN, vconn_handler);
+ return rv;
+}
+
+int ecp_vlink_handler_init(ECPContext *ctx, ECPConnHandler *vlink_handler) {
+ int rv;
+
+ ecp_conn_handler_init(vlink_handler, ecp_vlink_handle_msg, ecp_vlink_handle_open, ecp_vlink_handle_close, NULL);
+ rv = ecp_ctx_set_handler(ctx, ECP_CTYPE_VLINK, vlink_handler);
+ return rv;
}
diff --git a/ecp/src/ecp/vconn/vconn.h b/ecp/src/ecp/vconn/vconn.h
index 8871ded..62275bf 100644
--- a/ecp/src/ecp/vconn/vconn.h
+++ b/ecp/src/ecp/vconn/vconn.h
@@ -5,29 +5,39 @@
#define ECP_MTYPE_EXEC 0x02
#define ECP_MTYPE_RELAY 0x01
-/* inbound only */
-typedef struct ECPVConn {
+typedef struct ECPVConnInb {
ECPConnection b;
+ ECPConnection *next;
ECPDHPub key_next[ECP_MAX_NODE_KEY];
unsigned char key_next_curr;
-} ECPVConn;
+} ECPVConnInb;
+
+typedef struct ECPVConnOutb {
+ ECPConnection b;
+ ECPConnection *next;
+} ECPVConnOutb;
ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *payload, ECPBuffer *packet, size_t pkt_size, ecp_tr_addr_t *addr);
-int ecp_vconn_create(ECPConnection vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPConnection *conn);
+void ecp_vconn_init(ECPVConnOutb vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPSocket *sock);
#ifdef ECP_WITH_HTABLE
-int ecp_vconn_create_inb(ECPVConn *conn, ECPSocket *sock);
-void ecp_vconn_destroy(ECPConnection *conn);
+void ecp_vconn_init_inb(ECPVConnInb *vconn, ECPSocket *sock);
#endif
-int ecp_vconn_open(ECPConnection *conn, ECPNode *node);
-
-int ecp_vlink_create(ECPConnection *conn, ECPSocket *sock);
+int ecp_vconn_open(ECPVConnOutb *vconn, ECPConnection *conn, ECPNode *node);
#ifdef ECP_WITH_HTABLE
-int ecp_vlink_create_inb(ECPConnection *conn, ECPSocket *sock);
-void ecp_vlink_destroy(ECPConnection *conn);
-#endif
-
int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs);
void ecp_vconn_handle_close(ECPConnection *conn);
+#endif
ssize_t ecp_vconn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs);
ssize_t ecp_vconn_send_open_req(ECPConnection *conn, unsigned char *cookie);
+
+
+void ecp_vlink_init(ECPConnection *conn, ECPSocket *sock);
+#ifdef ECP_WITH_HTABLE
+int ecp_vlink_handle_open(ECPConnection *conn, ECP2Buffer *bufs);
+void ecp_vlink_handle_close(ECPConnection *conn);
+#endif
+ssize_t ecp_vlink_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs);
+
+int ecp_vconn_handler_init(ECPContext *ctx, ECPConnHandler *vconn_handler);
+int ecp_vlink_handler_init(ECPContext *ctx, ECPConnHandler *vlink_handler);
diff --git a/ecp/src/platform/fe310/time.c b/ecp/src/platform/fe310/time.c
index 5e4bc26..4bf530c 100644
--- a/ecp/src/platform/fe310/time.c
+++ b/ecp/src/platform/fe310/time.c
@@ -1,7 +1,7 @@
#include <stdlib.h>
-#include <core.h>
-#include <tr.h>
+#include <ecp/core.h>
+#include <ecp/tm.h>
#include <eos/eos.h>
#include <eos/event.h>
@@ -23,7 +23,11 @@ int ecp_tm_init(ECPContext *ctx) {
return ECP_OK;
}
-ecp_sts_t ecp_tm_get_tick(void) {
+ecp_sts_t ecp_tm_get_s(void) {
+ return eos_time_get_tick() / EOS_TIMER_RTC_FREQ;
+}
+
+ecp_sts_t ecp_tm_get_ms(void) {
return eos_time_get_tick() * 1000 / EOS_TIMER_RTC_FREQ;
}
diff --git a/ecp/src/platform/fe310/transport.c b/ecp/src/platform/fe310/transport.c
index c359bd1..bc758c9 100644
--- a/ecp/src/platform/fe310/transport.c
+++ b/ecp/src/platform/fe310/transport.c
@@ -2,8 +2,8 @@
#include <string.h>
#include <stdio.h>
-#include <core.h>
-#include <tr.h>
+#include <ecp/core.h>
+#include <ecp/tr.h>
#include <eos/eos.h>
#include <eos/dev/net.h>
@@ -65,7 +65,7 @@ int ecp_tr_addr_set(ecp_tr_addr_t *addr, void *addr_s) {
return ECP_ERR;
}
-int ecp_tr_open(ECPSocket *sock, void *addr_s) {
+int ecp_tr_open(ECPSocket *sock, ecp_tr_addr_t *addr) {
sock->sock = eos_sock_open_udp(packet_handler, NULL);
if (sock->sock < 0) {
sock->sock = 0;
diff --git a/ecp/src/platform/posix/features.mk b/ecp/src/platform/posix/features.mk
index 2ce8220..ea5e44c 100644
--- a/ecp/src/platform/posix/features.mk
+++ b/ecp/src/platform/posix/features.mk
@@ -1,7 +1,8 @@
with_pthread = yes
with_htable = yes
with_vconn = yes
-with_dirsrv = yes
+with_frag = yes
with_rbuf = yes
with_msgq = yes
+with_dir = yes
with_debug = yes
diff --git a/ecp/src/platform/posix/time.c b/ecp/src/platform/posix/time.c
index 7030bf3..49a85e7 100644
--- a/ecp/src/platform/posix/time.c
+++ b/ecp/src/platform/posix/time.c
@@ -1,15 +1,20 @@
#include <stdlib.h>
#include <unistd.h>
+#include <time.h>
#include <sys/time.h>
-#include <core.h>
-#include <tm.h>
+#include <ecp/core.h>
+#include <ecp/tm.h>
int ecp_tm_init(ECPContext *ctx) {
return ECP_OK;
}
-ecp_sts_t ecp_tm_get_tick(void) {
+ecp_sts_t ecp_tm_get_s(void) {
+ return time(NULL);
+}
+
+ecp_sts_t ecp_tm_get_ms(void) {
struct timeval tv;
ecp_sts_t ms_now;
diff --git a/ecp/src/platform/posix/transport.c b/ecp/src/platform/posix/transport.c
index ebfbc7b..51f311a 100644
--- a/ecp/src/platform/posix/transport.c
+++ b/ecp/src/platform/posix/transport.c
@@ -6,8 +6,8 @@
#include <arpa/inet.h>
#include <poll.h>
-#include <core.h>
-#include <tr.h>
+#include <ecp/core.h>
+#include <ecp/tr.h>
#define MAX_ADDR_STR 32
@@ -49,20 +49,15 @@ int ecp_tr_addr_set(ecp_tr_addr_t *addr, void *addr_s) {
return 0;
}
-int ecp_tr_open(ECPSocket *sock, void *addr_s) {
+int ecp_tr_open(ECPSocket *sock, ecp_tr_addr_t *addr) {
struct sockaddr_in _myaddr;
int rv;
memset((char *)&_myaddr, 0, sizeof(_myaddr));
_myaddr.sin_family = AF_INET;
- if (addr_s) {
- ecp_tr_addr_t addr;
-
- rv = ecp_tr_addr_set(&addr, addr_s);
- if (rv) return rv;
-
- memcpy((void *)&_myaddr.sin_addr, addr.host, sizeof(addr.host));
- _myaddr.sin_port = addr.port;
+ if (addr) {
+ memcpy((void *)&_myaddr.sin_addr, addr->host, sizeof(addr->host));
+ _myaddr.sin_port = addr->port;
} else {
_myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
_myaddr.sin_port = htons(0);
diff --git a/ecp/test/Makefile b/ecp/test/Makefile
index 50a4202..b2fd6f8 100644
--- a/ecp/test/Makefile
+++ b/ecp/test/Makefile
@@ -1,13 +1,15 @@
src_dir = ../src
include $(src_dir)/ecp/common.mk
CFLAGS += -I../util -Wno-int-to-void-pointer-cast
+dep = ../build-posix/*.a ../util/libecputil.a
+
+target = basic client server vc_inb vc_outb vcs vc_server vc_client
-dep=../build-posix/*.a ../util/libecputil.a
%.o: %.c
$(CC) $(CFLAGS) -c $<
-all: basic client server vcs vc_server vc_client
+all: $(target)
basic: basic.o init.o $(dep)
$(CC) -o $@ $< init.o $(dep) $(LDFLAGS)
@@ -18,6 +20,12 @@ client: client.o init.o $(dep)
server: server.o init.o $(dep)
$(CC) -o $@ $< init.o $(dep) $(LDFLAGS)
+vc_inb: vc_inb.o vc_common.o init_vconn.o $(dep)
+ $(CC) -o $@ $< vc_common.o init_vconn.o $(dep) $(LDFLAGS)
+
+vc_outb: vc_outb.o vc_common.o init_vconn.o $(dep)
+ $(CC) -o $@ $< vc_common.o init_vconn.o $(dep) $(LDFLAGS)
+
vcs: vcs.o init_vconn.o $(dep)
$(CC) -o $@ $< init_vconn.o $(dep) $(LDFLAGS)
@@ -29,4 +37,4 @@ vc_client: vc_client.o init_vconn.o $(dep)
clean:
rm -f *.o
- rm -f basic dir client server echo frag stress vcs vc_server vc_client vc_client_t voip
+ rm -f $(target)
diff --git a/ecp/test/basic.c b/ecp/test/basic.c
index b266a07..637a829 100644
--- a/ecp/test/basic.c
+++ b/ecp/test/basic.c
@@ -2,7 +2,9 @@
#include <unistd.h>
#include <stdio.h>
-#include <core.h>
+#include <ecp/core.h>
+
+#include "init.h"
ECPContext ctx_s;
ECPSocket sock_s;
@@ -43,6 +45,7 @@ static ssize_t handle_msg_s(ECPConnection *conn, ecp_seq_t seq, unsigned char mt
}
int main(int argc, char *argv[]) {
+ ecp_tr_addr_t addr;
ECPDHKey key_perma_c;
ECPDHKey key_perma_s;
ECPNode node;
@@ -53,7 +56,7 @@ int main(int argc, char *argv[]) {
printf("ecp_init RV:%d\n", rv);
ecp_conn_handler_init(&handler_s, handle_msg_s, NULL, NULL, NULL);
- ecp_ctx_set_handler(&ctx_s, &handler_s, CTYPE_TEST);
+ ecp_ctx_set_handler(&ctx_s, CTYPE_TEST, &handler_s);
rv = ecp_dhkey_gen(&key_perma_s);
printf("ecp_dhkey_gen RV:%d\n", rv);
@@ -61,7 +64,10 @@ int main(int argc, char *argv[]) {
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");
+ rv = ecp_addr_init(&addr, "0.0.0.0:3000");
+ printf("ecp_addr_init RV:%d\n", rv);
+
+ rv = ecp_sock_open(&sock_s, &addr);
printf("ecp_sock_open RV:%d\n", rv);
rv = ecp_start_receiver(&sock_s);
@@ -72,7 +78,7 @@ int main(int argc, char *argv[]) {
printf("ecp_init RV:%d\n", rv);
ecp_conn_handler_init(&handler_c, handle_msg_c, handle_open_c, NULL, NULL);
- ecp_ctx_set_handler(&ctx_c, &handler_c, CTYPE_TEST);
+ ecp_ctx_set_handler(&ctx_c, CTYPE_TEST, &handler_c);
rv = ecp_dhkey_gen(&key_perma_c);
printf("ecp_dhkey_gen RV:%d\n", rv);
@@ -86,12 +92,11 @@ int main(int argc, char *argv[]) {
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);
+ ecp_node_init(&node, &key_perma_s.public, NULL);
+ rv = ecp_node_set_addr(&node, "127.0.0.1:3000");
+ printf("ecp_node_set_addr RV:%d\n", rv);
+ ecp_conn_init(&conn, &sock_c, CTYPE_TEST);
rv = ecp_conn_open(&conn, &node);
printf("ecp_conn_open RV:%d\n", rv);
diff --git a/ecp/test/client.c b/ecp/test/client.c
index d526f76..52a8587 100644
--- a/ecp/test/client.c
+++ b/ecp/test/client.c
@@ -3,10 +3,12 @@
#include <unistd.h>
#include <stdio.h>
-#include <core.h>
+#include <ecp/core.h>
#include <util.h>
+#include "init.h"
+
ECPContext ctx;
ECPSocket sock;
ECPConnHandler handler;
@@ -48,7 +50,7 @@ int main(int argc, char *argv[]) {
printf("ecp_init RV:%d\n", rv);
ecp_conn_handler_init(&handler, handle_msg, handle_open, NULL, NULL);
- ecp_ctx_set_handler(&ctx, &handler, CTYPE_TEST);
+ ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler);
rv = ecp_dhkey_gen(&key_perma);
printf("ecp_dhkey_gen RV:%d\n", rv);
@@ -62,15 +64,14 @@ int main(int argc, char *argv[]) {
rv = ecp_start_receiver(&sock);
printf("ecp_start_receiver RV:%d\n", rv);
- rv = ecp_conn_create(&conn, &sock, CTYPE_TEST);
- printf("ecp_conn_create RV:%d\n", rv);
-
rv = ecp_util_load_pub(&node_pub, argv[2]);
printf("ecp_util_load_pub RV:%d\n", rv);
- rv = ecp_node_init(&node, &node_pub, argv[1]);
- printf("ecp_node_init RV:%d\n", rv);
+ ecp_node_init(&node, &node_pub, NULL);
+ rv = ecp_node_set_addr(&node, argv[1]);
+ printf("ecp_node_set_addr RV:%d\n", rv);
+ ecp_conn_init(&conn, &sock, CTYPE_TEST);
rv = ecp_conn_open(&conn, &node);
printf("ecp_conn_open RV:%d\n", rv);
diff --git a/ecp/test/init.c b/ecp/test/init.c
index f4b033a..b75b2ee 100644
--- a/ecp/test/init.c
+++ b/ecp/test/init.c
@@ -1,34 +1,27 @@
#include <stdlib.h>
#include <stdio.h>
-#include <core.h>
+#include <ecp/core.h>
-void handle_err(ECPConnection *conn, unsigned char mtype, int err) {
+static void handle_err(ECPConnection *conn, unsigned char mtype, int err) {
printf("ERR: CTYPE:%d MTYPE:%x ERR:%d\n", conn->type, mtype, err);
}
-static ECPConnection *conn_alloc(ECPSocket *sock, unsigned char type) {
+static ECPConnection *conn_new(ECPSocket *sock, unsigned char type) {
ECPConnection *conn;
- int rv;
conn = malloc(sizeof(ECPConnection));
- if (conn == NULL) return NULL;
-
- rv = ecp_conn_create_inb(conn, sock, type);
- if (rv) {
- free(conn);
- return NULL;
- }
+ if (conn) ecp_conn_init(conn, sock, type);
return conn;
}
static void conn_free(ECPConnection *conn) {
- free(conn);
+ if (ecp_conn_is_gc(conn)) free(conn);
}
int ecp_init(ECPContext *ctx) {
int rv;
- rv = ecp_ctx_init(ctx, handle_err, NULL, conn_alloc, conn_free);
+ rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free);
return rv;
}
diff --git a/ecp/test/init.h b/ecp/test/init.h
new file mode 100644
index 0000000..a1a21d1
--- /dev/null
+++ b/ecp/test/init.h
@@ -0,0 +1 @@
+int ecp_init(ECPContext *ctx); \ No newline at end of file
diff --git a/ecp/test/init_vconn.c b/ecp/test/init_vconn.c
index 88b6fa0..b690bec 100644
--- a/ecp/test/init_vconn.c
+++ b/ecp/test/init_vconn.c
@@ -2,50 +2,59 @@
#include <unistd.h>
#include <stdio.h>
-#include <core.h>
-#include <vconn/vconn.h>
+#include <ecp/core.h>
+#include <ecp/vconn/vconn.h>
-void handle_err(ECPConnection *conn, unsigned char mtype, int err) {
+static void handle_err(ECPConnection *conn, unsigned char mtype, int err) {
printf("ERR: CTYPE:0x%x MTYPE:0x%x ERR:%d\n", conn->type, mtype, err);
}
-static ECPConnection *conn_alloc(ECPSocket *sock, unsigned char type) {
- ECPConnection *conn;
- int rv;
+static ECPConnection *conn_new(ECPSocket *sock, unsigned char type) {
+ ECPConnection *conn = NULL;
switch (type) {
- case ECP_CTYPE_VCONN:
- conn = malloc(sizeof(ECPVConn));
- if (conn) rv = ecp_vconn_create_inb((ECPVConn *)conn, sock);
+ case ECP_CTYPE_VCONN: {
+ ECPVConnInb *_conn;
+
+ _conn = malloc(sizeof(ECPVConnInb));
+ if (_conn) {
+ ecp_vconn_init_inb(_conn, sock);
+ conn = &_conn->b;
+ }
break;
+ }
- case ECP_CTYPE_VLINK:
+ case ECP_CTYPE_VLINK: {
conn = malloc(sizeof(ECPConnection));
- if (conn) rv = ecp_vlink_create_inb(conn, sock);
+ if (conn) ecp_vlink_init(conn, sock);
break;
+ }
- default:
+ default: {
conn = malloc(sizeof(ECPConnection));
- if (conn) rv = ecp_conn_create_inb(conn, sock, type);
+ if (conn) ecp_conn_init(conn, sock, type);
break;
- }
-
- if (conn == NULL) return NULL;
- if (rv) {
- free(conn);
- return NULL;
+ }
}
return conn;
}
static void conn_free(ECPConnection *conn) {
- free(conn);
+ if (ecp_conn_is_gc(conn)) free(conn);
}
-int ecp_init(ECPContext *ctx) {
+int ecp_init(ECPContext *ctx, ECPConnHandler *vconn_handler, ECPConnHandler *vlink_handler) {
int rv;
- rv = ecp_ctx_init(ctx, handle_err, NULL, conn_alloc, conn_free);
- return rv;
+ rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free);
+ if (rv) return rv;
+
+ rv = ecp_vconn_handler_init(ctx, vconn_handler);
+ if (rv) return rv;
+
+ rv = ecp_vlink_handler_init(ctx, vlink_handler);
+ if (rv) return rv;
+
+ return ECP_OK;
} \ No newline at end of file
diff --git a/ecp/test/init_vconn.h b/ecp/test/init_vconn.h
new file mode 100644
index 0000000..64e3269
--- /dev/null
+++ b/ecp/test/init_vconn.h
@@ -0,0 +1 @@
+int ecp_init(ECPContext *ctx, ECPConnHandler *vconn_handler, ECPConnHandler *vlink_handler); \ No newline at end of file
diff --git a/ecp/test/server.c b/ecp/test/server.c
index 228dbea..19b2f4f 100644
--- a/ecp/test/server.c
+++ b/ecp/test/server.c
@@ -3,10 +3,12 @@
#include <unistd.h>
#include <stdio.h>
-#include <core.h>
+#include <ecp/core.h>
#include <util.h>
+#include "init.h"
+
ECPContext ctx;
ECPSocket sock;
ECPDHKey key_perma;
@@ -31,6 +33,7 @@ static void usage(char *arg) {
}
int main(int argc, char *argv[]) {
+ ecp_tr_addr_t addr;
ECPDHKey key_perma;
int rv;
@@ -41,7 +44,7 @@ int main(int argc, char *argv[]) {
printf("ecp_init RV:%d\n", rv);
ecp_conn_handler_init(&handler, handle_msg, NULL, NULL, NULL);
- ecp_ctx_set_handler(&ctx, &handler, CTYPE_TEST);
+ ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler);
rv = ecp_util_load_key(&key_perma.public, &key_perma.private, argv[2]);
printf("ecp_util_load_key RV:%d\n", rv);
@@ -50,7 +53,10 @@ int main(int argc, char *argv[]) {
rv = ecp_sock_create(&sock, &ctx, &key_perma);
printf("ecp_sock_create RV:%d\n", rv);
- rv = ecp_sock_open(&sock, argv[1]);
+ rv = ecp_addr_init(&addr, argv[1]);
+ printf("ecp_addr_init RV:%d\n", rv);
+
+ rv = ecp_sock_open(&sock, &addr);
printf("ecp_sock_open RV:%d\n", rv);
rv = ecp_start_receiver(&sock);
diff --git a/ecp/test/stress.c b/ecp/test/stress.c
deleted file mode 100644
index 6eed851..0000000
--- a/ecp/test/stress.c
+++ /dev/null
@@ -1,256 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <pthread.h>
-
-#include "core.h"
-
-#ifdef __linux__
-#define SIGINFO SIGTSTP
-#endif
-
-#define NUM_S 32
-#define NUM_C 256
-#define MSG_RATE 65
-
-#define CTYPE_TEST 0
-#define MTYPE_MSG 8
-
-ECPContext ctx_s;
-ECPDHKey key_perma_s;
-ECPConnHandler handler_s;
-ECPSocket *sock_s;
-
-ECPConnHandler handler_c;
-ECPContext *ctx_c;
-ECPSocket *sock_c;
-ECPDHKey *key_perma_c;
-
-ECPNode *node;
-ECPConnection *conn;
-
-pthread_t *s_thd;
-pthread_t *r_thd;
-pthread_mutex_t *t_mtx;
-int *t_sent, *t_rcvd;
-
-uint64_t t_start = 0, t_end = 0;
-int c_start = 0;
-
-int num_s = NUM_S, num_c = NUM_C;
-int msg_rate = MSG_RATE;
-
-static void display(void) {
- int i, s = 0, r = 0;
-
- for (i=0; i<num_c; i++) {
- pthread_mutex_lock(&t_mtx[i]);
- s += t_sent[i];
- r += t_rcvd[i];
- pthread_mutex_unlock(&t_mtx[i]);
- }
-
- uint64_t t_time = t_end - t_start;
-
- printf("TOTAL SENT:%d RCVD:%d\n", s, r);
- printf("L:%f%%\n", (s-r)/(float)s*100);
- printf("T/S S:%f R:%f\n", s/((float)t_time/1000000), r/((float)t_time/1000000));
-}
-
-static void catchINFO(int sig) {
- struct timeval tv;
-
- if (!c_start) {
- gettimeofday(&tv, NULL);
- t_start = tv.tv_sec*(uint64_t)1000000+tv.tv_usec;
- c_start = 1;
- printf("COUNTER START\n");
- } else {
- gettimeofday(&tv, NULL);
- t_end = tv.tv_sec*(uint64_t)1000000+tv.tv_usec;
- display();
- }
-}
-
-void *sender(ECPConnection *c) {
- int idx = (int)(c->conn_data);
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_MAX_PKT];
- unsigned char pld_buf[ECP_MAX_PLD];
-
- packet.buffer = pkt_buf;
- packet.size = ECP_MAX_PKT;
- payload.buffer = pld_buf;
- payload.size = ECP_MAX_PLD;
-
- printf("OPEN:%d\n", idx);
- while(1) {
- uint32_t rnd;
- c->sock->ctx->rng(&rnd, sizeof(uint32_t));
- usleep(rnd % (2000000/msg_rate));
-
- ecp_pld_set_type(payload.buffer, payload.size, MTYPE_MSG);
- ssize_t _rv = 0;
- // XXX refactor
- // _rv = ecp_pld_send(c, &packet, &payload, ECP_SIZE_PLD(1000, 0));
- if (c_start && (_rv > 0)) {
- pthread_mutex_lock(&t_mtx[idx]);
- t_sent[idx]++;
- pthread_mutex_unlock(&t_mtx[idx]);
- }
- }
-}
-
-ssize_t handle_open_c(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *p, ssize_t s, ECP2Buffer *b) {
- int idx = (int)(conn->conn_data);
- int rv = 0;
-
- ecp_conn_handle_open(conn, sq, t, p, s, b);
- rv = pthread_create(&s_thd[idx], NULL, (void *(*)(void *))sender, (void *)conn);
- if (rv) {
- char msg[256];
- sprintf(msg, "THD %d CREATE\n", idx);
- perror(msg);
- exit(1);
- }
- return s;
-}
-
-ssize_t handle_msg_c(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *p, ssize_t s, ECP2Buffer *b) {
- int idx = (int)(conn->conn_data);
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_MAX_PKT];
- unsigned char pld_buf[ECP_MAX_PLD];
-
- packet.buffer = pkt_buf;
- packet.size = ECP_MAX_PKT;
- payload.buffer = pld_buf;
- payload.size = ECP_MAX_PLD;
-
- if (c_start) {
- pthread_mutex_lock(&t_mtx[idx]);
- t_rcvd[idx]++;
- pthread_mutex_unlock(&t_mtx[idx]);
- }
-
- // ecp_pld_set_type(payload.buffer, payload.size, MTYPE_MSG);
- // ssize_t _rv = ecp_pld_send(c, &packet, &payload, ECP_SIZE_PLD(1000, 0));
- return s;
-}
-
-ssize_t handle_msg_s(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *p, ssize_t s, ECP2Buffer *b) {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_MAX_PKT];
- unsigned char pld_buf[ECP_MAX_PLD];
-
- packet.buffer = pkt_buf;
- packet.size = ECP_MAX_PKT;
- payload.buffer = pld_buf;
- payload.size = ECP_MAX_PLD;
-
- ecp_pld_set_type(payload.buffer, payload.size, MTYPE_MSG);
- // XXX refactor
- // ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(1000, 0));
- return s;
-}
-
-int main(int argc, char *argv[]) {
- char addr[256];
- int rv;
- int i;
-
- ECPConnHandler handler_c;
-
- ECPContext *ctx_c;
- ECPSocket *sock_c;
- ECPDHKey *key_perma_c;
-
- ECPNode *node;
- ECPConnection *conn;
-
- sock_s = malloc(num_s * sizeof(ECPSocket));
- ctx_c = malloc(num_c * sizeof(ECPContext));
- sock_c = malloc(num_c * sizeof(ECPSocket));
- key_perma_c = malloc(num_c * sizeof(ECPDHKey));
- node = malloc(num_c * sizeof(ECPNode));
- conn = malloc(num_c * sizeof(ECPConnection));
-
- s_thd = malloc(num_c * sizeof(pthread_t));
- r_thd = malloc(num_c * sizeof(pthread_t));
- t_mtx = malloc(num_c * sizeof(pthread_mutex_t));
- t_sent = malloc(num_c * sizeof(int));
- t_rcvd = malloc(num_c * sizeof(int));
- memset(t_rcvd, 0, num_c * sizeof(int));
- memset(t_sent, 0, num_c * sizeof(int));
-
- struct sigaction actINFO;
- memset(&actINFO, 0, sizeof(actINFO));
- actINFO.sa_handler = &catchINFO;
- sigaction(SIGINFO, &actINFO, NULL);
-
- rv = ecp_init(&ctx_s);
- if (!rv) rv = ecp_conn_handler_init(&handler_s);
- handler_s.msg[MTYPE_MSG] = handle_msg_s;
- ctx_s.handler[CTYPE_TEST] = &handler_s;
-
- if (!rv) rv = ecp_dhkey_gen(&ctx_s, &key_perma_s);
-
- for (i=0; i<num_s; i++) {
- if (!rv) rv = ecp_sock_init(&sock_s[i], &ctx_s, &key_perma_s);
-
- strcpy(addr, "0.0.0.0:");
- sprintf(addr+strlen(addr), "%d", 3000+i);
- if (!rv) rv = ecp_sock_open(&sock_s[i], addr);
-
- if (!rv) rv = pthread_create(&r_thd[i], NULL, (void *(*)(void *))ecp_receiver, (void *)&sock_s[i]);
-
- if (rv) {
- char msg[256];
- sprintf(msg, "SERVER %d CREATE:%d\n", i, rv);
- perror(msg);
- exit(1);
- }
- }
-
- rv = ecp_conn_handler_init(&handler_c);
-
- handler_c.msg[ECP_MTYPE_OPEN] = handle_open_c;
- handler_c.msg[MTYPE_MSG] = handle_msg_c;
-
- for (i=0; i<num_c; i++) {
- pthread_mutex_init(&t_mtx[i], NULL);
-
- if (!rv) rv = ecp_init(&ctx_c[i]);
- ctx_c[i].handler[CTYPE_TEST] = &handler_c;
-
- if (!rv) rv = ecp_dhkey_gen(&ctx_c[i], &key_perma_c[i]);
- if (!rv) rv = ecp_sock_init(&sock_c[i], &ctx_c[i], &key_perma_c[i]);
- if (!rv) rv = ecp_sock_open(&sock_c[i], NULL);
-
- if (!rv) rv = pthread_create(&r_thd[i], NULL, (void *(*)(void *))ecp_receiver, (void *)&sock_c[i]);
-
- strcpy(addr, "127.0.0.1:");
- sprintf(addr+strlen(addr), "%d", 3000 + (i % num_s));
- if (!rv) rv = ecp_node_init(&node[i], &key_perma_s.public, addr);
-
- if (!rv) rv = ecp_conn_init(&conn[i], &sock_c[i], CTYPE_TEST);
- conn[i].conn_data = (void *)i;
-
- if (!rv) rv = ecp_conn_open(&conn[i], &node[i]);
-
- if (rv) {
- char msg[256];
- sprintf(msg, "CLIENT %d CREATE:%d\n", i, rv);
- perror(msg);
- exit(1);
- }
-
- }
- while (1) sleep(1);
-} \ No newline at end of file
diff --git a/ecp/test/vc_client.c b/ecp/test/vc_client.c
index 89602ca..41c364d 100644
--- a/ecp/test/vc_client.c
+++ b/ecp/test/vc_client.c
@@ -3,16 +3,20 @@
#include <unistd.h>
#include <stdio.h>
-#include <core.h>
-#include <vconn/vconn.h>
+#include <ecp/core.h>
+#include <ecp/vconn/vconn.h>
#include <util.h>
+#include "init_vconn.h"
+
ECPContext ctx;
ECPSocket sock;
ECPConnHandler handler;
+ECPConnHandler vconn_handler;
+ECPConnHandler vlink_handler;
ECPConnection conn;
-ECPConnection vconn[3];
+ECPVConnOutb vconn[3];
#define CTYPE_TEST 0
#define MTYPE_MSG 0
@@ -47,11 +51,11 @@ int main(int argc, char *argv[]) {
if ((argc < 4) || (argc > 6)) usage(argv[0]);
- rv = ecp_init(&ctx);
+ rv = ecp_init(&ctx, &vconn_handler, &vlink_handler);
printf("ecp_init RV:%d\n", rv);
ecp_conn_handler_init(&handler, handle_msg, handle_open, NULL, NULL);
- ecp_ctx_set_handler(&ctx, &handler, CTYPE_TEST);
+ ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler);
rv = ecp_dhkey_gen(&key_perma);
printf("ecp_dhkey_gen RV:%d\n", rv);
@@ -65,24 +69,21 @@ int main(int argc, char *argv[]) {
rv = ecp_start_receiver(&sock);
printf("ecp_start_receiver RV:%d\n", rv);
+ rv = ecp_util_load_pub(&node_pub, argv[1]);
+ printf("ecp_util_load_pub RV:%d\n", rv);
+
+ ecp_node_init(&node, &node_pub, NULL);
+ rv = ecp_node_set_addr(&node, argv[2]);
+ printf("ecp_node_set_addr RV:%d\n", rv);
+
for (i=3; i<argc; i++) {
rv = ecp_util_load_pub(&vconn_pub[i-3], argv[i]);
printf("ecp_util_load_pub RV:%d\n", rv);
}
- rv = ecp_conn_create(&conn, &sock, CTYPE_TEST);
- printf("ecp_conn_create RV:%d\n", rv);
-
- rv = ecp_vconn_create(vconn, vconn_pub, argc-3, &conn);
- printf("ecp_vconn_create RV:%d\n", rv);
-
- rv = ecp_util_load_pub(&node_pub, argv[1]);
- printf("ecp_util_load_pub RV:%d\n", rv);
-
- rv = ecp_node_init(&node, &node_pub, argv[2]);
- printf("ecp_node_init RV:%d\n", rv);
-
- rv = ecp_vconn_open(&conn, &node);
+ ecp_conn_init(&conn, &sock, CTYPE_TEST);
+ ecp_vconn_init(vconn, vconn_pub, argc-3, &sock);
+ rv = ecp_vconn_open(vconn, &conn, &node);
printf("ecp_vconn_open RV:%d\n", rv);
while (1) sleep(1);
diff --git a/ecp/test/vc_client_t.c b/ecp/test/vc_client_t.c
deleted file mode 100644
index 968d643..0000000
--- a/ecp/test/vc_client_t.c
+++ /dev/null
@@ -1,118 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/time.h>
-
-#include "core.h"
-#include "vconn/vconn.h"
-#include "util.h"
-
-ECPContext ctx;
-ECPSocket sock;
-ECPConnHandler handler;
-
-ECPNode node;
-ECPConnection conn;
-
-ECPVConnOut vconn[20];
-ECPNode vconn_node[20];
-
-#define CTYPE_TEST 0
-#define MTYPE_MSG 8
-
-
-int counter = 0;
-uint64_t t_start = 0;
-uint64_t t_end = 0;
-ssize_t handle_open(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *p, ssize_t s, ECP2Buffer *b) {
- ssize_t rv = ecp_conn_handle_open(conn, sq, t, p, s, b);
- if (rv < 0) {
- printf("OPEN ERR:%ld\n", s);
- return rv;
- }
-
- printf("OPEN\n");
- char *msg = "PERA JE CAR!";
- unsigned char buf[1000];
-
- strcpy((char *)buf, msg);
- // ssize_t _rv = ecp_send(conn, MTYPE_MSG, buf, 1000);
-
- struct timeval tv;
- gettimeofday(&tv, NULL);
- t_start = tv.tv_sec*(uint64_t)1000000+tv.tv_usec;
-
- return rv;
-}
-
-ssize_t handle_msg(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *p, ssize_t s, ECP2Buffer *b) {
- ecp_send(conn, t, p, s);
- write(2, p+1, s-1);
- fflush(stderr);
- // printf("MSG C:%s size:%ld\n", p, s);
- return s;
-
- counter++;
- char *msg = "PERA JE CAR!";
- unsigned char buf[1000];
-
- strcpy((char *)buf, msg);
- ssize_t _rv = ecp_send(conn, MTYPE_MSG, buf, 1000);
-
- if (counter % 100 == 0) {
- struct timeval tv;
- uint64_t t_time;
-
- gettimeofday(&tv, NULL);
- t_end = tv.tv_sec*(uint64_t)1000000+tv.tv_usec;
- t_time = t_end - t_start;
- printf("T:%f\n", (float)t_time/1000000);
- t_start = t_end;
- }
- return s;
-}
-
-static void usage(char *arg) {
- fprintf(stderr, "Usage: %s <server.pub> <vcs1.pub> ... <vcsn.pub>\n", arg);
- exit(1);
-}
-
-int main(int argc, char *argv[]) {
- int rv, i;
-
- if ((argc < 3) || (argc > 22)) usage(argv[0]);
-
- rv = ecp_init(&ctx);
- printf("ecp_init RV:%d\n", rv);
-
- rv = ecp_conn_handler_init(&handler);
- handler.msg[ECP_MTYPE_OPEN] = handle_open;
- handler.msg[MTYPE_MSG] = handle_msg;
- ctx.handler[CTYPE_TEST] = &handler;
-
- rv = ecp_sock_init(&sock, &ctx, NULL);
- printf("ecp_sock_init RV:%d\n", rv);
-
- rv = ecp_sock_open(&sock, NULL);
- printf("ecp_sock_open RV:%d\n", rv);
-
- rv = ecp_start_receiver(&sock);
- printf("ecp_start_receiver RV:%d\n", rv);
-
- rv = ecp_util_node_load(&ctx, &node, argv[1]);
- printf("ecp_util_node_load RV:%d\n", rv);
-
- for (i=0; i<argc-2; i++) {
- rv = ecp_util_node_load(&ctx, &vconn_node[i], argv[i+2]);
- printf("ecp_util_node_load RV:%d\n", rv);
- }
-
- rv = ecp_conn_init(&conn, &sock, CTYPE_TEST);
- printf("ecp_conn_init RV:%d\n", rv);
-
- rv = ecp_vconn_open(&conn, &node, vconn, vconn_node, argc-2);
- printf("ecp_vconn_open RV:%d\n", rv);
-
- while (1) sleep(1);
-}
diff --git a/ecp/test/vc_common.c b/ecp/test/vc_common.c
new file mode 100644
index 0000000..0508ac1
--- /dev/null
+++ b/ecp/test/vc_common.c
@@ -0,0 +1,127 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <ecp/core.h>
+#include <ecp/dir/dir.h>
+#include <ecp/vconn/vconn.h>
+
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+
+#include "vc_common.h"
+
+#define VCONN_NODES 3
+
+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
+
+static void msg_remove_item(unsigned char *msg, uint16_t i, uint16_t c) {
+ if (c - i - 1) memmove(msg + i * ECP_SIZE_DIR_ITEM, msg + (i + 1) * ECP_SIZE_DIR_ITEM, (c - i - 1) * ECP_SIZE_DIR_ITEM);
+}
+
+static void hrw_select(unsigned char *msg, uint16_t count, ecp_ecdh_public_t *pub, ecp_ecdh_public_t *hrw_pub, ecp_ecdh_public_t vconn_pub[], size_t *_vconn_size, ecp_tr_addr_t *addr) {
+ unsigned char *_msg = msg;
+ unsigned char hash[SHA_DIGEST_LENGTH];
+ unsigned char hrw_hash[SHA_DIGEST_LENGTH];
+ ecp_ecdh_public_t hash_pub[2];
+ size_t vconn_size = *_vconn_size;
+ ECPDirItem dir_item;
+ SHA_CTX ctx;
+ int i, hrw_i;
+
+ if (count == 0) return;
+
+ memset(hrw_hash, 0, sizeof(hrw_hash));
+ memcpy(&hash_pub[0], pub, sizeof(ecp_ecdh_public_t));
+
+ for (i=0; i<count; i++) {
+ unsigned char *host;
+ uint16_t port;
+ size_t rv;
+
+ rv = ecp_dir_item_parse(&dir_item, _msg);
+ _msg += rv;
+
+ host = dir_item.node.addr.host;
+ port = dir_item.node.addr.port;
+ printf("ITEM: %d.%d.%d.%d:%d\n", host[0], host[1], host[2], host[3], ntohs(port));
+
+ memcpy(&hash_pub[1], &dir_item.node.key_perma.public, sizeof(ecp_ecdh_public_t));
+ SHA1_Init(&ctx);
+ SHA1_Update(&ctx, hash_pub, sizeof(hash_pub));
+ SHA1_Final(hash, &ctx);
+ if (memcmp(hrw_hash, hash, sizeof(hash)) < 0) {
+ hrw_i = i;
+ memcpy(hrw_hash, hash, sizeof(hash));
+ memcpy(hrw_pub, &dir_item.node.key_perma, sizeof(ecp_ecdh_public_t));
+ }
+ }
+
+ printf("SELECTED: %d\n", hrw_i);
+ msg_remove_item(msg, hrw_i, count);
+ count--;
+
+ vconn_size = MIN(count, vconn_size);
+ for (i=0; i<vconn_size; i++) {
+ uint16_t s;
+
+ s = arc4random() % count;
+ _msg = msg + s * ECP_SIZE_DIR_ITEM;
+ ecp_dir_item_parse(&dir_item, _msg);
+ memcpy(&vconn_pub[i], &dir_item.node.key_perma, sizeof(ecp_ecdh_public_t));
+ if (i==0) *addr = dir_item.node.addr;
+ msg_remove_item(msg, s, count);
+ count--;
+ }
+ *_vconn_size = vconn_size;
+}
+
+int vc_open_inb(ECPConnection *vlink, unsigned char *msg, uint16_t count, ecp_ecdh_public_t *local_pub) {
+ ecp_ecdh_public_t vconn_pub[VCONN_NODES - 1];
+ ecp_ecdh_public_t hrw_pub;
+ ecp_tr_addr_t addr;
+ ECPNode node;
+ ECPVConnOutb *vconn;
+ size_t vconn_size;
+ int rv;
+
+ vconn_size = VCONN_NODES - 1;
+ hrw_select(msg, count, local_pub, &hrw_pub, vconn_pub, &vconn_size, &addr);
+
+ vconn = malloc(sizeof(ECPVConnOutb) * vconn_size);
+ if (vconn == NULL) return ECP_ERR_ALLOC;
+
+ ecp_vconn_init(vconn, vconn_pub, vconn_size, vlink->sock);
+ ecp_node_init(&node, &hrw_pub, &addr);
+ rv = ecp_vconn_open(vconn, vlink, &node);
+ printf("ecp_vconn_open RV:%d\n", rv);
+
+ return ECP_OK;
+}
+
+int vc_open_outb(ECPConnection *conn, unsigned char *msg, uint16_t count, ecp_ecdh_public_t *remote_pub) {
+ ecp_ecdh_public_t vconn_pub[VCONN_NODES];
+ ecp_ecdh_public_t hrw_pub;
+ ecp_tr_addr_t addr;
+ ECPNode node;
+ ECPVConnOutb *vconn;
+ size_t vconn_size;
+ int rv;
+
+ vconn_size = VCONN_NODES - 1;
+ hrw_select(msg, count, remote_pub, &hrw_pub, vconn_pub, &vconn_size, &addr);
+ memcpy(&vconn_pub[vconn_size], &hrw_pub, sizeof(ecp_ecdh_public_t));
+ vconn_size++;
+
+ vconn = malloc(sizeof(ECPVConnOutb) * vconn_size);
+ if (vconn == NULL) return ECP_ERR_ALLOC;
+
+ ecp_vconn_init(vconn, vconn_pub, vconn_size, conn->sock);
+ ecp_node_init(&node, remote_pub, &addr);
+ rv = ecp_vconn_open(vconn, conn, &node);
+ printf("ecp_vconn_open RV:%d\n", rv);
+
+ return ECP_OK;
+}
diff --git a/ecp/test/vc_common.h b/ecp/test/vc_common.h
new file mode 100644
index 0000000..a684566
--- /dev/null
+++ b/ecp/test/vc_common.h
@@ -0,0 +1,2 @@
+int vc_open_inb(ECPConnection *vlink, unsigned char *msg, uint16_t count, ecp_ecdh_public_t *local_pub);
+int vc_open_outb(ECPConnection *conn, unsigned char *msg, uint16_t count, ecp_ecdh_public_t *remote_pub);
diff --git a/ecp/test/vc_inb.c b/ecp/test/vc_inb.c
new file mode 100644
index 0000000..13b493c
--- /dev/null
+++ b/ecp/test/vc_inb.c
@@ -0,0 +1,124 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <ecp/core.h>
+#include <ecp/dir/dir.h>
+#include <ecp/vconn/vconn.h>
+
+#include <util.h>
+
+#include "init_vconn.h"
+#include "vc_common.h"
+
+ECPContext ctx;
+ECPSocket sock;
+ECPConnHandler handler;
+ECPConnHandler dir_handler;
+ECPConnHandler vconn_handler;
+ECPConnHandler vlink_handler;
+
+#define CTYPE_TEST 0
+#define MTYPE_MSG 0
+
+static int handle_open(ECPConnection *conn, ECP2Buffer *b) {
+ printf("OPEN\n");
+
+ return ECP_OK;
+}
+
+static ssize_t handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
+ char *_msg = "VAISTINU JE CAR!";
+ ssize_t rv;
+
+ printf("MSG:%s size:%ld\n", msg, msg_size);
+ rv = ecp_msg_send(conn, MTYPE_MSG, (unsigned char *)_msg, strlen(_msg)+1);
+
+ return msg_size;
+}
+
+static ssize_t handle_dir_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
+ size_t rsize;
+ uint16_t count;
+ ECPConnection *vlink;
+ int rv;
+
+ if (msg_size < sizeof(uint16_t)) return ECP_ERR_SIZE;
+
+ count = \
+ ((uint16_t)msg[0] << 8) | \
+ ((uint16_t)msg[1]);
+
+ printf("DIR MSG:%d\n", count);
+
+ rsize = sizeof(uint16_t) + count * ECP_SIZE_DIR_ITEM;
+ if (msg_size < rsize) return ECP_ERR_SIZE;
+
+ msg += sizeof(uint16_t);
+
+ vlink = malloc(sizeof(ECPConnection));
+ if (vlink == NULL) return ECP_ERR_ALLOC;
+
+ ecp_vlink_init(vlink, conn->sock);
+ rv = vc_open_inb(vlink, msg, count, &conn->sock->key_perma.public);
+ if (rv) {
+ free(vlink);
+ return rv;
+ }
+
+ return rsize;
+}
+
+static void usage(char *arg) {
+ fprintf(stderr, "Usage: %s <my.priv> <dir pub> <dir addr>\n", arg);
+ exit(1);
+}
+
+int main(int argc, char *argv[]) {
+ ECPConnection *conn_dir;
+ ECPNode node_dir;
+ ecp_ecdh_public_t dir_pub;
+ ECPDHKey key_perma;
+ int rv;
+
+ if (argc != 4) usage(argv[0]);
+
+ rv = ecp_init(&ctx, &vconn_handler, &vlink_handler);
+ printf("ecp_init RV:%d\n", rv);
+
+ ecp_conn_handler_init(&dir_handler, handle_dir_msg, ecp_dir_handle_open, NULL, NULL);
+ ecp_ctx_set_handler(&ctx, ECP_CTYPE_DIR, &dir_handler);
+
+ ecp_conn_handler_init(&handler, handle_msg, handle_open, NULL, NULL);
+ ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler);
+
+ rv = ecp_util_load_key(&key_perma.public, &key_perma.private, argv[1]);
+ printf("ecp_util_load_key RV:%d\n", rv);
+ key_perma.valid = 1;
+
+ rv = ecp_sock_create(&sock, &ctx, &key_perma);
+ printf("ecp_sock_create RV:%d\n", rv);
+
+ rv = ecp_sock_open(&sock, NULL);
+ printf("ecp_sock_open RV:%d\n", rv);
+
+ rv = ecp_start_receiver(&sock);
+ printf("ecp_start_receiver RV:%d\n", rv);
+
+ rv = ecp_util_load_pub(&dir_pub, argv[2]);
+ printf("ecp_util_load_pub RV:%d\n", rv);
+
+ ecp_node_init(&node_dir, &dir_pub, NULL);
+ rv = ecp_node_set_addr(&node_dir, argv[3]);
+ printf("ecp_node_set_addr RV:%d\n", rv);
+
+ conn_dir = malloc(sizeof(ECPConnection));
+ if (conn_dir == NULL) printf("out of memory\n");
+
+ ecp_dir_conn_init(conn_dir, &sock);
+ rv = ecp_conn_open(conn_dir, &node_dir);
+ printf("ecp_conn_open RV:%d\n", rv);
+
+ while (1) sleep(1);
+}
diff --git a/ecp/test/vc_outb.c b/ecp/test/vc_outb.c
new file mode 100644
index 0000000..6018602
--- /dev/null
+++ b/ecp/test/vc_outb.c
@@ -0,0 +1,128 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <ecp/core.h>
+#include <ecp/dir/dir.h>
+#include <ecp/vconn/vconn.h>
+
+#include <util.h>
+
+#include "init_vconn.h"
+#include "vc_common.h"
+
+ECPContext ctx;
+ECPSocket sock;
+ECPConnHandler handler;
+ECPConnHandler dir_handler;
+ECPConnHandler vconn_handler;
+ECPConnHandler vlink_handler;
+ecp_ecdh_public_t remote_pub;
+
+#define CTYPE_TEST 0
+#define MTYPE_MSG 0
+
+static int handle_open(ECPConnection *conn, ECP2Buffer *b) {
+ char *_msg = "PERA JE CAR!";
+ ssize_t rv;
+
+ printf("OPEN\n");
+ rv = ecp_msg_send(conn, MTYPE_MSG, (unsigned char *)_msg, strlen(_msg)+1);
+
+ return ECP_OK;
+}
+
+static ssize_t handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
+ printf("MSG:%s size:%ld\n", msg, msg_size);
+
+ return msg_size;
+}
+
+static ssize_t handle_dir_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
+ size_t rsize;
+ uint16_t count;
+ ECPConnection *_conn;
+ int rv;
+
+ if (msg_size < sizeof(uint16_t)) return ECP_ERR_SIZE;
+
+ count = \
+ ((uint16_t)msg[0] << 8) | \
+ ((uint16_t)msg[1]);
+
+ printf("DIR MSG:%d\n", count);
+
+ rsize = sizeof(uint16_t) + count * ECP_SIZE_DIR_ITEM;
+ if (msg_size < rsize) return ECP_ERR_SIZE;
+
+ msg += sizeof(uint16_t);
+
+ _conn = malloc(sizeof(ECPConnection));
+ if (_conn == NULL) return ECP_ERR_ALLOC;
+
+ ecp_conn_init(_conn, conn->sock, CTYPE_TEST);
+ rv = vc_open_outb(_conn, msg, count, &remote_pub);
+ if (rv) {
+ printf("vc_open_outb RV:%d\n", rv);
+ free(_conn);
+ return rv;
+ }
+
+ return rsize;
+}
+
+static void usage(char *arg) {
+ fprintf(stderr, "Usage: %s <remote.pub> <dir pub> <dir addr>\n", arg);
+ exit(1);
+}
+
+int main(int argc, char *argv[]) {
+ ECPConnection *conn_dir;
+ ECPNode node_dir;
+ ecp_ecdh_public_t dir_pub;
+ ECPDHKey key_perma;
+ int rv;
+
+ if (argc != 4) usage(argv[0]);
+
+ rv = ecp_init(&ctx, &vconn_handler, &vlink_handler);
+ printf("ecp_init RV:%d\n", rv);
+
+ ecp_conn_handler_init(&dir_handler, handle_dir_msg, ecp_dir_handle_open, NULL, NULL);
+ ecp_ctx_set_handler(&ctx, ECP_CTYPE_DIR, &dir_handler);
+
+ ecp_conn_handler_init(&handler, handle_msg, handle_open, NULL, NULL);
+ ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler);
+
+ rv = ecp_dhkey_gen(&key_perma);
+ printf("ecp_dhkey_gen RV:%d\n", rv);
+
+ rv = ecp_sock_create(&sock, &ctx, &key_perma);
+ printf("ecp_sock_create RV:%d\n", rv);
+
+ rv = ecp_sock_open(&sock, NULL);
+ printf("ecp_sock_open RV:%d\n", rv);
+
+ rv = ecp_start_receiver(&sock);
+ printf("ecp_start_receiver RV:%d\n", rv);
+
+ rv = ecp_util_load_pub(&remote_pub, argv[1]);
+ printf("ecp_util_load_pub RV:%d\n", rv);
+
+ rv = ecp_util_load_pub(&dir_pub, argv[2]);
+ printf("ecp_util_load_pub RV:%d\n", rv);
+
+ ecp_node_init(&node_dir, &dir_pub, NULL);
+ rv = ecp_node_set_addr(&node_dir, argv[3]);
+ printf("ecp_node_set_addr RV:%d\n", rv);
+
+ conn_dir = malloc(sizeof(ECPConnection));
+ if (conn_dir == NULL) printf("out of memory\n");
+
+ ecp_dir_conn_init(conn_dir, &sock);
+ rv = ecp_conn_open(conn_dir, &node_dir);
+ printf("ecp_conn_open RV:%d\n", rv);
+
+ while (1) sleep(1);
+}
diff --git a/ecp/test/vc_server.c b/ecp/test/vc_server.c
index de7f275..548b52d 100644
--- a/ecp/test/vc_server.c
+++ b/ecp/test/vc_server.c
@@ -3,16 +3,20 @@
#include <unistd.h>
#include <stdio.h>
-#include <core.h>
-#include <vconn/vconn.h>
+#include <ecp/core.h>
+#include <ecp/vconn/vconn.h>
#include <util.h>
+#include "init_vconn.h"
+
ECPContext ctx;
ECPSocket sock;
ECPConnHandler handler;
+ECPConnHandler vconn_handler;
+ECPConnHandler vlink_handler;
ECPConnection conn;
-ECPConnection vconn[3];
+ECPVConnOutb vconn[3];
#define CTYPE_TEST 0
#define MTYPE_MSG 0
@@ -46,11 +50,11 @@ int main(int argc, char *argv[]) {
if ((argc < 4) || (argc > 7)) usage(argv[0]);
- rv = ecp_init(&ctx);
+ rv = ecp_init(&ctx, &vconn_handler, &vlink_handler);
printf("ecp_init RV:%d\n", rv);
ecp_conn_handler_init(&handler, handle_msg, handle_open, NULL, NULL);
- ecp_ctx_set_handler(&ctx, &handler, CTYPE_TEST);
+ ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler);
rv = ecp_util_load_key(&key_perma.public, &key_perma.private, argv[1]);
printf("ecp_util_load_key RV:%d\n", rv);
@@ -65,29 +69,29 @@ int main(int argc, char *argv[]) {
rv = ecp_start_receiver(&sock);
printf("ecp_start_receiver RV:%d\n", rv);
- rv = ecp_vlink_create(&conn, &sock);
- printf("ecp_vlink_create RV:%d\n", rv);
+ rv = ecp_util_load_pub(&node_pub, argv[argc-1]);
+ printf("ecp_util_load_pub RV:%d\n", rv);
+ ecp_node_init(&node, &node_pub, NULL);
+ rv = ecp_node_set_addr(&node, argv[2]);
+ printf("ecp_node_set_addr RV:%d\n", rv);
+
+ ecp_vlink_init(&conn, &sock);
if (argc > 4) {
- ecp_ecdh_public_t vconn_key[3];
+ ecp_ecdh_public_t vconn_pub[3];
for (i=3; i<argc-1; i++) {
- rv = ecp_util_load_pub(&vconn_key[i-3], argv[i]);
+ rv = ecp_util_load_pub(&vconn_pub[i-3], argv[i]);
printf("ecp_util_load_pub RV:%d\n", rv);
}
+ ecp_vconn_init(vconn, vconn_pub, argc-4, &sock);
- rv = ecp_vconn_create(vconn, vconn_key, argc-4, &conn);
- printf("ecp_vconn_create RV:%d\n", rv);
+ rv = ecp_vconn_open(vconn, &conn, &node);
+ printf("ecp_vconn_open RV:%d\n", rv);
+ } else {
+ rv = ecp_conn_open(&conn, &node);
+ printf("ecp_conn_open RV:%d\n", rv);
}
- rv = ecp_util_load_pub(&node_pub, argv[argc-1]);
- printf("ecp_util_load_pub RV:%d\n", rv);
-
- rv = ecp_node_init(&node, &node_pub, argv[2]);
- printf("ecp_node_init RV:%d\n", rv);
-
- rv = ecp_vconn_open(&conn, &node);
- printf("ecp_vconn_open RV:%d\n", rv);
-
while (1) sleep(1);
}
diff --git a/ecp/test/vcs.c b/ecp/test/vcs.c
index c4beed7..92d1eb2 100644
--- a/ecp/test/vcs.c
+++ b/ecp/test/vcs.c
@@ -3,14 +3,18 @@
#include <unistd.h>
#include <stdio.h>
-#include <core.h>
-#include <vconn/vconn.h>
+#include <ecp/core.h>
+#include <ecp/vconn/vconn.h>
#include <util.h>
+#include "init_vconn.h"
+
ECPContext ctx;
ECPSocket sock;
ECPConnection conn;
+ECPConnHandler vconn_handler;
+ECPConnHandler vlink_handler;
static void usage(char *arg) {
fprintf(stderr, "Usage: %s <my addr> <my.priv> [ <node addr> <node.pub> ]\n", arg);
@@ -18,12 +22,13 @@ static void usage(char *arg) {
}
int main(int argc, char *argv[]) {
+ ecp_tr_addr_t addr;
ECPDHKey key_perma;
int rv;
if ((argc < 3) || (argc > 5)) usage(argv[0]);
- rv = ecp_init(&ctx);
+ rv = ecp_init(&ctx, &vconn_handler, &vlink_handler);
printf("ecp_init RV:%d\n", rv);
rv = ecp_util_load_key(&key_perma.public, &key_perma.private, argv[2]);
@@ -33,7 +38,10 @@ int main(int argc, char *argv[]) {
rv = ecp_sock_create(&sock, &ctx, &key_perma);
printf("ecp_sock_create RV:%d\n", rv);
- rv = ecp_sock_open(&sock, argv[1]);
+ rv = ecp_addr_init(&addr, argv[1]);
+ printf("ecp_addr_init RV:%d\n", rv);
+
+ rv = ecp_sock_open(&sock, &addr);
printf("ecp_sock_open RV:%d\n", rv);
rv = ecp_start_receiver(&sock);
@@ -43,15 +51,14 @@ int main(int argc, char *argv[]) {
ECPNode node;
ecp_ecdh_public_t node_pub;
- rv = ecp_vlink_create(&conn, &sock);
- printf("ecp_vlink_create RV:%d\n", rv);
-
rv = ecp_util_load_pub(&node_pub, argv[4]);
printf("ecp_util_load_pub RV:%d\n", rv);
- rv = ecp_node_init(&node, &node_pub, argv[3]);
- printf("ecp_node_init RV:%d\n", rv);
+ ecp_node_init(&node, &node_pub, NULL);
+ rv = ecp_node_set_addr(&node, argv[3]);
+ printf("ecp_node_set_addr RV:%d\n", rv);
+ ecp_vlink_init(&conn, &sock);
rv = ecp_conn_open(&conn, &node);
printf("ecp_conn_open RV:%d\n", rv);
}
diff --git a/ecp/util/mknode.c b/ecp/util/mknode.c
index 764ac18..bc66da0 100644
--- a/ecp/util/mknode.c
+++ b/ecp/util/mknode.c
@@ -4,7 +4,7 @@
#include <stdio.h>
#include <string.h>
-#include <core.h>
+#include <ecp/core.h>
#include "util.h"
@@ -38,8 +38,11 @@ int main(int argc, char *argv[]) {
rv = ecp_dhkey_gen(&key);
if (rv) goto err;
- rv = ecp_node_init(&node, &key.public, addr);
- if (rv) goto err;
+ ecp_node_init(&node, &key.public, NULL);
+ if (addr) {
+ rv = ecp_node_set_addr(&node, addr);
+ if (rv) goto err;
+ }
rv = ecp_util_save_key(&key.public, &key.private, fn_key);
if (rv) goto err;
diff --git a/ecp/util/util.c b/ecp/util/util.c
index 2b67127..efcf152 100644
--- a/ecp/util/util.c
+++ b/ecp/util/util.c
@@ -3,7 +3,7 @@
#include <unistd.h>
#include <sys/stat.h>
-#include <core.h>
+#include <ecp/core.h>
#include "util.h"