From eb4833fc5dddd755c974f5ac7a8b4829c95ffa7b Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Fri, 8 Apr 2022 04:41:46 +0200 Subject: connection exire added --- ecp/src/ecp/core.c | 231 +++++++++++++++++++++++++++++++++---- ecp/src/ecp/core.h | 39 ++++--- ecp/src/ecp/ht.h | 19 ++- ecp/src/ecp/htable/hashtable.c | 8 +- ecp/src/ecp/htable/hashtable.h | 22 ++-- ecp/src/ecp/htable/hashtable_itr.c | 20 ++-- ecp/src/ecp/htable/hashtable_itr.h | 25 ++-- ecp/src/ecp/htable/htable.c | 56 +++++++-- 8 files changed, 324 insertions(+), 96 deletions(-) (limited to 'ecp') diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c index a0251c8..1ba042d 100644 --- a/ecp/src/ecp/core.c +++ b/ecp/src/ecp/core.c @@ -37,8 +37,6 @@ int ecp_dhkey_gen(ECPDHKey *key) { int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_dir_handler_t handle_dir, ecp_conn_alloc_t conn_alloc, ecp_conn_free_t conn_free) { int rv; - if (ctx == NULL) return ECP_ERR; - memset(ctx, 0, sizeof(ECPContext)); ctx->handle_err = handle_err; ctx->handle_dir = handle_dir; @@ -47,6 +45,7 @@ int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_dir_handler_ rv = ecp_tr_init(ctx); if (rv) return rv; + rv = ecp_tm_init(ctx); if (rv) return rv; @@ -101,36 +100,57 @@ static int conn_table_create(ECPConnTable *conn_table) { memset(conn_table, 0, sizeof(ECPConnTable)); +#ifdef ECP_WITH_PTHREAD + rv = pthread_mutex_init(&conn_table->mutex, NULL); + if (rv) { + return ECP_ERR; + } + + rv = pthread_mutex_init(&conn_table->mutex_inb, NULL); + if (rv) { + pthread_mutex_destroy(&conn_table->mutex); + return ECP_ERR; + } +#endif + + rv = ECP_OK; + #ifdef ECP_WITH_HTABLE conn_table->keys = ecp_ht_create_keys(); - if (conn_table->keys == NULL) return ECP_ERR_ALLOC; - conn_table->addrs = ecp_ht_create_addrs(); - if (conn_table->addrs == NULL) { - ecp_ht_destroy(conn_table->keys); - return ECP_ERR_ALLOC; + if (conn_table->keys == NULL) rv = ECP_ERR_ALLOC; + + if (!rv) { + conn_table->keys_inb = ecp_ht_create_keys(); + if (conn_table->keys_inb == NULL) rv = ECP_ERR_ALLOC; + } + + if (!rv) { + conn_table->addrs = ecp_ht_create_addrs(); + if (conn_table->addrs == NULL) rv = ECP_ERR_ALLOC; } -#endif -#ifdef ECP_WITH_PTHREAD - rv = pthread_mutex_init(&conn_table->mutex, NULL); if (rv) { -#ifdef ECP_WITH_HTABLE - ecp_ht_destroy(conn_table->addrs); - ecp_ht_destroy(conn_table->keys); +#ifdef ECP_WITH_PTHREAD + pthread_mutex_destroy(&conn_table->mutex_inb); + pthread_mutex_destroy(&conn_table->mutex); #endif - return ECP_ERR; + if (conn_table->addrs) ecp_ht_destroy(conn_table->addrs); + if (conn_table->keys_inb) ecp_ht_destroy(conn_table->keys_inb); + if (conn_table->keys) ecp_ht_destroy(conn_table->keys); } #endif - return ECP_OK; + return rv; } static void conn_table_destroy(ECPConnTable *conn_table) { #ifdef ECP_WITH_PTHREAD + pthread_mutex_destroy(&conn_table->mutex_inb); pthread_mutex_destroy(&conn_table->mutex); #endif #ifdef ECP_WITH_HTABLE ecp_ht_destroy(conn_table->addrs); + ecp_ht_destroy(conn_table->keys_inb); ecp_ht_destroy(conn_table->keys); #endif } @@ -191,6 +211,21 @@ static int conn_table_insert(ECPConnection *conn) { return ECP_OK; } +static int conn_table_insert_inb(ECPConnection *conn) { + ECPSocket *sock = conn->sock; + int rv = ECP_OK; + +#ifdef ECP_WITH_HTABLE + unsigned char idx; + + idx = conn->rkey_curr % ECP_MAX_NODE_KEY; + + rv = ecp_ht_insert(sock->conn_table.keys_inb, &conn->rkey[idx].public, conn); +#endif + + return rv; +} + static void conn_table_remove(ECPConnection *conn) { ECPSocket *sock = conn->sock; int i; @@ -287,6 +322,112 @@ static ECPConnection *conn_table_search(ECPSocket *sock, unsigned char c_idx, ec #endif } +static void conn_table_expire_inb(ECPSocket *sock, ecp_sts_t to) { + ECPConnection *conn; + ECPConnection *to_remove[ECP_MAX_EXP]; + int i, remove_cnt; + ecp_sts_t access_ts, now = ecp_tm_abstime_ms(0); + +#ifdef ECP_WITH_HTABLE + struct hashtable_itr itr; + void *remove_next; + int rv = ECP_OK; + + remove_next = NULL; + do { + remove_cnt = 0; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&sock->conn_table.mutex_inb); +#endif + + ecp_ht_itr_create(&itr, sock->conn_table.keys_inb); + if (remove_next) { + ecp_ht_itr_search(&itr, remove_next); + remove_next = NULL; + } + do { + conn = ecp_ht_itr_value(&itr); + if (conn) { +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + access_ts = conn->access_ts; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif + + if (now - access_ts > to) { + to_remove[remove_cnt] = conn; + remove_cnt++; + rv = ecp_ht_itr_remove(&itr); + if (remove_cnt == ECP_MAX_EXP) { + if (!rv) remove_next = ecp_ht_itr_key(&itr); + break; + } + } else { + rv = ecp_ht_itr_advance(&itr); + } + } else { + rv = ECP_ITR_END; + } + } while (rv == ECP_OK); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&sock->conn_table.mutex_inb); +#endif + + for (i=0; iconn_table.mutex); +#endif + + for (i=0; iconn_table.size; i++) { + conn = sock->conn_table.arr[i]; + if (ecp_conn_is_inb(conn)) { +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + access_ts = conn->access_ts; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif + + if (now - access_ts > to)) { + to_remove[remove_cnt] = conn; + remove_cnt++; + if (remove_cnt == ECP_MAX_EXP) break; + } + } + } + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&sock->conn_table.mutex); +#endif + + for (i=0; iminkey); - return rv; + if (rv) return rv; + + return ECP_OK; } int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) { @@ -453,6 +596,15 @@ void ecp_sock_get_nonce(ECPSocket *sock, ecp_nonce_t *nonce) { #endif } +int ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to) { + int rv; + + rv = ecp_sock_minkey_new(sock); + if (!rv) conn_table_expire_inb(sock, to); + + return rv; +} + int ecp_cookie_gen(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf) { ecp_bc_ctx_t bc_ctx; int i; @@ -864,6 +1016,25 @@ int ecp_conn_insert(ECPConnection *conn) { return rv; } +int ecp_conn_insert_inb(ECPConnection *conn) { + ECPSocket *sock = conn->sock; + int rv; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&sock->conn_table.mutex_inb); + pthread_mutex_lock(&conn->mutex); +#endif + + rv = conn_table_insert_inb(conn); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(&sock->conn_table.mutex_inb); +#endif + + return rv; +} + void ecp_conn_remove(ECPConnection *conn, unsigned short *refcount) { ECPSocket *sock = conn->sock; @@ -942,8 +1113,7 @@ int ecp_conn_reset(ECPConnection *conn) { return ECP_OK; } -void _ecp_conn_close(ECPConnection *conn) { - +static void conn_close(ECPConnection *conn) { if (ecp_conn_is_open(conn)) { ecp_close_handler_t handler; @@ -955,17 +1125,22 @@ void _ecp_conn_close(ECPConnection *conn) { if (ecp_conn_is_inb(conn)) ecp_conn_free(conn); } -int ecp_conn_close(ECPConnection *conn) { +int _ecp_conn_close(ECPConnection *conn) { unsigned short refcount = 0; ecp_timer_remove(conn); ecp_conn_remove(conn, &refcount); if (refcount) return ECP_ERR_BUSY; - _ecp_conn_close(conn); + conn_close(conn); return ECP_OK; } +int ecp_conn_close(ECPConnection *conn) { + if (ecp_conn_is_inb(conn)) return ECP_ERR; + return _ecp_conn_close(conn); +} + void ecp_conn_refcount_inc(ECPConnection *conn) { #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); @@ -994,7 +1169,7 @@ void ecp_conn_refcount_dec(ECPConnection *conn) { pthread_mutex_unlock(&conn->mutex); #endif - if (!is_reg && (refcount == 0)) _ecp_conn_close(conn); + if (!is_reg && (refcount == 0)) conn_close(conn); } int ecp_conn_dhkey_new(ECPConnection *conn) { @@ -1578,7 +1753,7 @@ ssize_t ecp_handle_open(ECPConnection *conn, unsigned char mtype, unsigned char pthread_mutex_unlock(&conn->mutex); #endif - if (ecp_conn_is_inb(conn)) ecp_conn_close(conn); + if (ecp_conn_is_inb(conn)) _ecp_conn_close(conn); return rv; } @@ -1589,9 +1764,14 @@ ssize_t ecp_handle_open(ECPConnection *conn, unsigned char mtype, unsigned char _rv = ecp_send_open_rep(conn); if (_rv < 0) { - ecp_conn_close(conn); + _ecp_conn_close(conn); return _rv; } + rv = ecp_conn_insert_inb(conn); + if (rv) { + _ecp_conn_close(conn); + return rv; + } } else if (ecp_conn_is_root(conn)) { ecp_conn_remove_addr(conn); } @@ -2004,7 +2184,10 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, conn->nonce_in = nonce_in; conn->nonce_map = nonce_map; - if (is_inb && addr) conn->remote.addr = *addr; + if (is_inb) { + conn->access_ts = ecp_tm_abstime_ms(0); + if (addr) conn->remote.addr = *addr; + } #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h index 810e8cd..4b47bcb 100644 --- a/ecp/src/ecp/core.h +++ b/ecp/src/ecp/core.h @@ -8,23 +8,23 @@ #define ECP_OK 0 #define ECP_PASS 1 +#define ECP_ITR_END 2 #define ECP_ERR -1 #define ECP_ERR_TIMEOUT -2 #define ECP_ERR_ALLOC -3 #define ECP_ERR_SIZE -4 -#define ECP_ERR_ITER -5 -#define ECP_ERR_BUSY -6 -#define ECP_ERR_EMPTY -7 -#define ECP_ERR_FULL -8 -#define ECP_ERR_MTYPE -9 -#define ECP_ERR_CTYPE -10 -#define ECP_ERR_HANDLER -11 -#define ECP_ERR_COOKIE -12 - -#define ECP_ERR_NET_ADDR -13 -#define ECP_ERR_MAX_PARENT -14 -#define ECP_ERR_NEXT -15 +#define ECP_ERR_BUSY -5 +#define ECP_ERR_EMPTY -6 +#define ECP_ERR_FULL -7 +#define ECP_ERR_MTYPE -8 +#define ECP_ERR_CTYPE -9 +#define ECP_ERR_HANDLER -10 +#define ECP_ERR_COOKIE -11 + +#define ECP_ERR_NET_ADDR -12 +#define ECP_ERR_MAX_PARENT -13 +#define ECP_ERR_NEXT -14 #define ECP_ERR_ECDH_KEY_DUP -21 #define ECP_ERR_ECDH_IDX -22 @@ -46,6 +46,7 @@ #define ECP_MAX_MTYPE 16 #define ECP_MAX_PARENT 3 #define ECP_MAX_SEQ_FWD 1024 +#define ECP_MAX_EXP 100 #define ECP_SIZE_PROTO 2 #define ECP_SIZE_NONCE 8 @@ -178,6 +179,9 @@ struct ECPConnection; struct ECPDirList; #endif +#ifdef ECP_WITH_HTABLE +#include "htable/htable.h" +#endif #include "crypto/crypto.h" #include "transport.h" #include "timer.h" @@ -253,14 +257,16 @@ typedef struct ECPContext { typedef struct ECPConnTable { #ifdef ECP_WITH_HTABLE - void *keys; - void *addrs; + ecp_ht_table_t *keys; + ecp_ht_table_t *keys_inb; + ecp_ht_table_t *addrs; #else struct ECPConnection *arr[ECP_MAX_SOCK_CONN]; unsigned short size; #endif #ifdef ECP_WITH_PTHREAD pthread_mutex_t mutex; + pthread_mutex_t mutex_inb; #endif } ECPConnTable; @@ -297,6 +303,7 @@ typedef struct ECPConnection { unsigned char key_next; unsigned char rkey_curr; ECPDHShkey shkey[ECP_MAX_NODE_KEY][ECP_MAX_NODE_KEY]; + ecp_sts_t access_ts; #ifdef ECP_WITH_PTHREAD pthread_mutex_t mutex; #endif @@ -327,6 +334,7 @@ int ecp_sock_dhkey_new(ECPSocket *sock); int ecp_sock_dhkey_get(ECPSocket *sock, unsigned char idx, ECPDHKey *key); int ecp_sock_dhkey_get_pub(ECPSocket *sock, unsigned char *idx, ecp_ecdh_public_t *public); void ecp_sock_get_nonce(ECPSocket *sock, ecp_nonce_t *nonce); +int ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to); int ecp_cookie_gen(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf); int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf); @@ -349,12 +357,13 @@ int ecp_conn_init_inb(ECPConnection *conn, ECPConnection *parent, unsigned char int ecp_conn_init_outb(ECPConnection *conn, ECPNode *node); int ecp_conn_insert(ECPConnection *conn); +int ecp_conn_insert_inb(ECPConnection *conn); void ecp_conn_remove(ECPConnection *conn, unsigned short *refcount); void ecp_conn_remove_addr(ECPConnection *conn); int ecp_conn_open(ECPConnection *conn, ECPNode *node); int ecp_conn_reset(ECPConnection *conn); -void _ecp_conn_close(ECPConnection *conn); +int _ecp_conn_close(ECPConnection *conn); int ecp_conn_close(ECPConnection *conn); void ecp_conn_refcount_inc(ECPConnection *conn); void ecp_conn_refcount_dec(ECPConnection *conn); diff --git a/ecp/src/ecp/ht.h b/ecp/src/ecp/ht.h index cf33454..31ca698 100644 --- a/ecp/src/ecp/ht.h +++ b/ecp/src/ecp/ht.h @@ -1,7 +1,14 @@ -void *ecp_ht_create_keys(void); -void *ecp_ht_create_addrs(void); +ecp_ht_table_t *ecp_ht_create_keys(void); +ecp_ht_table_t *ecp_ht_create_addrs(void); -void ecp_ht_destroy(void *h); -int ecp_ht_insert(void *h, void *k, ECPConnection *v); -ECPConnection *ecp_ht_remove(void *h, void *k); -ECPConnection *ecp_ht_search(void *h, void *k); +void ecp_ht_destroy(ecp_ht_table_t *h); +int ecp_ht_insert(ecp_ht_table_t *h, void *k, ECPConnection *v); +ECPConnection *ecp_ht_remove(ecp_ht_table_t *h, void *k); +ECPConnection *ecp_ht_search(ecp_ht_table_t *h, void *k); + +void ecp_ht_itr_create(ecp_ht_itr_t *i, ecp_ht_table_t *h); +int ecp_ht_itr_advance(ecp_ht_itr_t *i); +int ecp_ht_itr_remove(ecp_ht_itr_t *i); +int ecp_ht_itr_search(ecp_ht_itr_t *i, void *k); +void *ecp_ht_itr_key(ecp_ht_itr_t *i); +ECPConnection *ecp_ht_itr_value(ecp_ht_itr_t *i); diff --git a/ecp/src/ecp/htable/hashtable.c b/ecp/src/ecp/htable/hashtable.c index 36c8a6d..4a48edb 100755 --- a/ecp/src/ecp/htable/hashtable.c +++ b/ecp/src/ecp/htable/hashtable.c @@ -78,11 +78,15 @@ hashtable_prime_size(unsigned int minsize) void * hashtable_entry_key(struct entry *e) -{ return e->k; } +{ + return e->k; +} void * hashtable_entry_value(struct entry *e) -{ return e->v; } +{ + return e->v; +} /*****************************************************************************/ unsigned int diff --git a/ecp/src/ecp/htable/hashtable.h b/ecp/src/ecp/htable/hashtable.h index a0b1949..8faeafc 100755 --- a/ecp/src/ecp/htable/hashtable.h +++ b/ecp/src/ecp/htable/hashtable.h @@ -94,24 +94,18 @@ unsigned int hashtable_prime_size(unsigned int minsize); /*****************************************************************************/ -/* hashtable_iterator_key - * - return the key of the (key,value) pair at the current position */ +/* hashtable_entry_key + * - return the key of the (key,value) pair from hash table entry */ -extern inline void * -hashtable_entry_key(struct entry *e) -{ - return e->v; -} +void * +hashtable_entry_key(struct entry *e); /*****************************************************************************/ -/* hashtable_iterator_value - * - return the value of the (key,value) pair at the current position */ +/* hashtable_entry_value + * - return the value of the (key,value) pair from hash table entry */ -extern inline void * -hashtable_entry_value(struct entry *e) -{ - return e->v; -} +void * +hashtable_entry_value(struct entry *e); /***************************************************************************** * hashtable_insert diff --git a/ecp/src/ecp/htable/hashtable_itr.c b/ecp/src/ecp/htable/hashtable_itr.c index e77bbb0..85114f2 100755 --- a/ecp/src/ecp/htable/hashtable_itr.c +++ b/ecp/src/ecp/htable/hashtable_itr.c @@ -8,7 +8,7 @@ /*****************************************************************************/ /* hashtable_iterator - iterator constructor */ -int +void hashtable_iterator(struct hashtable_itr *itr, struct hashtable *h) { unsigned int i, tablelength; @@ -17,7 +17,7 @@ hashtable_iterator(struct hashtable_itr *itr, struct hashtable *h) itr->parent = NULL; tablelength = h->tablelength; itr->index = tablelength; - if (0 == h->entrycount) return -1; + if (0 == h->entrycount) return; for (i = 0; i < tablelength; i++) { @@ -28,7 +28,6 @@ hashtable_iterator(struct hashtable_itr *itr, struct hashtable *h) break; } } - return -1; } /*****************************************************************************/ @@ -38,15 +37,21 @@ hashtable_iterator(struct hashtable_itr *itr, struct hashtable *h) void * hashtable_iterator_key(struct hashtable_itr *i) -{ return i->e->k; } +{ + return i->e ? i->e->k : NULL; +} void * hashtable_iterator_value(struct hashtable_itr *i) -{ return i->e->v; } +{ + return i->e ? i->e->v : NULL; +} struct entry * hashtable_iterator_entry(struct hashtable_itr *i) -{ return i->e; } +{ + return i->e; +} /*****************************************************************************/ /* advance - advance the iterator to the next element @@ -158,7 +163,6 @@ hashtable_iterator_search(struct hashtable_itr *itr, void *k) itr->index = index; itr->e = e; itr->parent = parent; - itr->h = h; return -1; } parent = e; @@ -184,8 +188,8 @@ hashtable_iterator_search_next(struct hashtable_itr *itr, void *k) /* Check hash value to short circuit heavier comparison */ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { - itr->parent = parent; itr->e = e; + itr->parent = parent; return -1; } parent = e; diff --git a/ecp/src/ecp/htable/hashtable_itr.h b/ecp/src/ecp/htable/hashtable_itr.h index 47b29cc..04f462f 100755 --- a/ecp/src/ecp/htable/hashtable_itr.h +++ b/ecp/src/ecp/htable/hashtable_itr.h @@ -21,38 +21,29 @@ struct hashtable_itr /* hashtable_iterator */ -int -hashtable_iterator(struct hashtable_itr *, struct hashtable *h); +void +hashtable_iterator(struct hashtable_itr *i, struct hashtable *h); /*****************************************************************************/ /* hashtable_iterator_key * - return the key of the (key,value) pair at the current position */ -extern inline void * -hashtable_iterator_key(struct hashtable_itr *i) -{ - return i->e->k; -} +void * +hashtable_iterator_key(struct hashtable_itr *i); /*****************************************************************************/ /* hashtable_iterator_value * - return the value of the (key,value) pair at the current position */ -extern inline void * -hashtable_iterator_value(struct hashtable_itr *i) -{ - return i->e->v; -} +void * +hashtable_iterator_value(struct hashtable_itr *i); /*****************************************************************************/ /* hashtable_iterator_entry * - return the hash table entry at the current position */ -extern inline struct entry * -hashtable_iterator_entry(struct hashtable_itr *i) -{ - return i->e; -} +struct entry * +hashtable_iterator_entry(struct hashtable_itr *i); /*****************************************************************************/ /* advance - advance the iterator to the next element diff --git a/ecp/src/ecp/htable/htable.c b/ecp/src/ecp/htable/htable.c index bd8ab2d..c0efebb 100644 --- a/ecp/src/ecp/htable/htable.c +++ b/ecp/src/ecp/htable/htable.c @@ -5,30 +5,66 @@ #include #include -#include "hashtable.h" - -void *ecp_ht_create_keys(void) { +ecp_ht_table_t *ecp_ht_create_keys(void) { return hashtable_create(1000, (unsigned int (*)(void *))ecp_ecdh_pub_hash, (int (*)(void *, void *))ecp_ecdh_pub_eq); } -void *ecp_ht_create_addrs(void) { +ecp_ht_table_t *ecp_ht_create_addrs(void) { return hashtable_create(1000, (unsigned int (*)(void *))ecp_tr_addr_hash, (int (*)(void *, void *))ecp_tr_addr_eq); } -void ecp_ht_destroy(void *h) { +void ecp_ht_destroy(ecp_ht_table_t *h) { hashtable_destroy(h, 0); } -int ecp_ht_insert(void *h, void *k, ECPConnection *v) { - int rv = hashtable_insert(h, k, v); - if (!rv) return ECP_ERR; +int ecp_ht_insert(ecp_ht_table_t *h, void *k, ECPConnection *v) { + int rv; + + rv = hashtable_insert(h, k, v); + if (rv == 0) return ECP_ERR; return ECP_OK; } -ECPConnection *ecp_ht_remove(void *h, void *k) { +ECPConnection *ecp_ht_remove(ecp_ht_table_t *h, void *k) { return hashtable_remove(h, k); } -ECPConnection *ecp_ht_search(void *h, void *k) { +ECPConnection *ecp_ht_search(ecp_ht_table_t *h, void *k) { return hashtable_search(h, k); } + +void ecp_ht_itr_create(ecp_ht_itr_t *i, ecp_ht_table_t *h) { + hashtable_iterator(i, h); +} + +int ecp_ht_itr_advance(ecp_ht_itr_t *i) { + int rv; + + rv = hashtable_iterator_advance(i); + if (rv == 0) return ECP_ITR_END; + return rv; +} + +int ecp_ht_itr_remove(ecp_ht_itr_t *i) { + int rv; + + rv = hashtable_iterator_remove(i); + if (rv == 0) return ECP_ITR_END; + return ECP_OK; +} + +int ecp_ht_itr_search(ecp_ht_itr_t *i, void *k) { + int rv; + + rv = hashtable_iterator_search(i, k); + if (rv == 0) return ECP_ERR; + return ECP_OK; +} + +void *ecp_ht_itr_key(ecp_ht_itr_t *i) { + return hashtable_iterator_key(i); +} + +ECPConnection *ecp_ht_itr_value(ecp_ht_itr_t *i) { + return hashtable_iterator_value(i); +} -- cgit v1.2.3