diff options
Diffstat (limited to 'ecp')
-rw-r--r-- | ecp/src/core.c | 994 | ||||
-rw-r--r-- | ecp/src/core.h | 98 | ||||
-rw-r--r-- | ecp/src/rbuf.c | 44 | ||||
-rw-r--r-- | ecp/src/rbuf.h | 28 | ||||
-rw-r--r-- | ecp/src/rbuf_recv.c | 59 | ||||
-rw-r--r-- | ecp/src/rbuf_send.c | 8 | ||||
-rw-r--r-- | ecp/src/vconn/vconn.c | 143 | ||||
-rw-r--r-- | ecp/test/basic.c | 8 | ||||
-rw-r--r-- | ecp/test/frag.c | 8 | ||||
-rw-r--r-- | ecp/test/stress.c | 10 | ||||
-rw-r--r-- | ecp/util/mknode.c | 2 |
11 files changed, 810 insertions, 592 deletions
diff --git a/ecp/src/core.c b/ecp/src/core.c index 51f2849..a0f1bdb 100644 --- a/ecp/src/core.c +++ b/ecp/src/core.c @@ -8,15 +8,18 @@ #include "ht.h" #endif -int ecp_dhkey_generate(ECPContext *ctx, ECPDHKey *key) { +int ecp_ctx_init(ECPContext *ctx) { int rv; - if (ctx->rng == NULL) return ECP_ERR_RNG; + if (ctx == NULL) return ECP_ERR; - rv = ecp_cr_dh_mkpair(&key->public, &key->private, ctx->rng); + memset(ctx, 0, sizeof(ECPContext)); + + rv = ecp_tr_init(ctx); + if (rv) return rv; + rv = ecp_tm_init(ctx); if (rv) return rv; - key->valid = 1; return ECP_OK; } @@ -35,18 +38,35 @@ int ecp_node_init(ECPNode *node, ecp_dh_public_t *public, void *addr) { return ECP_OK; } -int ecp_ctx_init(ECPContext *ctx) { - int rv; +int ecp_seq_item_init(ECPSeqItem *seq_item) { + memset(seq_item, 0, sizeof(ECPSeqItem)); - if (ctx == NULL) return ECP_ERR; + return ECP_OK; +} - memset(ctx, 0, sizeof(ECPContext)); +int ecp_frag_iter_init(ECPFragIter *iter, unsigned char *buffer, size_t buf_size) { + memset(iter, 0, sizeof(ECPFragIter)); + iter->buffer = buffer; + iter->buf_size = buf_size; - rv = ecp_tr_init(ctx); - if (rv) return rv; - rv = ecp_tm_init(ctx); + return ECP_OK; +} + +void ecp_frag_iter_reset(ECPFragIter *iter) { + iter->content_size = 0; + iter->seq = 0; + iter->frag_cnt = 0; +} + +int ecp_dhkey_gen(ECPContext *ctx, ECPDHKey *key) { + int rv; + + if (ctx->rng == NULL) return ECP_ERR_RNG; + + rv = ecp_cr_dh_mkpair(&key->public, &key->private, ctx->rng); if (rv) return rv; + key->valid = 1; return ECP_OK; } @@ -182,9 +202,10 @@ int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) { sock->poll_timeout = ECP_POLL_TIMEOUT; sock->key_curr = 0; if (key) sock->key_perma = *key; - sock->conn_new = ecp_conn_handle_new; + sock->handler[ECP_MTYPE_OPEN] = ecp_sock_handle_open; + sock->handler[ECP_MTYPE_KGET] = ecp_sock_handle_kget; - rv = ecp_dhkey_generate(sock->ctx, &sock->key[sock->key_curr]); + rv = ecp_dhkey_gen(sock->ctx, &sock->key[sock->key_curr]); if (!rv) rv = ctable_create(&sock->conn, sock->ctx); if (rv) return rv; @@ -247,7 +268,7 @@ int ecp_sock_dhkey_new(ECPSocket *sock) { ECPDHKey new_key; int rv; - rv = ecp_dhkey_generate(sock->ctx, &new_key); + rv = ecp_dhkey_gen(sock->ctx, &new_key); if (rv) return rv; #ifdef ECP_WITH_PTHREAD @@ -329,7 +350,6 @@ static int conn_dhkey_new_pub_local(ECPConnection *conn, unsigned char idx) { return ECP_OK; } - static int conn_dhkey_new_pub_remote(ECPConnection *conn, unsigned char idx, unsigned char *public) { // We obtained remote key ECPSocket *sock = conn->sock; @@ -434,6 +454,26 @@ static int conn_shsec_set(ECPConnection *conn, unsigned char s_idx, unsigned cha return ECP_OK; } +int ecp_conn_init(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_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) { int i, rv; @@ -505,40 +545,6 @@ void ecp_conn_unregister(ECPConnection *conn) { #endif } -static ssize_t _conn_send_kget(ECPConnection *conn, ECPTimerItem *ti) { - ECPBuffer packet; - ECPBuffer payload; - unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KGET_REQ, conn)]; - unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn)]; - packet.buffer = pkt_buf; - packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KGET_REQ, conn); - payload.buffer = pld_buf; - payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn); - - ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REQ); - return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti); -} - -int ecp_conn_init(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_generate(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_open(ECPConnection *conn, ECPNode *node) { int rv; ssize_t _rv; @@ -546,7 +552,7 @@ int ecp_conn_open(ECPConnection *conn, ECPNode *node) { rv = ecp_conn_init(conn, node); if (rv) return rv; - _rv = ecp_timer_send(conn, _conn_send_kget, ECP_MTYPE_KGET_REP, 3, 500); + _rv = ecp_conn_send_kget(conn); if (_rv < 0) { ecp_conn_unregister(conn); return _rv; @@ -606,7 +612,7 @@ int ecp_conn_reset(ECPConnection *conn) { int rv; int i; - rv = ecp_dhkey_generate(ctx, &key); + rv = ecp_dhkey_gen(ctx, &key); if (rv) return rv; #ifdef ECP_WITH_PTHREAD @@ -650,94 +656,149 @@ int ecp_conn_handler_init(ECPConnHandler *handler) { return ECP_OK; } +int ecp_conn_dhkey_new(ECPConnection *conn) { + ECPSocket *sock = conn->sock; + ECPDHKey new_key; + int rv; + ssize_t _rv; + + rv = ecp_dhkey_gen(sock->ctx, &new_key); + if (rv) return rv; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&sock->conn.mutex); + pthread_mutex_lock(&conn->mutex); +#endif + rv = conn_dhkey_new_pair(conn, &new_key); +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(&sock->conn.mutex); +#endif + + if (rv) return rv; + + _rv = ecp_conn_send_kput(conn); + if (_rv < 0) return _rv; + + return ECP_OK; +} + +int ecp_conn_dhkey_new_pub(ECPConnection *conn, unsigned char idx, unsigned char *public) { + ECPSocket *sock = conn->sock; + int rv; + + if (conn == NULL) return ECP_ERR; + if (public == NULL) return ECP_ERR; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&sock->conn.mutex); + pthread_mutex_lock(&conn->mutex); +#endif + rv = conn_dhkey_new_pub_remote(conn, idx, public); +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(&sock->conn.mutex); +#endif + if (rv == ECP_ERR_ECDH_KEY_DUP) rv = ECP_OK; + + return rv; +} + +int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned char *public) { + unsigned char _idx; + ECPSocket *sock = conn->sock; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + _idx = conn->key_curr; + if (_idx != ECP_ECDH_IDX_INV) ecp_cr_dh_pub_to_buf(public, &conn->key[_idx].public); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif + + if (_idx == ECP_ECDH_IDX_INV) return ecp_sock_dhkey_get_curr(sock, idx, public); + + if (idx) *idx = _idx; + return ECP_OK; +} + static ssize_t _conn_send_open(ECPConnection *conn, ECPTimerItem *ti) { ECPBuffer packet; ECPBuffer payload; unsigned char pkt_buf[ECP_SIZE_PKT_BUF(1, ECP_MTYPE_OPEN_REQ, conn)]; unsigned char pld_buf[ECP_SIZE_PLD_BUF(1, ECP_MTYPE_OPEN_REQ, conn)]; - unsigned char *buf = ecp_pld_get_buf(pld_buf, ECP_MTYPE_OPEN_REQ); + unsigned char *buf; packet.buffer = pkt_buf; packet.size = ECP_SIZE_PKT_BUF(1, ECP_MTYPE_OPEN_REQ, conn); payload.buffer = pld_buf; payload.size = ECP_SIZE_PLD_BUF(1, ECP_MTYPE_OPEN_REQ, conn); - ecp_pld_set_type(pld_buf, ECP_MTYPE_OPEN_REQ); + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_OPEN_REQ); + buf = ecp_pld_get_buf(payload.buffer, payload.size); buf[0] = conn->type; return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(1, ECP_MTYPE_OPEN_REQ), 0, ti); } -ssize_t ecp_conn_send_open(ECPConnection *conn) { - return ecp_timer_send(conn, _conn_send_open, ECP_MTYPE_OPEN_REP, 3, 500); -} - -int ecp_conn_handle_new(ECPSocket *sock, ECPConnection *parent, unsigned char *payload, size_t payload_size, ECPConnection **_conn) { - ECPConnection *conn = NULL; - ecp_conn_create_t handle_create = NULL; - ecp_conn_destroy_t handle_destroy = NULL; - unsigned char ctype = 0; - int rv; +static ssize_t _conn_send_kget(ECPConnection *conn, ECPTimerItem *ti) { + ECPBuffer packet; + ECPBuffer payload; + unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KGET_REQ, conn)]; + unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn)]; - if (payload_size < 1) return ECP_ERR; + packet.buffer = pkt_buf; + packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KGET_REQ, conn); + payload.buffer = pld_buf; + payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn); - ctype = payload[0]; + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KGET_REQ); + 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); +} - conn = sock->ctx->conn_alloc ? sock->ctx->conn_alloc(ctype) : NULL; - if (conn == NULL) return ECP_ERR_ALLOC; +static ssize_t _conn_send_kput(ECPConnection *conn, ECPTimerItem *ti) { + ECPBuffer packet; + ECPBuffer payload; + unsigned char pkt_buf[ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn)]; + unsigned char pld_buf[ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn)]; + unsigned char *buf; + int rv; - rv = ecp_conn_create(conn, sock, ctype); - 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; - } + packet.buffer = pkt_buf; + packet.size = ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn); + payload.buffer = pld_buf; + payload.size = ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn); - 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; + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KPUT_REQ); + buf = ecp_pld_get_buf(payload.buffer, payload.size); + rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1); + if (rv) return rv; - if (handle_create) rv = handle_create(conn, payload+1, payload_size-1); - if (rv) { - ecp_conn_destroy(conn); - if (sock->ctx->conn_free) sock->ctx->conn_free(conn); - return rv; - } + return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ), 0, ti); +} - 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; - } +ssize_t ecp_conn_send_open(ECPConnection *conn) { + return ecp_timer_send(conn, _conn_send_open, ECP_MTYPE_OPEN_REP, 3, 500); +} - if (parent) { -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&parent->mutex); -#endif - parent->refcount++; -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&parent->mutex); -#endif - } +ssize_t ecp_conn_send_kget(ECPConnection *conn) { + return ecp_timer_send(conn, _conn_send_kget, ECP_MTYPE_KGET_REP, 3, 500); +} - *_conn = conn; - return rv; +ssize_t ecp_conn_send_kput(ECPConnection *conn) { + return ecp_timer_send(conn, _conn_send_kput, ECP_MTYPE_KPUT_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; + #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); #endif - int is_open = ecp_conn_is_open(conn); + is_open = ecp_conn_is_open(conn); if (!is_open && (size >= 0)) conn->flags |= ECP_CONN_FLAG_OPEN; #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); @@ -774,7 +835,7 @@ ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char m payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_OPEN_REP, conn); ctype = msg[0]; - ecp_pld_set_type(pld_buf, ECP_MTYPE_OPEN_REP); + 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); return 1; @@ -786,13 +847,14 @@ ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char m if (mtype & ECP_MTYPE_FLAG_REP) { ECPContext *ctx = conn->sock->ctx; int rv; + int is_open; if (!conn->out) return ECP_ERR; #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); #endif - int is_open = ecp_conn_is_open(conn); + is_open = ecp_conn_is_open(conn); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); #endif @@ -826,7 +888,7 @@ ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char m 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 = ecp_pld_get_buf(pld_buf, 0); + unsigned char *buf; int rv; ssize_t _rv; @@ -835,7 +897,9 @@ ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char m payload.buffer = pld_buf; payload.size = ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, conn); - ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REP); + 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); @@ -870,7 +934,7 @@ ssize_t ecp_conn_handle_kput(ECPConnection *conn, ecp_seq_t seq, unsigned char m rv = ecp_conn_dhkey_new_pub(conn, msg[0], msg+1); if (rv) return rv; - ecp_pld_set_type(pld_buf, ECP_MTYPE_KPUT_REP); + 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); return ECP_ECDH_SIZE_KEY+1; @@ -878,7 +942,9 @@ ssize_t ecp_conn_handle_kput(ECPConnection *conn, ecp_seq_t seq, unsigned char m return ECP_ERR; } -/* Memory limited version: */ +#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; @@ -888,8 +954,8 @@ ssize_t ecp_conn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char m return ecp_pkt_handle(conn->sock, NULL, conn, b, size); } -/* Non memory limited version: */ -/* +#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; @@ -909,134 +975,192 @@ ssize_t ecp_conn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char m return ecp_pkt_handle(conn->sock, NULL, conn, &b2, size); } -*/ -static ssize_t _conn_send_kput(ECPConnection *conn, ECPTimerItem *ti) { - ECPBuffer packet; - ECPBuffer payload; - unsigned char pkt_buf[ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn)]; - unsigned char pld_buf[ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn)]; - unsigned char *buf = ecp_pld_get_buf(pld_buf, ECP_MTYPE_KPUT_REQ); - int rv; +#endif - packet.buffer = pkt_buf; - packet.size = ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn); - payload.buffer = pld_buf; - payload.size = ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn); +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; + unsigned char mtype = 0; + unsigned char *content = NULL; + size_t rem_size = msg_size; + ssize_t rv; + int _rv; - ecp_pld_set_type(pld_buf, ECP_MTYPE_KPUT_REQ); - rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1); - if (rv) return rv; + while (rem_size) { + _rv = ecp_msg_get_type(msg, rem_size, &mtype); + if (_rv) return ECP_ERR_MIN_MSG; + if ((mtype & ECP_MTYPE_MASK) >= ECP_MAX_MTYPE) return ECP_ERR_MAX_MTYPE; - return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ), 0, ti); + ecp_timer_pop(conn, mtype); + + 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); + if (_rv == ECP_ITER_NEXT) break; + if (_rv < 0) return _rv; + } else { + return ECP_ERR_ITER; + } +#endif + } + + content = ecp_msg_get_content(msg, rem_size); + 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; + if (handler) { + rv = handler(conn, seq, mtype, content, rem_size, bufs); + if (rv < 0) return rv; + if (rv > rem_size) return ECP_ERR; + if (mtype & ECP_MTYPE_FLAG_FRAG) break; + + rem_size -= rv; + msg = content + rv; + } else { + return msg_size - rem_size - 1; + } + } + + return msg_size; } -int ecp_conn_dhkey_new(ECPConnection *conn) { - ECPSocket *sock = conn->sock; - ECPDHKey new_key; +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) { + 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; int rv; - ssize_t _rv; - rv = ecp_dhkey_generate(sock->ctx, &new_key); - if (rv) return rv; + if (msg_size < 1) return ECP_ERR; -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&sock->conn.mutex); - pthread_mutex_lock(&conn->mutex); -#endif - rv = conn_dhkey_new_pair(conn, &new_key); -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&conn->mutex); - pthread_mutex_unlock(&sock->conn.mutex); -#endif + ctype = msg[0]; - if (rv) return rv; + conn = sock->ctx->conn_alloc ? sock->ctx->conn_alloc(ctype) : NULL; + if (conn == NULL) return ECP_ERR_ALLOC; - _rv = ecp_timer_send(conn, _conn_send_kput, ECP_MTYPE_KPUT_REP, 3, 500); - if (_rv < 0) return _rv; + rv = ecp_conn_create(conn, sock, ctype); + 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; + } - return ECP_OK; -} + 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; -int ecp_conn_dhkey_new_pub(ECPConnection *conn, unsigned char idx, unsigned char *public) { - ECPSocket *sock = conn->sock; - int rv; + 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; + } - if (conn == NULL) return ECP_ERR; - if (public == NULL) return ECP_ERR; + 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(&sock->conn.mutex); - pthread_mutex_lock(&conn->mutex); + pthread_mutex_lock(&parent->mutex); #endif - rv = conn_dhkey_new_pub_remote(conn, idx, public); + parent->refcount++; #ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&conn->mutex); - pthread_mutex_unlock(&sock->conn.mutex); + pthread_mutex_unlock(&parent->mutex); #endif - if (rv == ECP_ERR_ECDH_KEY_DUP) rv = ECP_OK; + } - return rv; + *_conn = conn; + return ECP_OK; } -int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned char *public) { - unsigned char _idx; - ECPSocket *sock = conn->sock; +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) { + 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; -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&conn->mutex); -#endif + _packet.buffer = pkt_buf; + _packet.size = ECP_SIZE_PKT_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent); + _payload.buffer = pld_buf; + _payload.size = ECP_SIZE_PLD_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent); - _idx = conn->key_curr; - if (_idx != ECP_ECDH_IDX_INV) ecp_cr_dh_pub_to_buf(public, &conn->key[_idx].public); + ecp_pld_set_type(_payload.buffer, _payload.size, ECP_MTYPE_KGET_REP); + buf = ecp_pld_get_buf(_payload.buffer, _payload.size); -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&conn->mutex); -#endif + rv = ecp_sock_dhkey_get_curr(sock, buf, buf+1); + if (rv) return rv; - if (_idx == ECP_ECDH_IDX_INV) return ecp_sock_dhkey_get_curr(sock, idx, public); + _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; - if (idx) *idx = _idx; return ECP_OK; } -ssize_t ecp_pkt_pack(ECPContext *ctx, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, unsigned char *payload, size_t pld_size) { + +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 rv; + unsigned char s_idx, c_idx; if (pkt_size < ECP_SIZE_PKT_HDR) return ECP_ERR; // ECP_SIZE_PROTO packet[0] = 0; packet[1] = 0; - s_idx = s_idx & 0x0F; - c_idx = c_idx & 0x0F; + 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, public); - memcpy(packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY, nonce, ECP_AEAD_SIZE_NONCE); - - payload[0] = (seq & 0xFF000000) >> 24; - payload[1] = (seq & 0x00FF0000) >> 16; - payload[2] = (seq & 0x0000FF00) >> 8; - payload[3] = (seq & 0x000000FF); - rv = ecp_cr_aead_enc(packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, payload, pld_size, shsec, nonce); + ecp_cr_dh_pub_to_buf(packet+ECP_SIZE_PROTO+1, &pkt_meta->public); + memcpy(packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY, pkt_meta->nonce, ECP_AEAD_SIZE_NONCE); + + payload[0] = (pkt_meta->seq & 0xFF000000) >> 24; + payload[1] = (pkt_meta->seq & 0x00FF0000) >> 16; + payload[2] = (pkt_meta->seq & 0x0000FF00) >> 8; + payload[3] = (pkt_meta->seq & 0x000000FF); + rv = ecp_cr_aead_enc(packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, payload, pld_size, &pkt_meta->shsec, pkt_meta->nonce); if (rv < 0) return ECP_ERR_ENCRYPT; - memcpy(nonce, packet+ECP_SIZE_PKT_HDR, ECP_AEAD_SIZE_NONCE); + memcpy(pkt_meta->nonce, packet+ECP_SIZE_PKT_HDR, ECP_AEAD_SIZE_NONCE); return rv+ECP_SIZE_PKT_HDR; } -ssize_t ecp_pkt_pack_raw(ECPSocket *sock, ECPConnection *parent, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECPNetAddr *addr) { - ECPContext *ctx = sock->ctx; +#ifndef ECP_WITH_VCONN +ssize_t ecp_pack(ECPContext *ctx, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) { + if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR; + if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR; - return ecp_pkt_pack(ctx, packet, pkt_size, s_idx, c_idx, public, shsec, nonce, seq, payload, pld_size); + return _ecp_pack(ctx, packet->buffer, packet->size, pkt_meta, payload->buffer, pld_size); } +#endif -ssize_t ecp_conn_pack(ECPConnection *conn, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, unsigned char *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr) { - ecp_aead_key_t shsec; - ecp_dh_public_t public; - ecp_seq_t _seq; - unsigned char nonce[ECP_AEAD_SIZE_NONCE]; +ssize_t _ecp_pack_conn(ECPConnection *conn, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, ECPSeqItem *si, unsigned char *payload, size_t pld_size, ECPNetAddr *addr) { + ECPPktMeta pkt_meta; int rv; ssize_t _rv; @@ -1057,35 +1181,40 @@ ssize_t ecp_conn_pack(ECPConnection *conn, unsigned char *packet, size_t pkt_siz if (conn->remote.key_curr != ECP_ECDH_IDX_INV) c_idx = conn->remote.key[conn->remote.key_curr].idx; } } - rv = conn_shsec_get(conn, s_idx, c_idx, &shsec); - if (!rv) memcpy(nonce, conn->nonce, sizeof(nonce)); + 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) { ECPDHKey *key = conn_dhkey_get(conn, c_idx); if ((key == NULL) || !key->valid) rv = ECP_ERR_ECDH_IDX; - if (!rv) memcpy(&public, &key->public, sizeof(public)); + if (!rv) memcpy(&pkt_meta.public, &key->public, sizeof(pkt_meta.public)); } else { - memcpy(&public, &conn->remote.key[conn->remote.key_curr].public, sizeof(public)); + memcpy(&pkt_meta.public, &conn->remote.key[conn->remote.key_curr].public, sizeof(pkt_meta.public)); } } if (!rv) { if (si) { if (si->seq_w) { - _seq = si->seq; + pkt_meta.seq = si->seq; } else { - _seq = conn->seq_out + 1; - si->seq = _seq; + pkt_meta.seq = conn->seq_out + 1; + si->seq = pkt_meta.seq; } #ifdef ECP_WITH_RBUF - if (conn->rbuf.send) rv = ecp_rbuf_pkt_prep(conn->rbuf.send, si, ecp_pld_get_type(payload)); + 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); + } #endif - if (!rv && !si->seq_w) conn->seq_out = _seq; + if (!rv && !si->seq_w) conn->seq_out = pkt_meta.seq; } else { - _seq = conn->seq_out + 1; - conn->seq_out = _seq; + pkt_meta.seq = conn->seq_out + 1; + conn->seq_out = pkt_meta.seq; } if (!rv && addr) *addr = conn->node.addr; } @@ -1096,13 +1225,15 @@ ssize_t ecp_conn_pack(ECPConnection *conn, unsigned char *packet, size_t pkt_siz if (rv) return rv; - _rv = ecp_pkt_pack(conn->sock->ctx, packet, pkt_size, s_idx, c_idx, &public, &shsec, nonce, _seq, payload, pld_size); + pkt_meta.s_idx = s_idx; + pkt_meta.c_idx = c_idx; + _rv = _ecp_pack(conn->sock->ctx, packet, pkt_size, &pkt_meta, payload, pld_size); if (_rv < 0) return _rv; #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); #endif - memcpy(conn->nonce, nonce, sizeof(conn->nonce)); + memcpy(conn->nonce, pkt_meta.nonce, sizeof(conn->nonce)); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); #endif @@ -1111,18 +1242,11 @@ ssize_t ecp_conn_pack(ECPConnection *conn, unsigned char *packet, size_t pkt_siz } #ifndef ECP_WITH_VCONN -ssize_t ecp_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr) { +ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPSeqItem *si, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) { if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR; if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR; - return ecp_conn_pack(conn, packet->buffer, packet->size, s_idx, c_idx, payload->buffer, pld_size, si, addr); -} - -ssize_t ecp_pack_raw(ECPSocket *sock, ECPConnection *parent, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) { - if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR; - if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR; - - return ecp_pkt_pack_raw(sock, parent, packet->buffer, packet->size, s_idx, c_idx, public, shsec, nonce, seq, payload->buffer, pld_size, addr); + return _ecp_pack_conn(conn, packet->buffer, packet->size, s_idx, c_idx, si, payload->buffer, pld_size, addr); } #endif @@ -1132,18 +1256,22 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP unsigned char l_idx = ECP_ECDH_IDX_INV; unsigned char *payload = bufs->payload->buffer; unsigned char *packet = bufs->packet->buffer; + size_t pld_size = bufs->payload->size; + ssize_t dec_size; ecp_aead_key_t shsec; ecp_dh_public_t public; ecp_dh_private_t private; + unsigned char *public_buf; + unsigned char *nonce; + unsigned char nonce_next[ECP_AEAD_SIZE_NONCE]; ECPConnection *conn = NULL; ECPDHKey *key = NULL; + unsigned char mtype; unsigned char is_open = 0; - unsigned char is_new = 0; - unsigned char seq_check = 1; - unsigned char seq_reset = 0; - ecp_seq_t seq_c, seq_p, seq_n; + unsigned char seq_check; + unsigned char seq_reset; + ecp_seq_t seq_pkt, seq_conn, seq_last; ecp_ack_t seq_map; - ssize_t dec_size; int rv = ECP_OK; *_conn = NULL; @@ -1152,11 +1280,14 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP s_idx = (packet[ECP_SIZE_PROTO] & 0xF0) >> 4; c_idx = (packet[ECP_SIZE_PROTO] & 0x0F); + public_buf = packet+ECP_SIZE_PROTO+1; + nonce = packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY; + #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&sock->conn.mutex); #endif - conn = ctable_search(sock, c_idx, packet+ECP_SIZE_PROTO+1, NULL); + conn = ctable_search(sock, c_idx, public_buf, NULL); if (conn && !conn->out && (s_idx == ECP_ECDH_IDX_PERMA)) conn = NULL; #ifdef ECP_WITH_PTHREAD @@ -1188,7 +1319,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP conn->refcount++; is_open = ecp_conn_is_open(conn); if (is_open) { - seq_c = conn->seq_in; + seq_conn = conn->seq_in; seq_map = conn->seq_in_map; } } @@ -1200,73 +1331,73 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP if (rv) return rv; if (key) { - ecp_cr_dh_pub_from_buf(&public, packet+ECP_SIZE_PROTO+1); + ecp_cr_dh_pub_from_buf(&public, public_buf); ecp_cr_dh_shsec(&shsec, &public, &private); memset(&private, 0, sizeof(private)); } - dec_size = ecp_cr_aead_dec(payload, bufs->payload->size, packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, &shsec, packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY); + dec_size = ecp_cr_aead_dec(payload, pld_size, packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, &shsec, nonce); if (dec_size < ECP_SIZE_PLD_HDR+1) rv = ECP_ERR_DECRYPT; if (rv) goto ecp_unpack_err; - seq_p = \ + seq_pkt = \ (payload[0] << 24) | \ (payload[1] << 16) | \ (payload[2] << 8) | \ (payload[3]); - if ((payload[ECP_SIZE_PLD_HDR] & ECP_MTYPE_MASK) < ECP_MAX_MTYPE_SYS) ecp_tr_release(bufs->packet, 1); + mtype = payload[ECP_SIZE_PLD_HDR]; + memcpy(nonce_next, packet+ECP_SIZE_PKT_HDR, sizeof(nonce_next)); + // XXX! + // if ((mtype & ECP_MTYPE_MASK) < ECP_MAX_MTYPE_SYS) ecp_tr_release(bufs->packet, 1); if (conn == NULL) { - if (payload[ECP_SIZE_PLD_HDR] == ECP_MTYPE_OPEN_REQ) { - is_new = 1; - rv = sock->conn_new(sock, parent, payload+ECP_SIZE_PLD_HDR+1, dec_size-ECP_SIZE_PLD_HDR-1, &conn); - if (rv) return rv; - } else if (payload[ECP_SIZE_PLD_HDR] == ECP_MTYPE_KGET_REQ) { - ECPBuffer _packet; - ECPBuffer _payload; - unsigned char pkt_buf[ECP_SIZE_PKT_RAW_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent)]; - unsigned char pld_buf[ECP_SIZE_PLD_RAW_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent)]; - - unsigned char *buf = ecp_pld_get_buf(pld_buf, ECP_MTYPE_KGET_REP); - ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REP); - - _packet.buffer = pkt_buf; - _packet.size = ECP_SIZE_PKT_RAW_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent); - _payload.buffer = pld_buf; - _payload.size = ECP_SIZE_PLD_RAW_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent); - - rv = ecp_sock_dhkey_get_curr(sock, buf, buf+1); - if (!rv) { - ssize_t _rv; - - _rv = ecp_pld_send_raw(sock, parent, addr, &_packet, s_idx, c_idx, &public, &shsec, packet+ECP_SIZE_PKT_HDR, seq_p, &_payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0); - if (_rv < 0) rv = _rv; - } + 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; + + 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.nonce, nonce_next, sizeof(pkt_meta.nonce)); + pkt_meta.seq = seq_pkt; + pkt_meta.s_idx = s_idx; + pkt_meta.c_idx = c_idx; + + handler = sock->handler[mtype & ECP_MTYPE_MASK]; + if (handler) { + rv = handler(sock, addr, parent, msg, msg_size, &pkt_meta, bufs, &conn); if (rv) return rv; - } else { - return ECP_ERR_CONN_NOT_FOUND; } } if (conn == NULL) return dec_size; + seq_check = 1; + seq_reset = 0; + if (is_open) { #ifdef ECP_WITH_RBUF - if (conn->rbuf.recv || (payload[ECP_SIZE_PLD_HDR] == ECP_MTYPE_RBACK) || (payload[ECP_SIZE_PLD_HDR] == ECP_MTYPE_RBFLUSH)) seq_check = 0; + if (conn->rbuf.recv || (mtype == ECP_MTYPE_RBACK) || (mtype == ECP_MTYPE_RBFLUSH)) { + seq_check = 0; + } #endif if (seq_check) { - if (ECP_SEQ_LTE(seq_p, seq_c)) { - ecp_seq_t seq_offset = seq_c - seq_p; + if (ECP_SEQ_LTE(seq_pkt, seq_conn)) { + ecp_seq_t seq_offset = seq_conn - seq_pkt; if (seq_offset < ECP_SIZE_ACKB) { ecp_ack_t ack_mask = ((ecp_ack_t)1 << seq_offset); if (ack_mask & seq_map) rv = ECP_ERR_SEQ; - if (!rv) seq_n = seq_c; + if (!rv) seq_last = seq_conn; } else { rv = ECP_ERR_SEQ; } } else { - ecp_seq_t seq_offset = seq_p - seq_c; + ecp_seq_t seq_offset = seq_pkt - seq_conn; if (seq_offset < ECP_MAX_SEQ_FWD) { if (seq_offset < ECP_SIZE_ACKB) { seq_map = seq_map << seq_offset; @@ -1274,13 +1405,13 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP seq_map = 0; } seq_map |= 1; - seq_n = seq_p; + seq_last = seq_pkt; } else { rv = ECP_ERR_SEQ; } } - if ((rv == ECP_ERR_SEQ) && (payload[ECP_SIZE_PLD_HDR] == ECP_MTYPE_OPEN_REQ) && key) { + if ((rv == ECP_ERR_SEQ) && (mtype == ECP_MTYPE_OPEN_REQ) && key) { rv = ECP_OK; seq_reset = 1; } @@ -1289,12 +1420,12 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP } if (!is_open || seq_reset) { - seq_n = seq_p; + seq_last = seq_pkt; seq_map = 1; #ifdef ECP_WITH_RBUF if (conn->rbuf.recv) { - rv = ecp_rbuf_recv_start(conn, seq_p); + rv = ecp_rbuf_recv_start(conn, seq_pkt); if (rv) goto ecp_unpack_err; } #endif @@ -1303,14 +1434,13 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); #endif - memcpy(conn->nonce, packet+ECP_SIZE_PKT_HDR, sizeof(conn->nonce)); + memcpy(conn->nonce, nonce_next, sizeof(conn->nonce)); if (addr) conn->node.addr = *addr; if (seq_check) { - conn->seq_in = seq_n; + conn->seq_in = seq_last; conn->seq_in_map = seq_map; } if (key) { - if (is_new) rv = conn_dhkey_new_pub_remote(conn, c_idx, packet+ECP_SIZE_PROTO+1); if (!rv) rv = conn_dhkey_new_pub_local(conn, l_idx); if (!rv) rv = conn_shsec_set(conn, s_idx, c_idx, &shsec); } @@ -1321,7 +1451,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP if (rv) goto ecp_unpack_err; *_conn = conn; - *_seq = seq_p; + *_seq = seq_pkt; return dec_size; ecp_unpack_err: @@ -1350,9 +1480,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); + 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); + } #endif - if (rv == 0) rv = ecp_msg_handle(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR, bufs); + 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); @@ -1379,46 +1511,56 @@ ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_ return rv; } -int ecp_seq_item_init(ECPSeqItem *seq_item) { - memset(seq_item, 0, sizeof(ECPSeqItem)); +int ecp_msg_get_type(unsigned char *msg, size_t msg_size, unsigned char *mtype) { + if (msg_size == 0) ECP_ERR; + *mtype = msg[0]; return ECP_OK; } -int ecp_frag_iter_init(ECPFragIter *iter, unsigned char *buffer, size_t buf_size) { - memset(iter, 0, sizeof(ECPFragIter)); - iter->buffer = buffer; - iter->buf_size = buf_size; +int ecp_msg_set_type(unsigned char *msg, size_t msg_size, unsigned char type) { + if (msg_size == 0) ECP_ERR; + msg[0] = type; return ECP_OK; } -unsigned char ecp_msg_get_type(unsigned char *msg) { - return msg[0]; -} +int ecp_msg_get_frag(unsigned char *msg, size_t msg_size, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_size) { + if (msg_size < 3) return ECP_ERR; + if (!(msg[0] & ECP_MTYPE_FLAG_FRAG)) return ECP_ERR; + if (msg[2] == 0) return ECP_ERR; -unsigned char *ecp_msg_get_content(unsigned char *msg, size_t msg_size) { - size_t offset = 1 + ECP_SIZE_MT_FLAG(msg[0]); + *frag_cnt = msg[1]; + *frag_tot = msg[2]; + *frag_size = \ + (msg[3] << 8) | \ + (msg[4]); - if (msg_size < offset) return NULL; - return msg + offset; + return ECP_OK; } -int ecp_msg_get_frag(unsigned char *msg, size_t msg_size, unsigned char *frag_cnt, unsigned char *frag_tot) { - if (!(msg[0] & ECP_MTYPE_FLAG_FRAG)) return ECP_ERR; +int ecp_msg_set_frag(unsigned char *msg, size_t msg_size, unsigned char frag_cnt, unsigned char frag_tot, uint16_t frag_size) { if (msg_size < 3) return ECP_ERR; + if (!(msg[0] & ECP_MTYPE_FLAG_FRAG)) return ECP_ERR; - *frag_cnt = msg[1]; - *frag_tot = msg[2]; + msg[1] = frag_cnt; + msg[2] = frag_tot; + msg[3] = (frag_size & 0xFF00) >> 8; + msg[4] = (frag_size & 0x00FF); return ECP_OK; } int ecp_msg_get_pts(unsigned char *msg, size_t msg_size, ecp_pts_t *pts) { - unsigned char mtype = msg[0]; - size_t offset = 1 + ECP_SIZE_MT_FRAG(mtype); + unsigned char mtype; + size_t offset; + + if (msg_size == 0) ECP_ERR; + mtype = msg[0]; if (!(mtype & ECP_MTYPE_FLAG_PTS)) return ECP_ERR; + + offset = 1 + ECP_SIZE_MT_FRAG(mtype); if (msg_size < offset + sizeof(ecp_pts_t)) return ECP_ERR; *pts = \ @@ -1430,145 +1572,148 @@ int ecp_msg_get_pts(unsigned char *msg, size_t msg_size, ecp_pts_t *pts) { return ECP_OK; } -int ecp_msg_defrag(ECPFragIter *iter, ecp_seq_t seq, unsigned char *msg_in, size_t msg_in_size, unsigned char **msg_out, size_t *msg_out_size) { - unsigned char frag_cnt, frag_tot; - int rv; +int ecp_msg_set_pts(unsigned char *msg, size_t msg_size, ecp_pts_t pts) { + unsigned char mtype; + size_t offset; - rv = ecp_msg_get_frag(msg_in, msg_in_size, &frag_cnt, &frag_tot); - if (rv == ECP_OK) { - unsigned char mtype = ecp_msg_get_type(msg_in) & (~ECP_MTYPE_FLAG_FRAG); - unsigned char *content = NULL; - size_t content_size = 0; - size_t buf_offset = 0; + if (msg_size == 0) ECP_ERR; - content = ecp_msg_get_content(msg_in, msg_in_size); - if (content == NULL) return ECP_ERR_MIN_MSG; + mtype = msg[0]; + if (!(mtype & ECP_MTYPE_FLAG_PTS)) return ECP_ERR; - content_size = msg_in_size - (content - msg_in); - if (frag_cnt == 0) { - iter->seq = seq; - iter->frag_cnt = 0; - iter->frag_size = content_size; - iter->buffer[0] = mtype; - if (ECP_SIZE_MT_FLAG(mtype)) { - memcpy(iter->buffer + 1, msg_in, ECP_SIZE_MT_FLAG(mtype)); - } - } else { - if (iter->seq + frag_cnt != seq) { - iter->seq = seq - frag_cnt; - iter->frag_cnt = 0; - return ECP_ERR_ITER; - } - if (iter->frag_cnt != frag_cnt) return ECP_ERR_ITER; - } - if ((1 + ECP_SIZE_MT_FLAG(mtype) + iter->frag_size * frag_tot) > iter->buf_size) return ECP_ERR_SIZE; + offset = 1 + ECP_SIZE_MT_FRAG(mtype); + if (msg_size < offset + sizeof(ecp_pts_t)) return ECP_ERR; - buf_offset = 1 + ECP_SIZE_MT_FLAG(mtype) + iter->frag_size * frag_cnt; - memcpy(iter->buffer + buf_offset, content, content_size); - iter->frag_cnt++; + msg[offset] = (pts & 0xFF000000) >> 24; + msg[offset + 1] = (pts & 0x00FF0000) >> 16; + msg[offset + 2] = (pts & 0x0000FF00) >> 8; + msg[offset + 3] = (pts & 0x000000FF); - if (iter->frag_cnt == frag_tot) { - *msg_out = iter->buffer; - *msg_out_size = buf_offset + content_size; - return ECP_OK; - } else { - return ECP_ITER_NEXT; - } - } else { - iter->seq = seq; - *msg_out = msg_in; - *msg_out_size = msg_in_size; - return ECP_OK; - } + return ECP_OK; } -ssize_t ecp_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { - ecp_conn_handler_msg_t handler = NULL; - unsigned char mtype = 0; - unsigned char *content = NULL; - size_t rem_size = msg_size; - ssize_t rv; - int _rv; +unsigned char *ecp_msg_get_content(unsigned char *msg, size_t msg_size) { + unsigned char mtype; + size_t offset; - while (rem_size) { - mtype = ecp_msg_get_type(msg); - if ((mtype & ECP_MTYPE_MASK) >= ECP_MAX_MTYPE) return ECP_ERR_MAX_MTYPE; + if (msg_size == 0) ECP_ERR; - ecp_timer_pop(conn, mtype); + mtype = msg[0]; + offset = 1 + ECP_SIZE_MT_FLAG(mtype); + if (msg_size < offset) return NULL; -#ifdef ECP_WITH_RBUF - if (conn->rbuf.recv && conn->rbuf.recv->frag_iter) { + return msg + offset; +} - _rv = ecp_msg_defrag(conn->rbuf.recv->frag_iter, seq, msg, msg_size, &msg, &rem_size); - if (_rv < 0) return _rv; - if (_rv == ECP_ITER_NEXT) return msg_size; - } -#endif +int ecp_msg_defrag(ECPFragIter *iter, ecp_seq_t seq, unsigned char mtype, unsigned char *msg_in, size_t msg_in_size, unsigned char **msg_out, size_t *msg_out_size) { + unsigned char *content; + unsigned char frag_cnt, frag_tot; + uint16_t frag_size; + size_t content_size; + size_t buf_offset; + int rv; - content = ecp_msg_get_content(msg, rem_size); - if (content == NULL) return ECP_ERR_MIN_MSG; - rem_size -= content - msg; + rv = ecp_msg_get_frag(msg_in, msg_in_size, &frag_cnt, &frag_tot, &frag_size); + if (rv) return ECP_ERR_MIN_MSG; - handler = conn->sock->ctx->handler[conn->type] ? conn->sock->ctx->handler[conn->type]->msg[mtype & ECP_MTYPE_MASK] : NULL; - if (handler) { - rv = handler(conn, seq, mtype, content, rem_size, bufs); - if (rv < 0) return rv; - if (rv > rem_size) return ECP_ERR; + content = ecp_msg_get_content(msg_in, msg_in_size); + if (content == NULL) return ECP_ERR_MIN_MSG; - rem_size -= rv; - msg = content + rv; - } else { - return msg_size - rem_size - 1; + content_size = msg_in_size - (content - msg_in); + if (content_size == 0) return ECP_ERR_MIN_MSG; + + if (iter->content_size && (iter->seq + frag_cnt != seq)) ecp_frag_iter_reset(iter); + + if (iter->content_size == 0) { + iter->seq = seq - frag_cnt; + iter->frag_cnt = 0; + } + + mtype &= (~ECP_MTYPE_FLAG_FRAG); + if (frag_cnt == 0) { + if (1 + ECP_SIZE_MT_FLAG(mtype) > iter->buf_size) return ECP_ERR_SIZE; + iter->buffer[0] = mtype; + if (ECP_SIZE_MT_FLAG(mtype)) { + memcpy(iter->buffer + 1, msg_in, ECP_SIZE_MT_FLAG(mtype)); } } - return msg_size; + buf_offset = 1 + ECP_SIZE_MT_FLAG(mtype) + frag_size * frag_cnt; + if (buf_offset + content_size > iter->buf_size) return ECP_ERR_SIZE; + + memcpy(iter->buffer + buf_offset, content, content_size); + iter->frag_cnt++; + iter->content_size += content_size; + if (iter->frag_cnt == frag_tot) { + *msg_out = iter->buffer; + *msg_out_size = iter->content_size; + return ECP_OK; + } else { + return ECP_ITER_NEXT; + } } -void ecp_pld_set_type(unsigned char *payload, unsigned char mtype) { - payload[ECP_SIZE_PLD_HDR] = mtype; +int ecp_pld_get_type(unsigned char *payload, size_t pld_size, unsigned char *mtype) { + payload += ECP_SIZE_PLD_HDR; + pld_size -= ECP_SIZE_PLD_HDR; + + return ecp_msg_get_type(payload, pld_size, mtype); } -int ecp_pld_set_frag(unsigned char *payload, unsigned char mtype, unsigned char frag_cnt, unsigned char frag_tot) { - size_t offset = ECP_SIZE_PLD_HDR + 1; +int ecp_pld_set_type(unsigned char *payload, size_t pld_size, unsigned char mtype) { + payload += ECP_SIZE_PLD_HDR; + pld_size -= ECP_SIZE_PLD_HDR; - if (!(mtype & ECP_MTYPE_FLAG_FRAG)) return ECP_ERR; - payload[offset] = frag_cnt; - payload[offset + 1] = frag_tot; - return ECP_OK; + return ecp_msg_set_type(payload, pld_size, mtype); } -int ecp_pld_set_pts(unsigned char *payload, unsigned char mtype, ecp_pts_t pts) { - size_t offset = ECP_SIZE_PLD_HDR + 1 + ECP_SIZE_MT_FRAG(mtype); +int ecp_pld_get_frag(unsigned char *payload, size_t pld_size, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_size) { + payload += ECP_SIZE_PLD_HDR; + pld_size -= ECP_SIZE_PLD_HDR; - if (!(mtype & ECP_MTYPE_FLAG_PTS)) return ECP_ERR; + return ecp_msg_get_frag(payload, pld_size, frag_cnt, frag_tot, frag_size); +} - payload[offset] = (pts & 0xFF000000) >> 24; - payload[offset + 1] = (pts & 0x00FF0000) >> 16; - payload[offset + 2] = (pts & 0x0000FF00) >> 8; - payload[offset + 3] = (pts & 0x000000FF); +int ecp_pld_set_frag(unsigned char *payload, size_t pld_size, unsigned char frag_cnt, unsigned char frag_tot, uint16_t frag_size) { + payload += ECP_SIZE_PLD_HDR; + pld_size -= ECP_SIZE_PLD_HDR; - return ECP_OK; + return ecp_msg_set_frag(payload, pld_size, frag_cnt, frag_tot, frag_size); } -unsigned char ecp_pld_get_type(unsigned char *payload) { - return payload[ECP_SIZE_PLD_HDR]; +int ecp_pld_get_pts(unsigned char *payload, size_t pld_size, ecp_pts_t *pts) { + payload += ECP_SIZE_PLD_HDR; + pld_size -= ECP_SIZE_PLD_HDR; + + return ecp_msg_get_pts(payload, pld_size, pts); } -unsigned char *ecp_pld_get_buf(unsigned char *payload, unsigned char mtype) { - return payload + ECP_SIZE_PLD_HDR + 1 + ECP_SIZE_MT_FLAG(mtype); +int ecp_pld_set_pts(unsigned char *payload, size_t pld_size, ecp_pts_t pts) { + payload += ECP_SIZE_PLD_HDR; + pld_size -= ECP_SIZE_PLD_HDR; + + return ecp_msg_set_pts(payload, pld_size, pts); +} + +unsigned char *ecp_pld_get_buf(unsigned char *payload, size_t pld_size) { + payload += ECP_SIZE_PLD_HDR; + pld_size -= ECP_SIZE_PLD_HDR; + + return ecp_msg_get_content(payload, pld_size); } -static ssize_t pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti, ECPSeqItem *si) { +static ssize_t pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPSeqItem *si, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) { ECPSocket *sock = conn->sock; ECPNetAddr addr; ssize_t rv; - rv = ecp_pack(conn, packet, s_idx, c_idx, payload, pld_size, si, &addr); + rv = ecp_pack_conn(conn, packet, s_idx, c_idx, si, payload, pld_size, &addr); if (rv < 0) return rv; #ifdef ECP_WITH_RBUF - if (conn->rbuf.send) return ecp_rbuf_pkt_send(conn->rbuf.send, conn->sock, &addr, packet, rv, flags, ti, si); + if (conn->rbuf.send) { + return ecp_rbuf_pkt_send(conn->rbuf.send, conn->sock, &addr, packet, rv, flags, ti, si); + } #endif if (ti) { @@ -1577,42 +1722,42 @@ static ssize_t pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_ _rv = ecp_timer_push(ti); if (_rv) return _rv; } - return ecp_pkt_send(sock, &addr, packet, rv, flags); -} -ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags) { - return ecp_pld_send_ll(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, flags, NULL); -} - -ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) { - return ecp_pld_send_ll(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, flags, ti); + return ecp_pkt_send(sock, &addr, packet, rv, flags); } -ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) { - ECPSeqItem *_seq_item = NULL; - +ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPSeqItem *si, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) { #ifdef ECP_WITH_RBUF - ECPSeqItem seq_item; - int rv; + if ((si == NULL) && conn->rbuf.send) { + ECPSeqItem seq_item; + int rv; - if (conn->rbuf.send) { rv = ecp_seq_item_init(&seq_item); if (rv) return rv; - _seq_item = &seq_item; + + return pld_send(conn, packet, s_idx, c_idx, &seq_item, payload, pld_size, flags, ti); } #endif - return pld_send(conn, packet, s_idx, c_idx, payload, pld_size, flags, ti, _seq_item); + return pld_send(conn, packet, s_idx, c_idx, NULL, payload, pld_size, flags, ti); +} + +ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags) { + return _ecp_pld_send(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, NULL, payload, pld_size, flags, NULL); +} + +ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) { + return _ecp_pld_send(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, NULL, payload, pld_size, flags, ti); } -ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *addr, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, unsigned char flags) { +ssize_t ecp_pld_send_tr(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, unsigned char flags) { ECPNetAddr _addr; ssize_t rv; - rv = ecp_pack_raw(sock, parent, packet, s_idx, c_idx, public, shsec, nonce, seq, payload, pld_size, &_addr); + rv = ecp_pack(sock->ctx, parent, packet, pkt_meta, payload, pld_size, &_addr); if (rv < 0) return rv; - return ecp_pkt_send(sock, parent ? &_addr : addr, packet, rv, flags); + return ecp_pkt_send(sock, addr ? addr : &_addr, packet, rv, flags); } ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *content, size_t content_size) { @@ -1620,28 +1765,29 @@ ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *conten ECPBuffer payload; unsigned char pkt_buf[ECP_MAX_PKT]; unsigned char pld_buf[ECP_MAX_PLD]; + unsigned char *content_buf; ssize_t rv = 0; int pkt_cnt = 0; int vc_cnt = conn->pcount + 1; - size_t size_max = ECP_MAX_PKT - (ECP_SIZE_PKT_HDR + ECP_AEAD_SIZE_TAG + ECP_SIZE_SEQ + 1) * vc_cnt; + size_t pld_max = ECP_MAX_PKT - (ECP_SIZE_PKT_HDR + ECP_AEAD_SIZE_TAG + ECP_SIZE_PLD_HDR + 1) * vc_cnt; packet.buffer = pkt_buf; packet.size = ECP_MAX_PKT; payload.buffer = pld_buf; payload.size = ECP_MAX_PLD; - if (content_size + ECP_SIZE_MT_FLAG(mtype) > size_max) { - int i; - int _rv = ECP_OK; + if (ECP_SIZE_PLD(content_size, mtype) > pld_max) { size_t frag_size, frag_size_final; - ecp_seq_t seq_start = 0; + ecp_seq_t seq_start; ECPSeqItem seq_item; + int i; + int _rv; _rv = ecp_seq_item_init(&seq_item); if (_rv) return _rv; mtype |= ECP_MTYPE_FLAG_FRAG; - frag_size = size_max - ECP_SIZE_MT_FLAG(mtype); + frag_size = pld_max - (ECP_SIZE_PLD_HDR +1 +ECP_SIZE_MT_FLAG(mtype)); pkt_cnt = content_size / frag_size; frag_size_final = content_size - frag_size * pkt_cnt; if (frag_size_final) pkt_cnt++; @@ -1661,21 +1807,25 @@ ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *conten for (i=0; i<pkt_cnt; i++) { ssize_t _rv; + ecp_pld_set_type(pld_buf, ECP_MAX_PLD, mtype); + ecp_pld_set_frag(pld_buf, ECP_MAX_PLD, i, pkt_cnt, frag_size); + content_buf = ecp_pld_get_buf(pld_buf, ECP_MAX_PLD); + if ((i == pkt_cnt - 1) && frag_size_final) frag_size = frag_size_final; - ecp_pld_set_type(pld_buf, mtype); - ecp_pld_set_frag(pld_buf, mtype, i, pkt_cnt); - memcpy(ecp_pld_get_buf(pld_buf, mtype), content, frag_size); + memcpy(content_buf, content, frag_size); content += frag_size; - seq_item.seq = seq_start + i; - _rv = pld_send(conn, &packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(frag_size, mtype), 0, NULL, &seq_item); + + _rv = _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &seq_item, &payload, ECP_SIZE_PLD(frag_size, mtype), 0, NULL); if (_rv < 0) return _rv; rv += _rv; } } else { - ecp_pld_set_type(pld_buf, mtype); - memcpy(ecp_pld_get_buf(pld_buf, mtype), content, content_size); + ecp_pld_set_type(pld_buf, ECP_MAX_PLD, mtype); + content_buf = ecp_pld_get_buf(pld_buf, ECP_MAX_PLD); + + memcpy(content_buf, content, content_size); rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(content_size, mtype), 0); } return rv; diff --git a/ecp/src/core.h b/ecp/src/core.h index 3c62450..bb96f26 100644 --- a/ecp/src/core.h +++ b/ecp/src/core.h @@ -7,6 +7,8 @@ #include <pthread.h> #endif +#define ECP_MEM_TINY 1 + #define ECP_OK 0 #define ECP_ITER_NEXT 1 @@ -52,6 +54,7 @@ #define ECP_MAX_CTYPE 8 #define ECP_MAX_MTYPE 16 #define ECP_MAX_MTYPE_SYS 4 +#define ECP_MAX_MTYPE_SOCK ECP_MAX_MTYPE_SYS #define ECP_MAX_SEQ_FWD 1024 #define ECP_SIZE_PKT_HDR (ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY+ECP_AEAD_SIZE_NONCE) @@ -75,7 +78,7 @@ #define ECP_MTYPE_OPEN 0x00 #define ECP_MTYPE_KGET 0x01 #define ECP_MTYPE_KPUT 0x02 -#define ECP_MTYPE_NOP 0x03 +#define ECP_MTYPE_DIR 0x03 #define ECP_MTYPE_OPEN_REQ (ECP_MTYPE_OPEN) #define ECP_MTYPE_OPEN_REP (ECP_MTYPE_OPEN | ECP_MTYPE_FLAG_REP) @@ -115,7 +118,7 @@ typedef uint32_t ecp_seq_t; #define ECP_SEQ_LTE(a,b) ((ecp_seq_t)((ecp_seq_t)(b) - (ecp_seq_t)(a)) < ECP_SEQ_HALF) -#define ECP_SIZE_MT_FRAG(F) ((F) & ECP_MTYPE_FLAG_FRAG ? 2 : 0) +#define ECP_SIZE_MT_FRAG(F) ((F) & ECP_MTYPE_FLAG_FRAG ? 2 + sizeof(uint16_t) : 0) #define ECP_SIZE_MT_PTS(F) ((F) & ECP_MTYPE_FLAG_PTS ? sizeof(ecp_pts_t) : 0) #define ECP_SIZE_MT_FLAG(F) (ECP_SIZE_MT_FRAG(F)+ECP_SIZE_MT_PTS(F)) #define ECP_SIZE_PLD(X,F) ((X) + ECP_SIZE_PLD_HDR+1+ECP_SIZE_MT_FLAG(F)) @@ -126,8 +129,8 @@ typedef uint32_t ecp_seq_t; #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) -#define ECP_SIZE_PLD_RAW_BUF(X,T,P) (ECP_SIZE_PLD(X,T)+((P) ? ((P)->pcount+1)*(ECP_SIZE_PKT_HDR+ECP_SIZE_MSG_BUF(T,P)+ECP_AEAD_SIZE_TAG) : 0)) -#define ECP_SIZE_PKT_RAW_BUF(X,T,P) (ECP_SIZE_PLD_RAW_BUF(X,T,P)+ECP_SIZE_PKT_HDR+ECP_AEAD_SIZE_TAG) +#define ECP_SIZE_PLD_BUF_TR(X,T,P) (ECP_SIZE_PLD(X,T)+((P) ? ((P)->pcount+1)*(ECP_SIZE_PKT_HDR+ECP_SIZE_MSG_BUF(T,P)+ECP_AEAD_SIZE_TAG) : 0)) +#define ECP_SIZE_PKT_BUF_TR(X,T,P) (ECP_SIZE_PLD_BUF_TR(X,T,P)+ECP_SIZE_PKT_HDR+ECP_AEAD_SIZE_TAG) #ifdef ECP_DEBUG #include <stdio.h> @@ -139,7 +142,7 @@ struct ECPContext; struct ECPSocket; struct ECPConnection; struct ECPSeqItem; -struct ECPFragIter; +struct ECPPktMeta; #include "platform/transport.h" #include "crypto/crypto.h" @@ -151,7 +154,7 @@ struct ECPFragIter; typedef int (*ecp_rng_t) (void *, size_t); -typedef int (*ecp_conn_handler_new_t) (struct ECPSocket *s, struct ECPConnection *p, unsigned char *msg, size_t sz, struct ECPConnection **c); +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 struct ECPConnection * (*ecp_conn_alloc_t) (unsigned char t); @@ -210,12 +213,21 @@ typedef struct ECPSeqItem { typedef struct ECPFragIter { ecp_seq_t seq; - size_t frag_size; unsigned char frag_cnt; unsigned char *buffer; size_t buf_size; + size_t content_size; } ECPFragIter; +typedef struct ECPPktMeta { + ecp_aead_key_t shsec; + ecp_dh_public_t public; + ecp_seq_t seq; + 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; @@ -253,7 +265,7 @@ typedef struct ECPSocket { unsigned char key_curr; ECPSockCTable conn; ECPTimer timer; - ecp_conn_handler_new_t conn_new; + ecp_sock_handler_msg_t handler[ECP_MAX_MTYPE_SOCK]; #ifdef ECP_WITH_PTHREAD pthread_t rcvr_thd; pthread_mutex_t mutex; @@ -290,11 +302,12 @@ typedef struct ECPConnection { } ECPConnection; int ecp_init(ECPContext *ctx); - -int ecp_dhkey_generate(ECPContext *ctx, ECPDHKey *key); -int ecp_node_init(ECPNode *node, ecp_dh_public_t *public, void *addr); - int ecp_ctx_init(ECPContext *ctx); +int ecp_node_init(ECPNode *node, ecp_dh_public_t *public, void *addr); +int ecp_seq_item_init(ECPSeqItem *seq_item); +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); void ecp_sock_destroy(ECPSocket *sock); @@ -303,59 +316,64 @@ void ecp_sock_close(ECPSocket *sock); int ecp_sock_dhkey_get_curr(ECPSocket *sock, unsigned char *idx, unsigned char *public); int ecp_sock_dhkey_new(ECPSocket *sock); +int ecp_conn_init(ECPConnection *conn, ECPNode *node); int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype); void ecp_conn_destroy(ECPConnection *conn); int ecp_conn_register(ECPConnection *conn); void ecp_conn_unregister(ECPConnection *conn); -int ecp_conn_init(ECPConnection *conn, ECPNode *node); int ecp_conn_open(ECPConnection *conn, ECPNode *node); int ecp_conn_close(ECPConnection *conn, ecp_cts_t timeout); - +int ecp_conn_reset(ECPConnection *conn); int ecp_conn_handler_init(ECPConnHandler *handler); + +int ecp_conn_dhkey_new(ECPConnection *conn); +int ecp_conn_dhkey_new_pub(ECPConnection *conn, unsigned char idx, unsigned char *public); +int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned char *public); + ssize_t ecp_conn_send_open(ECPConnection *conn); -int ecp_conn_handle_new(ECPSocket *sock, ECPConnection *parent, unsigned char *payload, size_t payload_size, ECPConnection **_conn); +ssize_t ecp_conn_send_kget(ECPConnection *conn); +ssize_t ecp_conn_send_kput(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); 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); -int ecp_conn_dhkey_new(ECPConnection *conn); -int ecp_conn_dhkey_new_pub(ECPConnection *conn, unsigned char idx, unsigned char *public); -int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned char *public); +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) ; -ssize_t ecp_pkt_pack(ECPContext *ctx, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, unsigned char *payload, size_t pld_size); -ssize_t ecp_pkt_pack_raw(ECPSocket *sock, ECPConnection *parent, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECPNetAddr *addr); -ssize_t ecp_conn_pack(ECPConnection *conn, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, unsigned char *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr); - -ssize_t ecp_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr); -ssize_t ecp_pack_raw(ECPSocket *sock, ECPConnection *parent, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr); +ssize_t _ecp_pack_conn(ECPConnection *conn, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, ECPSeqItem *si, unsigned char *payload, size_t pld_size, ECPNetAddr *addr); +ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPSeqItem *si, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr); ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size, ECPConnection **_conn, ecp_seq_t *_seq); ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size); - ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags); -int ecp_seq_item_init(ECPSeqItem *seq_item); -int ecp_frag_iter_init(ECPFragIter *iter, unsigned char *buffer, size_t buf_size); - -unsigned char ecp_msg_get_type(unsigned char *msg); -unsigned char *ecp_msg_get_content(unsigned char *msg, size_t msg_size); -int ecp_msg_get_frag(unsigned char *msg, size_t msg_size, unsigned char *frag_cnt, unsigned char *frag_tot); +int ecp_msg_get_type(unsigned char *msg, size_t msg_size, unsigned char *mtype); +int ecp_msg_set_type(unsigned char *msg, size_t msg_size, unsigned char mtype); +int ecp_msg_get_frag(unsigned char *msg, size_t msg_size, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_size); +int ecp_msg_set_frag(unsigned char *msg, size_t msg_size, unsigned char frag_cnt, unsigned char frag_tot, uint16_t frag_size); int ecp_msg_get_pts(unsigned char *msg, size_t msg_size, ecp_pts_t *pts); -int ecp_msg_defrag(ECPFragIter *iter, ecp_seq_t seq, unsigned char *msg_in, size_t msg_in_size, unsigned char **msg_out, size_t *msg_out_size); -ssize_t ecp_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs); +int ecp_msg_set_pts(unsigned char *msg, size_t msg_size, ecp_pts_t pts); +unsigned char *ecp_msg_get_content(unsigned char *msg, size_t msg_size); +int ecp_msg_defrag(ECPFragIter *iter, ecp_seq_t seq, unsigned char mtype, unsigned char *msg_in, size_t msg_in_size, unsigned char **msg_out, size_t *msg_out_size); -void ecp_pld_set_type(unsigned char *payload, unsigned char mtype); -int ecp_pld_set_frag(unsigned char *payload, unsigned char mtype, unsigned char frag_cnt, unsigned char frag_tot); -int ecp_pld_set_pts(unsigned char *payload, unsigned char mtype, ecp_pts_t pts); -unsigned char *ecp_pld_get_buf(unsigned char *payload, unsigned char mtype); -unsigned char ecp_pld_get_type(unsigned char *payload); +int ecp_pld_get_type(unsigned char *payload, size_t pld_size, unsigned char *mtype); +int ecp_pld_set_type(unsigned char *payload, size_t pld_size, unsigned char mtype); +int ecp_pld_get_frag(unsigned char *payload, size_t pld_size, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_size); +int ecp_pld_set_frag(unsigned char *payload, size_t pld_size, unsigned char frag_cnt, unsigned char frag_tot, uint16_t frag_size); +int ecp_pld_get_pts(unsigned char *payload, size_t pld_size, ecp_pts_t *pts); +int ecp_pld_set_pts(unsigned char *payload, size_t pld_size, ecp_pts_t pts); +unsigned char *ecp_pld_get_buf(unsigned char *payload, size_t pld_size); +ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPSeqItem *si, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti); ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags); ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti); -ssize_t ecp_pld_send_ll(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti); -ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *parent, ECPNetAddr *addr, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, unsigned char flags); +ssize_t ecp_pld_send_tr(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, unsigned char flags); ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *content, size_t content_size); ssize_t ecp_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ecp_cts_t timeout); diff --git a/ecp/src/rbuf.c b/ecp/src/rbuf.c index 05eb5ae..9a5bd8c 100644 --- a/ecp/src/rbuf.c +++ b/ecp/src/rbuf.c @@ -1,19 +1,32 @@ #include "core.h" +int ecp_rbuf_init(ECPRBuffer *rbuf, ECPRBMessage *msg, unsigned int msg_size) { + rbuf->msg = msg; + if (msg_size) { + if (msg == NULL) return ECP_ERR; + rbuf->msg_size = msg_size; + memset(rbuf->msg, 0, sizeof(ECPRBMessage) * msg_size); + } else { + rbuf->msg_size = ECP_SEQ_HALF; + } + + return ECP_OK; +} + 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; - + if (buf_s) { rv = ecp_rbuf_send_create(conn, buf_s, msg_s, msg_s_size); if (rv) return rv; - + rv = ecp_rbuf_send_start(conn); if (rv) { ecp_rbuf_send_destroy(conn); return rv; } } - + if (buf_r) { rv = ecp_rbuf_recv_create(conn, buf_r, msg_r, msg_r_size); if (rv) { @@ -21,7 +34,7 @@ int ecp_rbuf_create(ECPConnection *conn, ECPRBSend *buf_s, ECPRBMessage *msg_s, return rv; } } - + return ECP_OK; } @@ -30,19 +43,6 @@ void ecp_rbuf_destroy(ECPConnection *conn) { ecp_rbuf_recv_destroy(conn); } -int ecp_rbuf_init(ECPRBuffer *rbuf, ECPRBMessage *msg, unsigned int msg_size) { - rbuf->msg = msg; - if (msg_size) { - if (msg == NULL) return ECP_ERR; - rbuf->msg_size = msg_size; - memset(rbuf->msg, 0, sizeof(ECPRBMessage) * msg_size); - } else { - rbuf->msg_size = ECP_SEQ_HALF; - } - - return ECP_OK; -} - int ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq) { rbuf->seq_max = seq; rbuf->seq_start = seq + 1; @@ -64,7 +64,7 @@ ssize_t ecp_rbuf_msg_store(ECPRBuffer *rbuf, ecp_seq_t seq, int idx, unsigned ch 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; @@ -78,16 +78,16 @@ ssize_t ecp_rbuf_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *pay ECPNetAddr addr; ECPSeqItem seq_item; ssize_t rv; - int _rv; - + int _rv; + _rv = ecp_seq_item_init(&seq_item); if (_rv) return _rv; - + seq_item.seq = seq; seq_item.seq_w = 1; seq_item.rb_pass = 1; - rv = ecp_pack(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, &seq_item, &addr); + rv = ecp_pack_conn(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &seq_item, payload, pld_size, &addr); if (rv < 0) return rv; rv = ecp_pkt_send(sock, &addr, packet, rv, flags); diff --git a/ecp/src/rbuf.h b/ecp/src/rbuf.h index 289a0c4..3a2a51b 100644 --- a/ecp/src/rbuf.h +++ b/ecp/src/rbuf.h @@ -10,6 +10,7 @@ #define ECP_MTYPE_RBACK 0x04 #define ECP_MTYPE_RBFLUSH 0x05 #define ECP_MTYPE_RBFLUSH_PTS 0x06 +#define ECP_MTYPE_NOP 0x07 #define ECP_ERR_RBUF_DUP -100 #define ECP_ERR_RBUF_FULL -101 @@ -23,6 +24,16 @@ typedef uint32_t ecp_win_t; #include "msgq.h" #endif +typedef struct ECPRBTimerItem { + unsigned char occupied; + ECPTimerItem item; +} ECPRBTimerItem; + +typedef struct ECPRBTimer { + ECPRBTimerItem item[ECP_MAX_TIMER]; + unsigned short idx_w; +} ECPRBTimer; + typedef struct ECPRBMessage { unsigned char msg[ECP_MAX_PKT]; ssize_t size; @@ -38,17 +49,6 @@ typedef struct ECPRBuffer { ECPRBMessage *msg; } ECPRBuffer; - -typedef struct ECPRBTimerItem { - unsigned char occupied; - ECPTimerItem item; -} ECPRBTimerItem; - -typedef struct ECPRBTimer { - ECPRBTimerItem item[ECP_MAX_TIMER]; - unsigned short idx_w; -} ECPRBTimer; - typedef struct ECPRBRecv { unsigned char flags; unsigned char timer_pts; @@ -89,17 +89,15 @@ typedef struct ECPConnRBuffer { ECPRBSend *send; } ECPConnRBuffer; - int ecp_rbuf_init(ECPRBuffer *rbuf, ECPRBMessage *msg, unsigned int msg_size); +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_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_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); diff --git a/ecp/src/rbuf_recv.c b/ecp/src/rbuf_recv.c index e949da7..17bbd01 100644 --- a/ecp/src/rbuf_recv.c +++ b/ecp/src/rbuf_recv.c @@ -8,13 +8,18 @@ static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *b) { ECPRBRecv *buf = conn->rbuf.recv; unsigned char flags = ECP_RBUF_FLAG_IN_RBUF; - unsigned char mtype = ecp_msg_get_type(msg) & ECP_MTYPE_MASK; + unsigned char mtype; ssize_t rv; + int _rv; + + _rv = ecp_msg_get_type(msg, msg_size, &mtype); + if (_rv) return _rv; + mtype &= ECP_MTYPE_MASK; if (mtype < ECP_MAX_MTYPE_SYS) flags |= ECP_RBUF_FLAG_SYS; -#ifdef ECP_WITH_MSGQ if (buf->flags & ECP_RBUF_FLAG_MSGQ) { +#ifdef ECP_WITH_MSGQ ecp_seq_t seq_offset; int _rv = ECP_OK; @@ -24,14 +29,14 @@ 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 + } 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; - if (flags & ECP_RBUF_FLAG_SYS) ecp_msg_handle(conn, seq, msg, msg_size, b); + if (flags & ECP_RBUF_FLAG_SYS) ecp_conn_handle_msg(conn, seq, msg, msg_size, b); return rv; } @@ -62,9 +67,10 @@ static void msg_flush(ECPConnection *conn, ECP2Buffer *b) { ecp_seq_t seq = buf->rbuf.seq_start + i; unsigned char frag_tot; unsigned char frag_cnt; + uint16_t frag_size; int rv; - rv = ecp_msg_get_frag(buf->rbuf.msg[idx].msg, buf->rbuf.msg[idx].size, &frag_cnt, &frag_tot); + rv = ecp_msg_get_frag(buf->rbuf.msg[idx].msg, buf->rbuf.msg[idx].size, &frag_cnt, &frag_tot, &frag_size); if (!rv && (frag_cnt != 0) && (seq != seq_next)) { ecp_seq_t seq_fend = seq + (ecp_seq_t)(frag_tot - frag_cnt - 1); @@ -98,12 +104,16 @@ static void msg_flush(ECPConnection *conn, ECP2Buffer *b) { seq_next = seq + 1; if (buf->flags & ECP_RBUF_FLAG_MSGQ) { #ifdef ECP_WITH_MSGQ - rv = ecp_conn_msgq_push(conn, seq, ecp_msg_get_type(buf->rbuf.msg[idx].msg)); + unsigned char mtype; + + rv = ecp_msg_get_type(buf->rbuf.msg[idx].msg, buf->rbuf.msg[idx].size, &mtype); + if (!rv) rv = ecp_conn_msgq_push(conn, seq, mtype); if (rv) break; + buf->rbuf.msg[idx].flags |= ECP_RBUF_FLAG_IN_MSGQ; #endif } else { - ecp_msg_handle(conn, seq, buf->rbuf.msg[idx].msg, buf->rbuf.msg[idx].size, b); + 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; @@ -132,7 +142,7 @@ static int ack_send(ECPConnection *conn) { ECPBuffer payload; unsigned char pkt_buf[ECP_SIZE_PKT_BUF(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK, conn)]; unsigned char pld_buf[ECP_SIZE_PLD_BUF(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK, conn)]; - unsigned char *buf_ = ecp_pld_get_buf(pld_buf, ECP_MTYPE_RBACK); + unsigned char *_buf; ssize_t rv; packet.buffer = pkt_buf; @@ -140,15 +150,16 @@ static int ack_send(ECPConnection *conn) { payload.buffer = pld_buf; payload.size = ECP_SIZE_PLD_BUF(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK, conn); - ecp_pld_set_type(pld_buf, ECP_MTYPE_RBACK); - buf_[0] = (buf->seq_ack & 0xFF000000) >> 24; - buf_[1] = (buf->seq_ack & 0x00FF0000) >> 16; - buf_[2] = (buf->seq_ack & 0x0000FF00) >> 8; - buf_[3] = (buf->seq_ack & 0x000000FF); - buf_[4] = (buf->ack_map & 0xFF000000) >> 24; - buf_[5] = (buf->ack_map & 0x00FF0000) >> 16; - buf_[6] = (buf->ack_map & 0x0000FF00) >> 8; - buf_[7] = (buf->ack_map & 0x000000FF); + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_RBACK); + _buf = ecp_pld_get_buf(payload.buffer, payload.size); + _buf[0] = (buf->seq_ack & 0xFF000000) >> 24; + _buf[1] = (buf->seq_ack & 0x00FF0000) >> 16; + _buf[2] = (buf->seq_ack & 0x0000FF00) >> 8; + _buf[3] = (buf->seq_ack & 0x000000FF); + _buf[4] = (buf->ack_map & 0xFF000000) >> 24; + _buf[5] = (buf->ack_map & 0x00FF0000) >> 16; + _buf[6] = (buf->ack_map & 0x0000FF00) >> 8; + _buf[7] = (buf->ack_map & 0x000000FF); rv = ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK), 0, 0); if (rv < 0) return rv; @@ -258,12 +269,12 @@ int ecp_rbuf_recv_start(ECPConnection *conn, ecp_seq_t seq) { rv = ecp_rbuf_start(&buf->rbuf, seq); if (rv) return rv; -#ifdef ECP_WITH_MSGQ if (buf->flags & ECP_RBUF_FLAG_MSGQ) { +#ifdef ECP_WITH_MSGQ rv = ecp_conn_msgq_start(&buf->msgq, seq); if (rv) return rv; - } #endif + } return ECP_OK; } @@ -290,10 +301,14 @@ ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *m ECPRBRecv *buf = conn->rbuf.recv; ecp_seq_t ack_pkt = 0; ssize_t rv; + int _rv; unsigned char mtype; - mtype = ecp_msg_get_type(msg) & ECP_MTYPE_MASK; - if ((mtype == ECP_MTYPE_RBACK) || (mtype == ECP_MTYPE_RBFLUSH)) return ecp_msg_handle(conn, seq, msg, msg_size, b); + _rv = ecp_msg_get_type(msg, msg_size, &mtype); + if (_rv) return _rv; + + mtype &= ECP_MTYPE_MASK; + if ((mtype == ECP_MTYPE_RBACK) || (mtype == ECP_MTYPE_RBFLUSH)) return ecp_conn_handle_msg(conn, seq, msg, msg_size, b); if (ECP_SEQ_LT(buf->rbuf.seq_max, seq)) { ack_pkt = seq - buf->rbuf.seq_max; @@ -321,7 +336,7 @@ ssize_t ecp_rbuf_recv_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *m rv = msg_store(conn, seq, msg, msg_size, b); if (rv < 0) return rv; } else { - ecp_msg_handle(conn, seq, msg, msg_size, b); + ecp_conn_handle_msg(conn, seq, msg, msg_size, b); rv = msg_size; buf->rbuf.seq_max++; buf->rbuf.seq_start++; diff --git a/ecp/src/rbuf_send.c b/ecp/src/rbuf_send.c index 13b314e..a680285 100644 --- a/ecp/src/rbuf_send.c +++ b/ecp/src/rbuf_send.c @@ -14,7 +14,7 @@ static ssize_t flush_send(ECPConnection *conn, ECPTimerItem *ti) { payload.buffer = pld_buf; payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_RBFLUSH, conn); - ecp_pld_set_type(pld_buf, ECP_MTYPE_RBFLUSH); + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_RBFLUSH); if (ti == NULL) { ECPTimerItem _ti; int rv; @@ -153,7 +153,7 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt payload.buffer = pld_buf; payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_NOP, conn); - ecp_pld_set_type(pld_buf, ECP_MTYPE_NOP); + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_NOP); ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_NOP), 0, seq_ack + i); } else { ECPBuffer packet; @@ -305,12 +305,14 @@ int ecp_rbuf_send_flush(ECPConnection *conn) { } 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 - int idx = ecp_rbuf_msg_idx(&buf->rbuf, si->seq); + idx = ecp_rbuf_msg_idx(&buf->rbuf, si->seq); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&buf->mutex); #endif diff --git a/ecp/src/vconn/vconn.c b/ecp/src/vconn/vconn.c index a4109a8..286a79a 100644 --- a/ecp/src/vconn/vconn.c +++ b/ecp/src/vconn/vconn.c @@ -81,15 +81,15 @@ static ssize_t _vconn_send_open(ECPConnection *conn, ECPTimerItem *ti) { payload.buffer = pld_buf; payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn); - ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REQ); - return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti); + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KGET_REQ); + 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) { ECPTimerItem ti; ECPVConnection *conn_v = (ECPVConnection *)conn; ECPConnection *conn_next = conn_v->next; - ssize_t rv + ssize_t rv; if (conn_next == NULL) return ECP_ERR; @@ -195,7 +195,7 @@ static ssize_t vconn_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned c payload.buffer = msg - ECP_SIZE_PLD_HDR - 1; payload.size = b->payload->size - (payload.buffer - b->payload->buffer); - ecp_pld_set_type(payload.buffer, ECP_MTYPE_EXEC); + 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 @@ -259,7 +259,7 @@ static ssize_t _vlink_send_open(ECPConnection *conn, ECPTimerItem *ti) { ECPBuffer payload; unsigned char pkt_buf[ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ, conn)]; unsigned char pld_buf[ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ, conn)]; - unsigned char *buf = ecp_pld_get_buf(pld_buf, ECP_MTYPE_OPEN_REQ); + unsigned char *buf; packet.buffer = pkt_buf; packet.size = ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ, conn); @@ -267,7 +267,8 @@ static ssize_t _vlink_send_open(ECPConnection *conn, ECPTimerItem *ti) { payload.size = ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ, conn); // XXX server should verify perma_key - ecp_pld_set_type(pld_buf, ECP_MTYPE_OPEN_REQ); + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_OPEN_REQ); + buf = ecp_pld_get_buf(payload.buffer, payload.size); buf[0] = conn->type; memcpy(buf+1, ecp_cr_dh_pub_get_buf(&sock->key_perma.public), ECP_ECDH_SIZE_KEY); @@ -367,7 +368,7 @@ static ssize_t vlink_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned c payload.buffer = msg - ECP_SIZE_PLD_HDR - 1; payload.size = b->payload->size - (payload.buffer - b->payload->buffer); - ecp_pld_set_type(payload.buffer, ECP_MTYPE_EXEC); + 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 @@ -393,8 +394,8 @@ static ssize_t vconn_set_msg(ECPConnection *conn, ECPBuffer *payload, unsigned c if (payload->size < ECP_SIZE_PLD_HDR + 3 + 2 * ECP_ECDH_SIZE_KEY) return ECP_ERR; if (conn_next == NULL) return ECP_ERR; - ecp_pld_set_type(payload->buffer, ECP_MTYPE_OPEN_REQ); - buf = ecp_pld_get_buf(payload->buffer, 0); + ecp_pld_set_type(payload->buffer, payload->size, ECP_MTYPE_OPEN_REQ); + buf = ecp_pld_get_buf(payload->buffer, payload->size); buf[0] = ECP_CTYPE_VCONN; rv = ecp_conn_dhkey_get_curr(conn_next, NULL, buf+1); @@ -407,104 +408,138 @@ static ssize_t vconn_set_msg(ECPConnection *conn, ECPBuffer *payload, unsigned c } else { if (payload->size < ECP_SIZE_PLD_HDR + 1) return ECP_ERR; - ecp_pld_set_type(payload->buffer, ECP_MTYPE_RELAY); + ecp_pld_set_type(payload->buffer, payload->size, ECP_MTYPE_RELAY); return ECP_SIZE_PLD_HDR + 1; } } -/* Memory limited version: */ -ssize_t ecp_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr) { +#ifdef ECP_MEM_TINY +/* Memory limited version */ + +ssize_t ecp_pack(ECPContext *ctx, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) { if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR; if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR; - if (conn->parent) { - unsigned char mtype = ecp_pld_get_type(payload->buffer); - ssize_t rv, hdr_size = vconn_set_msg(conn->parent, packet, mtype); + if (parent) { + unsigned char mtype; + ssize_t rv, hdr_size; + int _rv; + + _rv = ecp_pld_get_type(payload->buffer, payload->size, &mtype); + if (_rv) return _rv; + + hdr_size = vconn_set_msg(parent, packet, mtype); if (hdr_size < 0) return hdr_size; - rv = ecp_conn_pack(conn, packet->buffer+hdr_size, packet->size-hdr_size, s_idx, c_idx, payload->buffer, pld_size, si, NULL); + rv = _ecp_pack(ctx, packet->buffer+hdr_size, packet->size-hdr_size, pkt_meta, payload->buffer, pld_size); if (rv < 0) return rv; if (payload->size < rv+hdr_size) return ECP_ERR; memcpy(payload->buffer, packet->buffer, rv+hdr_size); - return ecp_pack(conn->parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, rv+hdr_size, NULL, addr); + return ecp_pack_conn(parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, NULL, payload, rv+hdr_size, addr); } else { - return ecp_conn_pack(conn, packet->buffer, packet->size, s_idx, c_idx, payload->buffer, pld_size, si, addr); + return _ecp_pack(ctx, packet->buffer, packet->size, pkt_meta, payload->buffer, pld_size); } } -ssize_t ecp_pack_raw(ECPSocket *sock, ECPConnection *parent, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) { - ECPContext *ctx = sock->ctx; +#else +ssize_t ecp_pack(ECPContext *ctx, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) { if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR; if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR; if (parent) { - unsigned char mtype = ecp_pld_get_type(payload->buffer); - ssize_t rv, hdr_size = vconn_set_msg(parent, packet, mtype); + ECPBuffer _payload; + unsigned char pld_buf[ECP_MAX_PLD]; + unsigned char mtype; + ssize_t rv, hdr_size; + int _rv; + + _payload.buffer = pld_buf; + _payload.size = ECP_MAX_PLD; + + _rv = ecp_pld_get_type(payload->buffer, payload->size, &mtype); + if (_rv) return _rv; + + hdr_size = vconn_set_msg(parent, &_payload, mtype); if (hdr_size < 0) return hdr_size; - rv = ecp_pkt_pack(ctx, packet->buffer+hdr_size, packet->size-hdr_size, s_idx, c_idx, public, shsec, nonce, seq, payload->buffer, pld_size); + rv = _ecp_pack(ctx, _payload.buffer+hdr_size, _payload.size-hdr_size, pkt_meta, payload->buffer, pld_size); if (rv < 0) return rv; - if (payload->size < rv+hdr_size) return ECP_ERR; - memcpy(payload->buffer, packet->buffer, rv+hdr_size); - - return ecp_pack(parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, rv+hdr_size, NULL, addr); + return ecp_pack_conn(parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, NULL, &_payload, rv+hdr_size, addr); } else { - return ecp_pkt_pack(ctx, packet->buffer, packet->size, s_idx, c_idx, public, shsec, nonce, seq, payload->buffer, pld_size); + return _ecp_pack(ctx, packet->buffer, packet->size, pkt_meta, payload->buffer, pld_size); } } -/* Non memory limited version: */ -/* -static ssize_t ecp_pack(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPSeqItem *si, ECPNetAddr *addr) { +#endif + +#ifdef ECP_MEM_TINY +/* Memory limited version */ + +ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPSeqItem *si, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) { + if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR; + if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR; + if (conn->parent) { - ECPBuffer payload_; - unsigned char pld_buf[ECP_MAX_PLD]; + unsigned char mtype; + ssize_t rv, hdr_size; + int _rv; - payload_.buffer = pld_buf; - payload_.size = ECP_MAX_PLD; + _rv = ecp_pld_get_type(payload->buffer, payload->size, &mtype); + if (_rv) return _rv; - unsigned char mtype = ecp_pld_get_type(payload->buffer); - ssize_t rv, hdr_size = vconn_set_msg(conn->parent, &payload_, mtype); + hdr_size = vconn_set_msg(conn->parent, packet, mtype); if (hdr_size < 0) return hdr_size; - rv = ecp_conn_pack(conn, payload_.buffer+hdr_size, payload_.size-hdr_size, s_idx, c_idx, payload->buffer, pld_size, si, NULL); + rv = _ecp_pack_conn(conn, packet->buffer+hdr_size, packet->size-hdr_size, s_idx, c_idx, si, payload->buffer, pld_size, NULL); if (rv < 0) return rv; - return ecp_pack(conn->parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &payload_, rv+hdr_size, NULL, addr); + if (payload->size < rv+hdr_size) return ECP_ERR; + memcpy(payload->buffer, packet->buffer, rv+hdr_size); + + return ecp_pack_conn(conn->parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, NULL, payload, rv+hdr_size, addr); } else { - return ecp_conn_pack(conn, packet->buffer, packet->size, s_idx, c_idx, payload->buffer, pld_size, si, addr); + return _ecp_pack_conn(conn, packet->buffer, packet->size, s_idx, c_idx, si, payload->buffer, pld_size, addr); } } -static ssize_t ecp_pack_raw(ECPSocket *sock, ECPConnection *parent, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, ecp_seq_t seq, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) { - ECPContext *ctx = sock->ctx; +#else - if (parent) { - ECPBuffer payload_; +ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPSeqItem *si, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) { + if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR; + if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR; + + if (conn->parent) { + ECPBuffer _payload; unsigned char pld_buf[ECP_MAX_PLD]; + unsigned char mtype; + ssize_t rv, hdr_size; + int _rv; - payload_.buffer = pld_buf; - payload_.size = ECP_MAX_PLD; + _payload.buffer = pld_buf; + _payload.size = ECP_MAX_PLD; - unsigned char mtype = ecp_pld_get_type(payload->buffer); - ssize_t rv, hdr_size = vconn_set_msg(parent, &payload_, mtype); + _rv = ecp_pld_get_type(payload->buffer, payload->size, &mtype); + if (_rv) return _rv; + + hdr_size = vconn_set_msg(conn->parent, &_payload, mtype); if (hdr_size < 0) return hdr_size; - rv = ecp_pkt_pack(ctx, payload_.buffer+hdr_size, payload_.size-hdr_size, s_idx, c_idx, public, shsec, nonce, seq, payload->buffer, pld_size); + rv = _ecp_pack_conn(conn, _payload.buffer+hdr_size, _payload.size-hdr_size, s_idx, c_idx, si, payload->buffer, pld_size, NULL); if (rv < 0) return rv; - return ecp_pack(parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &payload_, rv+hdr_size, NULL, addr); + return ecp_pack_conn(conn->parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, NULL, &_payload, rv+hdr_size, addr); } else { - return ecp_pkt_pack(ctx, packet->buffer, packet->size, s_idx, c_idx, public, shsec, nonce, seq, payload->buffer, pld_size); + return _ecp_pack_conn(conn, packet->buffer, packet->size, s_idx, c_idx, si, payload->buffer, pld_size, addr); } } -*/ + +#endif int ecp_vconn_ctx_init(ECPContext *ctx) { int rv; @@ -614,8 +649,8 @@ static ssize_t _vconn_send_kget(ECPConnection *conn, ECPTimerItem *ti) { payload.buffer = pld_buf; payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn); - ecp_pld_set_type(pld_buf, ECP_MTYPE_KGET_REQ); - return ecp_pld_send_ll(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti); + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KGET_REQ); + 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) { diff --git a/ecp/test/basic.c b/ecp/test/basic.c index 8268599..eb14b0e 100644 --- a/ecp/test/basic.c +++ b/ecp/test/basic.c @@ -65,8 +65,8 @@ int main(int argc, char *argv[]) { handler_s.msg[MTYPE_MSG] = handle_msg_s; ctx_s.handler[CTYPE_TEST] = &handler_s; - rv = ecp_dhkey_generate(&ctx_s, &key_perma_s); - printf("ecp_dhkey_generate RV:%d\n", rv); + 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); @@ -85,8 +85,8 @@ int main(int argc, char *argv[]) { handler_c.msg[MTYPE_MSG] = handle_msg_c; ctx_c.handler[CTYPE_TEST] = &handler_c; - rv = ecp_dhkey_generate(&ctx_c, &key_perma_c); - printf("ecp_dhkey_generate RV:%d\n", rv); + 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); diff --git a/ecp/test/frag.c b/ecp/test/frag.c index 2bba856..bf7c1a2 100644 --- a/ecp/test/frag.c +++ b/ecp/test/frag.c @@ -71,8 +71,8 @@ int main(int argc, char *argv[]) { handler_s.msg[MTYPE_MSG] = handle_msg_s; ctx_s.handler[CTYPE_TEST] = &handler_s; - rv = ecp_dhkey_generate(&ctx_s, &key_perma_s); - printf("ecp_dhkey_generate RV:%d\n", rv); + 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); @@ -91,8 +91,8 @@ int main(int argc, char *argv[]) { handler_c.msg[MTYPE_MSG] = handle_msg_c; ctx_c.handler[CTYPE_TEST] = &handler_c; - rv = ecp_dhkey_generate(&ctx_c, &key_perma_c); - printf("ecp_dhkey_generate RV:%d\n", rv); + 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); diff --git a/ecp/test/stress.c b/ecp/test/stress.c index 73c511e..4dae990 100644 --- a/ecp/test/stress.c +++ b/ecp/test/stress.c @@ -93,7 +93,7 @@ void *sender(ECPConnection *c) { c->sock->ctx->rng(&rnd, sizeof(uint32_t)); usleep(rnd % (2000000/msg_rate)); - ecp_pld_set_type(pld_buf, MTYPE_MSG); + ecp_pld_set_type(payload.buffer, payload.size, MTYPE_MSG); ssize_t _rv = 0; // XXX refactor // _rv = ecp_pld_send(c, &packet, &payload, ECP_SIZE_PLD(1000, 0)); @@ -138,7 +138,7 @@ ssize_t handle_msg_c(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigne pthread_mutex_unlock(&t_mtx[idx]); } - // ecp_pld_set_type(payload, MTYPE_MSG); + // ecp_pld_set_type(payload.buffer, payload.size, MTYPE_MSG); // ssize_t _rv = ecp_pld_send(c, &packet, &payload, ECP_SIZE_PLD(1000, 0)); return s; } @@ -154,7 +154,7 @@ ssize_t handle_msg_s(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigne payload.buffer = pld_buf; payload.size = ECP_MAX_PLD; - ecp_pld_set_type(pld_buf, MTYPE_MSG); + ecp_pld_set_type(payload.buffer, payload.size, MTYPE_MSG); // XXX refactor // ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(1000, 0)); return s; @@ -199,7 +199,7 @@ int main(int argc, char *argv[]) { handler_s.msg[MTYPE_MSG] = handle_msg_s; ctx_s.handler[CTYPE_TEST] = &handler_s; - if (!rv) rv = ecp_dhkey_generate(&ctx_s, &key_perma_s); + 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); @@ -229,7 +229,7 @@ int main(int argc, char *argv[]) { if (!rv) rv = ecp_init(&ctx_c[i]); ctx_c[i].handler[CTYPE_TEST] = &handler_c; - if (!rv) rv = ecp_dhkey_generate(&ctx_c[i], &key_perma_c[i]); + 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_open(&sock_c[i], NULL); diff --git a/ecp/util/mknode.c b/ecp/util/mknode.c index 882c58d..0c262fe 100644 --- a/ecp/util/mknode.c +++ b/ecp/util/mknode.c @@ -45,7 +45,7 @@ int main(int argc, char *argv[]) { if (rv) goto err; ctx.rng = v_rng; - rv = ecp_dhkey_generate(&ctx, &key); + rv = ecp_dhkey_gen(&ctx, &key); if (rv) goto err; rv = ecp_node_init(&node, &key.public, (argc == 3) ? argv[2] : NULL); |