diff options
Diffstat (limited to 'ecp/src')
-rw-r--r-- | ecp/src/ecp/core.c | 206 | ||||
-rw-r--r-- | ecp/src/ecp/core.h | 10 | ||||
-rw-r--r-- | ecp/src/ecp/timer.c | 8 |
3 files changed, 142 insertions, 82 deletions
diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c index be70614..3def373 100644 --- a/ecp/src/ecp/core.c +++ b/ecp/src/ecp/core.c @@ -235,17 +235,6 @@ static int conn_table_insert(ECPConnection *conn) { return ECP_OK; } -static int conn_table_insert_gc(ECPConnection *conn) { - ECPSocket *sock = conn->sock; - int rv = ECP_OK; - -#ifdef ECP_WITH_HTABLE - rv = ecp_ht_insert(sock->conn_table.keys_gc, &conn->remote.key_perma.public, conn); -#endif - - return rv; -} - static void conn_table_remove(ECPConnection *conn) { ECPSocket *sock = conn->sock; int i; @@ -421,7 +410,7 @@ static void conn_table_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t pthread_mutex_lock(&conn->mutex); #endif - expired = conn_expired(conn, now, to) || !_ecp_conn_is_reg(conn); + expired = conn_expired(conn, now, to); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); @@ -451,7 +440,7 @@ static void conn_table_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t #endif for (i=0; i<remove_cnt; i++) { - ecp_conn_close(to_remove[i]); + ecp_conn_remove(to_remove[i]); ecp_conn_refcount_dec(to_remove[i]); } } while (remove_next); @@ -472,7 +461,7 @@ static void conn_table_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t pthread_mutex_lock(&conn->mutex); #endif - expired = conn_expired(conn, now, to) || !_ecp_conn_is_reg(conn); + expired = conn_expired(conn, now, to); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); @@ -491,7 +480,7 @@ static void conn_table_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t #endif for (i=0; i<remove_cnt; i++) { - ecp_conn_close(to_remove[i]); + ecp_conn_remove(to_remove[i]); ecp_conn_refcount_dec(to_remove[i]); } @@ -935,6 +924,21 @@ void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) { conn->keyx_ts = 0; } +int ecp_conn_init_outb(ECPConnection *conn) { + ECPDHKey key; + int rv; + + conn->key_curr = 0; + + rv = ecp_dhkey_gen(&key); + if (rv) return rv; + + rv = conn_dhkey_new(conn, conn->key_curr, &key); + if (rv) return rv; + + return ECP_OK; +} + int ecp_conn_reset(ECPConnection *conn) { if (conn->flags) return ECP_ERR; @@ -984,6 +988,7 @@ int ecp_conn_create(ECPConnection *conn, ECPConnection *parent) { ecp_conn_refcount_inc(parent); } #endif + if (!ecp_conn_is_gc(conn)) conn->refcount++; return ECP_OK; } @@ -1002,7 +1007,6 @@ int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned cha rv = conn_shkey_set(conn, s_idx, c_idx, shkey); if (rv) return rv; - ecp_conn_set_flags(conn, ECP_CONN_FLAG_GC); conn->refcount = 1; conn->key_curr = s_idx; conn->rkey_curr = c_idx; @@ -1025,23 +1029,34 @@ int ecp_conn_create_outb(ECPConnection *conn, ECPConnection *parent, ECPNode *no conn->refcount = 1; if (node) conn->remote = *node; - rv = ecp_conn_reset_outb(conn); + rv = ecp_conn_init_outb(conn); if (rv) return rv; rv = ecp_conn_create(conn, parent); - return rv; + if (rv) return rv; + + return ECP_OK; } int ecp_conn_reset_outb(ECPConnection *conn) { - ECPDHKey key; - int rv; + int rv = ECP_OK; - conn->key_curr = 0; + ecp_conn_remove(conn); - rv = ecp_dhkey_gen(&key); +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + if (_ecp_conn_is_open(conn)) rv = ECP_ERR; + if (!rv) rv = ecp_conn_reset(conn); + if (!rv) rv = ecp_conn_init_outb(conn); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif if (rv) return rv; - rv = conn_dhkey_new(conn, conn->key_curr, &key); + rv = ecp_conn_insert(conn); if (rv) return rv; return ECP_OK; @@ -1051,6 +1066,7 @@ void ecp_conn_destroy(ECPConnection *conn) { #ifdef ECP_WITH_VCONN if (conn->parent) { ecp_conn_refcount_dec(conn->parent); + conn->parent = NULL; } #endif @@ -1073,54 +1089,54 @@ int ecp_conn_insert(ECPConnection *conn) { ECPSocket *sock = conn->sock; int rv; - _ecp_conn_set_reg(conn); - #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&sock->conn_table.mutex); + pthread_mutex_lock(&conn->mutex); #endif + _ecp_conn_set_reg(conn); rv = conn_table_insert(conn); + if (rv) _ecp_conn_clr_reg(conn); #ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); pthread_mutex_unlock(&sock->conn_table.mutex); #endif - if (rv) _ecp_conn_clr_reg(conn); - return rv; } int ecp_conn_insert_gc(ECPConnection *conn) { ECPSocket *sock = conn->sock; - int rv; + int rv = ECP_OK; +#ifdef ECP_WITH_HTABLE #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&sock->conn_table.mutex_gc); #endif - rv = conn_table_insert_gc(conn); + rv = ecp_ht_insert(sock->conn_table.keys_gc, &conn->remote.key_perma.public, conn); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&sock->conn_table.mutex_gc); #endif + if (!rv) ecp_conn_refcount_inc(conn); + +#endif /* ECP_WITH_HTABLE */ + return rv; } -int ecp_conn_remove(ECPConnection *conn, int *refcount) { +void ecp_conn_remove(ECPConnection *conn) { ECPSocket *sock = conn->sock; - int rv = ECP_OK; #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&sock->conn_table.mutex); pthread_mutex_lock(&conn->mutex); #endif - if (refcount) { - if ((*refcount != -1) && (*refcount != conn->refcount)) rv = ECP_ERR_BUSY; - *refcount = conn->refcount; - } - if (!rv && _ecp_conn_is_reg(conn)) { + if (_ecp_conn_is_reg(conn)) { conn_table_remove(conn); _ecp_conn_clr_reg(conn); } @@ -1129,8 +1145,6 @@ int ecp_conn_remove(ECPConnection *conn, int *refcount) { pthread_mutex_unlock(&conn->mutex); pthread_mutex_unlock(&sock->conn_table.mutex); #endif - - return rv; } void ecp_conn_remove_addr(ECPConnection *conn) { @@ -1150,8 +1164,45 @@ void ecp_conn_remove_addr(ECPConnection *conn) { } +void ecp_conn_remove_gc(ECPConnection *conn) { + ECPSocket *sock = conn->sock; + ECPConnection *_conn = NULL; + +#ifdef ECP_WITH_HTABLE +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&sock->conn_table.mutex_gc); +#endif + + _conn = ecp_ht_remove_kv(sock->conn_table.keys_gc, &conn->remote.key_perma.public, conn); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&sock->conn_table.mutex_gc); +#endif +#endif + + if (_conn) { + ecp_conn_refcount_dec(conn); + } else { + int destroy = 0; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + if ((conn->refcount == 0) && !_ecp_conn_is_reg(conn)) destroy = 1; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif + + if (destroy) { + _ecp_conn_close(conn); + } + } +} + int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, ECPNode *node, int retry) { - int rv = ECP_OK; + int rv; ssize_t _rv; rv = ecp_conn_create_outb(conn, parent, node); @@ -1165,7 +1216,9 @@ int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, ECPNode *node, in _rv = ecp_send_init_req(conn, retry); if (_rv < 0) { - ecp_conn_close(conn); + ecp_timer_remove(conn); + ecp_conn_remove(conn); + if (!ecp_conn_is_gc(conn)) ecp_conn_refcount_dec(conn); rv = _rv; } @@ -1174,6 +1227,15 @@ int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, ECPNode *node, in return rv; } +int _ecp_conn_reopen(ECPConnection *conn, int retry) { + int rv; + + rv = ecp_conn_reset_outb(conn); + if (rv) return rv; + + return ecp_send_init_req(conn, retry); +} + int ecp_conn_open(ECPConnection *conn, ECPNode *node) { int rv; @@ -1188,7 +1250,14 @@ int ecp_conn_try_open(ECPConnection *conn, ECPNode *node) { return rv; } -static void _conn_close(ECPConnection *conn) { +int ecp_conn_reopen(ECPConnection *conn) { + int rv; + + rv = _ecp_conn_reopen(conn, 1); + return rv; +} + +void _ecp_conn_close(ECPConnection *conn) { if (_ecp_conn_is_open(conn)) { ecp_close_handler_t handler; @@ -1200,15 +1269,14 @@ static void _conn_close(ECPConnection *conn) { ecp_conn_destroy(conn); } -int ecp_conn_close(ECPConnection *conn) { - int refcount = -1; - +void ecp_conn_close(ECPConnection *conn) { ecp_timer_remove(conn); - ecp_conn_remove(conn, &refcount); - if (refcount) return ECP_ERR_BUSY; - _conn_close(conn); - - return ECP_OK; + ecp_conn_remove(conn); + if (ecp_conn_is_gc(conn)) { + ecp_conn_remove_gc(conn); + } else { + ecp_conn_refcount_dec(conn); + } } int _ecp_conn_expired(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to) { @@ -1260,7 +1328,9 @@ void ecp_conn_refcount_dec(ECPConnection *conn) { pthread_mutex_unlock(&conn->mutex); #endif - if (!is_reg && (refcount == 0)) _conn_close(conn); + if (!is_reg && (refcount == 0)) { + _ecp_conn_close(conn); + } } void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags) { @@ -1534,22 +1604,11 @@ static ssize_t _send_ireq(ECPConnection *conn, ECPTimerItem *ti) { } static ssize_t _retry_ireq(ECPConnection *conn, ECPTimerItem *ti) { - int refcount = 1; int rv; - /* timer holds one reference to this connection, nobody else should */ - rv = ecp_conn_remove(conn, &refcount); - if (rv) return rv; - - rv = ecp_conn_reset(conn); - if (rv) return rv; - rv = ecp_conn_reset_outb(conn); if (rv) return rv; - rv = ecp_conn_insert(conn); - if (rv) return rv; - return _send_ireq(conn, ti); } @@ -1844,31 +1903,21 @@ ssize_t ecp_handle_open(ECPConnection *conn, unsigned char mtype, unsigned char is_gc = ecp_conn_is_gc(conn); if (is_gc) { - ECPSocket *sock = conn->sock; - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&sock->conn_table.mutex_gc); - pthread_mutex_lock(&conn->mutex); -#endif - - _rv = conn_table_insert_gc(conn); - if (!_rv) conn->refcount++; - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&conn->mutex); - pthread_mutex_unlock(&sock->conn_table.mutex_gc); -#endif - + _rv = ecp_conn_insert_gc(conn); if (_rv) return _rv; } _rv = ecp_ext_conn_open(conn); - if (_rv) return _rv; + if (_rv) { + if (is_gc) ecp_conn_remove_gc(conn); + return _rv; + } handler = ecp_get_open_handler(conn); if (handler) { _rv = handler(conn, bufs); if (_rv) { + if (is_gc) ecp_conn_remove_gc(conn); ecp_ext_conn_close(conn); return _rv; } @@ -2351,7 +2400,8 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, if (is_open_msg) { rv = ecp_pld_handle_one(conn, seq, payload, pld_size, bufs); if (rv < 0) { - ecp_conn_close(conn); + ecp_conn_remove(conn); + if (!ecp_conn_is_gc(conn)) ecp_conn_refcount_dec(conn); goto unpack_fin; } diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h index b40d813..f988c19 100644 --- a/ecp/src/ecp/core.h +++ b/ecp/src/ecp/core.h @@ -381,6 +381,7 @@ int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *pub ECPConnection *ecp_conn_new_inb(ECPSocket *sock, unsigned char ctype); void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype); +int ecp_conn_init_outb(ECPConnection *conn); int ecp_conn_reset(ECPConnection *conn); int ecp_conn_create(ECPConnection *conn, ECPConnection *parent); int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *rkey_perma, ecp_aead_key_t *shkey); @@ -391,13 +392,18 @@ void ecp_conn_free(ECPConnection *conn); int ecp_conn_insert(ECPConnection *conn); int ecp_conn_insert_gc(ECPConnection *conn); -int ecp_conn_remove(ECPConnection *conn, int *refcount); +void ecp_conn_remove(ECPConnection *conn); void ecp_conn_remove_addr(ECPConnection *conn); +void ecp_conn_remove_gc(ECPConnection *conn); int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, ECPNode *node, int retry); +int _ecp_conn_reopen(ECPConnection *conn, int retry); int ecp_conn_open(ECPConnection *conn, ECPNode *node); int ecp_conn_try_open(ECPConnection *conn, ECPNode *node); -int ecp_conn_close(ECPConnection *conn); +int ecp_conn_reopen(ECPConnection *conn); + +void _ecp_conn_close(ECPConnection *conn); +void ecp_conn_close(ECPConnection *conn); int _ecp_conn_expired(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to); int ecp_conn_is_zombie(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to); void ecp_conn_refcount_inc(ECPConnection *conn); diff --git a/ecp/src/ecp/timer.c b/ecp/src/ecp/timer.c index 9e86a88..c8e03b9 100644 --- a/ecp/src/ecp/timer.c +++ b/ecp/src/ecp/timer.c @@ -181,11 +181,15 @@ ecp_sts_t ecp_timer_exe(ECPSocket *sock) { _rv = retry(conn, to_exec+i); if (_rv < 0) rv = _rv; } - if (rv && (rv != ECP_ERR_CLOSED)) ecp_err_handle(conn, mtype, rv); + if (rv && (rv != ECP_ERR_CLOSED)) { + ecp_err_handle(conn, mtype, rv); + } } else { rv = ECP_ERR_TIMEOUT; ecp_err_handle(conn, mtype, rv); - if (mtype == ECP_MTYPE_OPEN_REP) ecp_conn_close(conn); + if (mtype == ECP_MTYPE_OPEN_REP) { + ecp_conn_remove(conn); + } } #ifdef ECP_DEBUG |