summaryrefslogtreecommitdiff
path: root/ecp/src/ecp/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'ecp/src/ecp/core.c')
-rw-r--r--ecp/src/ecp/core.c231
1 files changed, 207 insertions, 24 deletions
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; i<remove_cnt; i++) {
+ _ecp_conn_close(to_remove[i]);
+ }
+
+ } while (remove_next);
+
+#else /* ECP_WITH_HTABLE */
+
+ do {
+ remove_cnt = 0;
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&sock->conn_table.mutex);
+#endif
+
+ for (i=0; i<sock->conn_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; i<remove_cnt; i++) {
+ _ecp_conn_close(to_remove[i]);
+ }
+
+ } while (remove_cnt < ECP_MAX_EXP);
+
+#endif /* ECP_WITH_HTABLE */
+}
+
int ecp_sock_init(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) {
int rv;
@@ -299,7 +440,9 @@ int ecp_sock_init(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) {
if (rv) return rv;
rv = ecp_bc_key_gen(&sock->minkey);
- 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);