diff options
Diffstat (limited to 'ecp/src')
35 files changed, 1239 insertions, 1187 deletions
| 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 1ba042d..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;                  } @@ -202,25 +222,24 @@ static int conn_table_insert(ECPConnection *conn) {              }          }      } -#else + +#else   /* ECP_WITH_HTABLE */ +      if (sock->conn_table.size == ECP_MAX_SOCK_CONN) return ECP_ERR_FULL;      sock->conn_table.arr[sock->conn_table.size] = conn;      sock->conn_table.size++; -#endif + +#endif  /* ECP_WITH_HTABLE */      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; @@ -231,14 +250,15 @@ static void conn_table_remove(ECPConnection *conn) {      int i;  #ifdef ECP_WITH_HTABLE +      if (ecp_conn_is_outb(conn)) {          for (i=0; i<ECP_MAX_CONN_KEY; i++) {              if (conn->key[i].valid) {                  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++) { @@ -247,7 +267,9 @@ static void conn_table_remove(ECPConnection *conn) {              }          }      } -#else + +#else   /* ECP_WITH_HTABLE */ +      for (i=0; i<sock->conn_table.size; i++) {          if (conn == sock->conn_table.arr[i]) {              while (i < (sock->conn_table.size-1)) { @@ -259,130 +281,176 @@ static void conn_table_remove(ECPConnection *conn) {              return;          }      } -#endif + +#endif  /* ECP_WITH_HTABLE */  }  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 -    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; -    } -#else +    return ecp_ht_search(sock->conn_table.keys, c_public); +#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_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 (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; +            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; -                } +            _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]; +    } + +    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; + +    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; +        } +    } + +    return NULL; +#endif  /* ECP_WITH_HTABLE */ +} + +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; + +    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 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_inb(ECPSocket *sock, ecp_sts_t to) { +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_abstime_ms(0); +    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 */ @@ -396,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; @@ -482,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);  } @@ -596,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;  } @@ -654,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 @@ -662,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); @@ -679,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 @@ -713,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; @@ -744,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 @@ -756,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); @@ -837,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) { @@ -868,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_init_outb(ECPConnection *conn, ECPNode *node) { +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_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); @@ -1011,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; @@ -1043,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; @@ -1072,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; +    } + +    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); +    _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) { @@ -1137,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) { @@ -1163,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); @@ -1172,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; @@ -1198,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) { @@ -1264,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; @@ -1272,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; @@ -1286,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); @@ -1314,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;  } @@ -1334,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; @@ -1346,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) { @@ -1444,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); @@ -1452,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; @@ -1521,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; @@ -1533,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; @@ -1674,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 */ @@ -1708,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)]; @@ -1802,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) { @@ -1847,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;      } @@ -1860,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: @@ -1891,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;  } @@ -1910,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; @@ -1928,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; @@ -1952,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]; @@ -1974,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; @@ -2073,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; @@ -2098,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; @@ -2116,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;              } @@ -2148,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; @@ -2162,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;              } @@ -2177,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_abstime_ms(0); -                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 @@ -2209,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; @@ -2225,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; @@ -2240,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: @@ -2473,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 81327d5..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_abstime_ms(0); +                    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 445c343..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_abstime_ms(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_abstime_ms(0); +    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 af84b66..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_abstime_ms(ecp_sts_t msec); -void ecp_tm_sleep_ms(ecp_sts_t msec); +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 1e5eb17..4bf530c 100644 --- a/ecp/src/platform/fe310/time.c +++ b/ecp/src/platform/fe310/time.c @@ -1,12 +1,12 @@  #include <stdlib.h> -#include <core.h> -#include <tr.h> +#include <ecp/core.h> +#include <ecp/tm.h>  #include <eos/eos.h> -#include <eos/net.h>  #include <eos/event.h> -#include <eos/timer.h> +#include <eos/soc/timer.h> +#include <eos/dev/net.h>  extern ECPSocket *_ecp_tr_sock; @@ -23,11 +23,15 @@ int ecp_tm_init(ECPContext *ctx) {      return ECP_OK;  } -ecp_sts_t ecp_tm_abstime_ms(ecp_sts_t msec) { -    return eos_time_get_tick() * 1000 / EOS_TIMER_RTC_FREQ + msec; +ecp_sts_t ecp_tm_get_s(void) { +    return eos_time_get_tick() / EOS_TIMER_RTC_FREQ;  } -void ecp_tm_sleep_ms(ecp_sts_t msec) { +ecp_sts_t ecp_tm_get_ms(void) { +    return eos_time_get_tick() * 1000 / EOS_TIMER_RTC_FREQ; +} + +void ecp_tm_sleep(ecp_sts_t msec) {      eos_time_sleep(msec);  } diff --git a/ecp/src/platform/fe310/transport.c b/ecp/src/platform/fe310/transport.c index 2640ecf..bc758c9 100644 --- a/ecp/src/platform/fe310/transport.c +++ b/ecp/src/platform/fe310/transport.c @@ -2,11 +2,11 @@  #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/net.h> +#include <eos/dev/net.h>  ECPSocket *_ecp_tr_sock = NULL;  unsigned char pld_buf[ECP_MAX_PLD]; @@ -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/fe310/transport.h b/ecp/src/platform/fe310/transport.h index 1e0c526..52ece15 100644 --- a/ecp/src/platform/fe310/transport.h +++ b/ecp/src/platform/fe310/transport.h @@ -1,4 +1,4 @@ -#include <eos/sock.h> +#include <eos/net/sock.h>  typedef struct EOSNetAddr ecp_tr_addr_t;  typedef int ecp_tr_sock_t; 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 efee4f8..49a85e7 100644 --- a/ecp/src/platform/posix/time.c +++ b/ecp/src/platform/posix/time.c @@ -1,25 +1,30 @@  #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_abstime_ms(ecp_sts_t msec) { +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;      gettimeofday(&tv, NULL);      ms_now = tv.tv_sec * 1000 + tv.tv_usec / 1000; -    return ms_now + msec; +    return ms_now;  } -void ecp_tm_sleep_ms(ecp_sts_t msec) { -    usleep(msec*1000); +void ecp_tm_sleep(ecp_sts_t msec) { +    usleep(msec * 1000);  }  void ecp_tm_timer_set(ecp_sts_t next) {} 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); | 
