diff options
author | Uros Majstorovic <majstor@majstor.org> | 2024-06-06 22:33:46 +0200 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2024-06-06 22:33:46 +0200 |
commit | 4a6d383192ac59195cfe927f5a0b1eb104da5550 (patch) | |
tree | 67a787120f0332f619ee333b1b9f65393acfc563 /ecp/src | |
parent | 109f39e09630409a30a9f4e8183f539c499f07ba (diff) |
open / keyx sync implemented; vconn close fixed; rendezvous hashing fixed
Diffstat (limited to 'ecp/src')
-rw-r--r-- | ecp/src/ecp/common.mk | 3 | ||||
-rw-r--r-- | ecp/src/ecp/core.c | 94 | ||||
-rw-r--r-- | ecp/src/ecp/core.h | 17 | ||||
-rw-r--r-- | ecp/src/ecp/crypto/crypto.c | 14 | ||||
-rw-r--r-- | ecp/src/ecp/dir/dir.c | 32 | ||||
-rw-r--r-- | ecp/src/ecp/dir/dir.h | 2 | ||||
-rw-r--r-- | ecp/src/ecp/dir/dir_client.c | 96 | ||||
-rw-r--r-- | ecp/src/ecp/dir/dir_client.h | 9 | ||||
-rw-r--r-- | ecp/src/ecp/vconn/vconn.c | 57 | ||||
-rw-r--r-- | ecp/src/ecp/vconn/vconn.h | 1 | ||||
-rw-r--r-- | ecp/src/platform/posix/features_tmpl.mk | 1 |
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 |