summaryrefslogtreecommitdiff
path: root/ecp/src
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2024-06-06 22:33:46 +0200
committerUros Majstorovic <majstor@majstor.org>2024-06-06 22:33:46 +0200
commit4a6d383192ac59195cfe927f5a0b1eb104da5550 (patch)
tree67a787120f0332f619ee333b1b9f65393acfc563 /ecp/src
parent109f39e09630409a30a9f4e8183f539c499f07ba (diff)
open / keyx sync implemented; vconn close fixed; rendezvous hashing fixed
Diffstat (limited to 'ecp/src')
-rw-r--r--ecp/src/ecp/common.mk3
-rw-r--r--ecp/src/ecp/core.c94
-rw-r--r--ecp/src/ecp/core.h17
-rw-r--r--ecp/src/ecp/crypto/crypto.c14
-rw-r--r--ecp/src/ecp/dir/dir.c32
-rw-r--r--ecp/src/ecp/dir/dir.h2
-rw-r--r--ecp/src/ecp/dir/dir_client.c96
-rw-r--r--ecp/src/ecp/dir/dir_client.h9
-rw-r--r--ecp/src/ecp/vconn/vconn.c57
-rw-r--r--ecp/src/ecp/vconn/vconn.h1
-rw-r--r--ecp/src/platform/posix/features_tmpl.mk1
11 files changed, 253 insertions, 73 deletions
diff --git a/ecp/src/ecp/common.mk b/ecp/src/ecp/common.mk
index d23c68d..c8c373b 100644
--- a/ecp/src/ecp/common.mk
+++ b/ecp/src/ecp/common.mk
@@ -11,6 +11,9 @@ CFLAGS += -I$(src_dir) -I$(platform_dir) -I$(ssl_dir)/include -I$(ssl_dir)/crypt
ifeq ($(with_pthread),yes)
CFLAGS += -DECP_WITH_PTHREAD=1
+ifeq ($(with_sync),yes)
+CFLAGS += -DECP_WITH_SYNC=1
+endif
endif
ifeq ($(with_htable),yes)
diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c
index 60a346b..2cef860 100644
--- a/ecp/src/ecp/core.c
+++ b/ecp/src/ecp/core.c
@@ -546,8 +546,8 @@ int ecp_sock_open(ECPSocket *sock, ecp_tr_addr_t *myaddr) {
}
void ecp_sock_close(ECPSocket *sock) {
- ecp_sock_destroy(sock);
ecp_tr_close(sock);
+ ecp_sock_destroy(sock);
}
void ecp_sock_ckey_new(ECPSocket *sock) {
@@ -1231,6 +1231,18 @@ int ecp_conn_create(ECPConnection *conn, ECPConnection *parent) {
}
#endif
+#ifdef ECP_WITH_SYNC
+ rv = pthread_cond_init(&conn->cond, NULL);
+ if (rv) {
+ pthread_mutex_destroy(&conn->mutex);
+#ifdef ECP_WITH_VCONN
+ if (conn->parent) ecp_conn_refcount_dec(conn->parent);
+#endif
+
+ return ECP_ERR;
+ }
+#endif
+
if (!ecp_conn_is_gc(conn)) conn->refcount++;
return ECP_OK;
@@ -1287,6 +1299,10 @@ void ecp_conn_destroy(ECPConnection *conn) {
if (conn->parent) ecp_conn_refcount_dec(conn->parent);
#endif
+#ifdef ECP_WITH_SYNC
+ pthread_cond_destroy(&conn->cond);
+#endif
+
#ifdef ECP_WITH_PTHREAD
pthread_mutex_destroy(&conn->mutex);
#endif
@@ -1617,6 +1633,64 @@ void ecp_conn_refcount_dec(ECPConnection *conn) {
}
}
+#ifdef ECP_WITH_SYNC
+
+int ecp_conn_open_sync(ECPConnection *conn, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr) {
+ int rv;
+
+ conn->rv_sync = 1;
+ rv = ecp_conn_open(conn, public, addr);
+ return rv;
+}
+
+int ecp_conn_keyx_sync(ECPConnection *conn) {
+ ssize_t rv;
+ int rv_sync;
+
+ pthread_mutex_lock(&conn->mutex);
+ rv_sync = conn->rv_sync;
+ if (!rv_sync) conn->rv_sync = 1;
+ pthread_mutex_unlock(&conn->mutex);
+
+ if (rv_sync) return ECP_ERR_BUSY;
+
+ rv = ecp_send_keyx_req(conn, 1);
+ if (rv < 0) return rv;
+
+ return ECP_OK;
+}
+
+int ecp_conn_signal(ECPConnection *conn, int rv_sync) {
+ int rv;
+
+ pthread_mutex_lock(&conn->mutex);
+ if (conn->rv_sync > 0) {
+ conn->rv_sync = rv_sync;
+ pthread_cond_signal(&conn->cond);
+ rv = 1;
+ } else {
+ rv = 0;
+ }
+ pthread_mutex_unlock(&conn->mutex);
+
+ return rv;
+}
+
+int ecp_conn_wait(ECPConnection *conn) {
+ int rv;
+
+ pthread_mutex_lock(&conn->mutex);
+ while (conn->rv_sync > 0) {
+ pthread_cond_wait(&conn->cond, &conn->mutex);
+ }
+ rv = conn->rv_sync;
+ pthread_mutex_unlock(&conn->mutex);
+
+ return rv;
+}
+
+#endif
+
int ecp_conn_dhkey_new(ECPConnection *conn) {
ECPSocket *sock = conn->sock;
ECPDHKey new_key;
@@ -1817,9 +1891,16 @@ ecp_oreq_send_t ecp_get_oreq_send_f(ECPConnection *conn) {
void ecp_err_handle(ECPConnection *conn, unsigned char mtype, int err) {
ECPContext *ctx = conn->sock->ctx;
ecp_err_handler_t err_handler;
- int rv;
if (err == ECP_ERR_CLOSED) return;
+#ifdef ECP_WITH_SYNC
+ if ((mtype == ECP_MTYPE_OPEN_REP) || (mtype == ECP_MTYPE_KEYX_REP)) {
+ int rv;
+
+ rv = ecp_conn_signal(conn, err);
+ if (rv) return;
+ }
+#endif
err_handler = ecp_get_err_handler(conn);
if (err_handler == NULL) err_handler = ctx->handle_err;
@@ -2291,6 +2372,9 @@ ssize_t ecp_handle_keyx(ECPConnection *conn, unsigned char mtype, unsigned char
if (ecp_conn_is_inb(conn)) return ECP_ERR;
ecp_conn_dhkey_set_curr(conn);
+#ifdef ECP_WITH_SYNC
+ ecp_conn_signal(conn, ECP_OK);
+#endif
} else {
if (ecp_conn_is_outb(conn)) return ECP_ERR;
@@ -2749,6 +2833,10 @@ ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *ad
mtype = ecp_conn_is_inb(conn) ? ECP_MTYPE_OPEN_REQ : ECP_MTYPE_OPEN_REP;
ecp_err_handle(conn, mtype, _rv);
rv = 0;
+ } else {
+#ifdef ECP_WITH_SYNC
+ ecp_conn_signal(conn, ECP_OK);
+#endif
}
}
@@ -3274,7 +3362,7 @@ void ecp_receiver(ECPSocket *sock) {
ctx = sock->ctx;
sock->running = 1;
- while(sock->running) {
+ while (sock->running) {
packet.buffer = pkt_buf;
packet.size = ECP_MAX_PKT;
diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h
index 5fa00a7..da200b7 100644
--- a/ecp/src/ecp/core.h
+++ b/ecp/src/ecp/core.h
@@ -299,6 +299,7 @@ typedef ssize_t (*ecp_conn_auth_t) (struct ECPSocket *sock, struct ECPConnection
typedef struct ECPConnection * (*ecp_conn_new_t) (struct ECPSocket *sock, struct ECPConnection *parent, unsigned char type);
typedef void (*ecp_conn_free_t) (struct ECPConnection *conn);
typedef void (*ecp_err_handler_t) (struct ECPConnection *conn, unsigned char mtype, int err);
+typedef void (*ecp_dir_handler_t) (struct ECPConnection *conn, void *dir_list, int err);
typedef int (*ecp_logger_t) (const char *fmt, ...);
typedef int (*ecp_open_handler_t) (struct ECPConnection *conn, struct ECP2Buffer *b);
@@ -364,6 +365,9 @@ typedef struct ECPContext {
ecp_conn_new_t conn_new; /* inbound connections only */
ecp_conn_free_t conn_free;
ecp_err_handler_t handle_err;
+#ifdef ECP_WITH_DIR
+ ecp_dir_handler_t handle_dir;
+#endif
ecp_logger_t logger;
ECPConnHandler *handler[ECP_MAX_CTYPE];
ECPConnHandler *handler_sys[ECP_MAX_CTYPE_SYS];
@@ -399,7 +403,7 @@ typedef struct ECPVConnTable {
typedef struct ECPSocket {
ECPContext *ctx;
- unsigned char running;
+ volatile int running;
ecp_tr_sock_t sock;
ecp_nonce_t nonce_out;
ECPDHKey key_perma;
@@ -448,6 +452,10 @@ typedef struct ECPConnection {
#ifdef ECP_WITH_PTHREAD
pthread_mutex_t mutex;
#endif
+#ifdef ECP_WITH_SYNC
+ pthread_cond_t cond;
+ int rv_sync;
+#endif
} ECPConnection;
int ecp_dhkey_gen(ECPDHKey *key);
@@ -523,6 +531,13 @@ void ecp_conn_unlock(ECPConnection *conn);
int ecp_conn_refcount_inc(ECPConnection *conn);
void ecp_conn_refcount_dec(ECPConnection *conn);
+#ifdef ECP_WITH_SYNC
+int ecp_conn_open_sync(ECPConnection *conn, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr);
+int ecp_conn_keyx_sync(ECPConnection *conn);
+int ecp_conn_signal(ECPConnection *conn, int rv_sync);
+int ecp_conn_wait(ECPConnection *conn);
+#endif
+
int ecp_conn_dhkey_new(ECPConnection *conn);
int ecp_conn_dhkey_get(ECPConnection *conn, unsigned char idx, ECPDHKey *key);
void ecp_conn_dhkey_set_curr(ECPConnection *conn);
diff --git a/ecp/src/ecp/crypto/crypto.c b/ecp/src/ecp/crypto/crypto.c
index 95598da..53cedfa 100644
--- a/ecp/src/ecp/crypto/crypto.c
+++ b/ecp/src/ecp/crypto/crypto.c
@@ -142,19 +142,23 @@ void ecp_hash(unsigned char *hd, unsigned char *m, size_t ml) {
}
int ecp_str2key(uint8_t *key, char *str) {
- uint32_t u[8];
+ unsigned int u[8];
int i, rv;
if (str[ECP_SIZE_ECDH_KEY_BUF - 1] != '\0') return ECP_ERR;
+ for (i=8; i<ECP_SIZE_ECDH_KEY_BUF - 1; i+=9) {
+ if (str[i] != ':') return ECP_ERR;
+ }
+
rv = sscanf(str, "%X:%X:%X:%X:%X:%X:%X:%X", &u[0], &u[1], &u[2], &u[3], &u[4], &u[5], &u[6], &u[7]);
if (rv != 8) return ECP_ERR;
for (i=0; i<8; i++) {
- key[0] = u[i] >> 24;
- key[1] = u[i] >> 16;
- key[2] = u[i] >> 8;
- key[3] = u[i];
+ key[0] = (uint32_t)u[i] >> 24;
+ key[1] = (uint32_t)u[i] >> 16;
+ key[2] = (uint32_t)u[i] >> 8;
+ key[3] = (uint32_t)u[i];
key += 4;
}
diff --git a/ecp/src/ecp/dir/dir.c b/ecp/src/ecp/dir/dir.c
index b997f5c..d7b8f1d 100644
--- a/ecp/src/ecp/dir/dir.c
+++ b/ecp/src/ecp/dir/dir.c
@@ -96,10 +96,12 @@ int ecp_dir_handle_open(ECPConnection *conn, ECP2Buffer *b) {
if (ecp_conn_is_inb(conn)) return ECP_ERR;
+#ifndef ECP_WITH_SYNC
region = (unsigned char)ecp_conn_set_param(conn, NULL);
rv = ecp_dir_send_req(conn, region);
if (rv < 0) return rv;
+#endif
return ECP_OK;
}
@@ -135,9 +137,37 @@ void ecp_dir_conn_init(ECPConnection *conn, ECPSocket *sock) {
}
int ecp_dir_request(ECPConnection *conn, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr, unsigned char region) {
+ ssize_t _rv;
int rv;
+#ifdef ECP_WITH_SYNC
+
+ rv = ecp_conn_open_sync(conn, public, addr);
+ if (rv) {
+ ecp_conn_free(conn);
+ return rv;
+ }
+ rv = ecp_conn_wait(conn);
+ if (rv) {
+ ecp_conn_close(conn);
+ return rv;
+ }
+ _rv = ecp_dir_send_req(conn, region);
+ if (_rv < 0) {
+ ecp_conn_close(conn);
+ return _rv;
+ }
+
+#else
+
ecp_conn_set_param(conn, (void *)region);
rv = ecp_conn_open(conn, public, addr);
- return rv;
+ if (rv) {
+ ecp_conn_free(conn);
+ return rv;
+ }
+
+#endif
+
+ return ECP_OK;
}
diff --git a/ecp/src/ecp/dir/dir.h b/ecp/src/ecp/dir/dir.h
index e343ecc..a7bbd49 100644
--- a/ecp/src/ecp/dir/dir.h
+++ b/ecp/src/ecp/dir/dir.h
@@ -9,6 +9,8 @@
#define ECP_ROLE_DIR 0x01
#define ECP_ROLE_VCONN 0x02
+#define ECP_ROLE_UNAVAILABLE 0x80
+
typedef struct ECPDirItem {
ECPNode node;
uint8_t region;
diff --git a/ecp/src/ecp/dir/dir_client.c b/ecp/src/ecp/dir/dir_client.c
index 7c34189..cf82754 100644
--- a/ecp/src/ecp/dir/dir_client.c
+++ b/ecp/src/ecp/dir/dir_client.c
@@ -7,8 +7,6 @@
#include "dir_client.h"
-static ecp_dir_result_t dir_result_f = NULL;
-
static int dir_list_create_items(ECPDirList *dir_list, uint16_t list_size) {
dir_list->items = malloc(list_size * sizeof(ECPDirItem));
if (dir_list->items == NULL) return ECP_ERR_ALLOC;
@@ -106,7 +104,9 @@ handle_dir_msg_fin:
ecp_frag_end(conn, seq, frag_cnt, rv);
if (rv || is_last) {
- if (dir_result_f) dir_result_f(conn->sock, dir_list_fin, rv);
+ ECPContext *ctx = conn->sock->ctx;
+
+ if (ctx->handle_dir) ctx->handle_dir(conn, dir_list_fin, rv);
ecp_conn_close(conn);
}
@@ -114,8 +114,10 @@ handle_dir_msg_fin:
return msg_size;
}
-static void dir_handle_err(ECPConnection *conn, unsigned char mtype, int err) {
- if (dir_result_f) dir_result_f(conn->sock, NULL, err);
+void ecp_dir_handle_err(ECPConnection *conn, unsigned char mtype, int err) {
+ ECPContext *ctx = conn->sock->ctx;
+
+ if (ctx->handle_dir) ctx->handle_dir(conn, NULL, err);
ecp_conn_close(conn);
}
@@ -154,11 +156,11 @@ ECPDirList *ecp_dir_list_copy(ECPDirList *dir_list) {
return dir_list_copy;
}
-int ecp_dir_set_handler(ECPContext *ctx, ECPConnHandler *handler, ecp_dir_result_t dir_result) {
+int ecp_dir_set_handler(ECPContext *ctx, ECPConnHandler *handler, ecp_dir_handler_t handle_dir) {
int rv;
- dir_result_f = dir_result;
- ecp_conn_handler_init(handler, dir_handle_open, dir_handle_close, dir_handle_msg, dir_handle_err);
+ ctx->handle_dir = handle_dir;
+ ecp_conn_handler_init(handler, dir_handle_open, dir_handle_close, dir_handle_msg, ecp_dir_handle_err);
rv = ecp_ctx_set_handler(ctx, ECP_CTYPE_DIR, handler);
return rv;
}
@@ -171,40 +173,85 @@ int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ecp_ecdh_public_t *public,
return rv;
}
+void ecp_dir_set_unavailable(ECPDirList *dir_list, ecp_ecdh_public_t *public) {
+ ECPDHPub *key;
+ int i;
+
+ for (i=0; i<dir_list->count; i++) {
+ key = &dir_list->items[i].node.key_perma;
+ if (memcmp(&key->public, public, sizeof(key->public)) == 0) {
+ dir_list->items[i].roles |= ECP_ROLE_UNAVAILABLE;
+ }
+ }
+}
+
+int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, struct ECPNetAddr *addr) {
+ ECPDHPub *key;
+ uint16_t dir_cnt;
+ uint32_t rnd_sel;
+ int i;
+
+ dir_cnt = 0;
+ for (i=0; i<dir_list->count; i++) {
+ if (!(dir_list->items[i].roles & ECP_ROLE_DIR) || (dir_list->items[i].roles & ECP_ROLE_UNAVAILABLE)) continue;
+ dir_cnt++;
+ }
+ if (dir_cnt == 0) return ECP_ERR_EMPTY;
+
+ rnd_sel = arc4random_uniform(dir_cnt);
+ dir_cnt = 0;
+ for (i=0; i<dir_list->count; i++) {
+ if (!(dir_list->items[i].roles & ECP_ROLE_DIR) || (dir_list->items[i].roles & ECP_ROLE_UNAVAILABLE)) continue;
+ if (rnd_sel == dir_cnt) {
+ key = &dir_list->items[i].node.key_perma;
+ memcpy(public, &key->public, sizeof(key->public));
+ *addr = dir_list->items[i].node.addr;
+ break;
+ }
+ }
+
+ return ECP_OK;
+}
+
#ifdef ECP_WITH_VCONN
-ssize_t ecp_dir_hrw_select(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, struct ECPNetAddr *addr) {
+ssize_t ecp_dir_sel_vconn(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, struct ECPNetAddr *addr) {
unsigned char tmp_hash[ECP_SIZE_HASH_DIGEST];
unsigned char hrw_hash[ECP_SIZE_HASH_DIGEST];
ecp_ecdh_public_t public[2];
uint16_t sel[ECP_MAX_PARENT];
- uint16_t hrw_i, sel_cnt;
- uint32_t rnd_i;
+ uint16_t hrw_i, hrw_sel, sel_cnt, vconn_cnt, _vconn_cnt;
+ uint32_t rnd_sel;
int i, j, k;
- if ((dir_list->count == 0) || (vconn_size == 0)) return ECP_ERR_EMPTY;
+ if (vconn_size == 0) return ECP_ERR_EMPTY;
if (vconn_size > ECP_MAX_PARENT) vconn_size = ECP_MAX_PARENT;
memset(hrw_hash, 0, sizeof(hrw_hash));
memcpy(&public[0], srv_pub, sizeof(public[0]));
+ vconn_cnt = 0;
for (i=0; i<dir_list->count; i++) {
+ if (!(dir_list->items[i].roles & ECP_ROLE_VCONN) || (dir_list->items[i].roles & ECP_ROLE_UNAVAILABLE)) continue;
memcpy(&public[1], &dir_list->items[i].node.key_perma.public, sizeof(public[1]));
ecp_hash(tmp_hash, (unsigned char *)public, sizeof(public));
if (memcmp(hrw_hash, tmp_hash, sizeof(hrw_hash)) < 0) {
hrw_i = i;
+ hrw_sel = vconn_cnt;
memcpy(hrw_hash, tmp_hash, sizeof(hrw_hash));
}
+ vconn_cnt++;
}
- sel[0] = hrw_i;
+ if (vconn_cnt == 0) return ECP_ERR_EMPTY;
+ sel[0] = hrw_sel;
sel_cnt = 1;
for (i=0; i<vconn_size-1; i++) {
- if ((dir_list->count - sel_cnt) == 0) goto dir_hrw_select_fin;
- rnd_i = arc4random_uniform(dir_list->count - sel_cnt);
+ if ((vconn_cnt - sel_cnt) == 0) goto dir_sel_vconn_fin;
+ rnd_sel = arc4random_uniform(vconn_cnt - sel_cnt);
for (j=0; j<sel_cnt; j++) {
- if (rnd_i >= sel[j]) {
- rnd_i++;
+ if (rnd_sel >= sel[j]) {
+ rnd_sel++;
} else {
for (k=sel_cnt; k>j; k--) {
sel[k] = sel[k-1];
@@ -212,13 +259,20 @@ ssize_t ecp_dir_hrw_select(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp
break;
}
}
- sel[j] = rnd_i;
+ sel[j] = rnd_sel;
sel_cnt++;
- memcpy(&vconn_keys[i], &dir_list->items[rnd_i].node.key_perma.public, sizeof(vconn_keys[i]));
- if (i == 0) *addr = dir_list->items[rnd_i].node.addr;
+ _vconn_cnt = 0;
+ for (j=0; j<dir_list->count; j++) {
+ if (!(dir_list->items[j].roles & ECP_ROLE_VCONN) || (dir_list->items[j].roles & ECP_ROLE_UNAVAILABLE)) continue;
+ if (_vconn_cnt == rnd_sel) {
+ memcpy(&vconn_keys[i], &dir_list->items[j].node.key_perma.public, sizeof(vconn_keys[i]));
+ if (i == 0) *addr = dir_list->items[j].node.addr;
+ }
+ _vconn_cnt++;
+ }
}
-dir_hrw_select_fin:
+dir_sel_vconn_fin:
memcpy(&vconn_keys[i], &dir_list->items[hrw_i].node.key_perma.public, sizeof(vconn_keys[i]));
if (i == 0) *addr = dir_list->items[hrw_i].node.addr;
return sel_cnt;
diff --git a/ecp/src/ecp/dir/dir_client.h b/ecp/src/ecp/dir/dir_client.h
index a1be56d..8efed1c 100644
--- a/ecp/src/ecp/dir/dir_client.h
+++ b/ecp/src/ecp/dir/dir_client.h
@@ -5,15 +5,18 @@ typedef struct ECPDirList {
ECPDirItem *items;
} ECPDirList;
-typedef void (*ecp_dir_result_t) (ECPSocket *sock, ECPDirList *dir_list, int err);
+void ecp_dir_handle_err(ECPConnection *conn, unsigned char mtype, int err);
ECPDirList *ecp_dir_list_create(uint16_t list_size);
void ecp_dir_list_destroy(ECPDirList *dir_list);
ECPDirList *ecp_dir_list_copy(ECPDirList *dir_list);
-int ecp_dir_set_handler(ECPContext *ctx, ECPConnHandler *handler, ecp_dir_result_t dir_result);
+int ecp_dir_set_handler(ECPContext *ctx, ECPConnHandler *handler, ecp_dir_handler_t handle_dir);
int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr, unsigned char region);
+void ecp_dir_set_unavailable(ECPDirList *dir_list, ecp_ecdh_public_t *public);
+int ecp_dir_sel_dir(ECPDirList *dir_list, ecp_ecdh_public_t *public, struct ECPNetAddr *addr);
+
#ifdef ECP_WITH_VCONN
-ssize_t ecp_dir_hrw_select(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, struct ECPNetAddr *addr);
+ssize_t ecp_dir_sel_vconn(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, struct ECPNetAddr *addr);
#endif
diff --git a/ecp/src/ecp/vconn/vconn.c b/ecp/src/ecp/vconn/vconn.c
index 615474c..3aaa1b9 100644
--- a/ecp/src/ecp/vconn/vconn.c
+++ b/ecp/src/ecp/vconn/vconn.c
@@ -330,16 +330,9 @@ int ecp_vconn_open_vlink(ECPVConnOutb *vconn, ecp_ecdh_public_t vconn_pub[], ecp
return rv;
}
-static void vconn_close(ECPVConnOutb *vconn) {
- ECPConnection *conn, *parent, *next;
+static void vconn_close(ECPConnection *conn) {
+ ECPConnection *parent;
- conn = vconn->next;
- while (conn->type == ECP_CTYPE_VCONN) {
- next = ((ECPVConnOutb *)conn)->next;
- ecp_conn_free(conn);
- conn = next;
- }
- conn = &vconn->b;
while (conn) {
parent = conn->parent;
ecp_conn_close(conn);
@@ -348,10 +341,22 @@ static void vconn_close(ECPVConnOutb *vconn) {
}
void ecp_vconn_close(ECPConnection *conn) {
- ECPVConnOutb *vconn;
+ if (ecp_conn_is_inb(conn)) return;
- vconn = (ECPVConnOutb *)conn->parent;
- if (vconn) vconn_close(vconn);
+ if (conn->type == ECP_CTYPE_VCONN) {
+ ECPConnection *_conn, *next;
+
+ _conn = ((ECPVConnOutb *)conn)->next;
+ while (_conn->type == ECP_CTYPE_VCONN) {
+ next = ((ECPVConnOutb *)_conn)->next;
+ ecp_conn_free(_conn);
+ _conn = next;
+ }
+ ecp_conn_free(_conn);
+ vconn_close(conn);
+ } else {
+ vconn_close(conn);
+ }
}
int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs) {
@@ -364,7 +369,7 @@ int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs) {
/* we should release incoming packet before sending next open packet */
ecp_tr_release(bufs->packet, 1);
rv = _ecp_conn_open(vconn->next, conn, 1);
- /* err will be handled by ecp_vconn_handle_err */
+ /* err will be handled by vconn err handler */
return rv;
}
@@ -398,30 +403,6 @@ void ecp_vconn_handle_close(ECPConnection *conn) {
#endif /* ECP_WITH_HTABLE */
-void ecp_vconn_handle_err(ECPConnection *conn, unsigned char mtype, int err) {
- if (ecp_conn_is_outb(conn) && (mtype == ECP_MTYPE_OPEN_REP)) {
- ECPVConnOutb *vconn = (ECPVConnOutb *)conn;
-
- while (vconn) {
- ECPConnection *_conn = &vconn->b;
-
- if (_conn->type != ECP_CTYPE_VCONN) {
- ecp_err_handle(_conn, mtype, err);
- break;
- }
- vconn = (ECPVConnOutb *)vconn->next;
- }
- vconn = (ECPVConnOutb *)conn;
- vconn_close(vconn);
- } else {
- ECPContext *ctx = conn->sock->ctx;
-
- if (ctx->handle_err) {
- ctx->handle_err(conn, mtype, err);
- }
- }
-}
-
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;
@@ -620,7 +601,7 @@ void ecp_vconn_sock_destroy(ECPSocket *sock) {
int ecp_vconn_handler_init(ECPContext *ctx, ECPConnHandler *vconn_handler) {
int rv;
- ecp_conn_handler_init(vconn_handler, ecp_vconn_handle_open, ecp_vconn_handle_close, ecp_vconn_handle_msg, ecp_vconn_handle_err);
+ ecp_conn_handler_init(vconn_handler, ecp_vconn_handle_open, ecp_vconn_handle_close, ecp_vconn_handle_msg, NULL);
ecp_conn_handler_set_oreq_f(vconn_handler, ecp_vconn_send_open_req);
rv = ecp_ctx_set_handler(ctx, ECP_CTYPE_VCONN, vconn_handler);
return rv;
diff --git a/ecp/src/ecp/vconn/vconn.h b/ecp/src/ecp/vconn/vconn.h
index ab1d2d1..431671d 100644
--- a/ecp/src/ecp/vconn/vconn.h
+++ b/ecp/src/ecp/vconn/vconn.h
@@ -37,7 +37,6 @@ int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs);
#ifdef ECP_WITH_HTABLE
void ecp_vconn_handle_close(ECPConnection *conn);
#endif
-void ecp_vconn_handle_err(ECPConnection *conn, unsigned char mtype, int err);
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);
diff --git a/ecp/src/platform/posix/features_tmpl.mk b/ecp/src/platform/posix/features_tmpl.mk
index 2887e08..85f22e3 100644
--- a/ecp/src/platform/posix/features_tmpl.mk
+++ b/ecp/src/platform/posix/features_tmpl.mk
@@ -1,4 +1,5 @@
with_pthread = yes
+with_sync = yes
with_htable = yes
with_vconn = yes
with_dir = yes