diff options
| author | Uros Majstorovic <majstor@majstor.org> | 2022-01-19 02:49:47 +0100 | 
|---|---|---|
| committer | Uros Majstorovic <majstor@majstor.org> | 2022-01-19 02:49:47 +0100 | 
| commit | a4f22127be441c4c158c10fe65916872d99253d2 (patch) | |
| tree | 0d476ce70c63b93ee2c4a2b3fafd0fa3df66b998 | |
| parent | e356da0b15f8fef6559c7761a1b04b8f6e2dc649 (diff) | |
code cleanup
| -rw-r--r-- | ecp/src/core.c | 587 | ||||
| -rw-r--r-- | ecp/src/core.h | 73 | ||||
| -rw-r--r-- | ecp/src/dir.c | 1 | ||||
| -rw-r--r-- | ecp/src/dir_srv.c | 20 | ||||
| -rw-r--r-- | ecp/src/dir_srv.h | 2 | ||||
| -rw-r--r-- | ecp/src/fe310/transport.h | 2 | ||||
| -rw-r--r-- | ecp/src/rbuf.c | 164 | ||||
| -rw-r--r-- | ecp/src/rbuf.h | 27 | ||||
| -rw-r--r-- | ecp/src/rbuf_recv.c | 31 | ||||
| -rw-r--r-- | ecp/src/rbuf_send.c | 103 | ||||
| -rw-r--r-- | ecp/src/timer.c | 28 | ||||
| -rw-r--r-- | ecp/src/vconn/vconn.c | 324 | ||||
| -rw-r--r-- | ecp/src/vconn/vconn.h | 9 | ||||
| -rw-r--r-- | ecp/test/basic.c | 12 | ||||
| -rw-r--r-- | ecp/test/client.c | 8 | ||||
| -rw-r--r-- | ecp/test/dir.c | 13 | ||||
| -rw-r--r-- | ecp/test/echo.c | 4 | ||||
| -rw-r--r-- | ecp/test/frag.c | 12 | ||||
| -rw-r--r-- | ecp/test/init.c | 15 | ||||
| -rw-r--r-- | ecp/test/init_vconn.c | 21 | ||||
| -rw-r--r-- | ecp/test/server.c | 4 | ||||
| -rw-r--r-- | ecp/test/stress.c | 6 | ||||
| -rw-r--r-- | ecp/test/vc_client.c | 10 | ||||
| -rw-r--r-- | ecp/test/vc_client_t.c | 20 | ||||
| -rw-r--r-- | ecp/test/vc_server.c | 22 | ||||
| -rw-r--r-- | ecp/test/vcs.c | 8 | ||||
| -rw-r--r-- | ecp/test/voip.c | 8 | 
27 files changed, 818 insertions, 716 deletions
diff --git a/ecp/src/core.c b/ecp/src/core.c index b4b6055..a8f8f01 100644 --- a/ecp/src/core.c +++ b/ecp/src/core.c @@ -8,6 +8,8 @@  #include "ht.h"  #endif +#include "dir_srv.h" +  int ecp_ctx_init(ECPContext *ctx) {      int rv; @@ -108,7 +110,7 @@ static int ctable_insert(ECPConnection *conn) {  #ifdef ECP_WITH_HTABLE      int i, rv = ECP_OK; -    if (conn->out) { +    if (ecp_conn_is_outb(conn)) {          for (i=0; i<ECP_MAX_CONN_KEY; i++) {              if (conn->key[i].valid) rv = ecp_ht_insert(sock->conn.htable, ecp_cr_dh_pub_get_buf(&conn->key[i].public), conn);              if (rv) { @@ -143,7 +145,7 @@ static void ctable_remove(ECPConnection *conn) {      ECPSocket *sock = conn->sock;  #ifdef ECP_WITH_HTABLE -    if (conn->out) { +    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.htable, ecp_cr_dh_pub_get_buf(&conn->key[i].public));      } else {          ECPDHRKeyBucket *remote = &conn->remote; @@ -171,7 +173,7 @@ static ECPConnection *ctable_search(ECPSocket *sock, unsigned char c_idx, unsign      if (c_public) {          for (i=0; i<sock->conn.size; i++) {              conn = sock->conn.array[i]; -            if (conn->out) { +            if (ecp_conn_is_outb(conn)) {                  if ((c_idx < ECP_MAX_CONN_KEY) && conn->key[c_idx].valid && ecp_cr_dh_pub_eq(c_public, &conn->key[c_idx].public))                      return conn;              } else { @@ -183,7 +185,7 @@ static ECPConnection *ctable_search(ECPSocket *sock, unsigned char c_idx, unsign          /* in case server is not returning client's public key in packet */          for (i=0; i<sock->conn.size; i++) {              conn = sock->conn.array[i]; -            if (conn->out && ecp_tr_addr_eq(&conn->node.addr, addr)) return conn; +            if (ecp_conn_is_outb(conn) && ecp_tr_addr_eq(&conn->node.addr, addr)) return conn;          }      } @@ -191,9 +193,7 @@ static ECPConnection *ctable_search(ECPSocket *sock, unsigned char c_idx, unsign  #endif  } -int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) { -    int rv; - +int ecp_sock_init(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) {      if (sock == NULL) return ECP_ERR;      if (ctx == NULL) return ECP_ERR; @@ -208,9 +208,13 @@ int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) {      sock->handler[ECP_MTYPE_DIR] = ecp_dir_handle_req;  #endif -    rv = ecp_dhkey_gen(sock->ctx, &sock->key[sock->key_curr]); -    if (!rv) rv = ctable_create(&sock->conn, sock->ctx); +    return ecp_dhkey_gen(sock->ctx, &sock->key[sock->key_curr]); +} + +int ecp_sock_create(ECPSocket *sock) { +    int rv; +    rv = ctable_create(&sock->conn, sock->ctx);      if (rv) return rv;      rv = ecp_timer_create(&sock->timer); @@ -240,13 +244,23 @@ void ecp_sock_destroy(ECPSocket *sock) {  }  int ecp_sock_open(ECPSocket *sock, void *myaddr) { +    int rv; + +    rv = ecp_sock_create(sock); +    if (rv) return rv; +      return ecp_tr_open(sock, myaddr);  }  void ecp_sock_close(ECPSocket *sock) { +    ecp_sock_destroy(sock);      ecp_tr_close(sock);  } +ecp_sock_msg_handler_t ecp_sock_get_msg_handler(ECPSocket *sock, unsigned char mtype) { +    return sock->handler[mtype]; +} +  int ecp_sock_dhkey_get_curr(ECPSocket *sock, unsigned char *idx, unsigned char *public) {      unsigned char _idx; @@ -302,7 +316,7 @@ static int conn_dhkey_new_pair(ECPConnection *conn, ECPDHKey *key) {      conn->key_curr = conn->key_curr == ECP_ECDH_IDX_INV ? 0 : (conn->key_curr+1) % ECP_MAX_CONN_KEY;  #ifdef ECP_WITH_HTABLE -    if (conn->out && ecp_conn_is_reg(conn) && conn->key[conn->key_curr].valid) { +    if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn) && conn->key[conn->key_curr].valid) {          ecp_ht_remove(sock->conn.htable, ecp_cr_dh_pub_get_buf(&conn->key[conn->key_curr].public));      }  #endif @@ -311,7 +325,7 @@ static int conn_dhkey_new_pair(ECPConnection *conn, ECPDHKey *key) {      conn->key_idx_map[conn->key_curr] = ECP_ECDH_IDX_INV;  #ifdef ECP_WITH_HTABLE -    if (conn->out && ecp_conn_is_reg(conn)) { +    if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn)) {          int rv;          rv = ecp_ht_insert(sock->conn.htable, ecp_cr_dh_pub_get_buf(&conn->key[conn->key_curr].public), conn); @@ -326,7 +340,7 @@ static void conn_dhkey_del_pair(ECPConnection *conn, unsigned char idx) {      ECPSocket *sock = conn->sock;  #ifdef ECP_WITH_HTABLE -    if (conn->out && 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.htable, ecp_cr_dh_pub_get_buf(&conn->key[idx].public));      }  #endif @@ -364,7 +378,7 @@ static int conn_dhkey_new_pub_remote(ECPConnection *conn, unsigned char idx, uns      if ((remote->key_idx_map[idx] != ECP_ECDH_IDX_INV) && ecp_cr_dh_pub_eq(public, &remote->key[remote->key_idx_map[idx]].public)) return ECP_ERR_ECDH_KEY_DUP;  #ifdef ECP_WITH_HTABLE -    if (!conn->out && ecp_conn_is_reg(conn) && (remote->key[new].idx != ECP_ECDH_IDX_INV)) { +    if (ecp_conn_is_inb(conn) && ecp_conn_is_reg(conn) && (remote->key[new].idx != ECP_ECDH_IDX_INV)) {          ecp_ht_remove(sock->conn.htable, ecp_cr_dh_pub_get_buf(&remote->key[new].public));      }  #endif @@ -376,7 +390,7 @@ static int conn_dhkey_new_pub_remote(ECPConnection *conn, unsigned char idx, uns      remote->key_curr = new;  #ifdef ECP_WITH_HTABLE -    if (!conn->out && ecp_conn_is_reg(conn)) { +    if (ecp_conn_is_inb(conn) && ecp_conn_is_reg(conn)) {          int rv;          rv = ecp_ht_insert(sock->conn.htable, ecp_cr_dh_pub_get_buf(&remote->key[new].public), conn); @@ -395,7 +409,7 @@ static int conn_shsec_get(ECPConnection *conn, unsigned char s_idx, unsigned cha          ECPDHKey *priv = NULL;          ecp_dh_public_t *public_p = NULL; -        if (conn->out) { +        if (ecp_conn_is_outb(conn)) {              public_p = &conn->node.public;              priv = conn_dhkey_get(conn, c_idx);          } else { @@ -414,8 +428,8 @@ static int conn_shsec_get(ECPConnection *conn, unsigned char s_idx, unsigned cha          if ((priv == NULL) || !priv->valid) return ECP_ERR_ECDH_IDX;          ecp_cr_dh_shsec(shsec, public_p, &priv->private);      } else { -        unsigned char l_idx = conn->out ? c_idx : s_idx; -        unsigned char r_idx = conn->out ? s_idx : c_idx; +        unsigned char l_idx = ecp_conn_is_outb(conn) ? c_idx : s_idx; +        unsigned char r_idx = ecp_conn_is_outb(conn) ? s_idx : c_idx;          ECPDHShared *shared = NULL;          if ((l_idx >= ECP_MAX_SOCK_KEY) || (r_idx >= ECP_MAX_SOCK_KEY)) return ECP_ERR_ECDH_IDX; @@ -443,8 +457,8 @@ static int conn_shsec_get(ECPConnection *conn, unsigned char s_idx, unsigned cha  }  static int conn_shsec_set(ECPConnection *conn, unsigned char s_idx, unsigned char c_idx, ecp_aead_key_t *shsec) { -    unsigned char l_idx = conn->out ? c_idx : s_idx; -    unsigned char r_idx = conn->out ? s_idx : c_idx; +    unsigned char l_idx = ecp_conn_is_outb(conn) ? c_idx : s_idx; +    unsigned char r_idx = ecp_conn_is_outb(conn) ? s_idx : c_idx;      ECPDHShared *shared = NULL;      if ((l_idx >= ECP_MAX_SOCK_KEY) || (r_idx >= ECP_MAX_SOCK_KEY)) return ECP_ERR_ECDH_IDX; @@ -459,8 +473,8 @@ static int conn_shsec_set(ECPConnection *conn, unsigned char s_idx, unsigned cha      return ECP_OK;  } -int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) { -    int i, rv; +int ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) { +    int i;      if (conn == NULL) return ECP_ERR;      if (sock == NULL) return ECP_ERR; @@ -469,6 +483,8 @@ int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) {      if (ctype >= ECP_MAX_CTYPE) return ECP_ERR_MAX_CTYPE; +    ecp_conn_set_new(conn); +    conn->sock = sock;      conn->type = ctype;      conn->key_curr = ECP_ECDH_IDX_INV;      conn->key_idx_curr = ECP_ECDH_IDX_INV; @@ -480,7 +496,11 @@ int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) {      }      memset(conn->remote.key_idx_map, ECP_ECDH_IDX_INV, sizeof(conn->remote.key_idx_map)); -    conn->sock = sock; +    return ECP_OK; +} + +int ecp_conn_create(ECPConnection *conn) { +    int rv;  #ifdef ECP_WITH_PTHREAD      rv = pthread_mutex_init(&conn->mutex, NULL); @@ -496,24 +516,78 @@ void ecp_conn_destroy(ECPConnection *conn) {  #endif  } +int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char c_idx, unsigned char *public) { +    ECPContext *ctx = conn->sock->ctx; +    int rv; + +    rv = ecp_conn_create(conn); +    if (rv) return rv; + +    conn->refcount = 1; +    conn->parent = parent; +    conn->pcount = parent ? parent->pcount+1 : 0; + +    rv = ctx->rng(&conn->seq_out, sizeof(conn->seq_out)); +    if (!rv) rv = conn_dhkey_new_pub_remote(conn, c_idx, public); + +    if (rv) { +        ecp_conn_destroy(conn); +        return rv; +    } + +    return ECP_OK; +} + +int ecp_conn_create_outb(ECPConnection *conn, ECPNode *node) { +    ECPContext *ctx = conn->sock->ctx; +    ECPDHKey key; +    int rv; + +    if (node == NULL) return ECP_ERR; + +    rv = ecp_conn_create(conn); +    if (rv) return rv; + +    ecp_conn_set_outb(conn); +    conn->node = *node; +    rv = ecp_dhkey_gen(ctx, &key); +    if (!rv) rv = ctx->rng(conn->nonce, ECP_AEAD_SIZE_NONCE); +    if (!rv) rv = ctx->rng(&conn->seq_out, sizeof(conn->seq_out)); + +    if (!rv) rv = conn_dhkey_new_pair(conn, &key); +    if (!rv) rv = conn_dhkey_new_pub_local(conn, conn->key_curr); + +    if (rv) { +        ecp_conn_destroy(conn); +        return rv; +    } + +    return ECP_OK; +} + +int ecp_conn_insert(ECPConnection *conn) { +    ecp_conn_clr_new(conn); +    return ecp_conn_register(conn); +} +  int ecp_conn_register(ECPConnection *conn) {      ECPSocket *sock = conn->sock;      int rv; -    conn->flags |= ECP_CONN_FLAG_REG; +    ecp_conn_set_reg(conn);  #ifdef ECP_WITH_PTHREAD      pthread_mutex_lock(&sock->conn.mutex);  #endif      rv = ctable_insert(conn); -    if (rv) conn->flags &= ~ECP_CONN_FLAG_REG;  #ifdef ECP_WITH_PTHREAD      pthread_mutex_unlock(&sock->conn.mutex);  #endif +    if (rv) ecp_conn_clr_reg(conn);      return rv;  } -void ecp_conn_unregister(ECPConnection *conn) { +void ecp_conn_unregister(ECPConnection *conn, unsigned short *refcount) {      ECPSocket *sock = conn->sock;  #ifdef ECP_WITH_PTHREAD @@ -522,45 +596,31 @@ void ecp_conn_unregister(ECPConnection *conn) {  #endif      if (ecp_conn_is_reg(conn)) {          ctable_remove(conn); -        conn->flags &= ~ECP_CONN_FLAG_REG; +        ecp_conn_clr_reg(conn);      } +    if (refcount) *refcount = conn->refcount;  #ifdef ECP_WITH_PTHREAD      pthread_mutex_unlock(&conn->mutex);      pthread_mutex_unlock(&sock->conn.mutex);  #endif  } -/* initializes outbound connection */ -int ecp_conn_set_remote(ECPConnection *conn, ECPNode *node) { -    ECPDHKey key; -    ECPContext *ctx = conn->sock->ctx; -    int rv; - -    if (node == NULL) return ECP_ERR; - -    conn->out = 1; -    conn->node = *node; -    rv = ecp_dhkey_gen(ctx, &key); -    if (!rv) rv = ctx->rng(conn->nonce, ECP_AEAD_SIZE_NONCE); -    if (!rv) rv = ctx->rng(&conn->seq_out, sizeof(conn->seq_out)); - -    if (!rv) rv = conn_dhkey_new_pair(conn, &key); -    if (!rv) rv = conn_dhkey_new_pub_local(conn, conn->key_curr); -    if (!rv) rv = ecp_conn_register(conn); - -    return rv; -} -  int ecp_conn_get_dirlist(ECPConnection *conn, ECPNode *node) {      int rv;      ssize_t _rv; -    rv = ecp_conn_set_remote(conn, node); +    rv = ecp_conn_create_outb(conn, node);      if (rv) return rv; +    rv = ecp_conn_insert(conn); +    if (rv) { +        ecp_conn_destroy(conn); +        return rv; +    } +      _rv = ecp_conn_send_dir(conn);      if (_rv < 0) { -        ecp_conn_unregister(conn); +        ecp_conn_close(conn);          return _rv;      } @@ -571,59 +631,48 @@ int ecp_conn_open(ECPConnection *conn, ECPNode *node) {      int rv;      ssize_t _rv; -    rv = ecp_conn_set_remote(conn, node); +    rv = ecp_conn_create_outb(conn, node);      if (rv) return rv; +    rv = ecp_conn_insert(conn); +    if (rv) { +        ecp_conn_destroy(conn); +        return rv; +    } +      _rv = ecp_conn_send_kget(conn);      if (_rv < 0) { -        ecp_conn_unregister(conn); +        ecp_conn_close(conn);          return _rv;      }      return ECP_OK;  } -int ecp_conn_close(ECPConnection *conn, ecp_cts_t timeout) { -    ECPSocket *sock = conn->sock; -    int refcount = 0; +void _ecp_conn_close(ECPConnection *conn) { +    ECPContext *ctx = conn->sock->ctx; -    ecp_conn_unregister(conn); -    ecp_timer_remove(conn); +    if (ecp_conn_is_inb(conn) && conn->parent) { +        ecp_conn_refcount_dec(conn->parent); +    } -#ifdef ECP_WITH_PTHREAD -    pthread_mutex_lock(&conn->mutex); -    refcount = conn->refcount; -    pthread_mutex_unlock(&conn->mutex); +    ecp_conn_destroy(conn); -    if (timeout && refcount) { -        ecp_tm_sleep_ms(timeout); -        pthread_mutex_lock(&conn->mutex); -        refcount = conn->refcount; -        pthread_mutex_unlock(&conn->mutex); -    } +    if (ecp_conn_is_inb(conn) && ctx->conn_free) ctx->conn_free(conn); +} -    if (refcount) return ECP_ERR_TIMEOUT; -#endif +int ecp_conn_close(ECPConnection *conn) { +    unsigned short refcount = 0; +    ecp_conn_close_t handler; -    if (conn->out) { -        ecp_conn_close_t handler = conn->sock->ctx->handler[conn->type] ? conn->sock->ctx->handler[conn->type]->conn_close : NULL; -        if (handler) handler(conn); -    } else { -        ecp_conn_destroy_t handler = conn->sock->ctx->handler[conn->type] ? conn->sock->ctx->handler[conn->type]->conn_destroy : NULL; -        if (handler) handler(conn); -        if (conn->parent) { -#ifdef ECP_WITH_PTHREAD -            pthread_mutex_lock(&conn->parent->mutex); -#endif -            conn->parent->refcount--; -#ifdef ECP_WITH_PTHREAD -            pthread_mutex_unlock(&conn->parent->mutex); -#endif -        } -        ecp_conn_destroy(conn); -        if (sock->ctx->conn_free) sock->ctx->conn_free(conn); -    } +    ecp_conn_unregister(conn, &refcount); +    ecp_timer_remove(conn); +    handler = ecp_conn_get_close_handler(conn); +    if (handler) handler(conn); + +    if (refcount) return ECP_ERR_BUSY; +    _ecp_conn_close(conn);      return ECP_OK;  } @@ -655,7 +704,7 @@ int ecp_conn_reset(ECPConnection *conn) {      if (!rv) rv = conn_dhkey_new_pub_local(conn, conn->key_curr);      if (!rv) rv = ctx->rng(conn->nonce, ECP_AEAD_SIZE_NONCE);      if (!rv) rv = ctx->rng(&conn->seq_out, sizeof(conn->seq_out)); -    conn->flags &= ~ECP_CONN_FLAG_OPEN; +    ecp_conn_clr_open(conn);  #ifdef ECP_WITH_PTHREAD      pthread_mutex_unlock(&conn->mutex); @@ -664,6 +713,33 @@ int ecp_conn_reset(ECPConnection *conn) {      return rv;  } +void ecp_conn_refcount_inc(ECPConnection *conn) { +#ifdef ECP_WITH_PTHREAD +    pthread_mutex_lock(&conn->mutex); +#endif +    conn->refcount++; +#ifdef ECP_WITH_PTHREAD +    pthread_mutex_unlock(&conn->mutex); +#endif +} + +void ecp_conn_refcount_dec(ECPConnection *conn) { +    int is_reg; +    unsigned short refcount; + +#ifdef ECP_WITH_PTHREAD +    pthread_mutex_lock(&conn->mutex); +#endif +    conn->refcount--; +    refcount = conn->refcount; +    is_reg = ecp_conn_is_reg(conn); +#ifdef ECP_WITH_PTHREAD +    pthread_mutex_unlock(&conn->mutex); +#endif + +    if (!is_reg && (refcount == 0)) _ecp_conn_close(conn); +} +  int ecp_conn_handler_init(ECPConnHandler *handler) {      memset(handler, 0, sizeof(ECPConnHandler));      handler->msg[ECP_MTYPE_OPEN] = ecp_conn_handle_open; @@ -677,10 +753,20 @@ int ecp_conn_handler_init(ECPConnHandler *handler) {      handler->msg[ECP_MTYPE_RBFLUSH] = ecp_rbuf_handle_flush;      handler->msg[ECP_MTYPE_RBFLUSH_PTS] = ecp_rbuf_handle_flush_pts;  #endif -    handler->conn_open = ecp_conn_send_open;      return ECP_OK;  } +ecp_conn_msg_handler_t ecp_conn_get_msg_handler(ECPConnection *conn, unsigned char mtype) { +    ECPContext *ctx = conn->sock->ctx; +    return ctx->handler[conn->type] ? ctx->handler[conn->type]->msg[mtype] : NULL; +} + +ecp_conn_close_t ecp_conn_get_close_handler(ECPConnection *conn) { +    ECPContext *ctx = conn->sock->ctx; +    return ctx->handler[conn->type] ? ctx->handler[conn->type]->conn_close : NULL; +} + +  int ecp_conn_dhkey_new(ECPConnection *conn) {      ECPSocket *sock = conn->sock;      ECPDHKey new_key; @@ -836,42 +922,64 @@ ssize_t ecp_conn_send_dir(ECPConnection *conn) {      return ecp_timer_send(conn, _conn_send_dir, ECP_MTYPE_DIR_REP, 3, 500);  } -ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { -    int is_open; +ssize_t _ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b, int *was_open) { +    ssize_t rv; +    int _rv; + +    if (mtype & ECP_MTYPE_FLAG_REP) { +        int is_open; + +        if (ecp_conn_is_inb(conn)) return ECP_ERR;  #ifdef ECP_WITH_PTHREAD -    pthread_mutex_lock(&conn->mutex); +        pthread_mutex_lock(&conn->mutex);  #endif -    is_open = ecp_conn_is_open(conn); -    if (!is_open && (size >= 0)) conn->flags |= ECP_CONN_FLAG_OPEN; +        is_open = ecp_conn_is_open(conn);  #ifdef ECP_WITH_PTHREAD -    pthread_mutex_unlock(&conn->mutex); +        pthread_mutex_unlock(&conn->mutex);  #endif -    if (mtype & ECP_MTYPE_FLAG_REP) { -        if (!conn->out) return ECP_ERR; -          if (is_open && size == ECP_ERR_TIMEOUT) { -            int rv; - -            rv = ecp_conn_reset(conn); -            if (rv) return rv; +            _rv = ecp_conn_reset(conn); +            if (_rv) return _rv;              return 0;          }          if (size < 0) return size; -        return 0; -    } else { -        if (size < 0) return size; -        if (size < 1) return ECP_ERR; -        if (conn->out) return ECP_ERR; +        if (was_open) *was_open = is_open; + +        if (!is_open) { +#ifdef ECP_WITH_PTHREAD +            pthread_mutex_lock(&conn->mutex); +#endif +            ecp_conn_set_open(conn); +#ifdef ECP_WITH_PTHREAD +            pthread_mutex_unlock(&conn->mutex); +#endif +        } + +        rv = 0; +    } else {          ECPBuffer packet;          ECPBuffer payload;          unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_OPEN_REP, conn)];          unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_OPEN_REP, conn)]; -        unsigned char ctype = 0; -        ssize_t _rv; +        unsigned char ctype; +        int is_new; + +        if (size < 0) return size; +        if (size < 1) return ECP_ERR; +        if (ecp_conn_is_outb(conn)) return ECP_ERR; + +        is_new = ecp_conn_is_new(conn); +        if (is_new) { +            ecp_conn_set_open(conn); +            _rv = ecp_conn_insert(conn); +            if (_rv) return rv; +        } + +        if (was_open) *was_open = !is_new;          packet.buffer = pkt_buf;          packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_OPEN_REP, conn); @@ -880,20 +988,27 @@ ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char m          ctype = msg[0];          ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_OPEN_REP); -        _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_OPEN_REP), 0); +        rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_OPEN_REP), 0); -        return 1; +        rv = 1;      } -    return ECP_ERR; + +    return rv;  } -ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { +ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { +    return _ecp_conn_handle_open(conn, seq, mtype, msg, size, b, NULL); +} + +ssize_t _ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b, ecp_conn_open_t conn_open) { +    ssize_t rv; +    int _rv; +      if (mtype & ECP_MTYPE_FLAG_REP) {          ECPContext *ctx = conn->sock->ctx; -        int rv;          int is_open; -        if (!conn->out) return ECP_ERR; +        if (ecp_conn_is_inb(conn)) return ECP_ERR;  #ifdef ECP_WITH_PTHREAD          pthread_mutex_lock(&conn->mutex); @@ -904,37 +1019,32 @@ ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char m  #endif          if ((size < 0) && !is_open) { -            ecp_conn_handler_msg_t handler = ctx->handler[conn->type] ? ctx->handler[conn->type]->msg[ECP_MTYPE_OPEN] : NULL; +            ecp_conn_msg_handler_t handler; + +            handler = ecp_conn_get_msg_handler(conn, ECP_MTYPE_OPEN);              return handler ? handler(conn, seq, mtype, msg, size, b) : size;          }          if (size < 0) return size;          if (size < ECP_ECDH_SIZE_KEY+1) return ECP_ERR; -        rv = ecp_conn_dhkey_new_pub(conn, msg[0], msg+1); -        if (!rv && !is_open) { -            ecp_conn_open_t conn_open = ctx->handler[conn->type] ? ctx->handler[conn->type]->conn_open : NULL; -            if (conn_open) { -                ssize_t _rv; +        _rv = ecp_conn_dhkey_new_pub(conn, msg[0], msg+1); +        if (_rv) return _rv; -                _rv = conn_open(conn); -                if (_rv < 0) rv = _rv; -            } +        if (!is_open && conn_open) { +            rv = conn_open(conn);          } -        if (rv) return rv; -        return ECP_ECDH_SIZE_KEY+1; +        rv = ECP_ECDH_SIZE_KEY+1;      } else { -        if (conn->out) return ECP_ERR; -        if (size < 0) return size; -          ECPBuffer packet;          ECPBuffer payload;          unsigned char pkt_buf[ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, conn)];          unsigned char pld_buf[ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, conn)];          unsigned char *buf; -        int rv; -        ssize_t _rv; + +        if (ecp_conn_is_outb(conn)) return ECP_ERR; +        if (size < 0) return size;          packet.buffer = pkt_buf;          packet.size = ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, conn); @@ -944,86 +1054,58 @@ ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char m          ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KGET_REP);          buf= ecp_pld_get_buf(payload.buffer, payload.size); -        rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1); -        if (rv) return rv; -        _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0); +        _rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1); +        if (_rv) return _rv; +        rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0); -        return 0; +        rv = 0;      } -    return ECP_ERR; + +    return rv; +} + +ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { +    return _ecp_conn_handle_kget(conn, seq, mtype, msg, size, b, ecp_conn_send_open);  }  ssize_t ecp_conn_handle_kput(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { +    ssize_t rv; +    int _rv; +      if (size < 0) return size;      if (mtype & ECP_MTYPE_FLAG_REP) { -        if (!conn->out) return ECP_ERR; -        return 0; -    } else { -        if (conn->out) return ECP_ERR; -        if (size < ECP_ECDH_SIZE_KEY+1) return ECP_ERR; +        if (ecp_conn_is_inb(conn)) return ECP_ERR; +        rv = 0; +    } else {          ECPBuffer packet;          ECPBuffer payload;          unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KPUT_REP, conn)];          unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KPUT_REP, conn)]; -        int rv; -        ssize_t _rv; + +        if (ecp_conn_is_outb(conn)) return ECP_ERR; +        if (size < ECP_ECDH_SIZE_KEY+1) return ECP_ERR;          packet.buffer = pkt_buf;          packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KPUT_REP, conn);          payload.buffer = pld_buf;          payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KPUT_REP, conn); -        rv = ecp_conn_dhkey_new_pub(conn, msg[0], msg+1); -        if (rv) return rv; +        _rv = ecp_conn_dhkey_new_pub(conn, msg[0], msg+1); +        if (_rv) return _rv;          ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KPUT_REP); -        _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KPUT_REP), 0); +        rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KPUT_REP), 0); -        return ECP_ECDH_SIZE_KEY+1; +        rv = ECP_ECDH_SIZE_KEY+1;      } -    return ECP_ERR; -} - -#ifdef ECP_MEM_TINY -/* Memory limited version */ - -ssize_t ecp_conn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { -    if (size < 0) return size; -    if (b == NULL) return ECP_ERR; -    if (b->packet->buffer == NULL) return ECP_ERR; - -    memcpy(b->packet->buffer, msg, size); -    return ecp_pkt_handle(conn->sock, NULL, conn, b, size); -} - -#else - -ssize_t ecp_conn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { -    if (size < 0) return size; -    if (b == NULL) return ECP_ERR; - -    ECP2Buffer b2; -    ECPBuffer packet; -    ECPBuffer payload; -    unsigned char pld_buf[ECP_MAX_PLD]; -    b2.packet = &packet; -    b2.payload = &payload; - -    packet.buffer = msg; -    packet.size = b->payload->size - (msg - b->payload->buffer); -    payload.buffer = pld_buf; -    payload.size = ECP_MAX_PLD; - -    return ecp_pkt_handle(conn->sock, NULL, conn, &b2, size); +    return rv;  } -#endif -  ssize_t ecp_conn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { -    ecp_conn_handler_msg_t handler = NULL; +    ecp_conn_msg_handler_t handler;      unsigned char mtype = 0;      unsigned char *content = NULL;      size_t rem_size = msg_size; @@ -1039,8 +1121,9 @@ ssize_t ecp_conn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char *m          if (mtype & ECP_MTYPE_FLAG_FRAG) {  #ifdef ECP_WITH_RBUF -            if (conn->rbuf.recv && conn->rbuf.recv->frag_iter) { -                _rv = ecp_msg_defrag(conn->rbuf.recv->frag_iter, seq, mtype, msg, msg_size, &msg, &rem_size); +            ECPFragIter *iter = ecp_rbuf_get_frag_iter(conn); +            if (iter) { +                _rv = ecp_msg_defrag(iter, seq, mtype, msg, msg_size, &msg, &rem_size);                  if (_rv == ECP_ITER_NEXT) break;                  if (_rv < 0) return _rv;              } else { @@ -1053,7 +1136,7 @@ ssize_t ecp_conn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char *m          if (content == NULL) return ECP_ERR_MIN_MSG;          rem_size -= content - msg; -        handler = conn->sock->ctx->handler[conn->type] ? conn->sock->ctx->handler[conn->type]->msg[mtype & ECP_MTYPE_MASK] : NULL; +        handler = ecp_conn_get_msg_handler(conn, mtype & ECP_MTYPE_MASK);          if (handler) {              rv = handler(conn, seq, mtype, content, rem_size, bufs);              if (rv < 0) return rv; @@ -1070,84 +1153,44 @@ ssize_t ecp_conn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char *m      return msg_size;  } -int ecp_sock_handle_open(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn) { +ssize_t ecp_sock_handle_open(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn) {      ECPConnection *conn = NULL; -    ecp_conn_create_t handle_create = NULL; -    ecp_conn_destroy_t handle_destroy = NULL; -    unsigned char ctype;      unsigned char c_idx = pkt_meta->c_idx; -    unsigned char s_idx = pkt_meta->s_idx; +    unsigned char ctype;      int rv; +    if (msg_size < 0) return msg_size;      if (msg_size < 1) return ECP_ERR;      ctype = msg[0]; -    conn = sock->ctx->conn_alloc ? sock->ctx->conn_alloc(ctype) : NULL; +    conn = sock->ctx->conn_alloc ? sock->ctx->conn_alloc(sock, ctype) : NULL;      if (conn == NULL) return ECP_ERR_ALLOC; -    rv = ecp_conn_create(conn, sock, ctype); +    rv = ecp_conn_create_inb(conn, parent, c_idx, pkt_meta->public);      if (rv) {          if (sock->ctx->conn_free) sock->ctx->conn_free(conn);          return rv;      } -    rv = sock->ctx->rng(&conn->seq_out, sizeof(conn->seq_out)); -    if (rv) { -        ecp_conn_destroy(conn); -        if (sock->ctx->conn_free) sock->ctx->conn_free(conn); -        return rv; -    } - -    conn->refcount = 1; -    conn->parent = parent; -    conn->pcount = parent ? parent->pcount+1 : 0; -    handle_create = conn->sock->ctx->handler[conn->type] ? conn->sock->ctx->handler[conn->type]->conn_create : NULL; -    handle_destroy = conn->sock->ctx->handler[conn->type] ? conn->sock->ctx->handler[conn->type]->conn_destroy : NULL; - -    if (handle_create) rv = handle_create(conn, msg+1, msg_size-1); -    if (rv) { -        ecp_conn_destroy(conn); -        if (sock->ctx->conn_free) sock->ctx->conn_free(conn); -        return rv; -    } - -    rv = conn_dhkey_new_pub_remote(conn, c_idx, ecp_cr_dh_pub_get_buf(&pkt_meta->public)); -    if (rv) { -        ecp_conn_destroy(conn); -        if (sock->ctx->conn_free) sock->ctx->conn_free(conn); -        return rv; -    } - -    rv = ecp_conn_register(conn); -    if (rv) { -        if (handle_destroy) handle_destroy(conn); -        ecp_conn_destroy(conn); -        if (sock->ctx->conn_free) sock->ctx->conn_free(conn); -        return rv; -    }      if (parent) { -#ifdef ECP_WITH_PTHREAD -        pthread_mutex_lock(&parent->mutex); -#endif -        parent->refcount++; -#ifdef ECP_WITH_PTHREAD -        pthread_mutex_unlock(&parent->mutex); -#endif +        ecp_conn_refcount_inc(parent);      }      *_conn = conn; -    return ECP_OK; +    return 1;  } -int ecp_sock_handle_kget(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn) { +ssize_t ecp_sock_handle_kget(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn) {      ECPBuffer packet;      ECPBuffer payload;      unsigned char pkt_buf[ECP_SIZE_PKT_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent)];      unsigned char pld_buf[ECP_SIZE_PLD_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent)];      unsigned char *buf; -    int rv; -    ssize_t _rv; +    ssize_t rv; +    int _rv; + +    if (msg_size < 0) return msg_size;      packet.buffer = pkt_buf;      packet.size = ECP_SIZE_PKT_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent); @@ -1157,13 +1200,13 @@ int ecp_sock_handle_kget(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *paren      ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KGET_REP);      buf = ecp_pld_get_buf(payload.buffer, payload.size); -    rv = ecp_sock_dhkey_get_curr(sock, buf, buf+1); -    if (rv) return rv; +    _rv = ecp_sock_dhkey_get_curr(sock, buf, buf+1); +    if (_rv) return _rv; -    _rv = ecp_pld_send_tr(sock, addr, parent, &packet, pkt_meta, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0); -    if (_rv < 0) return _rv; +    rv = ecp_pld_send_tr(sock, addr, parent, &packet, pkt_meta, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0); +    if (rv < 0) return rv; -    return ECP_OK; +    return msg_size;  } @@ -1179,7 +1222,7 @@ ssize_t _ecp_pack(ECPContext *ctx, unsigned char *packet, size_t pkt_size, ECPPk      s_idx = pkt_meta->s_idx & 0x0F;      c_idx = pkt_meta->c_idx & 0x0F;      packet[ECP_SIZE_PROTO] = (s_idx << 4) | c_idx; -    ecp_cr_dh_pub_to_buf(packet+ECP_SIZE_PROTO+1, &pkt_meta->public); +    memcpy(packet+ECP_SIZE_PROTO+1, pkt_meta->public, ECP_ECDH_SIZE_KEY);      memcpy(packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY, pkt_meta->nonce, ECP_AEAD_SIZE_NONCE);      payload[0] = (pkt_meta->seq & 0xFF000000) >> 24; @@ -1212,14 +1255,14 @@ ssize_t _ecp_pack_conn(ECPConnection *conn, unsigned char *packet, size_t pkt_si      pthread_mutex_lock(&conn->mutex);  #endif      if (s_idx == ECP_ECDH_IDX_INV) { -        if (conn->out) { +        if (ecp_conn_is_outb(conn)) {              if (conn->remote.key_curr != ECP_ECDH_IDX_INV) s_idx = conn->remote.key[conn->remote.key_curr].idx;          } else {              if (conn->key_idx_curr != ECP_ECDH_IDX_INV) s_idx = conn->key_idx[conn->key_idx_curr];          }      }      if (c_idx == ECP_ECDH_IDX_INV) { -        if (conn->out) { +        if (ecp_conn_is_outb(conn)) {              if (conn->key_idx_curr != ECP_ECDH_IDX_INV) c_idx = conn->key_idx[conn->key_idx_curr];          } else {              if (conn->remote.key_curr != ECP_ECDH_IDX_INV) c_idx = conn->remote.key[conn->remote.key_curr].idx; @@ -1228,7 +1271,7 @@ ssize_t _ecp_pack_conn(ECPConnection *conn, unsigned char *packet, size_t pkt_si      rv = conn_shsec_get(conn, s_idx, c_idx, &pkt_meta.shsec);      if (!rv) memcpy(pkt_meta.nonce, conn->nonce, sizeof(pkt_meta.nonce));      if (!rv) { -        if (conn->out) { +        if (ecp_conn_is_outb(conn)) {              ECPDHKey *key = conn_dhkey_get(conn, c_idx);              if ((key == NULL) || !key->valid) rv = ECP_ERR_ECDH_IDX; @@ -1248,10 +1291,7 @@ ssize_t _ecp_pack_conn(ECPConnection *conn, unsigned char *packet, size_t pkt_si  #ifdef ECP_WITH_RBUF              if (conn->rbuf.send) { -                unsigned char mtype; - -                rv = ecp_pld_get_type(payload, pld_size, &mtype); -                if (!rv) rv = ecp_rbuf_pkt_prep(conn->rbuf.send, si, mtype); +                rv = ecp_rbuf_set_seq(conn, si, payload, pld_size);              }  #endif @@ -1332,7 +1372,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP  #endif      conn = ctable_search(sock, c_idx, public_buf, NULL); -    if (conn && !conn->out && (s_idx == ECP_ECDH_IDX_PERMA)) conn = NULL; +    if (conn && ecp_conn_is_inb(conn) && (s_idx == ECP_ECDH_IDX_PERMA)) conn = NULL;  #ifdef ECP_WITH_PTHREAD      if (conn) pthread_mutex_lock(&conn->mutex); @@ -1343,7 +1383,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP          rv = conn_shsec_get(conn, s_idx, c_idx, &shsec);          if (rv == ECP_ERR_ECDH_IDX_LOCAL) {              rv = ECP_OK; -            l_idx = conn->out ? c_idx : s_idx; +            l_idx = ecp_conn_is_outb(conn) ? c_idx : s_idx;              key = conn_dhkey_get(conn, l_idx);              if ((key == NULL) || !key->valid) rv = ECP_ERR_ECDH_IDX;          } @@ -1398,23 +1438,25 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP          ECPPktMeta pkt_meta;          unsigned char *msg = payload+ECP_SIZE_PLD_HDR+1;          size_t msg_size = dec_size-ECP_SIZE_PLD_HDR-1; -        ecp_sock_handler_msg_t handler; +        ecp_sock_msg_handler_t handler;          if (key == NULL) return ECP_ERR;          if ((mtype & ECP_MTYPE_MASK) >= ECP_MAX_MTYPE_SOCK) return ECP_ERR_MAX_MTYPE;          if (mtype & ECP_MTYPE_FLAG_REP) return ECP_ERR; -        memcpy(&pkt_meta.public, &public, sizeof(pkt_meta.public)); -        memcpy(&pkt_meta.shsec, &shsec, sizeof(pkt_meta.shsec)); +        memcpy(pkt_meta.public, public_buf, sizeof(pkt_meta.public));          memcpy(pkt_meta.nonce, nonce_next, sizeof(pkt_meta.nonce)); +        memcpy(&pkt_meta.shsec, &shsec, sizeof(pkt_meta.shsec));          pkt_meta.seq = seq_pkt;          pkt_meta.s_idx = s_idx;          pkt_meta.c_idx = c_idx; -        handler = sock->handler[mtype & ECP_MTYPE_MASK]; +        handler = ecp_sock_get_msg_handler(sock, mtype & ECP_MTYPE_MASK);          if (handler) { -            rv = handler(sock, addr, parent, msg, msg_size, &pkt_meta, bufs, &conn); -            if (rv) return rv; +            ssize_t _rv; + +            _rv = handler(sock, addr, parent, msg, msg_size, &pkt_meta, bufs, &conn); +            if (_rv < 0) return _rv;          }      } @@ -1425,9 +1467,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP      if (is_open) {  #ifdef ECP_WITH_RBUF -        if (conn->rbuf.recv || (mtype == ECP_MTYPE_RBACK) || (mtype == ECP_MTYPE_RBFLUSH)) { -            seq_check = 0; -        } +        if (ecp_rbuf_handle_seq(conn, mtype)) seq_check = 0;  #endif          if (seq_check) { @@ -1500,15 +1540,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP  ecp_unpack_err:      if (conn == NULL) return rv; - -#ifdef ECP_WITH_PTHREAD -    pthread_mutex_lock(&conn->mutex); -#endif -    conn->refcount--; -#ifdef ECP_WITH_PTHREAD -    pthread_mutex_unlock(&conn->mutex); -#endif - +    ecp_conn_refcount_dec(conn);      return rv;  } @@ -1525,18 +1557,11 @@ ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent,      if (conn) {  #ifdef ECP_WITH_RBUF          if (conn->rbuf.recv) { -            rv = ecp_rbuf_recv_store(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR, bufs); +            rv = ecp_rbuf_store(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR, bufs);          }  #endif          if (rv == 0) rv = ecp_conn_handle_msg(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR, bufs); - -#ifdef ECP_WITH_PTHREAD -        pthread_mutex_lock(&conn->mutex); -#endif -        conn->refcount--; -#ifdef ECP_WITH_PTHREAD -        pthread_mutex_unlock(&conn->mutex); -#endif +        ecp_conn_refcount_dec(conn);      } else {          rv = pld_size-ECP_SIZE_PLD_HDR;      } @@ -1758,7 +1783,7 @@ static ssize_t pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_  #ifdef ECP_WITH_RBUF      if (conn->rbuf.send) { -        return ecp_rbuf_pkt_send(conn->rbuf.send, conn->sock, &addr, packet, rv, flags, ti, si); +        return ecp_rbuf_pkt_send(conn, conn->sock, &addr, packet, rv, flags, ti, si);      }  #endif diff --git a/ecp/src/core.h b/ecp/src/core.h index bf5228b..bf04947 100644 --- a/ecp/src/core.h +++ b/ecp/src/core.h @@ -17,6 +17,7 @@  #define ECP_ERR_ALLOC               -3  #define ECP_ERR_SIZE                -4  #define ECP_ERR_ITER                -5 +#define ECP_ERR_BUSY                -6  #define ECP_ERR_MAX_SOCK_CONN       -10  #define ECP_ERR_MAX_CTYPE           -11 @@ -89,14 +90,29 @@  #define ECP_MTYPE_DIR_REQ           (ECP_MTYPE_DIR)  #define ECP_MTYPE_DIR_REP           (ECP_MTYPE_DIR  | ECP_MTYPE_FLAG_REP) -#define ECP_CONN_FLAG_REG           0x01 -#define ECP_CONN_FLAG_OPEN          0x02 +#define ECP_CONN_FLAG_OUTB          0x01 +#define ECP_CONN_FLAG_NEW           0x02 +#define ECP_CONN_FLAG_REG           0x04 +#define ECP_CONN_FLAG_OPEN          0x08  #define ECP_SEND_FLAG_REPLY         0x01  #define ECP_SEND_FLAG_MORE          0x02 -#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_inb(conn)     (!((conn)->flags_ro & ECP_CONN_FLAG_OUTB)) +#define ecp_conn_is_outb(conn)      ((conn)->flags_ro & ECP_CONN_FLAG_OUTB) +#define ecp_conn_is_new(conn)       ((conn)->flags_ro & ECP_CONN_FLAG_NEW) +#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_set_outb(conn)     ((conn)->flags_ro |= ECP_CONN_FLAG_OUTB) +#define ecp_conn_set_new(conn)      ((conn)->flags_ro |= ECP_CONN_FLAG_NEW) +#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_clr_outb(conn)     ((conn)->flags_ro &= ~ECP_CONN_FLAG_OUTB) +#define ecp_conn_clr_new(conn)      ((conn)->flags_ro &= ~ECP_CONN_FLAG_NEW) +#define ecp_conn_clr_reg(conn)      ((conn)->flags    &= ~ECP_CONN_FLAG_REG) +#define ecp_conn_clr_open(conn)     ((conn)->flags    &= ~ECP_CONN_FLAG_OPEN)  // typedef long ssize_t; @@ -126,7 +142,7 @@ typedef uint32_t ecp_seq_t;  #define ECP_SIZE_PLD(X,F)           ((X) + ECP_SIZE_PLD_HDR+1+ECP_SIZE_MT_FLAG(F))  #define ECP_SIZE_PKT(X,F)           (ECP_SIZE_PKT_HDR+ECP_SIZE_PLD(X,F)+ECP_AEAD_SIZE_TAG) -#define ECP_SIZE_MSG_BUF(T,P)       ((P) && (P)->out && (((T) == ECP_MTYPE_OPEN_REQ) || ((T) == ECP_MTYPE_KGET_REQ)) ? ECP_SIZE_PLD_HDR+3+2*ECP_ECDH_SIZE_KEY : ECP_SIZE_PLD_HDR+1) +#define ECP_SIZE_MSG_BUF(T,P)       ((P) && ecp_conn_is_outb(P) && (((T) == ECP_MTYPE_OPEN_REQ) || ((T) == ECP_MTYPE_KGET_REQ)) ? ECP_SIZE_PLD_HDR+3+2*ECP_ECDH_SIZE_KEY : ECP_SIZE_PLD_HDR+1)  #define ECP_SIZE_PLD_BUF(X,T,C)     (ECP_SIZE_PLD(X,T)+(C)->pcount*(ECP_SIZE_PKT_HDR+ECP_SIZE_MSG_BUF(T,(C)->parent)+ECP_AEAD_SIZE_TAG))  #define ECP_SIZE_PKT_BUF(X,T,C)     (ECP_SIZE_PLD_BUF(X,T,C)+ECP_SIZE_PKT_HDR+ECP_AEAD_SIZE_TAG) @@ -150,7 +166,6 @@ struct ECPDirList;  #include "platform/transport.h"  #include "crypto/crypto.h"  #include "timer.h" -#include "dir_srv.h"  #ifdef ECP_WITH_RBUF  #include "rbuf.h" @@ -158,13 +173,11 @@ struct ECPDirList;  typedef int (*ecp_rng_t) (void *, size_t); -typedef int (*ecp_sock_handler_msg_t) (struct ECPSocket *s, ECPNetAddr *a, struct ECPConnection *p, unsigned char *msg, size_t sz, struct ECPPktMeta *m, struct ECP2Buffer *b, struct ECPConnection **c); -typedef ssize_t (*ecp_conn_handler_msg_t) (struct ECPConnection *c, ecp_seq_t s, unsigned char t, unsigned char *msg, ssize_t sz, struct ECP2Buffer *b); +typedef ssize_t (*ecp_sock_msg_handler_t) (struct ECPSocket *s, ECPNetAddr *a, struct ECPConnection *p, unsigned char *msg, size_t sz, struct ECPPktMeta *m, struct ECP2Buffer *b, struct ECPConnection **c); +typedef ssize_t (*ecp_conn_msg_handler_t) (struct ECPConnection *c, ecp_seq_t s, unsigned char t, unsigned char *msg, ssize_t sz, struct ECP2Buffer *b); -typedef struct ECPConnection * (*ecp_conn_alloc_t) (unsigned char t); +typedef struct ECPConnection * (*ecp_conn_alloc_t) (struct ECPSocket *s, unsigned char t);  typedef void (*ecp_conn_free_t) (struct ECPConnection *c); -typedef int (*ecp_conn_create_t) (struct ECPConnection *c, unsigned char *msg, size_t sz); -typedef void (*ecp_conn_destroy_t) (struct ECPConnection *c);  typedef ssize_t (*ecp_conn_open_t) (struct ECPConnection *c);  typedef void (*ecp_conn_close_t) (struct ECPConnection *c); @@ -225,18 +238,15 @@ typedef struct ECPFragIter {  typedef struct ECPPktMeta {      ecp_aead_key_t shsec; -    ecp_dh_public_t public;      ecp_seq_t seq; +    unsigned char public[ECP_ECDH_SIZE_KEY];      unsigned char nonce[ECP_AEAD_SIZE_NONCE];      unsigned char s_idx;      unsigned char c_idx;  } ECPPktMeta;  typedef struct ECPConnHandler { -    ecp_conn_handler_msg_t msg[ECP_MAX_MTYPE]; -    ecp_conn_create_t conn_create; -    ecp_conn_destroy_t conn_destroy; -    ecp_conn_open_t conn_open; +    ecp_conn_msg_handler_t msg[ECP_MAX_MTYPE];      ecp_conn_close_t conn_close;  } ECPConnHandler; @@ -273,7 +283,7 @@ typedef struct ECPSocket {      unsigned char key_curr;      ECPSockCTable conn;      ECPTimer timer; -    ecp_sock_handler_msg_t handler[ECP_MAX_MTYPE_SOCK]; +    ecp_sock_msg_handler_t handler[ECP_MAX_MTYPE_SOCK];  #ifdef ECP_WITH_PTHREAD      pthread_t rcvr_thd;      pthread_mutex_t mutex; @@ -282,8 +292,8 @@ typedef struct ECPSocket {  typedef struct ECPConnection {      unsigned char type; -    unsigned char out;      unsigned char flags; +    unsigned char flags_ro;      unsigned short refcount;      ecp_seq_t seq_out;      ecp_seq_t seq_in; @@ -317,24 +327,34 @@ int ecp_frag_iter_init(ECPFragIter *iter, unsigned char *buffer, size_t buf_size  void ecp_frag_iter_reset(ECPFragIter *iter);  int ecp_dhkey_gen(ECPContext *ctx, ECPDHKey *key); -int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key); +int ecp_sock_init(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key); +int ecp_sock_create(ECPSocket *sock);  void ecp_sock_destroy(ECPSocket *sock);  int ecp_sock_open(ECPSocket *sock, void *myaddr);  void ecp_sock_close(ECPSocket *sock); +ecp_sock_msg_handler_t ecp_sock_get_msg_handler(ECPSocket *sock, unsigned char mtype);  int ecp_sock_dhkey_get_curr(ECPSocket *sock, unsigned char *idx, unsigned char *public);  int ecp_sock_dhkey_new(ECPSocket *sock); -int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype); +int ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype); +int ecp_conn_create(ECPConnection *conn);  void ecp_conn_destroy(ECPConnection *conn); +int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char c_idx, unsigned char *public); +int ecp_conn_create_outb(ECPConnection *conn, ECPNode *node); +int ecp_conn_insert(ECPConnection *conn);  int ecp_conn_register(ECPConnection *conn); -void ecp_conn_unregister(ECPConnection *conn); +void ecp_conn_unregister(ECPConnection *conn, unsigned short *refcount); -int ecp_conn_set_remote(ECPConnection *conn, ECPNode *node);  int ecp_conn_get_dirlist(ECPConnection *conn, ECPNode *node);  int ecp_conn_open(ECPConnection *conn, ECPNode *node); -int ecp_conn_close(ECPConnection *conn, ecp_cts_t timeout); +void _ecp_conn_close(ECPConnection *conn); +int ecp_conn_close(ECPConnection *conn);  int ecp_conn_reset(ECPConnection *conn); +void ecp_conn_refcount_inc(ECPConnection *conn); +void ecp_conn_refcount_dec(ECPConnection *conn);  int ecp_conn_handler_init(ECPConnHandler *handler); +ecp_conn_msg_handler_t ecp_conn_get_msg_handler(ECPConnection *conn, unsigned char mtype); +ecp_conn_close_t ecp_conn_get_close_handler(ECPConnection *conn);  int ecp_conn_dhkey_new(ECPConnection *conn);  int ecp_conn_dhkey_new_pub(ECPConnection *conn, unsigned char idx, unsigned char *public); @@ -345,13 +365,14 @@ ssize_t ecp_conn_send_kget(ECPConnection *conn);  ssize_t ecp_conn_send_kput(ECPConnection *conn);  ssize_t ecp_conn_send_dir(ECPConnection *conn); +ssize_t _ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b, int *was_open);  ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b); +ssize_t _ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b, ecp_conn_open_t conn_open);  ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b);  ssize_t ecp_conn_handle_kput(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b); -ssize_t ecp_conn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b);  ssize_t ecp_conn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs); -int ecp_sock_handle_open(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn); -int ecp_sock_handle_kget(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn); +ssize_t ecp_sock_handle_open(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn); +ssize_t ecp_sock_handle_kget(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn);  ssize_t _ecp_pack(ECPContext *ctx, unsigned char *packet, size_t pkt_size, ECPPktMeta *pkt_meta, unsigned char *payload, size_t pld_size);  ssize_t ecp_pack(ECPContext *ctx, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) ; diff --git a/ecp/src/dir.c b/ecp/src/dir.c index 8bc7a94..46d152e 100644 --- a/ecp/src/dir.c +++ b/ecp/src/dir.c @@ -2,6 +2,7 @@  #include "cr.h"  #include "dir.h" +#include "dir_srv.h"  static int dir_update(ECPDirList *list, ECPDirItem *item) {      int i; diff --git a/ecp/src/dir_srv.c b/ecp/src/dir_srv.c index f5d1893..563326d 100644 --- a/ecp/src/dir_srv.c +++ b/ecp/src/dir_srv.c @@ -2,6 +2,7 @@  #include "cr.h"  #include "dir.h" +#include "dir_srv.h"  #ifdef ECP_WITH_DIRSRV @@ -21,28 +22,29 @@ ssize_t ecp_dir_handle_update(ECPConnection *conn, ecp_seq_t seq, unsigned char      } else {          return ECP_ERR;      } -  } -int ecp_dir_handle_req(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn) { +ssize_t ecp_dir_handle_req(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn) {      ECPContext *ctx = sock->ctx;      ECPBuffer *packet = bufs->packet;      ECPBuffer *payload = bufs->payload;      ECPDirList *dir_online = ctx->dir_online; -    ssize_t _rv; -    int rv; +    ssize_t rv; +    int _rv; + +    if (msg_size < 0) return msg_size;      ecp_pld_set_type(payload->buffer, payload->size, ECP_MTYPE_DIR_REP);      msg = ecp_pld_get_buf(payload->buffer, payload->size);      msg_size = payload->size - (msg - payload->buffer); -    rv = ecp_dir_serialize(dir_online, msg, msg_size); -    if (rv) return rv; +    _rv = ecp_dir_serialize(dir_online, msg, msg_size); +    if (_rv) return _rv; -    _rv = ecp_pld_send_tr(sock, addr, parent, packet, pkt_meta, payload, ECP_SIZE_PLD(dir_online->count * ECP_SIZE_DIR_ITEM, ECP_MTYPE_DIR_REP), 0); -    if (_rv < 0) return _rv; +    rv = ecp_pld_send_tr(sock, addr, parent, packet, pkt_meta, payload, ECP_SIZE_PLD(dir_online->count * ECP_SIZE_DIR_ITEM, ECP_MTYPE_DIR_REP), 0); +    if (rv < 0) return rv; -    return ECP_OK; +    return msg_size;  }  #endif  /* ECP_WITH_DIRSRV */
\ No newline at end of file diff --git a/ecp/src/dir_srv.h b/ecp/src/dir_srv.h index cc2ebbe..3fc14ee 100644 --- a/ecp/src/dir_srv.h +++ b/ecp/src/dir_srv.h @@ -2,6 +2,6 @@  int ecp_dir_init(struct ECPContext *ctx, struct ECPDirList *dir_online, struct ECPDirList *dir_shadow);  ssize_t ecp_dir_handle_update(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b); -int ecp_dir_handle_req(struct ECPSocket *sock, struct ECPNetAddr *addr, struct ECPConnection *parent, unsigned char *msg, size_t msg_size, struct ECPPktMeta *pkt_meta, struct ECP2Buffer *bufs, struct ECPConnection **_conn); +ssize_t ecp_dir_handle_req(struct ECPSocket *sock, struct ECPNetAddr *addr, struct ECPConnection *parent, unsigned char *msg, size_t msg_size, struct ECPPktMeta *pkt_meta, struct ECP2Buffer *bufs, struct ECPConnection **_conn);  #endif  /* ECP_WITH_DIRSRV */
\ No newline at end of file diff --git a/ecp/src/fe310/transport.h b/ecp/src/fe310/transport.h index 0fcf43b..47ad482 100644 --- a/ecp/src/fe310/transport.h +++ b/ecp/src/fe310/transport.h @@ -1,5 +1,7 @@  #include <eos/sock.h> +#define ECP_IPv4_ADDR_SIZE          4 +  typedef EOSNetAddr ECPNetAddr;  typedef int ECPNetSock; diff --git a/ecp/src/rbuf.c b/ecp/src/rbuf.c index 9a5bd8c..9680d14 100644 --- a/ecp/src/rbuf.c +++ b/ecp/src/rbuf.c @@ -1,6 +1,6 @@  #include "core.h" -int ecp_rbuf_init(ECPRBuffer *rbuf, ECPRBMessage *msg, unsigned int msg_size) { +int _ecp_rbuf_init(ECPRBuffer *rbuf, ECPRBMessage *msg, unsigned int msg_size) {      rbuf->msg = msg;      if (msg_size) {          if (msg == NULL) return ECP_ERR; @@ -13,6 +13,35 @@ int ecp_rbuf_init(ECPRBuffer *rbuf, ECPRBMessage *msg, unsigned int msg_size) {      return ECP_OK;  } +int _ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq) { +    rbuf->seq_max = seq; +    rbuf->seq_start = seq + 1; + +    return ECP_OK; +} + +int _ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq) { +    ecp_seq_t seq_offset = seq - rbuf->seq_start; + +    // This also checks for seq_start <= seq if seq type range >> rbuf->msg_size +    if (seq_offset < rbuf->msg_size) return ECP_RBUF_IDX_MASK(rbuf->msg_start + seq_offset, rbuf->msg_size); +    return ECP_ERR_RBUF_FULL; +} + +ssize_t _ecp_rbuf_msg_store(ECPRBuffer *rbuf, ecp_seq_t seq, int idx, unsigned char *msg, size_t msg_size, unsigned char test_flags, unsigned char set_flags) { +    idx = idx < 0 ? _ecp_rbuf_msg_idx(rbuf, seq) : idx; +    if (idx < 0) return idx; + +    if (rbuf->msg == NULL) return 0; +    if (test_flags && (test_flags & rbuf->msg[idx].flags)) return ECP_ERR_RBUF_DUP; + +    if (msg_size) memcpy(rbuf->msg[idx].msg, msg, msg_size); +    rbuf->msg[idx].size = msg_size; +    rbuf->msg[idx].flags = set_flags; + +    return msg_size; +} +  int ecp_rbuf_create(ECPConnection *conn, ECPRBSend *buf_s, ECPRBMessage *msg_s, unsigned int msg_s_size, ECPRBRecv *buf_r, ECPRBMessage *msg_r, unsigned int msg_r_size) {      int rv; @@ -43,35 +72,6 @@ void ecp_rbuf_destroy(ECPConnection *conn) {      ecp_rbuf_recv_destroy(conn);  } -int ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq) { -    rbuf->seq_max = seq; -    rbuf->seq_start = seq + 1; - -    return ECP_OK; -} - -int ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq) { -    ecp_seq_t seq_offset = seq - rbuf->seq_start; - -    // This also checks for seq_start <= seq if seq type range >> rbuf->msg_size -    if (seq_offset < rbuf->msg_size) return ECP_RBUF_IDX_MASK(rbuf->msg_start + seq_offset, rbuf->msg_size); -    return ECP_ERR_RBUF_FULL; -} - -ssize_t ecp_rbuf_msg_store(ECPRBuffer *rbuf, ecp_seq_t seq, int idx, unsigned char *msg, size_t msg_size, unsigned char test_flags, unsigned char set_flags) { -    idx = idx < 0 ? ecp_rbuf_msg_idx(rbuf, seq) : idx; -    if (idx < 0) return idx; - -    if (rbuf->msg == NULL) return 0; -    if (test_flags && (test_flags & rbuf->msg[idx].flags)) return ECP_ERR_RBUF_DUP; - -    if (msg_size) memcpy(rbuf->msg[idx].msg, msg, msg_size); -    rbuf->msg[idx].size = msg_size; -    rbuf->msg[idx].flags = set_flags; - -    return msg_size; -} -  ssize_t ecp_rbuf_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_seq_t seq) {      ECPSocket *sock = conn->sock;      ECPContext *ctx = sock->ctx; @@ -96,3 +96,107 @@ ssize_t ecp_rbuf_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *pay      return rv;  } +int ecp_rbuf_handle_seq(ECPConnection *conn, unsigned char mtype) { +    if (conn->rbuf.recv || (mtype == ECP_MTYPE_RBACK) || (mtype == ECP_MTYPE_RBFLUSH)) return 1; +    return 0; +} + +int ecp_rbuf_set_seq(ECPConnection *conn, ECPSeqItem *si, unsigned char *payload, size_t pld_size) { +    ECPRBSend *buf; +    unsigned char mtype; +    int idx; +    int rv; + +    if (si->rb_pass) return ECP_OK; + +    buf = conn->rbuf.send; +#ifdef ECP_WITH_PTHREAD +    pthread_mutex_lock(&buf->mutex); +#endif +    idx = _ecp_rbuf_msg_idx(&buf->rbuf, si->seq); +#ifdef ECP_WITH_PTHREAD +    pthread_mutex_unlock(&buf->mutex); +#endif + +    if (idx < 0) return idx; + +    rv = ecp_pld_get_type(payload, pld_size, &mtype); +    if (rv) return rv; + +    si->rb_mtype = mtype; +    si->rb_idx = idx; +    buf->rbuf.msg[idx].size = 0; +    buf->rbuf.msg[idx].flags = 0; + +    return ECP_OK; +} + +ssize_t ecp_rbuf_pkt_send(ECPConnection *conn, ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ECPSeqItem *si) { +    ECPRBSend *buf; +    int do_send = 1; +    ssize_t rv = 0; + +    buf = conn->rbuf.send; +    if (!si->rb_pass) { +        unsigned char flags = 0; +        ecp_seq_t seq = si->seq; +        unsigned int idx = si->rb_idx; +        unsigned char mtype = si->rb_mtype & ECP_MTYPE_MASK; + +        if (mtype < ECP_MAX_MTYPE_SYS) flags |= ECP_RBUF_FLAG_SYS; + +        rv = _ecp_rbuf_msg_store(&buf->rbuf, seq, idx, packet->buffer, pkt_size, 0, flags); +        if (rv < 0) return rv; + +        if (buf->flags & ECP_RBUF_FLAG_CCONTROL) { +            int _rv = ECP_OK; + +#ifdef ECP_WITH_PTHREAD +            pthread_mutex_lock(&buf->mutex); +#endif + +            if (ECP_SEQ_LT(buf->rbuf.seq_max, seq)) buf->rbuf.seq_max = seq; + +            if (buf->cnt_cc || (buf->in_transit >= buf->win_size)) { +                if (!buf->cnt_cc) buf->seq_cc = seq; +                buf->cnt_cc++; +                buf->rbuf.msg[idx].flags |= ECP_RBUF_FLAG_IN_CCONTROL; +                do_send = 0; +                if (ti) { +                    ECPRBTimer *timer = &buf->timer; +                    ECPRBTimerItem *item = &timer->item[timer->idx_w]; + +                    if (!item->occupied) { +                        item->occupied = 1; +                        item->item = *ti; +                        buf->rbuf.msg[idx].idx_t = timer->idx_w; +                        timer->idx_w = (timer->idx_w) % ECP_MAX_TIMER; +                    } else { +                        _rv = ECP_ERR_MAX_TIMER; +                    } +                } else { +                    buf->rbuf.msg[idx].idx_t = -1; +                } +            } else { +                buf->in_transit++; +            } + +#ifdef ECP_WITH_PTHREAD +            pthread_mutex_unlock(&buf->mutex); +#endif + +            if (_rv) return _rv; +        } +    } + +    if (do_send) { +        if (ti) { +            int _rv; + +            _rv = ecp_timer_push(ti); +            if (_rv) return _rv; +        } +        rv = ecp_pkt_send(sock, addr, packet, pkt_size, flags); +    } +    return rv; +} diff --git a/ecp/src/rbuf.h b/ecp/src/rbuf.h index 3a2a51b..891f29d 100644 --- a/ecp/src/rbuf.h +++ b/ecp/src/rbuf.h @@ -89,31 +89,32 @@ typedef struct ECPConnRBuffer {      ECPRBSend *send;  } ECPConnRBuffer; -int ecp_rbuf_init(ECPRBuffer *rbuf, ECPRBMessage *msg, unsigned int msg_size); +int _ecp_rbuf_init(ECPRBuffer *rbuf, ECPRBMessage *msg, unsigned int msg_size); +int _ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq); +int _ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq); +ssize_t _ecp_rbuf_msg_store(ECPRBuffer *rbuf, ecp_seq_t seq, int idx, unsigned char *msg, size_t msg_size, unsigned char test_flags, unsigned char set_flags); +  int ecp_rbuf_create(struct ECPConnection *conn, ECPRBSend *buf_s, ECPRBMessage *msg_s, unsigned int msg_s_size, ECPRBRecv *buf_r, ECPRBMessage *msg_r, unsigned int msg_r_size);  void ecp_rbuf_destroy(struct ECPConnection *conn); -int ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq); -int ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq); - -ssize_t ecp_rbuf_msg_store(ECPRBuffer *rbuf, ecp_seq_t seq, int idx, unsigned char *msg, size_t msg_size, unsigned char test_flags, unsigned char set_flags);  ssize_t ecp_rbuf_pld_send(struct ECPConnection *conn, struct ECPBuffer *packet, struct ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_seq_t seq); +int ecp_rbuf_handle_seq(struct ECPConnection *conn, unsigned char mtype); +int ecp_rbuf_set_seq(struct ECPConnection *conn, struct ECPSeqItem *si, unsigned char *payload, size_t pld_size); +ssize_t ecp_rbuf_pkt_send(struct ECPConnection *conn, struct ECPSocket *sock, ECPNetAddr *addr, struct ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, struct ECPSeqItem *si);  int ecp_rbuf_recv_create(struct ECPConnection *conn, ECPRBRecv *buf, ECPRBMessage *msg, unsigned int msg_size);  void ecp_rbuf_recv_destroy(struct ECPConnection *conn);  int ecp_rbuf_recv_start(struct ECPConnection *conn, ecp_seq_t seq); -int ecp_rbuf_recv_set_hole(struct ECPConnection *conn, unsigned short hole_max); -int ecp_rbuf_recv_set_delay(struct ECPConnection *conn, ecp_pts_t delay); +int ecp_rbuf_set_hole(struct ECPConnection *conn, unsigned short hole_max); +int ecp_rbuf_set_delay(struct ECPConnection *conn, ecp_pts_t delay); -ssize_t ecp_rbuf_recv_store(struct ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b); +ssize_t ecp_rbuf_store(struct ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b); +struct ECPFragIter *ecp_rbuf_get_frag_iter(struct ECPConnection *conn);  int ecp_rbuf_send_create(struct ECPConnection *conn, ECPRBSend *buf, ECPRBMessage *msg, unsigned int msg_size);  void ecp_rbuf_send_destroy(struct ECPConnection *conn);  int ecp_rbuf_send_start(struct ECPConnection *conn); -int ecp_rbuf_send_flush(struct ECPConnection *conn); -int ecp_rbuf_send_set_wsize(struct ECPConnection *conn, ecp_win_t size); - -int ecp_rbuf_pkt_prep(ECPRBSend *buf, struct ECPSeqItem *si, unsigned char mtype); -ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, struct ECPSocket *sock, ECPNetAddr *addr, struct ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, struct ECPSeqItem *si); +int ecp_rbuf_flush(struct ECPConnection *conn); +int ecp_rbuf_set_wsize(struct ECPConnection *conn, ecp_win_t size);  ssize_t ecp_rbuf_handle_ack(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b);  ssize_t ecp_rbuf_handle_flush(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b); diff --git a/ecp/src/rbuf_recv.c b/ecp/src/rbuf_recv.c index 17bbd01..f2bb1c2 100644 --- a/ecp/src/rbuf_recv.c +++ b/ecp/src/rbuf_recv.c @@ -18,8 +18,8 @@ static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg,      mtype &= ECP_MTYPE_MASK;      if (mtype < ECP_MAX_MTYPE_SYS) flags |= ECP_RBUF_FLAG_SYS; -    if (buf->flags & ECP_RBUF_FLAG_MSGQ) {  #ifdef ECP_WITH_MSGQ +    if (buf->flags & ECP_RBUF_FLAG_MSGQ) {          ecp_seq_t seq_offset;          int _rv = ECP_OK; @@ -29,10 +29,10 @@ static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg,          pthread_mutex_unlock(&buf->msgq.mutex);          if (_rv) return _rv; -#endif      } +#endif -    rv = ecp_rbuf_msg_store(&buf->rbuf, seq, -1, msg, msg_size, ECP_RBUF_FLAG_IN_RBUF | ECP_RBUF_FLAG_IN_MSGQ, flags); +    rv = _ecp_rbuf_msg_store(&buf->rbuf, seq, -1, msg, msg_size, ECP_RBUF_FLAG_IN_RBUF | ECP_RBUF_FLAG_IN_MSGQ, flags);      if (rv < 0) return rv;      if (ECP_SEQ_LT(buf->rbuf.seq_max, seq)) buf->rbuf.seq_max = seq; @@ -102,8 +102,8 @@ static void msg_flush(ECPConnection *conn, ECP2Buffer *b) {                  }                  seq_next = seq + 1; -                if (buf->flags & ECP_RBUF_FLAG_MSGQ) {  #ifdef ECP_WITH_MSGQ +                if (buf->flags & ECP_RBUF_FLAG_MSGQ) {                      unsigned char mtype;                      rv = ecp_msg_get_type(buf->rbuf.msg[idx].msg, buf->rbuf.msg[idx].size, &mtype); @@ -111,10 +111,10 @@ static void msg_flush(ECPConnection *conn, ECP2Buffer *b) {                      if (rv) break;                      buf->rbuf.msg[idx].flags |= ECP_RBUF_FLAG_IN_MSGQ; +                } else +  #endif -                } else {                      ecp_conn_handle_msg(conn, seq, buf->rbuf.msg[idx].msg, buf->rbuf.msg[idx].size, b); -                }              }              buf->rbuf.msg[idx].flags &= ~ECP_RBUF_FLAG_IN_RBUF;          } else { @@ -232,7 +232,7 @@ int ecp_rbuf_recv_create(ECPConnection *conn, ECPRBRecv *buf, ECPRBMessage *msg,      int rv;      memset(buf, 0, sizeof(ECPRBRecv)); -    rv = ecp_rbuf_init(&buf->rbuf, msg, msg_size); +    rv = _ecp_rbuf_init(&buf->rbuf, msg, msg_size);      if (rv) return rv;      buf->ack_map = ECP_ACK_FULL; @@ -266,20 +266,20 @@ int ecp_rbuf_recv_start(ECPConnection *conn, ecp_seq_t seq) {      seq--;      buf->seq_ack = seq; -    rv = ecp_rbuf_start(&buf->rbuf, seq); +    rv = _ecp_rbuf_start(&buf->rbuf, seq);      if (rv) return rv; -    if (buf->flags & ECP_RBUF_FLAG_MSGQ) {  #ifdef ECP_WITH_MSGQ +    if (buf->flags & ECP_RBUF_FLAG_MSGQ) {          rv = ecp_conn_msgq_start(&buf->msgq, seq);          if (rv) return rv; -#endif      } +#endif      return ECP_OK;  } -int ecp_rbuf_recv_set_hole(ECPConnection *conn, unsigned short hole_max) { +int ecp_rbuf_set_hole(ECPConnection *conn, unsigned short hole_max) {      ECPRBRecv *buf = conn->rbuf.recv;      buf->hole_max = hole_max; @@ -289,7 +289,7 @@ int ecp_rbuf_recv_set_hole(ECPConnection *conn, unsigned short hole_max) {      return ECP_OK;  } -int ecp_rbuf_recv_set_delay(ECPConnection *conn, ecp_pts_t delay) { +int ecp_rbuf_set_delay(ECPConnection *conn, ecp_pts_t delay) {      ECPRBRecv *buf = conn->rbuf.recv;      buf->deliver_delay = delay; @@ -297,7 +297,7 @@ int ecp_rbuf_recv_set_delay(ECPConnection *conn, ecp_pts_t delay) {      return ECP_OK;  } -ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *b) { +ssize_t ecp_rbuf_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {      ECPRBRecv *buf = conn->rbuf.recv;      ecp_seq_t ack_pkt = 0;      ssize_t rv; @@ -361,3 +361,8 @@ ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *m      return rv;  } + +ECPFragIter *ecp_rbuf_get_frag_iter(ECPConnection *conn) { +    if (conn->rbuf.recv) return conn->rbuf.recv->frag_iter; +    return NULL; +} diff --git a/ecp/src/rbuf_send.c b/ecp/src/rbuf_send.c index a680285..faf2a7d 100644 --- a/ecp/src/rbuf_send.c +++ b/ecp/src/rbuf_send.c @@ -41,7 +41,7 @@ static void cc_flush(ECPConnection *conn) {      unsigned short max_t = 0;      if (pkt_to_send) { -        unsigned int idx = ecp_rbuf_msg_idx(rbuf, buf->seq_cc); +        unsigned int idx = _ecp_rbuf_msg_idx(rbuf, buf->seq_cc);          unsigned int _idx = idx;          for (i=0; i<pkt_to_send; i++) { @@ -118,7 +118,7 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt  #endif      ECPRBuffer *rbuf = &buf->rbuf; -    int idx = ecp_rbuf_msg_idx(rbuf, seq_ack); +    int idx = _ecp_rbuf_msg_idx(rbuf, seq_ack);      if (idx < 0) rv = idx;      if (!rv) { @@ -217,7 +217,7 @@ int ecp_rbuf_send_create(ECPConnection *conn, ECPRBSend *buf, ECPRBMessage *msg,      int rv;      memset(buf, 0, sizeof(ECPRBRecv)); -    rv = ecp_rbuf_init(&buf->rbuf, msg, msg_size); +    rv = _ecp_rbuf_init(&buf->rbuf, msg, msg_size);      if (rv) return rv;  #ifdef ECP_WITH_PTHREAD @@ -246,10 +246,10 @@ int ecp_rbuf_send_start(ECPConnection *conn) {      if (buf == NULL) return ECP_ERR; -    return ecp_rbuf_start(&buf->rbuf, conn->seq_out); +    return _ecp_rbuf_start(&buf->rbuf, conn->seq_out);  } -int ecp_rbuf_send_set_wsize(ECPConnection *conn, ecp_win_t size) { +int ecp_rbuf_set_wsize(ECPConnection *conn, ecp_win_t size) {      ECPRBSend *buf = conn->rbuf.send;      if (buf == NULL) return ECP_ERR; @@ -268,7 +268,7 @@ int ecp_rbuf_send_set_wsize(ECPConnection *conn, ecp_win_t size) {      return ECP_OK;  } -int ecp_rbuf_send_flush(ECPConnection *conn) { +int ecp_rbuf_flush(ECPConnection *conn) {      ECPRBSend *buf = conn->rbuf.send;      ecp_seq_t seq;      ssize_t rv; @@ -303,94 +303,3 @@ int ecp_rbuf_send_flush(ECPConnection *conn) {      return ECP_OK;  } - -int ecp_rbuf_pkt_prep(ECPRBSend *buf, ECPSeqItem *si, unsigned char mtype) { -    int idx; - -    if (si->rb_pass) return ECP_OK; - -#ifdef ECP_WITH_PTHREAD -    pthread_mutex_lock(&buf->mutex); -#endif -    idx = ecp_rbuf_msg_idx(&buf->rbuf, si->seq); -#ifdef ECP_WITH_PTHREAD -    pthread_mutex_unlock(&buf->mutex); -#endif - -    if (idx < 0) return idx; - -    si->rb_mtype = mtype; -    si->rb_idx = idx; -    buf->rbuf.msg[idx].size = 0; -    buf->rbuf.msg[idx].flags = 0; - -    return ECP_OK; -} - -ssize_t ecp_rbuf_pkt_send(ECPRBSend *buf, ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ECPSeqItem *si) { -    int do_send = 1; -    ssize_t rv = 0; - -    if (!si->rb_pass) { -        unsigned char flags = 0; -        ecp_seq_t seq = si->seq; -        unsigned int idx = si->rb_idx; -        unsigned char mtype = si->rb_mtype & ECP_MTYPE_MASK; - -        if (mtype < ECP_MAX_MTYPE_SYS) flags |= ECP_RBUF_FLAG_SYS; - -        rv = ecp_rbuf_msg_store(&buf->rbuf, seq, idx, packet->buffer, pkt_size, 0, flags); -        if (rv < 0) return rv; - -        if (buf->flags & ECP_RBUF_FLAG_CCONTROL) { -            int _rv = ECP_OK; - -#ifdef ECP_WITH_PTHREAD -            pthread_mutex_lock(&buf->mutex); -#endif - -            if (ECP_SEQ_LT(buf->rbuf.seq_max, seq)) buf->rbuf.seq_max = seq; - -            if (buf->cnt_cc || (buf->in_transit >= buf->win_size)) { -                if (!buf->cnt_cc) buf->seq_cc = seq; -                buf->cnt_cc++; -                buf->rbuf.msg[idx].flags |= ECP_RBUF_FLAG_IN_CCONTROL; -                do_send = 0; -                if (ti) { -                    ECPRBTimer *timer = &buf->timer; -                    ECPRBTimerItem *item = &timer->item[timer->idx_w]; - -                    if (!item->occupied) { -                        item->occupied = 1; -                        item->item = *ti; -                        buf->rbuf.msg[idx].idx_t = timer->idx_w; -                        timer->idx_w = (timer->idx_w) % ECP_MAX_TIMER; -                    } else { -                        _rv = ECP_ERR_MAX_TIMER; -                    } -                } else { -                    buf->rbuf.msg[idx].idx_t = -1; -                } -            } else { -                buf->in_transit++; -            } - -#ifdef ECP_WITH_PTHREAD -            pthread_mutex_unlock(&buf->mutex); -#endif - -            if (_rv) return _rv; -        } -    } - -    if (do_send) { -        if (ti) { -            int _rv; - -            _rv = ecp_timer_push(ti); -            if (_rv) return _rv; -        } -        rv = ecp_pkt_send(sock, addr, packet, pkt_size, flags); -    } -    return rv; -} diff --git a/ecp/src/timer.c b/ecp/src/timer.c index 7dd3c50..28d4cb1 100644 --- a/ecp/src/timer.c +++ b/ecp/src/timer.c @@ -97,13 +97,7 @@ void ecp_timer_pop(ECPConnection *conn, unsigned char mtype) {              } else {                  memset(timer->item+i, 0, sizeof(ECPTimerItem));              } -#ifdef ECP_WITH_PTHREAD -            pthread_mutex_lock(&conn->mutex); -#endif -            conn->refcount--; -#ifdef ECP_WITH_PTHREAD -            pthread_mutex_unlock(&conn->mutex); -#endif +            ecp_conn_refcount_dec(conn);              timer->head--;              break;          } @@ -132,13 +126,7 @@ void ecp_timer_remove(ECPConnection *conn) {              } else {                  memset(timer->item+i, 0, sizeof(ECPTimerItem));              } -#ifdef ECP_WITH_PTHREAD -            pthread_mutex_lock(&conn->mutex); -#endif -            conn->refcount--; -#ifdef ECP_WITH_PTHREAD -            pthread_mutex_unlock(&conn->mutex); -#endif +            ecp_conn_refcount_dec(conn);              timer->head--;          }      } @@ -184,7 +172,7 @@ ecp_cts_t ecp_timer_exe(ECPSocket *sock) {          ECPConnection *conn = to_exec[i].conn;          unsigned char mtype = to_exec[i].mtype;          ecp_timer_retry_t retry = to_exec[i].retry; -        ecp_conn_handler_msg_t handler = conn->sock->ctx->handler[conn->type] ? conn->sock->ctx->handler[conn->type]->msg[mtype & ECP_MTYPE_MASK] : NULL; +        ecp_conn_msg_handler_t handler = ecp_conn_get_msg_handler(conn, mtype & ECP_MTYPE_MASK);          int rv = ECP_OK;          if (to_exec[i].cnt > 0) { @@ -199,15 +187,7 @@ ecp_cts_t ecp_timer_exe(ECPSocket *sock) {          } else if (handler) {              handler(conn, 0, mtype, NULL, ECP_ERR_TIMEOUT, NULL);          } - -#ifdef ECP_WITH_PTHREAD -        pthread_mutex_lock(&conn->mutex); -#endif -        conn->refcount--; -#ifdef ECP_WITH_PTHREAD -        pthread_mutex_unlock(&conn->mutex); -#endif - +        ecp_conn_refcount_dec(conn);      }      return ret; diff --git a/ecp/src/vconn/vconn.c b/ecp/src/vconn/vconn.c index c414454..d60f5f2 100644 --- a/ecp/src/vconn/vconn.c +++ b/ecp/src/vconn/vconn.c @@ -16,51 +16,33 @@ static pthread_mutex_t key_next_mutex;  #endif  #endif -static unsigned char key_null[ECP_ECDH_SIZE_KEY] = { 0 }; -  static ECPConnHandler handler_vc;  static ECPConnHandler handler_vl;  #ifdef ECP_WITH_HTABLE -static int vconn_create(ECPConnection *conn, unsigned char *payload, size_t size) { -    ECPVConnIn *conn_v = (ECPVConnIn *)conn; -    int rv; - -    if (conn->out) return ECP_ERR; -    if (conn->type != ECP_CTYPE_VCONN) return ECP_ERR; -    if (size < 2*ECP_ECDH_SIZE_KEY) return ECP_ERR; - -    conn_v->key_next_curr = 0; -    memset(conn_v->key_next, 0, sizeof(conn_v->key_next)); -    memset(conn_v->key_out, 0, sizeof(conn_v->key_out)); -    memcpy(conn_v->key_next[conn_v->key_next_curr], payload, ECP_ECDH_SIZE_KEY); -    memcpy(conn_v->key_out, payload+ECP_ECDH_SIZE_KEY, ECP_ECDH_SIZE_KEY); - -#ifdef ECP_WITH_PTHREAD -    pthread_mutex_lock(&key_next_mutex); -#endif -    rv = ecp_ht_insert(key_next_table, conn_v->key_next[conn_v->key_next_curr], conn); -#ifdef ECP_WITH_PTHREAD -    pthread_mutex_unlock(&key_next_mutex); -#endif +static int key_is_null(unsigned char *key) { +    int i; -    return rv; +    for (i=0; i<ECP_ECDH_SIZE_KEY; i++) { +        if (key[i] != 0) return 0; +    } +    return 1;  } -static void vconn_destroy(ECPConnection *conn) { +static void vconn_remove(ECPConnection *conn) {      ECPVConnIn *conn_v = (ECPVConnIn *)conn; +    int i; -    if (conn->out) return;      if (conn->type != ECP_CTYPE_VCONN) return; +    if (ecp_conn_is_outb(conn)) return;  #ifdef ECP_WITH_PTHREAD      pthread_mutex_lock(&key_next_mutex);      pthread_mutex_lock(&conn->mutex);  #endif -    int i;      for (i=0; i<ECP_MAX_NODE_KEY; i++) { -        if (memcmp(conn_v->key_next[i], key_null, ECP_ECDH_SIZE_KEY)) ecp_ht_remove(key_next_table, conn_v->key_next[i]); +        if (!key_is_null(conn_v->key_next[i])) ecp_ht_remove(key_next_table, conn_v->key_next[i]);      }  #ifdef ECP_WITH_PTHREAD      pthread_mutex_unlock(&conn->mutex); @@ -85,12 +67,16 @@ static ssize_t _vconn_send_open(ECPConnection *conn, ECPTimerItem *ti) {      return _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, NULL, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti);  } -static ssize_t vconn_open(ECPConnection *conn) { +static ssize_t vconn_send_open(ECPConnection *conn) {      ECPTimerItem ti; -    ECPVConnection *conn_v = (ECPVConnection *)conn; -    ECPConnection *conn_next = conn_v->next; +    ECPVConnOut *conn_v = (ECPVConnOut *)conn; +    ECPConnection *conn_next;      ssize_t rv; +    if (conn->type != ECP_CTYPE_VCONN) return ECP_ERR; +    if (ecp_conn_is_inb(conn)) return ECP_ERR; + +    conn_next = conn_v->next;      if (conn_next == NULL) return ECP_ERR;      rv = ecp_timer_send(conn_next, _vconn_send_open, ECP_MTYPE_KGET_REP, 3, 1000); @@ -99,74 +85,106 @@ static ssize_t vconn_open(ECPConnection *conn) {      return rv;  } +static ssize_t vconn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { +    return _ecp_conn_handle_kget(conn, seq, mtype, msg, size, b, vconn_send_open); +} +  static ssize_t vconn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { +    ssize_t rv; +    int _rv; +      if (conn->type != ECP_CTYPE_VCONN) return ECP_ERR;      if (mtype & ECP_MTYPE_FLAG_REP) { -        if (!conn->out) return ECP_ERR; +        if (ecp_conn_is_inb(conn)) return ECP_ERR;          if (size < 0) { -            ecp_conn_handler_msg_t handler = NULL; -            while (conn->type == ECP_CTYPE_VCONN) { -                ECPVConnection *conn_v = (ECPVConnection *)conn; +            ecp_conn_msg_handler_t handler; +            while (conn && (conn->type == ECP_CTYPE_VCONN)) { +                ECPVConnOut *conn_v = (ECPVConnOut *)conn;                  conn = conn_v->next;              } -            handler = conn->sock->ctx->handler[conn->type] ? conn->sock->ctx->handler[conn->type]->msg[ECP_MTYPE_OPEN] : NULL; +            if (conn) handler = ecp_conn_get_msg_handler(conn, ECP_MTYPE_OPEN);              return handler ? handler(conn, seq, mtype, msg, size, b) : size;          } -        return ecp_conn_handle_open(conn, seq, mtype, msg, size, b); +        rv = ecp_conn_handle_open(conn, seq, mtype, msg, size, b);      } else { -        int rv = ECP_OK;  #ifdef ECP_WITH_HTABLE +          ECPVConnIn *conn_v = (ECPVConnIn *)conn; -        unsigned char ctype = 0; +        unsigned char ctype; +        int is_new, do_ins; -        if (conn->out) return ECP_ERR; +        if (ecp_conn_is_outb(conn)) return ECP_ERR;          if (size < 0) return size;          if (size < 1+2*ECP_ECDH_SIZE_KEY) return ECP_ERR; +        ctype = msg[0]; +        msg++; + +        is_new = ecp_conn_is_new(conn); +        do_ins = 0; +        if (is_new) { +            conn_v->key_next_curr = 0; +            memset(conn_v->key_next, 0, sizeof(conn_v->key_next)); +            memset(conn_v->key_out, 0, sizeof(conn_v->key_out)); +            memcpy(conn_v->key_next[conn_v->key_next_curr], msg, ECP_ECDH_SIZE_KEY); +            memcpy(conn_v->key_out, msg+ECP_ECDH_SIZE_KEY, ECP_ECDH_SIZE_KEY); +            do_ins = 1; + +            _rv = ecp_conn_insert(conn); +            if (_rv) return rv; +        } +  #ifdef ECP_WITH_PTHREAD          pthread_mutex_lock(&key_next_mutex);          pthread_mutex_lock(&conn->mutex);  #endif -        ctype = msg[0]; -        msg++; - -        if (!ecp_conn_is_open(conn)) conn->flags |= ECP_CONN_FLAG_OPEN; -        if (memcmp(conn_v->key_next[conn_v->key_next_curr], msg, ECP_ECDH_SIZE_KEY)) { +        _rv = ECP_OK; +        if (!is_new && memcmp(conn_v->key_next[conn_v->key_next_curr], msg, ECP_ECDH_SIZE_KEY)) {              conn_v->key_next_curr = (conn_v->key_next_curr + 1) % ECP_MAX_NODE_KEY; -            if (memcmp(conn_v->key_next[conn_v->key_next_curr], key_null, ECP_ECDH_SIZE_KEY)) ecp_ht_remove(key_next_table, conn_v->key_next[conn_v->key_next_curr]); -            rv = ecp_ht_insert(key_next_table, conn_v->key_next[conn_v->key_next_curr], conn); -            if (!rv) memcpy(conn_v->key_next[conn_v->key_next_curr], msg, ECP_ECDH_SIZE_KEY); +            if (!key_is_null(conn_v->key_next[conn_v->key_next_curr])) ecp_ht_remove(key_next_table, conn_v->key_next[conn_v->key_next_curr]); +            memcpy(conn_v->key_next[conn_v->key_next_curr], msg, ECP_ECDH_SIZE_KEY); +            do_ins = 1;          } +        if (do_ins) _rv = ecp_ht_insert(key_next_table, conn_v->key_next[conn_v->key_next_curr], conn); +        if (!_rv && !ecp_conn_is_open(conn)) ecp_conn_set_open(conn);  #ifdef ECP_WITH_PTHREAD          pthread_mutex_unlock(&conn->mutex);          pthread_mutex_unlock(&key_next_mutex);  #endif -        if (rv) return rv; -        return 1+2*ECP_ECDH_SIZE_KEY; +        if (_rv) { +            ecp_conn_close(conn); +            return _rv; +        } + +        rv = 1+2*ECP_ECDH_SIZE_KEY; +  #else   /* ECP_WITH_HTABLE */ -        return ECP_ERR_NOT_IMPLEMENTED; +        ecp_conn_close(conn); +        rv = ECP_ERR_NOT_IMPLEMENTED;  #endif  /* ECP_WITH_HTABLE */ +      } -    return ECP_ERR; +    return rv;  }  #ifdef ECP_WITH_HTABLE  static ssize_t vconn_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { +    ECPBuffer payload;      ECPConnection *conn_out = NULL;      ECPVConnIn *conn_v = (ECPVConnIn *)conn;      ssize_t rv; -    if (conn->out) return ECP_ERR;      if (conn->type != ECP_CTYPE_VCONN) return ECP_ERR; +    if (ecp_conn_is_outb(conn)) return ECP_ERR;      if (b == NULL) return ECP_ERR;      if (size < 0) return size; @@ -177,13 +195,7 @@ static ssize_t vconn_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned c  #endif      conn_out = ecp_ht_search(key_perma_table, conn_v->key_out);      if (conn_out) { -#ifdef ECP_WITH_PTHREAD -        pthread_mutex_lock(&conn_out->mutex); -#endif -        conn_out->refcount++; -#ifdef ECP_WITH_PTHREAD -        pthread_mutex_unlock(&conn_out->mutex); -#endif +        ecp_conn_refcount_inc(conn_out);      }  #ifdef ECP_WITH_PTHREAD      pthread_mutex_unlock(&key_perma_mutex); @@ -191,20 +203,13 @@ static ssize_t vconn_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned c      if (conn_out == NULL) return ECP_ERR; -    ECPBuffer payload;      payload.buffer = msg - ECP_SIZE_PLD_HDR - 1;      payload.size = b->payload->size - (payload.buffer - b->payload->buffer);      ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_EXEC);      rv = ecp_pld_send(conn_out, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size, ECP_SEND_FLAG_REPLY); -#ifdef ECP_WITH_PTHREAD -    pthread_mutex_lock(&conn_out->mutex); -#endif -    conn_out->refcount--; -#ifdef ECP_WITH_PTHREAD -    pthread_mutex_unlock(&conn_out->mutex); -#endif +    ecp_conn_refcount_dec(conn_out);      if (rv < 0) return rv;      return size; @@ -234,23 +239,6 @@ static void vlink_remove(ECPConnection *conn) {  #endif  } -static int vlink_create(ECPConnection *conn, unsigned char *payload, size_t size) { -    if (conn->out) return ECP_ERR; -    if (conn->type != ECP_CTYPE_VLINK) return ECP_ERR; - -    // XXX should verify perma_key -    if (size < ECP_ECDH_SIZE_KEY) return ECP_ERR; -    ecp_cr_dh_pub_from_buf(&conn->node.public, payload); - -    return vlink_insert(conn); -} - -static void vlink_destroy(ECPConnection *conn) { -    if (conn->out) return; -    if (conn->type != ECP_CTYPE_VLINK) return; - -    vlink_remove(conn); -}  #endif  /* ECP_WITH_HTABLE */  static ssize_t _vlink_send_open(ECPConnection *conn, ECPTimerItem *ti) { @@ -275,68 +263,74 @@ static ssize_t _vlink_send_open(ECPConnection *conn, ECPTimerItem *ti) {      return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ), 0, ti);  } -static ssize_t vlink_open(ECPConnection *conn) { +static ssize_t vlink_send_open(ECPConnection *conn) {      return ecp_timer_send(conn, _vlink_send_open, ECP_MTYPE_OPEN_REP, 3, 500);  } -static void vlink_close(ECPConnection *conn) { -#ifdef ECP_WITH_HTABLE -    vlink_remove(conn); -#endif  /* ECP_WITH_HTABLE */ +static ssize_t vlink_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { +    return _ecp_conn_handle_kget(conn, seq, mtype, msg, size, b, vlink_send_open);  }  static ssize_t vlink_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {      ssize_t rv; +    int _rv;      int is_open;      if (conn->type != ECP_CTYPE_VLINK) return ECP_ERR;      if (size < 0) return size; -#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 (ecp_conn_is_new(conn) && (size >= 1+ECP_ECDH_SIZE_KEY)) { +        // XXX we should verify perma_key +        ecp_cr_dh_pub_from_buf(&conn->node.public, msg+1); +    } -    rv = ecp_conn_handle_open(conn, seq, mtype, msg, size, b); +    rv = _ecp_conn_handle_open(conn, seq, mtype, msg, size, b, &is_open);      if (rv < 0) return rv;      if (mtype & ECP_MTYPE_FLAG_REP) { -        if (!conn->out) return ECP_ERR; +  #ifdef ECP_WITH_HTABLE -        if (!is_open) { -            int _rv; +        if (!is_open) {              _rv = vlink_insert(conn);              if (_rv) return _rv;          } +  #endif  /* ECP_WITH_HTABLE */ -        return rv; +      } else { -#ifdef ECP_WITH_HTABLE -        if (conn->out) return ECP_ERR;          if (size < rv+ECP_ECDH_SIZE_KEY) return ECP_ERR; +#ifdef ECP_WITH_HTABLE +          msg += rv; -        // XXX should verify perma_key -        return rv+ECP_ECDH_SIZE_KEY; +        if (!is_open) { +            _rv = vlink_insert(conn); +            if (_rv) { +                ecp_conn_close(conn); +                return _rv; +            } +        } + +        rv = rv+ECP_ECDH_SIZE_KEY;  #else   /* ECP_WITH_HTABLE */ -        return ECP_ERR; +        ecp_conn_close(conn); +        rv = ECP_ERR_NOT_IMPLEMENTED;  #endif  /* ECP_WITH_HTABLE */ +      } -    return ECP_ERR; +    return rv;  }  #ifdef ECP_WITH_HTABLE  static ssize_t vlink_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { +    ECPBuffer payload;      ssize_t rv;      if (conn->type != ECP_CTYPE_VLINK) return ECP_ERR; @@ -350,13 +344,7 @@ static ssize_t vlink_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned c  #endif      conn = ecp_ht_search(key_next_table, msg+ECP_SIZE_PROTO+1);      if (conn) { -#ifdef ECP_WITH_PTHREAD -        pthread_mutex_lock(&conn->mutex); -#endif -        conn->refcount++; -#ifdef ECP_WITH_PTHREAD -        pthread_mutex_unlock(&conn->mutex); -#endif +        ecp_conn_refcount_inc(conn);      }  #ifdef ECP_WITH_PTHREAD      pthread_mutex_unlock(&key_next_mutex); @@ -364,29 +352,58 @@ static ssize_t vlink_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned c      if (conn == NULL) return ECP_ERR; -    ECPBuffer payload;      payload.buffer = msg - ECP_SIZE_PLD_HDR - 1;      payload.size = b->payload->size - (payload.buffer - b->payload->buffer);      ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_EXEC);      rv = ecp_pld_send(conn, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size, ECP_SEND_FLAG_REPLY); -#ifdef ECP_WITH_PTHREAD -    pthread_mutex_lock(&conn->mutex); -#endif -    conn->refcount--; -#ifdef ECP_WITH_PTHREAD -    pthread_mutex_unlock(&conn->mutex); -#endif +    ecp_conn_refcount_dec(conn);      if (rv < 0) return rv;      return size;  }  #endif  /* ECP_WITH_HTABLE */ +#ifdef ECP_MEM_TINY +/* Memory limited version */ + +static ssize_t vconn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { +    if (size < 0) return size; +    if (b == NULL) return ECP_ERR; +    if (b->packet->buffer == NULL) return ECP_ERR; + +    memcpy(b->packet->buffer, msg, size); +    return ecp_pkt_handle(conn->sock, NULL, conn, b, size); +} + +#else + +static ssize_t vconn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) { +    if (size < 0) return size; +    if (b == NULL) return ECP_ERR; + +    ECP2Buffer b2; +    ECPBuffer packet; +    ECPBuffer payload; +    unsigned char pld_buf[ECP_MAX_PLD]; + +    b2.packet = &packet; +    b2.payload = &payload; + +    packet.buffer = msg; +    packet.size = b->payload->size - (msg - b->payload->buffer); +    payload.buffer = pld_buf; +    payload.size = ECP_MAX_PLD; + +    return ecp_pkt_handle(conn->sock, NULL, conn, &b2, size); +} + +#endif +  static ssize_t vconn_set_msg(ECPConnection *conn, ECPBuffer *payload, unsigned char mtype) { -    if (conn->out && (conn->type == ECP_CTYPE_VCONN) && ((mtype == ECP_MTYPE_OPEN_REQ) || (mtype == ECP_MTYPE_KGET_REQ))) { -        ECPVConnection *conn_v = (ECPVConnection *)conn; +    if (ecp_conn_is_outb(conn) && (conn->type == ECP_CTYPE_VCONN) && ((mtype == ECP_MTYPE_OPEN_REQ) || (mtype == ECP_MTYPE_KGET_REQ))) { +        ECPVConnOut *conn_v = (ECPVConnOut *)conn;          ECPConnection *conn_next = conn_v->next;          unsigned char *buf = NULL;          int rv; @@ -547,31 +564,24 @@ int ecp_vconn_ctx_init(ECPContext *ctx) {      rv = ecp_conn_handler_init(&handler_vc);      if (rv) return rv; -#ifdef ECP_WITH_HTABLE -    handler_vc.conn_create = vconn_create; -    handler_vc.conn_destroy = vconn_destroy; -#endif  /* ECP_WITH_HTABLE */ -    handler_vc.conn_open = vconn_open;      handler_vc.msg[ECP_MTYPE_OPEN] = vconn_handle_open; -    handler_vc.msg[ECP_MTYPE_EXEC] = ecp_conn_handle_exec; +    handler_vc.msg[ECP_MTYPE_KGET] = vconn_handle_kget; +    handler_vc.msg[ECP_MTYPE_EXEC] = vconn_handle_exec;  #ifdef ECP_WITH_HTABLE      handler_vc.msg[ECP_MTYPE_RELAY] = vconn_handle_relay; +    handler_vc.conn_close = vconn_remove;  #endif  /* ECP_WITH_HTABLE */      ctx->handler[ECP_CTYPE_VCONN] = &handler_vc;      rv = ecp_conn_handler_init(&handler_vl);      if (rv) return rv; -#ifdef ECP_WITH_HTABLE -    handler_vl.conn_create = vlink_create; -    handler_vl.conn_destroy = vlink_destroy; -#endif  /* ECP_WITH_HTABLE */ -    handler_vl.conn_open = vlink_open; -    handler_vl.conn_close = vlink_close;      handler_vl.msg[ECP_MTYPE_OPEN] = vlink_handle_open; -    handler_vl.msg[ECP_MTYPE_EXEC] = ecp_conn_handle_exec; +    handler_vl.msg[ECP_MTYPE_KGET] = vlink_handle_kget; +    handler_vl.msg[ECP_MTYPE_EXEC] = vconn_handle_exec;  #ifdef ECP_WITH_HTABLE      handler_vl.msg[ECP_MTYPE_RELAY] = vlink_handle_relay; +    handler_vl.conn_close = vlink_remove;  #endif  /* ECP_WITH_HTABLE */      ctx->handler[ECP_CTYPE_VLINK] = &handler_vl; @@ -605,21 +615,23 @@ int ecp_vconn_ctx_init(ECPContext *ctx) {      return ECP_OK;  } -int ecp_vconn_set_remote(ECPConnection *conn, ECPNode *conn_node, ECPVConnection vconn[], ECPNode vconn_node[], int size) { +int ecp_vconn_create_parent(ECPConnection *conn, ECPNode *conn_node, ECPVConnOut vconn[], ECPNode vconn_node[], int size) {      ECPSocket *sock = conn->sock; -    int i, rv; - -    rv = ecp_conn_set_remote(conn, conn_node); -    if (rv) return rv; +    int i, j, rv;      conn->parent = (ECPConnection *)&vconn[size-1];      conn->pcount = size;      for (i=0; i<size; i++) { -        rv = ecp_conn_create((ECPConnection *)&vconn[i], sock, ECP_CTYPE_VCONN); -        if (rv) return rv; - -        rv = ecp_conn_set_remote((ECPConnection *)&vconn[i], &vconn_node[i]); -        if (rv) return rv; +        rv = ecp_conn_init((ECPConnection *)&vconn[i], sock, ECP_CTYPE_VCONN); +        if (!rv) rv = ecp_conn_create_outb((ECPConnection *)&vconn[i], &vconn_node[i]); +        if (!rv) { +            rv = ecp_conn_insert((ECPConnection *)&vconn[i]); +            if (rv) ecp_conn_destroy((ECPConnection *)&vconn[i]); +        } +        if (rv) { +            for (j=0; j<i; j++) ecp_conn_close((ECPConnection *)&vconn[j]); +            return rv; +        }          if (i == 0) {              vconn[i].b.parent = NULL; @@ -653,13 +665,25 @@ static ssize_t _vconn_send_kget(ECPConnection *conn, ECPTimerItem *ti) {      return _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, NULL, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti);  } -int ecp_vconn_open(ECPConnection *conn, ECPNode *conn_node, ECPVConnection vconn[], ECPNode vconn_node[], int size) { +int ecp_vconn_open(ECPConnection *conn, ECPNode *conn_node, ECPVConnOut vconn[], ECPNode vconn_node[], int size) {      int rv;      ssize_t _rv; -    rv = ecp_vconn_set_remote(conn, conn_node, vconn, vconn_node, size); +    rv = ecp_conn_create_outb(conn, conn_node);      if (rv) return rv; +    rv = ecp_conn_insert(conn); +    if (rv) { +        ecp_conn_destroy(conn); +        return rv; +    } + +    rv = ecp_vconn_create_parent(conn, conn_node, vconn, vconn_node, size); +    if (rv) { +        ecp_conn_close(conn); +        return rv; +    } +      _rv = ecp_timer_send((ECPConnection *)&vconn[0], _vconn_send_kget, ECP_MTYPE_KGET_REP, 3, 500);      if (_rv < 0) return _rv; diff --git a/ecp/src/vconn/vconn.h b/ecp/src/vconn/vconn.h index 12eae77..73d9fd6 100644 --- a/ecp/src/vconn/vconn.h +++ b/ecp/src/vconn/vconn.h @@ -4,10 +4,10 @@  #define ECP_MTYPE_RELAY     0x08  #define ECP_MTYPE_EXEC      0x09 -typedef struct ECPVConnection { +typedef struct ECPVConnOut {      ECPConnection b;      ECPConnection *next; -} ECPVConnection; +} ECPVConnOut;  typedef struct ECPVConnIn {      ECPConnection b; @@ -16,6 +16,7 @@ typedef struct ECPVConnIn {      unsigned char key_out[ECP_ECDH_SIZE_KEY];  } ECPVConnIn; +ssize_t ecp_vconn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b);  int ecp_vconn_ctx_init(ECPContext *ctx); -int ecp_vconn_set_remote(ECPConnection *conn, ECPNode *conn_node, ECPVConnection vconn[], ECPNode vconn_node[], int size); -int ecp_vconn_open(ECPConnection *conn, ECPNode *conn_node, ECPVConnection vconn[], ECPNode vconn_node[], int size); +int ecp_vconn_create_parent(ECPConnection *conn, ECPNode *conn_node, ECPVConnOut vconn[], ECPNode vconn_node[], int size); +int ecp_vconn_open(ECPConnection *conn, ECPNode *conn_node, ECPVConnOut vconn[], ECPNode vconn_node[], int size); diff --git a/ecp/test/basic.c b/ecp/test/basic.c index eb14b0e..0f4e322 100644 --- a/ecp/test/basic.c +++ b/ecp/test/basic.c @@ -68,8 +68,8 @@ int main(int argc, char *argv[]) {      rv = ecp_dhkey_gen(&ctx_s, &key_perma_s);      printf("ecp_dhkey_gen RV:%d\n", rv); -    rv = ecp_sock_create(&sock_s, &ctx_s, &key_perma_s); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock_s, &ctx_s, &key_perma_s); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock_s, "0.0.0.0:3000");      printf("ecp_sock_open RV:%d\n", rv); @@ -88,8 +88,8 @@ int main(int argc, char *argv[]) {      rv = ecp_dhkey_gen(&ctx_c, &key_perma_c);      printf("ecp_dhkey_gen RV:%d\n", rv); -    rv = ecp_sock_create(&sock_c, &ctx_c, &key_perma_c); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock_c, &ctx_c, &key_perma_c); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock_c, NULL);      printf("ecp_sock_open RV:%d\n", rv); @@ -100,8 +100,8 @@ int main(int argc, char *argv[]) {      rv = ecp_node_init(&node, &key_perma_s.public, "127.0.0.1:3000");      printf("ecp_node_init RV:%d\n", rv); -    rv = ecp_conn_create(&conn, &sock_c, CTYPE_TEST); -    printf("ecp_conn_create RV:%d\n", rv); +    rv = ecp_conn_init(&conn, &sock_c, CTYPE_TEST); +    printf("ecp_conn_init RV:%d\n", rv);      rv = ecp_conn_open(&conn, &node);      printf("ecp_conn_open RV:%d\n", rv); diff --git a/ecp/test/client.c b/ecp/test/client.c index e6c8208..577a888 100644 --- a/ecp/test/client.c +++ b/ecp/test/client.c @@ -58,8 +58,8 @@ int main(int argc, char *argv[]) {      handler.msg[MTYPE_MSG] = handle_msg;      ctx.handler[CTYPE_TEST] = &handler; -    rv = ecp_sock_create(&sock, &ctx, NULL); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock, &ctx, NULL); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock, NULL);      printf("ecp_sock_open RV:%d\n", rv); @@ -70,8 +70,8 @@ int main(int argc, char *argv[]) {      rv = ecp_util_node_load(&ctx, &node, argv[1]);      printf("ecp_util_node_load RV:%d\n", rv); -    rv = ecp_conn_create(&conn, &sock, CTYPE_TEST); -    printf("ecp_conn_create RV:%d\n", rv); +    rv = ecp_conn_init(&conn, &sock, CTYPE_TEST); +    printf("ecp_conn_init RV:%d\n", rv);      rv = ecp_conn_open(&conn, &node);      printf("ecp_conn_open RV:%d\n", rv); diff --git a/ecp/test/dir.c b/ecp/test/dir.c index 413cd03..0c2ac72 100644 --- a/ecp/test/dir.c +++ b/ecp/test/dir.c @@ -5,6 +5,7 @@  #include "core.h"  #include "cr.h"  #include "dir.h" +#include "dir_srv.h"  ECPContext ctx_s;  ECPSocket sock_s; @@ -51,8 +52,8 @@ int main(int argc, char *argv[]) {      rv = ecp_dhkey_gen(&ctx_s, &key_perma_s);      printf("ecp_dhkey_gen RV:%d\n", rv); -    rv = ecp_sock_create(&sock_s, &ctx_s, &key_perma_s); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock_s, &ctx_s, &key_perma_s); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock_s, "0.0.0.0:3000");      printf("ecp_sock_open RV:%d\n", rv); @@ -70,8 +71,8 @@ int main(int argc, char *argv[]) {      rv = ecp_dhkey_gen(&ctx_c, &key_perma_c);      printf("ecp_dhkey_gen RV:%d\n", rv); -    rv = ecp_sock_create(&sock_c, &ctx_c, &key_perma_c); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock_c, &ctx_c, &key_perma_c); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock_c, NULL);      printf("ecp_sock_open RV:%d\n", rv); @@ -82,8 +83,8 @@ int main(int argc, char *argv[]) {      rv = ecp_node_init(&node, &key_perma_s.public, "127.0.0.1:3000");      printf("ecp_node_init RV:%d\n", rv); -    rv = ecp_conn_create(&conn, &sock_c, CTYPE_TEST); -    printf("ecp_conn_create RV:%d\n", rv); +    rv = ecp_conn_init(&conn, &sock_c, CTYPE_TEST); +    printf("ecp_conn_init RV:%d\n", rv);      rv = ecp_conn_get_dirlist(&conn, &node);      printf("ecp_conn_get_dirlist RV:%d\n", rv); diff --git a/ecp/test/echo.c b/ecp/test/echo.c index ff9c01c..f3057df 100644 --- a/ecp/test/echo.c +++ b/ecp/test/echo.c @@ -43,8 +43,8 @@ int main(int argc, char *argv[]) {      rv = ecp_util_key_load(&ctx_s, &key_perma_s, argv[2]);      printf("ecp_util_key_load RV:%d\n", rv); -    rv = ecp_sock_create(&sock_s, &ctx_s, &key_perma_s); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock_s, &ctx_s, &key_perma_s); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock_s, argv[1]);      printf("ecp_sock_open RV:%d\n", rv); diff --git a/ecp/test/frag.c b/ecp/test/frag.c index bf7c1a2..73e45cb 100644 --- a/ecp/test/frag.c +++ b/ecp/test/frag.c @@ -74,8 +74,8 @@ int main(int argc, char *argv[]) {      rv = ecp_dhkey_gen(&ctx_s, &key_perma_s);      printf("ecp_dhkey_gen RV:%d\n", rv); -    rv = ecp_sock_create(&sock_s, &ctx_s, &key_perma_s); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock_s, &ctx_s, &key_perma_s); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock_s, "0.0.0.0:3000");      printf("ecp_sock_open RV:%d\n", rv); @@ -94,8 +94,8 @@ int main(int argc, char *argv[]) {      rv = ecp_dhkey_gen(&ctx_c, &key_perma_c);      printf("ecp_dhkey_gen RV:%d\n", rv); -    rv = ecp_sock_create(&sock_c, &ctx_c, &key_perma_c); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock_c, &ctx_c, &key_perma_c); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock_c, NULL);      printf("ecp_sock_open RV:%d\n", rv); @@ -106,8 +106,8 @@ int main(int argc, char *argv[]) {      rv = ecp_node_init(&node, &key_perma_s.public, "127.0.0.1:3000");      printf("ecp_node_init RV:%d\n", rv); -    rv = ecp_conn_create(&conn, &sock_c, CTYPE_TEST); -    printf("ecp_conn_create RV:%d\n", rv); +    rv = ecp_conn_init(&conn, &sock_c, CTYPE_TEST); +    printf("ecp_conn_init RV:%d\n", rv);      rv = ecp_rbuf_create(&conn, NULL, NULL, 0, &rbuf_recv, rbuf_r_msg, 128);      printf("ecp_rbuf_create RV:%d\n", rv); diff --git a/ecp/test/init.c b/ecp/test/init.c index 4dff693..7b59578 100644 --- a/ecp/test/init.c +++ b/ecp/test/init.c @@ -14,8 +14,19 @@ static int v_rng(void *buf, size_t bufsize) {      return 0;  } -static ECPConnection *conn_alloc(unsigned char type) { -    return malloc(sizeof(ECPConnection)); +static ECPConnection *conn_alloc(ECPSocket *sock, unsigned char type) { +    ECPConnection *conn; +    int rv; + +    conn = malloc(sizeof(ECPConnection)); +    if (conn == NULL) return NULL; + +    rv = ecp_conn_init(conn, sock, type); +    if (rv) { +        free(conn); +        return NULL; +    } +    return conn;  }  static void conn_free(ECPConnection *conn) { diff --git a/ecp/test/init_vconn.c b/ecp/test/init_vconn.c index b79aa3d..59e9517 100644 --- a/ecp/test/init_vconn.c +++ b/ecp/test/init_vconn.c @@ -15,16 +15,31 @@ static int v_rng(void *buf, size_t bufsize) {      return 0;  } -static ECPConnection *conn_alloc(unsigned char type) { +static ECPConnection *conn_alloc(ECPSocket *sock, unsigned char type) { +    ECPConnection *conn; +    int rv; +      switch (type) {          case ECP_CTYPE_VCONN: -            return malloc(sizeof(ECPVConnIn)); +            conn = malloc(sizeof(ECPVConnIn)); +            break;          default: -            return malloc(sizeof(ECPConnection)); +            conn = malloc(sizeof(ECPConnection)); +            break; +    } +    if (conn == NULL) return NULL; + +    rv = ecp_conn_init(conn, sock, type); +    if (rv) { +        printf("free1\n"); +        free(conn); +        return NULL;      } +    return conn;  }  static void conn_free(ECPConnection *conn) { +    printf("free2\n");      free(conn);  } diff --git a/ecp/test/server.c b/ecp/test/server.c index f70cc79..fabaf4e 100644 --- a/ecp/test/server.c +++ b/ecp/test/server.c @@ -46,8 +46,8 @@ int main(int argc, char *argv[]) {      rv = ecp_util_key_load(&ctx, &key_perma, argv[2]);      printf("ecp_util_key_load RV:%d\n", rv); -    rv = ecp_sock_create(&sock, &ctx, &key_perma); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock, &ctx, &key_perma); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock, argv[1]);      printf("ecp_sock_open RV:%d\n", rv); diff --git a/ecp/test/stress.c b/ecp/test/stress.c index 4dae990..6eed851 100644 --- a/ecp/test/stress.c +++ b/ecp/test/stress.c @@ -202,7 +202,7 @@ int main(int argc, char *argv[]) {      if (!rv) rv = ecp_dhkey_gen(&ctx_s, &key_perma_s);      for (i=0; i<num_s; i++) { -        if (!rv) rv = ecp_sock_create(&sock_s[i], &ctx_s, &key_perma_s); +        if (!rv) rv = ecp_sock_init(&sock_s[i], &ctx_s, &key_perma_s);          strcpy(addr, "0.0.0.0:");          sprintf(addr+strlen(addr), "%d", 3000+i); @@ -230,7 +230,7 @@ int main(int argc, char *argv[]) {          ctx_c[i].handler[CTYPE_TEST] = &handler_c;          if (!rv) rv = ecp_dhkey_gen(&ctx_c[i], &key_perma_c[i]); -        if (!rv) rv = ecp_sock_create(&sock_c[i], &ctx_c[i], &key_perma_c[i]); +        if (!rv) rv = ecp_sock_init(&sock_c[i], &ctx_c[i], &key_perma_c[i]);          if (!rv) rv = ecp_sock_open(&sock_c[i], NULL);          if (!rv) rv = pthread_create(&r_thd[i], NULL, (void *(*)(void *))ecp_receiver, (void *)&sock_c[i]); @@ -239,7 +239,7 @@ int main(int argc, char *argv[]) {          sprintf(addr+strlen(addr), "%d", 3000 + (i % num_s));          if (!rv) rv = ecp_node_init(&node[i], &key_perma_s.public, addr); -        if (!rv) rv = ecp_conn_create(&conn[i], &sock_c[i], CTYPE_TEST); +        if (!rv) rv = ecp_conn_init(&conn[i], &sock_c[i], CTYPE_TEST);          conn[i].conn_data = (void *)i;          if (!rv) rv = ecp_conn_open(&conn[i], &node[i]); diff --git a/ecp/test/vc_client.c b/ecp/test/vc_client.c index d669697..cd0ea44 100644 --- a/ecp/test/vc_client.c +++ b/ecp/test/vc_client.c @@ -14,7 +14,7 @@ ECPConnHandler handler;  ECPConnection conn;  ECPNode node; -ECPVConnection vconn[20]; +ECPVConnOut vconn[20];  ECPNode vconn_node[20];  #define CTYPE_TEST  0 @@ -63,8 +63,8 @@ int main(int argc, char *argv[]) {      handler.msg[MTYPE_MSG] = handle_msg;      ctx.handler[CTYPE_TEST] = &handler; -    rv = ecp_sock_create(&sock, &ctx, NULL); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock, &ctx, NULL); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock, NULL);      printf("ecp_sock_open RV:%d\n", rv); @@ -80,8 +80,8 @@ int main(int argc, char *argv[]) {          printf("ecp_util_node_load RV:%d\n", rv);      } -    rv = ecp_conn_create(&conn, &sock, CTYPE_TEST); -    printf("ecp_conn_create RV:%d\n", rv); +    rv = ecp_conn_init(&conn, &sock, CTYPE_TEST); +    printf("ecp_conn_init RV:%d\n", rv);      rv = ecp_vconn_open(&conn, &node, vconn, vconn_node, argc-2);      printf("ecp_vconn_open RV:%d\n", rv); diff --git a/ecp/test/vc_client_t.c b/ecp/test/vc_client_t.c index b021c2d..968d643 100644 --- a/ecp/test/vc_client_t.c +++ b/ecp/test/vc_client_t.c @@ -15,7 +15,7 @@ ECPConnHandler handler;  ECPNode node;  ECPConnection conn; -ECPVConnection vconn[20]; +ECPVConnOut vconn[20];  ECPNode vconn_node[20];  #define CTYPE_TEST  0 @@ -80,23 +80,23 @@ static void usage(char *arg) {  int main(int argc, char *argv[]) {      int rv, i; -     +      if ((argc < 3) || (argc > 22)) usage(argv[0]); -     +      rv = ecp_init(&ctx);      printf("ecp_init RV:%d\n", rv); -     +      rv = ecp_conn_handler_init(&handler);      handler.msg[ECP_MTYPE_OPEN] = handle_open;      handler.msg[MTYPE_MSG] = handle_msg;      ctx.handler[CTYPE_TEST] = &handler; -     -    rv = ecp_sock_create(&sock, &ctx, NULL); -    printf("ecp_sock_create RV:%d\n", rv); + +    rv = ecp_sock_init(&sock, &ctx, NULL); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock, NULL);      printf("ecp_sock_open RV:%d\n", rv); -     +      rv = ecp_start_receiver(&sock);      printf("ecp_start_receiver RV:%d\n", rv); @@ -108,8 +108,8 @@ int main(int argc, char *argv[]) {          printf("ecp_util_node_load RV:%d\n", rv);      } -    rv = ecp_conn_create(&conn, &sock, CTYPE_TEST); -    printf("ecp_conn_create RV:%d\n", rv); +    rv = ecp_conn_init(&conn, &sock, CTYPE_TEST); +    printf("ecp_conn_init RV:%d\n", rv);      rv = ecp_vconn_open(&conn, &node, vconn, vconn_node, argc-2);      printf("ecp_vconn_open RV:%d\n", rv); diff --git a/ecp/test/vc_server.c b/ecp/test/vc_server.c index 55f15d1..b86d7b0 100644 --- a/ecp/test/vc_server.c +++ b/ecp/test/vc_server.c @@ -24,7 +24,7 @@ ssize_t handle_open(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned  }  ssize_t handle_msg(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *p, ssize_t s, ECP2Buffer *b) { -    // printf("MSG S:%s size:%ld\n", p, s); +    printf("MSG S:%s size:%ld\n", p, s);      char *msg = "VAISTINU JE CAR!";      unsigned char buf[1000]; @@ -42,34 +42,34 @@ static void usage(char *arg) {  int main(int argc, char *argv[]) {      int rv; -     +      if (argc != 3) usage(argv[0]); -     +      rv = ecp_init(&ctx);      printf("ecp_init RV:%d\n", rv); -     +      rv = ecp_conn_handler_init(&handler);      handler.msg[ECP_MTYPE_OPEN] = handle_open;      handler.msg[MTYPE_MSG] = handle_msg;      ctx.handler[CTYPE_TEST] = &handler; -     +      rv = ecp_util_key_load(&ctx, &key_perma, argv[1]);      printf("ecp_util_key_load RV:%d\n", rv); -     -    rv = ecp_sock_create(&sock, &ctx, &key_perma); -    printf("ecp_sock_create RV:%d\n", rv); + +    rv = ecp_sock_init(&sock, &ctx, &key_perma); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock, NULL);      printf("ecp_sock_open RV:%d\n", rv); -     +      rv = ecp_start_receiver(&sock);      printf("ecp_start_receiver RV:%d\n", rv);      rv = ecp_util_node_load(&ctx, &node, argv[2]);      printf("ecp_util_node_load RV:%d\n", rv); -    rv = ecp_conn_create(&conn, &sock, ECP_CTYPE_VLINK); -    printf("ecp_conn_create RV:%d\n", rv); +    rv = ecp_conn_init(&conn, &sock, ECP_CTYPE_VLINK); +    printf("ecp_conn_init RV:%d\n", rv);      rv = ecp_conn_open(&conn, &node);      printf("ecp_conn_open RV:%d\n", rv); diff --git a/ecp/test/vcs.c b/ecp/test/vcs.c index 23e2557..f3a0156 100644 --- a/ecp/test/vcs.c +++ b/ecp/test/vcs.c @@ -30,8 +30,8 @@ int main(int argc, char *argv[]) {      rv = ecp_util_key_load(&ctx, &key_perma, argv[2]);      printf("ecp_util_key_load RV:%d\n", rv); -    rv = ecp_sock_create(&sock, &ctx, &key_perma); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock, &ctx, &key_perma); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock, argv[1]);      printf("ecp_sock_open RV:%d\n", rv); @@ -43,8 +43,8 @@ int main(int argc, char *argv[]) {          rv = ecp_util_node_load(&ctx, &node, argv[3]);          printf("ecp_util_node_load RV:%d\n", rv); -        rv = ecp_conn_create(&conn, &sock, ECP_CTYPE_VLINK); -        printf("ecp_conn_create RV:%d\n", rv); +        rv = ecp_conn_init(&conn, &sock, ECP_CTYPE_VLINK); +        printf("ecp_conn_init RV:%d\n", rv);          rv = ecp_conn_open(&conn, &node);          printf("ecp_conn_open RV:%d\n", rv); diff --git a/ecp/test/voip.c b/ecp/test/voip.c index ad5032b..b0a9207 100644 --- a/ecp/test/voip.c +++ b/ecp/test/voip.c @@ -163,8 +163,8 @@ int main(int argc, char *argv[]) {      handler_c.msg[MTYPE_MSG] = handle_msg_c;      ctx_c.handler[CTYPE_TEST] = &handler_c; -    rv = ecp_sock_create(&sock_c, &ctx_c, NULL); -    printf("ecp_sock_create RV:%d\n", rv); +    rv = ecp_sock_init(&sock_c, &ctx_c, NULL); +    printf("ecp_sock_init RV:%d\n", rv);      rv = ecp_sock_open(&sock_c, NULL);      printf("ecp_sock_open RV:%d\n", rv); @@ -175,8 +175,8 @@ int main(int argc, char *argv[]) {      rv = ecp_util_node_load(&ctx_c, &node, argv[1]);      printf("ecp_util_node_load RV:%d\n", rv); -    rv = ecp_conn_create(&conn, &sock_c, CTYPE_TEST); -    printf("ecp_conn_create RV:%d\n", rv); +    rv = ecp_conn_init(&conn, &sock_c, CTYPE_TEST); +    printf("ecp_conn_init RV:%d\n", rv);      rv = ecp_conn_open(&conn, &node);      printf("ecp_conn_open RV:%d\n", rv);  | 
