diff options
-rw-r--r-- | code/Makefile | 4 | ||||
-rw-r--r-- | code/TODO | 6 | ||||
-rw-r--r-- | code/core.c | 641 | ||||
-rw-r--r-- | code/core.h | 113 | ||||
-rw-r--r-- | code/init.c | 2 | ||||
-rw-r--r-- | code/msgq.c | 59 | ||||
-rw-r--r-- | code/msgq.h | 14 | ||||
-rw-r--r-- | code/test/Makefile | 2 | ||||
-rw-r--r-- | code/test/server.c | 46 | ||||
-rw-r--r-- | code/test/stress.c | 53 | ||||
-rw-r--r-- | code/timer.c | 44 | ||||
-rw-r--r-- | code/timer.h | 12 |
12 files changed, 554 insertions, 442 deletions
diff --git a/code/Makefile b/code/Makefile index 023fa7a..be1a827 100644 --- a/code/Makefile +++ b/code/Makefile @@ -1,12 +1,12 @@ MAKE=make CFLAGS = -I. -pthread -O3 -DECP_DEBUG -obj = core.o timer.o msgq.o init.o +obj = core.o timer.o msgq.o subdirs = crypto posix htable test %.o: %.c %.h $(CC) $(CFLAGS) -c $< -all: $(obj) +all: $(obj) init.o init_proxy.o $(AR) rcs libecpcore.a $(obj) for i in $(subdirs); do \ (cd $$i && $(MAKE) && cd ..) || exit; \ @@ -3,3 +3,9 @@ - memzero keys after usage - implement socket message queue + +proxy: +- implement init +core: +- msgq marker +- implement exec diff --git a/code/core.c b/code/core.c index ced4c01..821487e 100644 --- a/code/core.c +++ b/code/core.c @@ -22,29 +22,6 @@ int ecp_node_init(ECPContext *ctx, ECPNode *node, void *addr, ecp_dh_public_t *p return ECP_OK; } -ssize_t ecp_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, unsigned char *seq, unsigned char *payload, size_t payload_size) { - ssize_t rv; - - if (packet == NULL) return ECP_ERR; - if (payload == NULL) return ECP_ERR; - - packet[0] = 0; - packet[1] = 0; - s_idx = s_idx & 0x0F; - c_idx = c_idx & 0x0F; - packet[ECP_SIZE_PROTO] = (s_idx << 4) | c_idx; - ctx->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); - - memcpy(payload, seq, ECP_SIZE_SEQ); - rv = ctx->cr.aead_enc(packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, payload, payload_size, shsec, packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY); - if (rv < 0) return ECP_ERR_ENCRYPT; - - memcpy(nonce, packet+ECP_SIZE_PKT_HDR, ECP_AEAD_SIZE_NONCE); - - return rv+ECP_SIZE_PKT_HDR; -} - int ecp_ctx_create(ECPContext *ctx) { int rv; @@ -184,10 +161,6 @@ static ECPConnection *ctable_search(ECPSocket *sock, unsigned char c_idx, unsign return NULL; } -static ssize_t conn_handle_open(ECPConnection *conn, unsigned char ptype, unsigned char *payload, ssize_t size); -static ssize_t conn_handle_kget(ECPConnection *conn, unsigned char ptype, unsigned char *payload, ssize_t size); -static ssize_t conn_handle_kput(ECPConnection *conn, unsigned char ptype, unsigned char *payload, ssize_t size); - int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) { int rv = ECP_OK; @@ -200,9 +173,7 @@ int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) { sock->poll_timeout = ECP_POLL_TIMEOUT; sock->key_curr = 0; sock->key_perma = *key; - sock->handler[ECP_PTYPE_OPEN] = conn_handle_open; - sock->handler[ECP_PTYPE_KGET] = conn_handle_kget; - sock->handler[ECP_PTYPE_KPUT] = conn_handle_kput; + sock->conn_new = ecp_conn_handle_new; rv = ecp_dhkey_generate(sock->ctx, &sock->key[sock->key_curr]); if (!rv) rv = ctable_create(&sock->conn, sock->ctx); @@ -246,7 +217,7 @@ int ecp_sock_dhkey_get_curr(ECPSocket *sock, unsigned char *idx, unsigned char * pthread_mutex_lock(&sock->mutex); #endif - *idx = sock->key_curr; + if (idx) *idx = sock->key_curr; if (*idx != ECP_ECDH_IDX_INV) sock->ctx->cr.dh_pub_to_buf(public, &sock->key[sock->key_curr].public); #ifdef ECP_WITH_PTHREAD @@ -425,148 +396,7 @@ static int conn_shsec_set(ECPConnection *conn, unsigned char s_idx, unsigned cha return ECP_OK; } - -static int conn_new(ECPConnection **_conn, ECPSocket *sock, unsigned char s_idx, unsigned char c_idx, unsigned char *c_public, ecp_aead_key_t *shsec, unsigned char *payload, size_t payload_size) { - ECPConnection *conn = NULL; - int rv = ECP_OK; - - if (_conn == NULL) return ECP_ERR; - if (sock == NULL) return ECP_ERR; - - conn = sock->ctx->conn_alloc ? sock->ctx->conn_alloc() : NULL; - if (conn == NULL) return ECP_ERR_ALLOC; - - rv = ecp_conn_create(conn, sock); - if (rv) { - if (sock->ctx->conn_free) sock->ctx->conn_free(conn); - return rv; - } - conn->refcount = 1; - rv = conn_dhkey_new_pub_local(conn, s_idx); - if (!rv) rv = conn_dhkey_new_pub_remote(conn, c_idx, c_public); - if (!rv) rv = conn_shsec_set(conn, s_idx, c_idx, shsec); - if (!rv && sock->conn_create) rv = sock->conn_create(conn, payload, payload_size); - 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 (sock->conn_destroy) sock->conn_destroy(conn); - ecp_conn_destroy(conn); - if (sock->ctx->conn_free) sock->ctx->conn_free(conn); - return rv; - } - - *_conn = conn; - return rv; -} - -static ssize_t conn_handle_open(ECPConnection *conn, unsigned char ptype, unsigned char *payload, ssize_t size) { - ecp_conn_handler_t *handler = conn->handler ? conn->handler->f[ptype] : NULL; - - if (conn->out) { - if (size < 0) return handler ? handler(conn, ptype, payload, size) : 0; - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&conn->mutex); -#endif - if (!ecp_conn_is_open(conn)) conn->flags |= ECP_CONN_FLAG_OPEN; -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&conn->mutex); -#endif - - return handler ? handler(conn, ptype, payload, size) : 0; - } else { - if (size < 0) return ECP_ERR; - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&conn->mutex); -#endif - if (!ecp_conn_is_open(conn)) conn->flags |= ECP_CONN_FLAG_OPEN; -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&conn->mutex); -#endif - - ssize_t _rv = ecp_send(conn, ECP_PTYPE_OPEN, NULL, 0); - - return handler ? handler(conn, ptype, payload, size) : 0; - } - - return ECP_ERR; -} - -static ssize_t conn_handle_kget(ECPConnection *conn, unsigned char ptype, unsigned char *payload, ssize_t size) { - ecp_conn_handler_t *handler = conn->handler ? conn->handler->f[ptype] : NULL; - - if (conn->out) { -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&conn->mutex); -#endif - int conn_is_open = ecp_conn_is_open(conn); -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&conn->mutex); -#endif - - if (size < 0) { - if (!conn_is_open) handler = conn->handler ? conn->handler->f[ECP_PTYPE_OPEN] : handler; - return handler ? handler(conn, ptype, payload, size) : 0; - } - - if (size < ECP_ECDH_SIZE_KEY+1) return ECP_ERR; - - int rv = ecp_conn_dhkey_new_pub(conn, payload[0], payload+1); - if (!rv && !conn_is_open) { - ECPTimerItem ti; - ssize_t _rv = 0; - - rv = ecp_timer_item_init(&ti, conn, ECP_PTYPE_OPEN, 3, 500); - if (!rv) rv = ecp_timer_push(conn, &ti); - if (!rv) _rv = ecp_send(conn, ECP_PTYPE_OPEN, NULL, 0); - if (_rv < 0) rv = _rv; - } - - return handler ? handler(conn, ptype, rv ? NULL : payload, rv ? rv : size) : ECP_ECDH_SIZE_KEY+1; - } else { - unsigned char payload[ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1)]; - unsigned char *buf = ecp_pld_get_buf(payload); - ecp_pld_set_type(payload, ECP_PTYPE_KGET); - - if (size < 0) return ECP_ERR; - - int rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1); - if (rv) return rv; - - ssize_t _rv = ecp_pld_send(conn, payload, sizeof(payload)); - - return handler ? handler(conn, ptype, payload, size) : 0; - } - - return ECP_ERR; -} - -static ssize_t conn_handle_kput(ECPConnection *conn, unsigned char ptype, unsigned char *payload, ssize_t size) { - ecp_conn_handler_t *handler = conn->handler ? conn->handler->f[ptype] : NULL; - - if (conn->out) { - return handler ? handler(conn, ptype, payload, size) : 0; - } else { - if (size < ECP_ECDH_SIZE_KEY+1) return ECP_ERR; - - int rv = ecp_conn_dhkey_new_pub(conn, payload[0], payload+1); - if (rv) return rv; - - ssize_t _rv = ecp_send(conn, ECP_PTYPE_KPUT, NULL, 0); - - return handler ? handler(conn, ptype, payload, size) : ECP_ECDH_SIZE_KEY+1; - } - - return ECP_ERR; -} - -int ecp_conn_create(ECPConnection *conn, ECPSocket *sock) { +int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) { int i; if (conn == NULL) return ECP_ERR; @@ -574,6 +404,9 @@ int ecp_conn_create(ECPConnection *conn, ECPSocket *sock) { memset(conn, 0, sizeof(ECPConnection)); + if (ctype >= ECP_MAX_CTYPE) return ECP_ERR_MAX_CTYPE; + + conn->type = ctype; conn->key_curr = ECP_ECDH_IDX_INV; conn->key_idx_curr = ECP_ECDH_IDX_INV; conn->remote.key_curr = ECP_ECDH_IDX_INV; @@ -623,9 +456,8 @@ int ecp_conn_register(ECPConnection *conn) { return rv; } -int ecp_conn_unregister(ECPConnection *conn, unsigned int timeout) { +void ecp_conn_unregister(ECPConnection *conn) { ECPSocket *sock = conn->sock; - int refcount = 0; #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&sock->conn.mutex); @@ -639,7 +471,57 @@ int ecp_conn_unregister(ECPConnection *conn, unsigned int timeout) { pthread_mutex_unlock(&conn->mutex); pthread_mutex_unlock(&sock->conn.mutex); #endif +} + +static ssize_t _conn_send_kget(ECPConnection *conn, ECPTimerItem *ti) { + unsigned char payload[ECP_SIZE_PLD(0)]; + ecp_pld_set_type(payload, ECP_MTYPE_KGET); + return ecp_pld_send_wkey(conn, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, payload, sizeof(payload)); +} + +int ecp_conn_init(ECPConnection *conn, ECPNode *node) { + ECPDHKey key; + ECPContext *ctx = conn->sock->ctx; + int rv = ECP_OK; + + if (conn == NULL) return ECP_ERR; + if (node == NULL) return ECP_ERR; + if (ctx->rng == NULL) return ECP_ERR_RNG; + + conn->out = 1; + conn->node = *node; + rv = ctx->rng(conn->nonce, ECP_AEAD_SIZE_NONCE); + if (!rv) rv = ecp_dhkey_generate(ctx, &key); + 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 = ecp_conn_init(conn, node); + if (rv) return rv; + + ssize_t _rv = ecp_timer_send(conn, _conn_send_kget, ECP_MTYPE_KGET, 3, 500); + if (_rv < 0) { + ecp_conn_unregister(conn); + return _rv; + } + + return ECP_OK; +} + +int ecp_conn_close(ECPConnection *conn, unsigned int timeout) { + ECPSocket *sock = conn->sock; + int refcount = 0; + + if (!conn->out) { + ecp_conn_destroy_t *handler = conn->sock->ctx->handler[conn->type] ? conn->sock->ctx->handler[conn->type]->conn_destroy : NULL; + if (handler) handler(conn); + if (sock->conn_destroy) sock->conn_destroy(conn); + } + ecp_conn_unregister(conn); ecp_timer_remove(conn); #ifdef ECP_WITH_PTHREAD @@ -657,91 +539,223 @@ int ecp_conn_unregister(ECPConnection *conn, unsigned int timeout) { if (refcount) return ECP_ERR_TIMEOUT; #endif + if (!conn->out) { + if (conn->proxy) { +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->proxy->mutex); +#endif + conn->proxy->refcount--; +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->proxy->mutex); +#endif + } + ecp_conn_destroy(conn); + if (sock->ctx->conn_free) sock->ctx->conn_free(conn); + } + return ECP_OK; } -static int _conn_kget_send(ECPConnection *conn, ECPTimerItem *ti) { - unsigned char payload[ECP_MIN_PLD]; - ecp_pld_set_type(payload, ECP_PTYPE_KGET); - ssize_t rv = ecp_pld_send_wkey(conn, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, payload, sizeof(payload)); - if (rv < 0) return rv; +int ecp_conn_handler_init(ECPConnHandler *handler) { + memset(handler, 0, sizeof(ECPConnHandler)); + handler->msg[ECP_MTYPE_OPEN] = ecp_conn_handle_open; + handler->msg[ECP_MTYPE_KGET] = ecp_conn_handle_kget; + handler->msg[ECP_MTYPE_KPUT] = ecp_conn_handle_kput; + handler->conn_open = ecp_conn_send_open; return ECP_OK; } -int ecp_conn_open(ECPConnection *conn, ECPNode *node, ECPConnHandler *handler) { +static ssize_t _conn_send_open(ECPConnection *conn, ECPTimerItem *ti) { + unsigned char payload[ECP_SIZE_PLD(1)]; + unsigned char *buf = ecp_pld_get_buf(payload); + + ecp_pld_set_type(payload, ECP_MTYPE_OPEN); + buf[0] = conn->type; + + return ecp_pld_send(conn, payload, sizeof(payload)); +} + +ssize_t ecp_conn_send_open(ECPConnection *conn) { + return ecp_timer_send(conn, _conn_send_open, ECP_MTYPE_OPEN, 3, 500); +} + +int ecp_conn_handle_new(ECPSocket *sock, ECPConnection **_conn, ECPConnection *proxy, unsigned char s_idx, unsigned char c_idx, unsigned char *c_public, ecp_aead_key_t *shsec, unsigned char *payload, size_t payload_size) { + ECPConnection *conn = NULL; int rv = ECP_OK; - ECPDHKey key; - ECPContext *ctx = conn->sock->ctx; + unsigned char ctype = 0; + ecp_conn_create_t *handle_create = NULL; + ecp_conn_destroy_t *handle_destroy = NULL; - if (conn == NULL) return ECP_ERR; - if (node == NULL) return ECP_ERR; - if (ctx->rng == NULL) return ECP_ERR_RNG; + if (payload_size < 1) return ECP_ERR; + + conn = sock->ctx->conn_alloc ? sock->ctx->conn_alloc(ctype) : NULL; + if (conn == NULL) return ECP_ERR_ALLOC; - conn->out = 1; - conn->node = *node; - conn->handler = handler; - rv = ctx->rng(conn->nonce, ECP_AEAD_SIZE_NONCE); - if (!rv) rv = ecp_dhkey_generate(ctx, &key); - 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); - if (rv) return rv; + ctype = payload[0]; + rv = ecp_conn_create(conn, sock, ctype); + if (rv) { + if (sock->ctx->conn_free) sock->ctx->conn_free(conn); + return rv; + } - rv = ecp_timer_send(conn, _conn_kget_send, ECP_PTYPE_KGET, 3, 500); + conn->refcount = 1; + conn->type = ctype; + conn->proxy = proxy; + 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; + + rv = conn_dhkey_new_pub_local(conn, s_idx); + if (!rv) rv = conn_dhkey_new_pub_remote(conn, c_idx, c_public); + if (!rv) rv = conn_shsec_set(conn, s_idx, c_idx, shsec); + if (!rv && sock->conn_create) rv = sock->conn_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; + } + if (handle_create) rv = handle_create(conn, payload+1, payload_size-1); if (rv) { - ecp_conn_unregister(conn, 0); + if (sock->conn_destroy) sock->conn_destroy(conn); + ecp_conn_destroy(conn); + if (sock->ctx->conn_free) sock->ctx->conn_free(conn); return rv; } - return ECP_OK; -} + rv = ecp_conn_register(conn); + if (rv) { + if (handle_destroy) handle_destroy(conn); + if (sock->conn_destroy) sock->conn_destroy(conn); + ecp_conn_destroy(conn); + if (sock->ctx->conn_free) sock->ctx->conn_free(conn); + return rv; + } -int ecp_conn_close(ECPConnection *conn, unsigned int timeout) { - return ecp_conn_unregister(conn, timeout); -} + if (proxy) { +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&proxy->mutex); +#endif + proxy->refcount++; +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&proxy->mutex); +#endif + } -int ecp_conn_hander_init(ECPConnHandler *handler) { - memset(handler, 0, sizeof(ECPConnHandler)); - return ECP_OK; + *_conn = conn; + return rv; } -int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned char *public) { - ECPSocket *sock = conn->sock; +ssize_t ecp_conn_handle_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, ssize_t size) { + if (size < 0) return size; #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); #endif + if (!ecp_conn_is_open(conn)) conn->flags |= ECP_CONN_FLAG_OPEN; +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif - *idx = conn->key_curr; - if (conn->key_curr != ECP_ECDH_IDX_INV) sock->ctx->cr.dh_pub_to_buf(public, &conn->key[conn->key_curr].public); + if (conn->out) { + return 0; + } else { + unsigned char payload[ECP_SIZE_PLD(0)]; + unsigned char ctype = 0; + + if (size < 1) return ECP_ERR; + + ctype = msg[0]; + + ecp_pld_set_type(payload, ECP_MTYPE_OPEN); + ssize_t _rv = ecp_pld_send(conn, payload, sizeof(payload)); + + return 1; + } + return ECP_ERR; +} +ssize_t ecp_conn_handle_kget(ECPConnection *conn, unsigned char mtype, unsigned char *msg, ssize_t size) { + if (conn->out) { + ECPContext *ctx = conn->sock->ctx; #ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_lock(&conn->mutex); #endif - - if (*idx == ECP_ECDH_IDX_INV) return ecp_sock_dhkey_get_curr(sock, idx, public); - return ECP_OK; + int conn_is_open = ecp_conn_is_open(conn); +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif + + if ((size < 0) && !conn_is_open) { + ecp_conn_handler_msg_t *handler = ctx->handler[conn->type] ? ctx->handler[conn->type]->msg[ECP_MTYPE_OPEN] : NULL; + return handler ? handler(conn, mtype, msg, size) : size; + } + + if (size < 0) return size; + if (size < ECP_ECDH_SIZE_KEY+1) return ECP_ERR; + + int rv = ecp_conn_dhkey_new_pub(conn, msg[0], msg+1); + if (!rv && !conn_is_open) { + ecp_conn_open_t *conn_open = ctx->handler[conn->type] ? ctx->handler[conn->type]->conn_open : NULL; + ssize_t _rv = conn_open(conn); + if (_rv < 0) rv = _rv; + } + if (rv) return rv; + + return ECP_ECDH_SIZE_KEY+1; + } else { + unsigned char payload[ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1)]; + unsigned char *buf = ecp_pld_get_buf(payload); + ecp_pld_set_type(payload, ECP_MTYPE_KGET); + + if (size < 0) return size; + + int rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1); + if (rv) return rv; + + ssize_t _rv = ecp_pld_send(conn, payload, sizeof(payload)); + + return 0; + } + return ECP_ERR; } - -static int _conn_kput_send(ECPConnection *conn, ECPTimerItem *ti) { + +ssize_t ecp_conn_handle_kput(ECPConnection *conn, unsigned char mtype, unsigned char *msg, ssize_t size) { + if (size < 0) return size; + + if (conn->out) { + return 0; + } else { + unsigned char payload[ECP_SIZE_PLD(0)]; + + if (size < ECP_ECDH_SIZE_KEY+1) return ECP_ERR; + + int rv = ecp_conn_dhkey_new_pub(conn, msg[0], msg+1); + if (rv) return rv; + + ecp_pld_set_type(payload, ECP_MTYPE_KPUT); + ssize_t _rv = ecp_pld_send(conn, payload, sizeof(payload)); + + return ECP_ECDH_SIZE_KEY+1; + } + return ECP_ERR; +} + +static ssize_t _conn_send_kput(ECPConnection *conn, ECPTimerItem *ti) { unsigned char payload[ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1)]; unsigned char *buf = ecp_pld_get_buf(payload); - ecp_pld_set_type(payload, ECP_PTYPE_KPUT); - - int rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1); + int rv = ECP_OK; + + ecp_pld_set_type(payload, ECP_MTYPE_KPUT); + rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1); if (rv) return rv; - ssize_t _rv = ecp_pld_send(conn, payload, sizeof(payload)); - if (_rv < 0) return _rv; - - return ECP_OK; + return ecp_pld_send(conn, payload, sizeof(payload)); } int ecp_conn_dhkey_new(ECPConnection *conn) { ECPSocket *sock = conn->sock; ECPDHKey new_key; - unsigned char key_curr; int rv; + ssize_t _rv; rv = ecp_dhkey_generate(sock->ctx, &new_key); if (rv) return rv; @@ -756,9 +770,12 @@ int ecp_conn_dhkey_new(ECPConnection *conn) { pthread_mutex_unlock(&sock->conn.mutex); #endif - if (!rv) rv = ecp_timer_send(conn, _conn_kput_send, ECP_PTYPE_KPUT, 3, 500); + if (rv) return rv; + + _rv = ecp_timer_send(conn, _conn_send_kput, ECP_MTYPE_KPUT, 3, 500); + if (_rv < 0) return _rv; - return rv; + return ECP_OK; } int ecp_conn_dhkey_new_pub(ECPConnection *conn, unsigned char idx, unsigned char *public) { @@ -782,6 +799,48 @@ int ecp_conn_dhkey_new_pub(ECPConnection *conn, unsigned char idx, unsigned char return rv; } +int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned char *public) { + ECPSocket *sock = conn->sock; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + if (idx) *idx = conn->key_curr; + if (conn->key_curr != ECP_ECDH_IDX_INV) sock->ctx->cr.dh_pub_to_buf(public, &conn->key[conn->key_curr].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); + return ECP_OK; +} + +ssize_t ecp_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, unsigned char *seq, unsigned char *payload, size_t payload_size) { + ssize_t rv; + + if (payload == NULL) return ECP_ERR; + 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; + packet[ECP_SIZE_PROTO] = (s_idx << 4) | c_idx; + ctx->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); + + memcpy(payload, seq, ECP_SIZE_SEQ); + rv = ctx->cr.aead_enc(packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, payload, payload_size, shsec, nonce); + if (rv < 0) return ECP_ERR_ENCRYPT; + + memcpy(nonce, packet+ECP_SIZE_PKT_HDR, ECP_AEAD_SIZE_NONCE); + + return rv+ECP_SIZE_PKT_HDR; +} + ssize_t ecp_conn_pack(ECPConnection *conn, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, unsigned char *payload, size_t payload_size) { ecp_aead_key_t shsec; ecp_dh_public_t public; @@ -825,7 +884,7 @@ ssize_t ecp_conn_pack(ECPConnection *conn, ECPNetAddr *addr, unsigned char *pack seq[1] = (conn->seq_out & 0x00FF0000) >> 16; seq[2] = (conn->seq_out & 0x0000FF00) >> 8; seq[3] = (conn->seq_out & 0x000000FF); - *addr = conn->node.addr; + if (addr) *addr = conn->node.addr; } #ifdef ECP_WITH_PTHREAD @@ -848,7 +907,28 @@ ssize_t ecp_conn_pack(ECPConnection *conn, ECPNetAddr *addr, unsigned char *pack return _rv; } -ssize_t ecp_pkt_handle_err(ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size) { +ssize_t ecp_proxy_pack(ECPConnection *conn, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, unsigned char *payload, size_t payload_size) { + ECPContext *ctx = conn->sock->ctx; + ssize_t rv = 0; + + if (conn->proxy && ctx->pr.init) { + return ctx->pr.pack(conn, addr, packet, pkt_size, s_idx, c_idx, payload, payload_size); + } else { + return ecp_conn_pack(conn, addr, packet, pkt_size, s_idx, c_idx, payload, payload_size); + } +} + +ssize_t ecp_proxy_pack_raw(ECPSocket *sock, ECPConnection *proxy, ECPNetAddr *addr, 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, unsigned char *seq, unsigned char *payload, size_t payload_size) { + ECPContext *ctx = sock->ctx; + + if (proxy && ctx->pr.init) { + return ctx->pr.pack_raw(proxy, addr, packet, pkt_size, s_idx, c_idx, public, shsec, nonce, seq, payload, payload_size); + } else { + return ecp_pack(ctx, packet, pkt_size, s_idx, c_idx, public, shsec, nonce, seq, payload, payload_size); + } +} + +ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *proxy, unsigned char *packet, size_t pkt_size) { unsigned char s_idx; unsigned char c_idx; unsigned char l_idx = ECP_ECDH_IDX_INV; @@ -860,7 +940,6 @@ ssize_t ecp_pkt_handle_err(ECPSocket *sock, ECPNetAddr *addr, unsigned char *pac ECPConnection *conn = NULL; ECPDHKey *key = NULL; int rv = ECP_OK; - ssize_t _rv = 0; uint32_t c_seq, p_seq, n_seq, seq_bitmap; ssize_t pld_size, cnt_size, proc_size; @@ -914,10 +993,9 @@ ssize_t ecp_pkt_handle_err(ECPSocket *sock, ECPNetAddr *addr, unsigned char *pac if (key) { sock->ctx->cr.dh_pub_from_buf(&public, packet+ECP_SIZE_PROTO+1); sock->ctx->cr.dh_shsec(&shsec, &public, &private); + memset(&private, 0, sizeof(private)); } - memset(private, 0, sizeof(private)); - pld_size = sock->ctx->cr.aead_dec(payload, ECP_MAX_PLD, packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, &shsec, packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY); if (pld_size < ECP_MIN_PLD) rv = ECP_ERR_DECRYPT; if (rv) goto pkt_handle_err; @@ -931,20 +1009,20 @@ ssize_t ecp_pkt_handle_err(ECPSocket *sock, ECPNetAddr *addr, unsigned char *pac memcpy(nonce, packet+ECP_SIZE_PKT_HDR, sizeof(nonce)); if (conn == NULL) { - if (payload[ECP_SIZE_SEQ] == ECP_PTYPE_OPEN) { - rv = conn_new(&conn, sock, s_idx, c_idx, packet+ECP_SIZE_PROTO+1, &shsec, payload+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR); + if (payload[ECP_SIZE_PLD_HDR] == ECP_MTYPE_OPEN) { + rv = sock->conn_new(sock, &conn, proxy, s_idx, c_idx, packet+ECP_SIZE_PROTO+1, &shsec, payload+ECP_SIZE_MSG_HDR, pld_size-ECP_SIZE_MSG_HDR); if (rv) return rv; seq_bitmap = 0; n_seq = p_seq; - } else if (payload[ECP_SIZE_SEQ] == ECP_PTYPE_KGET) { - unsigned char _payload[ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1)]; - unsigned char *buf = ecp_pld_get_buf(_payload); - ecp_pld_set_type(_payload, ECP_PTYPE_KGET); - + } else if (payload[ECP_SIZE_PLD_HDR] == ECP_MTYPE_KGET) { + unsigned char payload_[ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1)]; + unsigned char *buf = ecp_pld_get_buf(payload_); + ecp_pld_set_type(payload_, ECP_MTYPE_KGET); + rv = ecp_sock_dhkey_get_curr(sock, buf, buf+1); if (!rv) { - ssize_t _rv = ecp_pld_send_raw(sock, addr, s_idx, c_idx, &public, &shsec, nonce, payload, _payload, sizeof(_payload)); + ssize_t _rv = ecp_pld_send_raw(sock, proxy, addr, s_idx, c_idx, &public, &shsec, nonce, payload, payload_, sizeof(payload_)); if (_rv < 0) rv = _rv; } return ECP_MIN_PKT; @@ -990,13 +1068,13 @@ ssize_t ecp_pkt_handle_err(ECPSocket *sock, ECPNetAddr *addr, unsigned char *pac pthread_mutex_lock(&conn->mutex); #endif memcpy(conn->nonce, nonce, sizeof(conn->nonce)); - conn->node.addr = *addr; + if (addr) conn->node.addr = *addr; #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); #endif - cnt_size = pld_size-ECP_SIZE_SEQ; - proc_size = ecp_pld_handle(conn, payload+pld_size-cnt_size, cnt_size); + cnt_size = pld_size-ECP_SIZE_PLD_HDR; + proc_size = ecp_msg_handle(conn, payload+pld_size-cnt_size, cnt_size); if (proc_size < 0) rv = ECP_ERR_HANDLE; if (!rv) cnt_size -= proc_size; @@ -1038,7 +1116,7 @@ ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, s ssize_t rv = sock->ctx->tr.send(&sock->sock, packet, pkt_size, addr); if (rv < 0) return rv; if (rv < ECP_MIN_PKT) return ECP_ERR_SEND; - + return rv; } @@ -1050,44 +1128,48 @@ ssize_t ecp_pkt_recv(ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, s return rv; } -ssize_t ecp_pld_handle(ECPConnection *conn, unsigned char *payload, size_t payload_size) { - ecp_conn_handler_t *handler = NULL; +ssize_t ecp_msg_handle(ECPConnection *conn, unsigned char *msg, size_t msg_size) { + ecp_conn_handler_msg_t *handler = NULL; ssize_t rv = 0; - unsigned char ptype = 0; - size_t rem_size = payload_size; - ECPSocket *sock = conn->sock; + unsigned char mtype = 0; + size_t rem_size = msg_size; while (rem_size) { - ptype = payload[0]; - payload++; + mtype = msg[0]; + msg++; rem_size--; - if (ptype >= ECP_MAX_PTYPE) return ECP_ERR_MAX_PTYPE; + if (mtype >= ECP_MAX_MTYPE) return ECP_ERR_MAX_MTYPE; if (rem_size < ECP_MIN_MSG) return ECP_ERR_MIN_MSG; - ecp_timer_pop(conn, ptype); - handler = (ptype < ECP_MAX_PTYPE_SYS) && sock->handler[ptype] ? sock->handler[ptype] : (conn->handler ? conn->handler->f[ptype] : NULL); + ecp_timer_pop(conn, mtype); + handler = conn->sock->ctx->handler[conn->type] ? conn->sock->ctx->handler[conn->type]->msg[mtype] : NULL; if (handler) { - rv = handler(conn, ptype, payload, rem_size); - if (rv == 0) rv = rem_size; + rv = handler(conn, mtype, msg, rem_size); if (rv < 0) return rv; + if (rv == 0) rv = rem_size; + if (rv < ECP_MIN_MSG) rv = ECP_MIN_MSG; if (rv > rem_size) return ECP_ERR; rem_size -= rv; } else { - return payload_size-rem_size-1; + return msg_size-rem_size-1; } } - return payload_size; + return msg_size; } unsigned char *ecp_pld_get_buf(unsigned char *payload) { - return payload+ECP_SIZE_PLD_HDR; + return payload+ECP_SIZE_MSG_HDR; } -void ecp_pld_set_type(unsigned char *payload, unsigned char ptype) { - payload[ECP_SIZE_SEQ] = ptype; +void ecp_pld_set_type(unsigned char *payload, unsigned char mtype) { + payload[ECP_SIZE_PLD_HDR] = mtype; +} + +unsigned char ecp_pld_get_type(unsigned char *payload) { + return payload[ECP_SIZE_PLD_HDR]; } ssize_t ecp_pld_send(ECPConnection *conn, unsigned char *payload, size_t payload_size) { @@ -1095,51 +1177,36 @@ ssize_t ecp_pld_send(ECPConnection *conn, unsigned char *payload, size_t payload } ssize_t ecp_pld_send_wkey(ECPConnection *conn, unsigned char s_idx, unsigned char c_idx, unsigned char *payload, size_t payload_size) { + unsigned char packet[ECP_MAX_PKT]; ECPSocket *sock = conn->sock; ECPNetAddr addr; - unsigned char packet[ECP_MAX_PKT]; ssize_t rv; - rv = ecp_conn_pack(conn, &addr, packet, ECP_MAX_PKT, s_idx, c_idx, payload, payload_size); - if (rv < 0) return rv; - - rv = ecp_pkt_send(sock, &addr, packet, rv); + rv = ecp_proxy_pack(conn, &addr, packet, ECP_MAX_PKT, s_idx, c_idx, payload, payload_size); if (rv < 0) return rv; - return rv-ECP_SIZE_PKT_HDR-ECP_AEAD_SIZE_TAG; + return ecp_pkt_send(sock, &addr, packet, rv); } -ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPNetAddr *addr, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, unsigned char *seq, unsigned char *payload, size_t payload_size) { +ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *proxy, ECPNetAddr *addr, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, unsigned char *seq, unsigned char *payload, size_t payload_size) { unsigned char packet[ECP_MAX_PKT]; + ECPNetAddr _addr; ssize_t rv; - rv = ecp_pack(sock->ctx, packet, ECP_MAX_PKT, s_idx, c_idx, public, shsec, nonce, seq, payload, payload_size); + rv = ecp_proxy_pack_raw(sock, proxy, &_addr, packet, ECP_MAX_PKT, s_idx, c_idx, public, shsec, nonce, seq, payload, payload_size); if (rv < 0) return rv; - rv = ecp_pkt_send(sock, addr, packet, rv); - if (rv < 0) return rv; - - return rv-ECP_SIZE_PKT_HDR-ECP_AEAD_SIZE_TAG; + return ecp_pkt_send(sock, proxy ? &_addr : addr, packet, rv); } - -ssize_t ecp_send(ECPConnection *conn, unsigned char ptype, unsigned char *payload, size_t payload_size) { - ssize_t rv; - - if (payload == NULL) { - unsigned char _payload[ECP_MIN_PLD]; - ecp_pld_set_type(_payload, ptype); - rv = ecp_pld_send_wkey(conn, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, _payload, sizeof(_payload)); - } else { - ecp_pld_set_type(payload, ptype); - rv = ecp_pld_send_wkey(conn, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, ECP_SIZE_PLD(payload_size)); - } - return rv-ECP_SIZE_PLD_HDR; + +ssize_t ecp_send(ECPConnection *conn, unsigned char *payload, size_t payload_size) { + return ecp_pld_send(conn, payload, payload_size); } -ssize_t ecp_receive(ECPConnection *conn, unsigned char ptype, unsigned char *payload, size_t payload_size, unsigned int timeout) { +ssize_t ecp_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, unsigned int timeout) { #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); - ssize_t rv = ecp_conn_msgq_pop(conn, ptype, payload, payload_size, timeout); + ssize_t rv = ecp_conn_msgq_pop(conn, mtype, msg, msg_size, timeout); pthread_mutex_unlock(&conn->mutex); return rv; #else @@ -1154,7 +1221,7 @@ static int recv_p(ECPSocket *sock) { ssize_t rv = ecp_pkt_recv(sock, &addr, packet, ECP_MAX_PKT); if (rv < 0) return rv; - rv = ecp_pkt_handle(sock, &addr, packet, rv); + rv = ecp_pkt_handle(sock, &addr, NULL, packet, rv); if (rv < 0) return rv; return ECP_OK; diff --git a/code/core.h b/code/core.h index 09c3a2e..929461f 100644 --- a/code/core.h +++ b/code/core.h @@ -4,10 +4,13 @@ #define ECP_ERR_ALLOC -3 #define ECP_ERR_MAX_SOCK_CONN -10 -#define ECP_ERR_MAX_PTYPE -11 -#define ECP_ERR_MAX_PLD -12 -#define ECP_ERR_MIN_MSG -13 -#define ECP_ERR_NET_ADDR -14 +#define ECP_ERR_MAX_CTYPE -11 +#define ECP_ERR_MAX_MTYPE -12 +#define ECP_ERR_MIN_PKT -13 +#define ECP_ERR_MAX_PLD -14 +#define ECP_ERR_MIN_MSG -15 +#define ECP_ERR_MAX_MSG -16 +#define ECP_ERR_NET_ADDR -17 #define ECP_ERR_CONN_NOT_FOUND -20 #define ECP_ERR_ECDH_KEY_DUP -21 @@ -31,27 +34,32 @@ #define ECP_MAX_SOCK_KEY 8 #define ECP_MAX_CONN_KEY 2 #define ECP_MAX_NODE_KEY 2 -#define ECP_MAX_PTYPE 32 -#define ECP_MAX_PTYPE_SYS 4 +#define ECP_MAX_CTYPE 8 +#define ECP_MAX_MTYPE 16 #define ECP_SIZE_PKT_HDR (ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY+ECP_AEAD_SIZE_NONCE) -#define ECP_SIZE_PLD_HDR (ECP_SIZE_SEQ+1) +#define ECP_SIZE_PLD_HDR (ECP_SIZE_SEQ) +#define ECP_SIZE_MSG_HDR (ECP_SIZE_PLD_HDR+1) -#define ECP_MIN_MSG 16 #define ECP_MAX_PKT 1412 -#define ECP_MIN_PKT (ECP_SIZE_PKT_HDR+ECP_SIZE_PLD_HDR+ECP_MIN_MSG+ECP_AEAD_SIZE_TAG) -#define ECP_MAX_PLD (ECP_MAX_PKT-ECP_SIZE_PKT_HDR-ECP_SIZE_PLD_HDR-ECP_AEAD_SIZE_TAG) -#define ECP_MIN_PLD ECP_SIZE_PLD_HDR+ECP_MIN_MSG +#define ECP_MAX_PLD (ECP_MAX_PKT-ECP_SIZE_PKT_HDR-ECP_AEAD_SIZE_TAG) +#define ECP_MAX_MSG (ECP_MAX_PLD-ECP_SIZE_MSG_HDR) + +#define ECP_MIN_MSG 8 +#define ECP_MIN_PLD (ECP_SIZE_MSG_HDR+ECP_MIN_MSG) +#define ECP_MIN_PKT (ECP_SIZE_PKT_HDR+ECP_MIN_PLD+ECP_AEAD_SIZE_TAG) #define ECP_POLL_TIMEOUT 500 #define ECP_ECDH_IDX_INV 0xFF #define ECP_ECDH_IDX_PERMA 0x0F -#define ECP_PTYPE_OPEN 0x00 -#define ECP_PTYPE_KGET 0x01 -#define ECP_PTYPE_KPUT 0x02 +#define ECP_MTYPE_OPEN 0x00 +#define ECP_MTYPE_KGET 0x01 +#define ECP_MTYPE_KPUT 0x02 +#define ECP_MTYPE_EXEC 0x03 -#define ECP_SIZE_PLD(X) (X+ECP_SIZE_PLD_HDR) +#define ECP_SIZE_PLD(X) ((X) < ECP_MIN_MSG ? ECP_MIN_MSG + ECP_SIZE_MSG_HDR : (X) + ECP_SIZE_MSG_HDR) +#define ECP_SIZE_PKT(X) ((X) < ECP_MIN_MSG ? ECP_MIN_MSG + ECP_SIZE_PKT_HDR+ECP_SIZE_MSG_HDR+ECP_AEAD_SIZE_TAG : (X) + ECP_SIZE_PKT_HDR+ECP_SIZE_MSG_HDR+ECP_AEAD_SIZE_TAG) #define ECP_CONN_FLAG_REG 0x01 #define ECP_CONN_FLAG_OPEN 0x02 @@ -66,13 +74,16 @@ typedef long ssize_t; #ifdef ECP_WITH_PTHREAD #include <pthread.h> -#include "msgq.h" #endif #include "posix/transport.h" #include "crypto/crypto.h" #include "timer.h" +#ifdef ECP_WITH_PTHREAD +#include "msgq.h" +#endif + #ifdef ECP_DEBUG #include <stdio.h> #define DPRINT(cnd, format, ...) { if (cnd) { fprintf (stderr, format, __VA_ARGS__); } } @@ -81,14 +92,19 @@ typedef long ssize_t; #endif struct ECPContext; +struct ECPSocket; struct ECPConnection; typedef int ecp_rng_t (void *, size_t); -typedef struct ECPConnection * ecp_conn_alloc_t (void); -typedef void ecp_conn_free_t (struct ECPConnection *); -typedef int ecp_conn_create_t (struct ECPConnection *, unsigned char *, size_t); -typedef void ecp_conn_destroy_t (struct ECPConnection *); -typedef ssize_t ecp_conn_handler_t (struct ECPConnection *, unsigned char, unsigned char *, ssize_t); + +typedef int ecp_conn_handler_new_t (struct ECPSocket *s, struct ECPConnection **c, struct ECPConnection *p, unsigned char s_idx, unsigned char c_idx, unsigned char *pub, ecp_aead_key_t *sh, unsigned char *msg, size_t sz); +typedef ssize_t ecp_conn_handler_msg_t (struct ECPConnection *c, unsigned char t, unsigned char *msg, ssize_t sz); + +typedef struct ECPConnection * ecp_conn_alloc_t (unsigned char t); +typedef void ecp_conn_free_t (struct ECPConnection *c); +typedef int ecp_conn_create_t (struct ECPConnection *c, unsigned char *msg, size_t sz); +typedef void ecp_conn_destroy_t (struct ECPConnection *c); +typedef ssize_t ecp_conn_open_t (struct ECPConnection *c); typedef struct ECPCryptoIface { int init; @@ -134,6 +150,12 @@ typedef struct ECPTimeIface { void (*sleep_ms) (unsigned int); } ECPTimeIface; +typedef struct ECPProxyIface { + int init; + ssize_t (*pack) (struct ECPConnection *conn, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, unsigned char *payload, size_t payload_size); + ssize_t (*pack_raw) (struct ECPConnection *proxy, ECPNetAddr *addr, 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, unsigned char *seq, unsigned char *payload, size_t payload_size); +} ECPProxyIface; + typedef struct ECPDHKey { ecp_dh_public_t public; ecp_dh_private_t private; @@ -162,7 +184,10 @@ typedef struct ECPNode { } ECPNode; typedef struct ECPConnHandler { - ecp_conn_handler_t *f[ECP_MAX_PTYPE]; + ecp_conn_handler_msg_t *msg[ECP_MAX_MTYPE]; + ecp_conn_create_t *conn_create; + ecp_conn_destroy_t *conn_destroy; + ecp_conn_open_t *conn_open; } ECPConnHandler; typedef struct ECPSockCTable { @@ -182,6 +207,8 @@ typedef struct ECPContext { ECPHTableIface ht; ECPTransportIface tr; ECPTimeIface tm; + ECPProxyIface pr; + ECPConnHandler *handler[ECP_MAX_CTYPE]; } ECPContext; typedef struct ECPSocket { @@ -194,7 +221,7 @@ typedef struct ECPSocket { unsigned char key_curr; ECPSockCTable conn; ECPTimer timer; - ecp_conn_handler_t *handler[ECP_MAX_PTYPE_SYS]; + ecp_conn_handler_new_t *conn_new; ecp_conn_create_t *conn_create; ecp_conn_destroy_t *conn_destroy; #ifdef ECP_WITH_PTHREAD @@ -204,6 +231,7 @@ typedef struct ECPSocket { } ECPSocket; typedef struct ECPConnection { + unsigned char type; unsigned char out; unsigned char flags; unsigned short refcount; @@ -220,11 +248,11 @@ typedef struct ECPConnection { unsigned char key_idx_map[ECP_MAX_SOCK_KEY]; ECPDHShared shared[ECP_MAX_NODE_KEY][ECP_MAX_NODE_KEY]; unsigned char nonce[ECP_AEAD_SIZE_NONCE]; - ECPConnHandler *handler; #ifdef ECP_WITH_PTHREAD ECPConnMsgQ msgq; pthread_mutex_t mutex; #endif + struct ECPConnection *proxy; void *conn_data; } ECPConnection; @@ -236,7 +264,6 @@ int ecp_time_init(ECPTimeIface *t); int ecp_dhkey_generate(ECPContext *ctx, ECPDHKey *key); int ecp_node_init(ECPContext *ctx, ECPNode *node, void *addr, ecp_dh_public_t *public); -ssize_t ecp_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, unsigned char *seq, unsigned char *payload, size_t payload_size); int ecp_ctx_create(ECPContext *ctx); int ecp_ctx_destroy(ECPContext *ctx); @@ -248,31 +275,45 @@ 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_create(ECPConnection *conn, ECPSocket *sock); +int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype); void ecp_conn_destroy(ECPConnection *conn); int ecp_conn_register(ECPConnection *conn); -int ecp_conn_unregister(ECPConnection *conn, unsigned int timeout); -int ecp_conn_open(ECPConnection *conn, ECPNode *node, ECPConnHandler *handler); +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, unsigned int timeout); -int ecp_conn_hander_init(ECPConnHandler *handler); -int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned char *public); + +int ecp_conn_handler_init(ECPConnHandler *handler); +ssize_t ecp_conn_send_open(ECPConnection *conn); +int ecp_conn_handle_new(ECPSocket *sock, ECPConnection **_conn, ECPConnection *proxy, unsigned char s_idx, unsigned char c_idx, unsigned char *c_public, ecp_aead_key_t *shsec, unsigned char *payload, size_t payload_size); +ssize_t ecp_conn_handle_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, ssize_t size); +ssize_t ecp_conn_handle_kget(ECPConnection *conn, unsigned char mtype, unsigned char *msg, ssize_t size); +ssize_t ecp_conn_handle_kput(ECPConnection *conn, unsigned char mtype, unsigned char *msg, ssize_t size); + 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, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, unsigned char *seq, unsigned char *payload, size_t payload_size); ssize_t ecp_conn_pack(ECPConnection *conn, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, unsigned char *payload, size_t payload_size); +ssize_t ecp_proxy_pack(ECPConnection *conn, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, unsigned char *payload, size_t payload_size); +ssize_t ecp_proxy_pack_raw(ECPSocket *sock, ECPConnection *proxy, ECPNetAddr *addr, 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, unsigned char *seq, unsigned char *payload, size_t payload_size); -ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size); +ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *proxy, unsigned char *packet, size_t pkt_size); ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size); ssize_t ecp_pkt_recv(ECPSocket *sock, ECPNetAddr *addr, unsigned char *packet, size_t pkt_size); -ssize_t ecp_pld_handle(ECPConnection *conn, unsigned char *payload, size_t payload_size); +ssize_t ecp_msg_handle(ECPConnection *conn, unsigned char *msg, size_t msg_size); unsigned char *ecp_pld_get_buf(unsigned char *payload); -void ecp_pld_set_type(unsigned char *payload, unsigned char ptype); +void ecp_pld_set_type(unsigned char *payload, unsigned char mtype); +unsigned char ecp_pld_get_type(unsigned char *payload); ssize_t ecp_pld_send(ECPConnection *conn, unsigned char *payload, size_t payload_size); ssize_t ecp_pld_send_wkey(ECPConnection *conn, unsigned char s_idx, unsigned char c_idx, unsigned char *payload, size_t payload_size); -ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPNetAddr *addr, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, unsigned char *seq, unsigned char *payload, size_t payload_size); +ssize_t ecp_pld_send_raw(ECPSocket *sock, ECPConnection *proxy, ECPNetAddr *addr, unsigned char s_idx, unsigned char c_idx, ecp_dh_public_t *public, ecp_aead_key_t *shsec, unsigned char *nonce, unsigned char *seq, unsigned char *payload, size_t payload_size); -ssize_t ecp_send(ECPConnection *conn, unsigned char ptype, unsigned char *payload, size_t payload_size); -ssize_t ecp_receive(ECPConnection *conn, unsigned char ptype, unsigned char *payload, size_t payload_size, unsigned int timeout); +ssize_t ecp_send(ECPConnection *conn, unsigned char *payload, size_t payload_size); +ssize_t ecp_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, unsigned int timeout); int ecp_receiver(ECPSocket *sock); int ecp_start_receiver(ECPSocket *sock); diff --git a/code/init.c b/code/init.c index ba792f0..7e39f87 100644 --- a/code/init.c +++ b/code/init.c @@ -14,7 +14,7 @@ static int v_rng(void *buf, size_t bufsize) { return 0; } -static ECPConnection *conn_alloc(void) { +static ECPConnection *conn_alloc(unsigned char type) { return malloc(sizeof(ECPConnection)); } diff --git a/code/msgq.c b/code/msgq.c index 7f32b40..53c55ea 100644 --- a/code/msgq.c +++ b/code/msgq.c @@ -24,7 +24,7 @@ static struct timespec *abstime_ts(struct timespec *ts, unsigned int msec) { int ecp_conn_msgq_create(ECPConnection *conn) { int i; - for (i=0; i<ECP_MAX_PTYPE; i++) { + for (i=0; i<ECP_MAX_MTYPE; i++) { int rv = pthread_cond_init(&conn->msgq.cond[i], NULL); if (rv) { int j; @@ -42,35 +42,36 @@ int ecp_conn_msgq_create(ECPConnection *conn) { void ecp_conn_msgq_destroy(ECPConnection *conn) { int i; - for (i=0; i<ECP_MAX_PTYPE; i++) { + for (i=0; i<ECP_MAX_MTYPE; i++) { pthread_cond_destroy(&conn->msgq.cond[i]); } } -ssize_t ecp_conn_msgq_push(ECPConnection *conn, unsigned char *payload, size_t payload_size) { +ssize_t ecp_conn_msgq_push(ECPConnection *conn, unsigned char *msg, size_t msg_size) { ECPConnMsgQ *msgq = &conn->msgq; unsigned short msg_idx = msgq->empty_idx; unsigned short i; unsigned short done = 0; - unsigned char ptype; + unsigned char mtype; - if (payload_size == 0) return ECP_OK; + if (msg_size == 0) return ECP_OK; - ptype = *payload; - payload++; - payload_size--; + mtype = *msg; + msg++; + msg_size--; - if (ptype >= ECP_MAX_PTYPE) return ECP_ERR_MAX_PTYPE; - if (payload_size < ECP_MIN_MSG) return ECP_ERR_MIN_MSG; + if (mtype >= ECP_MAX_MTYPE) return ECP_ERR_MAX_MTYPE; + if (msg_size >= ECP_MAX_MSG) return ECP_ERR_MAX_MSG; + if (msg_size < ECP_MIN_MSG) return ECP_ERR_MIN_MSG; for (i=0; i<ECP_MAX_CONN_MSG; i++) { if (!msgq->occupied[msg_idx]) { - ECPMessage *msg = &msgq->msg[msg_idx]; - if (payload_size > 0) memcpy(msg->payload, payload, payload_size); - msg->size = payload_size; - if (msgq->r_idx[ptype] == msgq->w_idx[ptype]) pthread_cond_signal(&msgq->cond[ptype]); - msgq->msg_idx[ptype][msgq->w_idx[ptype]] = msg_idx; - msgq->w_idx[ptype] = MSG_NEXT(msgq->w_idx[ptype], ECP_MAX_CONN_MSG+1); + ECPMessage *message = &msgq->msg[msg_idx]; + if (msg_size > 0) memcpy(message->msg, msg, msg_size); + message->size = msg_size; + if (msgq->r_idx[mtype] == msgq->w_idx[mtype]) pthread_cond_signal(&msgq->cond[mtype]); + msgq->msg_idx[mtype][msgq->w_idx[mtype]] = msg_idx; + msgq->w_idx[mtype] = MSG_NEXT(msgq->w_idx[mtype], ECP_MAX_CONN_MSG+1); msgq->empty_idx = MSG_NEXT(msg_idx, ECP_MAX_CONN_MSG); msgq->occupied[msg_idx] = 1; @@ -80,38 +81,38 @@ ssize_t ecp_conn_msgq_push(ECPConnection *conn, unsigned char *payload, size_t p msg_idx = MSG_NEXT(msg_idx, ECP_MAX_CONN_MSG); } if (done) { - return payload_size+1; + return msg_size+1; } else { return ECP_ERR_MAX_CONN_MSG; } } -ssize_t ecp_conn_msgq_pop(ECPConnection *conn, unsigned char ptype, unsigned char *payload, size_t payload_size, unsigned int timeout) { +ssize_t ecp_conn_msgq_pop(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, unsigned int timeout) { ECPConnMsgQ *msgq = &conn->msgq; - ECPMessage *msg; + ECPMessage *message; ssize_t rv = ECP_OK; unsigned short msg_idx; - if (ptype >= ECP_MAX_PTYPE) return ECP_ERR_MAX_PTYPE; + if (mtype >= ECP_MAX_MTYPE) return ECP_ERR_MAX_MTYPE; - if (msgq->r_idx[ptype] == msgq->w_idx[ptype]) { + if (msgq->r_idx[mtype] == msgq->w_idx[mtype]) { if (timeout == -1) { - pthread_cond_wait(&msgq->cond[ptype], &conn->mutex); + pthread_cond_wait(&msgq->cond[mtype], &conn->mutex); } else { struct timespec ts; - int _rv = pthread_cond_timedwait(&msgq->cond[ptype], &conn->mutex, abstime_ts(&ts, timeout)); + int _rv = pthread_cond_timedwait(&msgq->cond[mtype], &conn->mutex, abstime_ts(&ts, timeout)); if (_rv) rv = ECP_ERR_TIMEOUT; } } if (!rv) { - msg_idx = msgq->msg_idx[ptype][msgq->r_idx[ptype]]; - msgq->r_idx[ptype] = MSG_NEXT(msgq->r_idx[ptype], ECP_MAX_CONN_MSG+1); + msg_idx = msgq->msg_idx[mtype][msgq->r_idx[mtype]]; + msgq->r_idx[mtype] = MSG_NEXT(msgq->r_idx[mtype], ECP_MAX_CONN_MSG+1); msgq->occupied[msg_idx] = 0; - msg = &msgq->msg[msg_idx]; - rv = msg->size; + message = &msgq->msg[msg_idx]; + rv = message->size; if (rv >= 0) { - rv = MIN(payload_size, rv); - memcpy(payload, msg->payload, rv); + rv = MIN(msg_size, rv); + memcpy(msg, message->msg, rv); } } return rv; diff --git a/code/msgq.h b/code/msgq.h index 0bf47b3..9d16f63 100644 --- a/code/msgq.h +++ b/code/msgq.h @@ -9,24 +9,24 @@ struct ECPConnection; typedef struct ECPMessage { - unsigned char payload[ECP_MAX_PKT]; + unsigned char msg[ECP_MAX_MSG]; ssize_t size; } ECPMessage; typedef struct ECPConnMsgQ { unsigned short empty_idx; unsigned short occupied[ECP_MAX_CONN_MSG]; - unsigned short w_idx[ECP_MAX_PTYPE]; - unsigned short r_idx[ECP_MAX_PTYPE]; - unsigned short msg_idx[ECP_MAX_PTYPE][ECP_MAX_CONN_MSG+1]; + unsigned short w_idx[ECP_MAX_MTYPE]; + unsigned short r_idx[ECP_MAX_MTYPE]; + unsigned short msg_idx[ECP_MAX_MTYPE][ECP_MAX_CONN_MSG+1]; ECPMessage msg[ECP_MAX_CONN_MSG]; pthread_mutex_t mutex; - pthread_cond_t cond[ECP_MAX_PTYPE]; + pthread_cond_t cond[ECP_MAX_MTYPE]; } ECPConnMsgQ; int ecp_conn_msgq_create(struct ECPConnection *conn); void ecp_conn_msgq_destroy(struct ECPConnection *conn); -ssize_t ecp_conn_msgq_push(struct ECPConnection *conn, unsigned char *payload, size_t payload_size); -ssize_t ecp_conn_msgq_pop(struct ECPConnection *conn, unsigned char ptype, unsigned char *payload, size_t payload_size, unsigned int timeout); +ssize_t ecp_conn_msgq_push(struct ECPConnection *conn, unsigned char *msg, size_t msg_size); +ssize_t ecp_conn_msgq_pop(struct ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, unsigned int timeout); #endif /* ECP_WITH_PTHREAD */
\ No newline at end of file diff --git a/code/test/Makefile b/code/test/Makefile index 7992127..02ade87 100644 --- a/code/test/Makefile +++ b/code/test/Makefile @@ -1,6 +1,6 @@ CFLAGS=-I.. -O3 -Wno-int-to-void-pointer-cast LDFLAGS=-lm -pthread -dep=../libecpcore.a ../crypto/libecpcr.a ../htable/libecpht.a ../posix/libecptr.a ../posix/libecptm.a +dep=../libecpcore.a ../crypto/libecpcr.a ../htable/libecpht.a ../posix/libecptr.a ../posix/libecptm.a ../init.o %.o: %.c $(CC) $(CFLAGS) -c $< diff --git a/code/test/server.c b/code/test/server.c index a03267e..5bb36ef 100644 --- a/code/test/server.c +++ b/code/test/server.c @@ -17,11 +17,13 @@ ECPConnHandler handler_c; ECPNode node; ECPConnection conn; -#define PTYPE_MSG 16 +#define CTYPE_TEST 0 +#define MTYPE_MSG 8 -ssize_t handle_open_c(ECPConnection *c, unsigned char t, unsigned char *p, ssize_t s) { +ssize_t handle_open_c(ECPConnection *conn, unsigned char t, unsigned char *p, ssize_t s) { uint32_t seq = 0; + ecp_conn_handle_open(conn, t, p, s); if (s < 0) { printf("OPEN ERR:%ld\n", s); return 0; @@ -31,52 +33,47 @@ ssize_t handle_open_c(ECPConnection *c, unsigned char t, unsigned char *p, ssize unsigned char *buf = ecp_pld_get_buf(payload); char *msg = "PERA JE CAR!"; + ecp_pld_set_type(payload, MTYPE_MSG); strcpy((char *)buf, msg); - ssize_t _rv = ecp_send(c, PTYPE_MSG, payload, 1000); + ssize_t _rv = ecp_send(conn, payload, sizeof(payload)); return 0; } -ssize_t handle_msg_c(ECPConnection *c, unsigned char t, unsigned char *p, ssize_t s) { +ssize_t handle_msg_c(ECPConnection *conn, unsigned char t, unsigned char *p, ssize_t s) { printf("MSG C:%s size:%ld\n", p, s); - return s; } -ssize_t handle_msg_s(ECPConnection *c, unsigned char t, unsigned char *p, ssize_t s) { +ssize_t handle_msg_s(ECPConnection *conn, unsigned char t, unsigned char *p, ssize_t s) { printf("MSG S:%s size:%ld\n", p, s); unsigned char payload[ECP_SIZE_PLD(1000)]; unsigned char *buf = ecp_pld_get_buf(payload); char *msg = "VAISTINU JE CAR!"; + ecp_pld_set_type(payload, MTYPE_MSG); strcpy((char *)buf, msg); - ssize_t _rv = ecp_send(c, PTYPE_MSG, payload, 1000); + ssize_t _rv = ecp_send(conn, payload, sizeof(payload)); return s; } -int conn_create(ECPConnection *c, unsigned char *p, size_t s) { - c->handler = &handler_s; - return ECP_OK; -} - int main(int argc, char *argv[]) { int rv; rv = ecp_init(&ctx_s); printf("ecp_init RV:%d\n", rv); + rv = ecp_conn_handler_init(&handler_s); + 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_sock_create(&sock_s, &ctx_s, &key_perma_s); printf("ecp_sock_create RV:%d\n", rv); - rv = ecp_conn_hander_init(&handler_s); - - handler_s.f[PTYPE_MSG] = handle_msg_s; - sock_s.conn_create = conn_create; - rv = ecp_sock_open(&sock_s, "0.0.0.0:3000"); printf("ecp_sock_open RV:%d\n", rv); @@ -85,6 +82,11 @@ int main(int argc, char *argv[]) { rv = ecp_init(&ctx_c); printf("ecp_init RV:%d\n", rv); + + rv = ecp_conn_handler_init(&handler_c); + handler_c.msg[ECP_MTYPE_OPEN] = handle_open_c; + 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); @@ -101,16 +103,10 @@ int main(int argc, char *argv[]) { rv = ecp_node_init(&ctx_c, &node, "127.0.0.1:3000", &key_perma_s.public); printf("ecp_node_init RV:%d\n", rv); - rv = ecp_conn_create(&conn, &sock_c); + rv = ecp_conn_create(&conn, &sock_c, CTYPE_TEST); printf("ecp_conn_create RV:%d\n", rv); - rv = ecp_conn_hander_init(&handler_c); - printf("ecp_conn_hander_init RV:%d\n", rv); - - handler_c.f[ECP_PTYPE_OPEN] = handle_open_c; - handler_c.f[PTYPE_MSG] = handle_msg_c; - - rv = ecp_conn_open(&conn, &node, &handler_c); + rv = ecp_conn_open(&conn, &node); printf("ecp_conn_open RV:%d\n", rv); while (1) sleep(1); diff --git a/code/test/stress.c b/code/test/stress.c index c278af1..808611e 100644 --- a/code/test/stress.c +++ b/code/test/stress.c @@ -16,7 +16,8 @@ #define NUM_C 256 #define MSG_RATE 65 -#define PTYPE_MSG 16 +#define CTYPE_TEST 0 +#define MTYPE_MSG 8 ECPContext ctx_s; ECPDHKey key_perma_s; @@ -84,7 +85,8 @@ void *sender(ECPConnection *c) { c->sock->ctx->rng(&rnd, sizeof(uint32_t)); usleep(rnd % (2000000/msg_rate)); - ssize_t _rv = ecp_send(c, PTYPE_MSG, payload, 1000); + ecp_pld_set_type(payload, MTYPE_MSG); + ssize_t _rv = ecp_send(c, payload, sizeof(payload)); if (c_start && (_rv > 0)) { pthread_mutex_lock(&t_mtx[idx]); t_sent[idx]++; @@ -93,9 +95,12 @@ void *sender(ECPConnection *c) { } } -ssize_t handle_open_c(ECPConnection *c, unsigned char t, unsigned char *p, ssize_t s) { - int idx = (int)(c->conn_data); - int rv = pthread_create(&s_thd[idx], NULL, (void *(*)(void *))sender, (void *)c); +ssize_t handle_open_c(ECPConnection *conn, unsigned char t, unsigned char *p, ssize_t s) { + int idx = (int)(conn->conn_data); + int rv = 0; + + ecp_conn_handle_open(conn, t, p, s); + rv = pthread_create(&s_thd[idx], NULL, (void *(*)(void *))sender, (void *)conn); if (rv) { char msg[256]; sprintf(msg, "THD %d CREATE\n", idx); @@ -105,8 +110,8 @@ ssize_t handle_open_c(ECPConnection *c, unsigned char t, unsigned char *p, ssize return 0; } -ssize_t handle_msg_c(ECPConnection *c, unsigned char t, unsigned char *p, ssize_t s) { - int idx = (int)(c->conn_data); +ssize_t handle_msg_c(ECPConnection *conn, unsigned char t, unsigned char *p, ssize_t s) { + int idx = (int)(conn->conn_data); unsigned char payload[ECP_SIZE_PLD(1000)]; if (c_start) { @@ -115,21 +120,18 @@ ssize_t handle_msg_c(ECPConnection *c, unsigned char t, unsigned char *p, ssize_ pthread_mutex_unlock(&t_mtx[idx]); } - // ssize_t _rv = ecp_send(c, PTYPE_MSG, payload, 1000); + // ecp_pld_set_type(payload, MTYPE_MSG); + // ssize_t _rv = ecp_send(c, payload, sizeof(payload)); return s; } -ssize_t handle_msg_s(ECPConnection *c, unsigned char t, unsigned char *p, ssize_t s) { +ssize_t handle_msg_s(ECPConnection *conn, unsigned char t, unsigned char *p, ssize_t s) { unsigned char payload[ECP_SIZE_PLD(1000)]; - ssize_t _rv = ecp_send(c, PTYPE_MSG, payload, 1000); + ecp_pld_set_type(payload, MTYPE_MSG); + ssize_t _rv = ecp_send(conn, payload, sizeof(payload)); return s; } -int conn_create(ECPConnection *c, unsigned char *p, size_t s) { - c->handler = &handler_s; - return ECP_OK; -} - int main(int argc, char *argv[]) { char addr[256]; int rv; @@ -165,14 +167,15 @@ int main(int argc, char *argv[]) { sigaction(SIGINFO, &actINFO, NULL); rv = ecp_init(&ctx_s); + if (!rv) rv = ecp_conn_handler_init(&handler_s); + 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_conn_hander_init(&handler_s); - handler_s.f[PTYPE_MSG] = handle_msg_s; for (i=0; i<num_s; i++) { if (!rv) rv = ecp_sock_create(&sock_s[i], &ctx_s, &key_perma_s); - sock_s[i].conn_create = conn_create; strcpy(addr, "0.0.0.0:"); sprintf(addr+strlen(addr), "%d", 3000+i); if (!rv) rv = ecp_sock_open(&sock_s[i], addr); @@ -187,15 +190,17 @@ int main(int argc, char *argv[]) { } } - rv = ecp_conn_hander_init(&handler_c); + rv = ecp_conn_handler_init(&handler_c); - handler_c.f[ECP_PTYPE_OPEN] = handle_open_c; - handler_c.f[PTYPE_MSG] = handle_msg_c; + handler_c.msg[ECP_MTYPE_OPEN] = handle_open_c; + handler_c.msg[MTYPE_MSG] = handle_msg_c; for (i=0; i<num_c; i++) { pthread_mutex_init(&t_mtx[i], NULL); 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_sock_create(&sock_c[i], &ctx_c[i], &key_perma_c[i]); if (!rv) rv = ecp_sock_open(&sock_c[i], NULL); @@ -203,13 +208,13 @@ int main(int argc, char *argv[]) { if (!rv) rv = pthread_create(&r_thd[i], NULL, (void *(*)(void *))ecp_receiver, (void *)&sock_c[i]); strcpy(addr, "127.0.0.1:"); - sprintf(addr+strlen(addr), "%d", 3000+(i % num_s)); + sprintf(addr+strlen(addr), "%d", 3000 + (i % num_s)); if (!rv) rv = ecp_node_init(&ctx_c[i], &node[i], addr, &key_perma_s.public); - if (!rv) rv = ecp_conn_create(&conn[i], &sock_c[i]); + if (!rv) rv = ecp_conn_create(&conn[i], &sock_c[i], CTYPE_TEST); conn[i].conn_data = (void *)i; - if (!rv) rv = ecp_conn_open(&conn[i], &node[i], &handler_c); + if (!rv) rv = ecp_conn_open(&conn[i], &node[i]); if (rv) { char msg[256]; diff --git a/code/timer.c b/code/timer.c index 065a375..cf77d6e 100644 --- a/code/timer.c +++ b/code/timer.c @@ -19,14 +19,14 @@ void ecp_timer_destroy(ECPTimer *timer) { #endif } -int ecp_timer_item_init(ECPTimerItem *ti, ECPConnection *conn, unsigned char ptype, unsigned short cnt, unsigned int timeout) { +int ecp_timer_item_init(ECPTimerItem *ti, ECPConnection *conn, unsigned char mtype, unsigned short cnt, unsigned int timeout) { unsigned int abstime = conn->sock->ctx->tm.abstime_ms(timeout); - if (ptype >= ECP_MAX_PTYPE) return ECP_ERR_MAX_PTYPE; + if (mtype >= ECP_MAX_MTYPE) return ECP_ERR_MAX_MTYPE; ti->conn = conn; - ti->ptype = ptype; - ti->cnt = cnt; + ti->mtype = mtype; + ti->cnt = cnt-1; ti->timeout = timeout; ti->abstime = abstime; ti->retry = NULL; @@ -36,8 +36,9 @@ int ecp_timer_item_init(ECPTimerItem *ti, ECPConnection *conn, unsigned char pty return ECP_OK; } -int ecp_timer_push(ECPConnection *conn, ECPTimerItem *ti) { +int ecp_timer_push(ECPTimerItem *ti) { int i, is_reg, rv = ECP_OK; + ECPConnection *conn = ti->conn; ECPTimer *timer = &conn->sock->timer; #ifdef ECP_WITH_PTHREAD @@ -76,7 +77,7 @@ int ecp_timer_push(ECPConnection *conn, ECPTimerItem *ti) { return rv; } -void ecp_timer_pop(ECPConnection *conn, unsigned char ptype) { +void ecp_timer_pop(ECPConnection *conn, unsigned char mtype) { int i; ECPTimer *timer = &conn->sock->timer; @@ -86,7 +87,7 @@ void ecp_timer_pop(ECPConnection *conn, unsigned char ptype) { for (i=timer->head; i>=0; i--) { ECPConnection *curr_conn = timer->item[i].conn; - if ((conn == curr_conn) && (ptype == timer->item[i].ptype)) { + if ((conn == curr_conn) && (mtype == timer->item[i].mtype)) { if (i != timer->head) { memmove(timer->item+i, timer->item+i+1, sizeof(ECPTimerItem) * (timer->head-i)); memset(timer->item+timer->head, 0, sizeof(ECPTimerItem)); @@ -176,25 +177,25 @@ unsigned int ecp_timer_exe(ECPSocket *sock) { int rv = ECP_OK; ECPConnection *conn = to_exec[i].conn; ECPSocket *sock = conn->sock; - unsigned char ptype = to_exec[i].ptype; + unsigned char mtype = to_exec[i].mtype; unsigned char *pld = to_exec[i].pld; unsigned char pld_size = to_exec[i].pld_size; ecp_timer_retry_t *retry = to_exec[i].retry; - ecp_conn_handler_t *handler = (ptype < ECP_MAX_PTYPE_SYS) && sock->handler[ptype] ? sock->handler[ptype] : (conn->handler ? conn->handler->f[ptype] : NULL); - + ecp_conn_handler_msg_t *handler = conn->sock->ctx->handler[conn->type] ? conn->sock->ctx->handler[conn->type]->msg[mtype] : NULL; + if (to_exec[i].cnt) { to_exec[i].cnt--; to_exec[i].abstime = now + to_exec[i].timeout; if (retry) { rv = retry(conn, to_exec+i); } else { - ssize_t _rv = pld ? ecp_pld_send(conn, pld, pld_size) : ecp_send(conn, ptype, NULL, 0); + ssize_t _rv = ecp_pld_send(conn, pld, pld_size); if (_rv < 0) rv = _rv; } - if (!rv) rv = ecp_timer_push(conn, to_exec+i); - if (rv && (rv != ECP_ERR_CLOSED) && handler) handler(conn, ptype, NULL, rv); + if (!rv) rv = ecp_timer_push(to_exec+i); + if (rv && (rv != ECP_ERR_CLOSED) && handler) handler(conn, mtype, NULL, rv); } else if (handler) { - handler(conn, ptype, NULL, ECP_ERR_TIMEOUT); + handler(conn, mtype, NULL, ECP_ERR_TIMEOUT); } #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); @@ -208,21 +209,16 @@ unsigned int ecp_timer_exe(ECPSocket *sock) { return ret; } -int ecp_timer_send(ECPConnection *conn, ecp_timer_retry_t *send_f, unsigned char ptype, unsigned short cnt, unsigned int timeout) { +ssize_t ecp_timer_send(ECPConnection *conn, ecp_timer_retry_t *send_f, unsigned char mtype, unsigned short cnt, unsigned int timeout) { + int rv = ECP_OK; ECPTimerItem ti; - int rv = ecp_timer_item_init(&ti, conn, ptype, cnt-1, timeout); + rv = ecp_timer_item_init(&ti, conn, mtype, cnt, timeout); if (rv) return rv; ti.retry = send_f; - rv = ecp_timer_push(conn, &ti); + rv = ecp_timer_push(&ti); if (rv) return rv; - ssize_t _rv = send_f(conn, NULL); - if (_rv < 0) { - ecp_timer_pop(conn, ptype); - return _rv; - } - - return ECP_OK; + return send_f(conn, NULL); } diff --git a/code/timer.h b/code/timer.h index dd9a2a8..0d43a99 100644 --- a/code/timer.h +++ b/code/timer.h @@ -12,11 +12,11 @@ struct ECPConnection; struct ECPSocket; struct ECPTimerItem; -typedef int ecp_timer_retry_t (struct ECPConnection *, struct ECPTimerItem *); +typedef ssize_t ecp_timer_retry_t (struct ECPConnection *, struct ECPTimerItem *); typedef struct ECPTimerItem { struct ECPConnection *conn; - unsigned char ptype; + unsigned char mtype; unsigned short cnt; unsigned int abstime; unsigned int timeout; @@ -35,9 +35,9 @@ typedef struct ECPTimer { int ecp_timer_create(ECPTimer *timer); void ecp_timer_destroy(ECPTimer *timer); -int ecp_timer_item_init(ECPTimerItem *ti, struct ECPConnection *conn, unsigned char ptype, unsigned short cnt, unsigned int timeout); -int ecp_timer_push(struct ECPConnection *conn, ECPTimerItem *ti); -void ecp_timer_pop(struct ECPConnection *conn, unsigned char ptype); +int ecp_timer_item_init(ECPTimerItem *ti, struct ECPConnection *conn, unsigned char mtype, unsigned short cnt, unsigned int timeout); +int ecp_timer_push(ECPTimerItem *ti); +void ecp_timer_pop(struct ECPConnection *conn, unsigned char mtype); void ecp_timer_remove(struct ECPConnection *conn); unsigned int ecp_timer_exe(struct ECPSocket *sock); -int ecp_timer_send(struct ECPConnection *conn, ecp_timer_retry_t *send_f, unsigned char ptype, unsigned short cnt, unsigned int timeout);
\ No newline at end of file +ssize_t ecp_timer_send(struct ECPConnection *conn, ecp_timer_retry_t *send_f, unsigned char mtype, unsigned short cnt, unsigned int timeout);
\ No newline at end of file |