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  | 
