From a4f22127be441c4c158c10fe65916872d99253d2 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 19 Jan 2022 02:49:47 +0100 Subject: code cleanup --- ecp/src/core.c | 587 ++++++++++++++++++++++++---------------------- ecp/src/core.h | 73 ++++-- ecp/src/dir.c | 1 + ecp/src/dir_srv.c | 20 +- ecp/src/dir_srv.h | 2 +- ecp/src/fe310/transport.h | 2 + ecp/src/rbuf.c | 164 ++++++++++--- ecp/src/rbuf.h | 27 ++- ecp/src/rbuf_recv.c | 31 ++- ecp/src/rbuf_send.c | 103 +------- ecp/src/timer.c | 28 +-- ecp/src/vconn/vconn.c | 324 +++++++++++++------------ ecp/src/vconn/vconn.h | 9 +- ecp/test/basic.c | 12 +- ecp/test/client.c | 8 +- ecp/test/dir.c | 13 +- ecp/test/echo.c | 4 +- ecp/test/frag.c | 12 +- ecp/test/init.c | 15 +- ecp/test/init_vconn.c | 21 +- ecp/test/server.c | 4 +- ecp/test/stress.c | 6 +- ecp/test/vc_client.c | 10 +- ecp/test/vc_client_t.c | 20 +- ecp/test/vc_server.c | 22 +- ecp/test/vcs.c | 8 +- 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; ikey[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; ikey[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; iconn.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; iconn.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 +#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; irbuf; - 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; iout) 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; ikey_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 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); -- cgit v1.2.3