summaryrefslogtreecommitdiff
path: root/ecp
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2022-03-12 13:08:52 +0100
committerUros Majstorovic <majstor@majstor.org>2022-03-12 13:08:52 +0100
commit3436ce5d3ffbc2777e785310bac971c830cbb4ff (patch)
treec3ffb0d18bb992e8b97818e4d0b369844979012d /ecp
parentd359dd9981f4137e8873a7a571e5c54c5b2449c4 (diff)
new rev compile OK
Diffstat (limited to 'ecp')
-rw-r--r--ecp/src/ecp/TODO4
-rw-r--r--ecp/src/ecp/core.c2727
-rw-r--r--ecp/src/ecp/core.h489
-rw-r--r--ecp/src/ecp/cr.h29
-rw-r--r--ecp/src/ecp/crypto/crypto.c106
-rw-r--r--ecp/src/ecp/crypto/crypto.h28
-rw-r--r--ecp/src/ecp/dir.c160
-rw-r--r--ecp/src/ecp/dir.h20
-rw-r--r--ecp/src/ecp/dir_srv.c86
-rw-r--r--ecp/src/ecp/dir_srv.h13
-rw-r--r--ecp/src/ecp/ht.h10
-rw-r--r--ecp/src/ecp/htable/htable.c20
-rw-r--r--ecp/src/ecp/msgq.c123
-rw-r--r--ecp/src/ecp/msgq.h31
-rw-r--r--ecp/src/ecp/rbuf.c236
-rw-r--r--ecp/src/ecp/rbuf.h115
-rw-r--r--ecp/src/ecp/rbuf_recv.c375
-rw-r--r--ecp/src/ecp/rbuf_send.c296
-rw-r--r--ecp/src/ecp/timer.c46
-rw-r--r--ecp/src/ecp/timer.h12
-rw-r--r--ecp/src/ecp/tm.h6
-rw-r--r--ecp/src/ecp/tr.h9
-rw-r--r--ecp/src/ecp/vconn/vconn.c733
-rw-r--r--ecp/src/ecp/vconn/vconn.h37
-rw-r--r--ecp/src/platform/fe310/time.c10
-rw-r--r--ecp/src/platform/fe310/transport.c16
-rw-r--r--ecp/src/platform/fe310/transport.h7
-rw-r--r--ecp/src/platform/posix/platform.mk2
-rw-r--r--ecp/src/platform/posix/platform_obj.mk2
-rw-r--r--ecp/src/platform/posix/time.c9
-rw-r--r--ecp/src/platform/posix/transport.c17
-rw-r--r--ecp/src/platform/posix/transport.h8
-rw-r--r--ecp/util/mknode.c23
-rw-r--r--ecp/util/util.c35
-rw-r--r--ecp/util/util.h8
35 files changed, 3081 insertions, 2767 deletions
diff --git a/ecp/src/ecp/TODO b/ecp/src/ecp/TODO
index 01c2a28..8f633ed 100644
--- a/ecp/src/ecp/TODO
+++ b/ecp/src/ecp/TODO
@@ -1,9 +1,5 @@
-+ check for nonce
-+ check for seq
-
- memzero keys after usage
- implement socket message queue
rbuf:
- implement _wait variants of open / send
-- msgq should subtract ECP_MAX_MTYPE_SYS from mtype (make ECPConnMsgQ smaller)
diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c
index 90ee925..d59ea8f 100644
--- a/ecp/src/ecp/core.c
+++ b/ecp/src/ecp/core.c
@@ -1,4 +1,20 @@
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef ECP_DEBUG
+#include <stdio.h>
+#endif
+
#include "core.h"
+#include "ext.h"
+
+#ifdef ECP_WITH_VCONN
+#include "vconn/vconn.h"
+#endif
+
+#ifdef ECP_WITH_DIR
+#include "dir.h"
+#endif
#include "cr.h"
#include "tr.h"
@@ -8,14 +24,17 @@
#include "ht.h"
#endif
-#include "dir_srv.h"
-int ecp_ctx_init(ECPContext *ctx) {
+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;
+ ctx->conn_alloc = conn_alloc;
+ ctx->conn_free = conn_free;
rv = ecp_tr_init(ctx);
if (rv) return rv;
@@ -25,10 +44,22 @@ int ecp_ctx_init(ECPContext *ctx) {
return ECP_OK;
}
-int ecp_node_init(ECPNode *node, ecp_dh_public_t *public, void *addr) {
+int ecp_ctx_set_handler(ECPContext *ctx, ECPConnHandler *handler, unsigned char ctype) {
+ if (ctype >= ECP_MAX_CTYPE) return ECP_ERR_CTYPE;
+
+ ctx->handler[ctype] = handler;
+ return ECP_OK;
+}
+
+int ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, void *addr) {
memset(node, 0, sizeof(ECPNode));
- if (public) memcpy(&node->public, public, sizeof(node->public));
+ if (public) {
+ ECPDHPub *key = &node->key_perma;
+
+ memcpy(&key->public, public, sizeof(key->public));
+ key->valid = 1;
+ }
if (addr) {
int rv;
@@ -40,53 +71,37 @@ int ecp_node_init(ECPNode *node, ecp_dh_public_t *public, void *addr) {
return ECP_OK;
}
-int ecp_seq_item_init(ECPSeqItem *seq_item) {
- memset(seq_item, 0, sizeof(ECPSeqItem));
-
- return ECP_OK;
-}
-
-int ecp_frag_iter_init(ECPFragIter *iter, unsigned char *buffer, size_t buf_size) {
- memset(iter, 0, sizeof(ECPFragIter));
- iter->buffer = buffer;
- iter->buf_size = buf_size;
-
- return ECP_OK;
-}
-
-void ecp_frag_iter_reset(ECPFragIter *iter) {
- iter->seq = 0;
- iter->frag_cnt = 0;
- iter->msg_size = 0;
-}
-
-int ecp_dhkey_gen(ECPContext *ctx, ECPDHKey *key) {
+int ecp_dhkey_gen(ECPDHKey *key) {
int rv;
- if (ctx->rng == NULL) return ECP_ERR_RNG;
-
- rv = ecp_cr_dh_mkpair(&key->public, &key->private, ctx->rng);
+ rv = ecp_ecdh_mkpair(&key->public, &key->private);
if (rv) return rv;
key->valid = 1;
return ECP_OK;
}
-static int ctable_create(ECPSockCTable *conn, ECPContext *ctx) {
+static int conn_table_create(ECPConnTable *conn_table) {
int rv;
- memset(conn, 0, sizeof(ECPSockCTable));
+ memset(conn_table, 0, sizeof(ECPConnTable));
#ifdef ECP_WITH_HTABLE
- conn->htable = ecp_ht_create(ctx);
- if (conn->htable == NULL) return ECP_ERR_ALLOC;
+ 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;
+ }
#endif
#ifdef ECP_WITH_PTHREAD
- rv = pthread_mutex_init(&conn->mutex, NULL);
+ rv = pthread_mutex_init(&conn_table->mutex, NULL);
if (rv) {
#ifdef ECP_WITH_HTABLE
- ecp_ht_destroy(conn->htable);
+ ecp_ht_destroy(conn_table->addrs);
+ ecp_ht_destroy(conn_table->keys);
#endif
return ECP_ERR;
}
@@ -95,97 +110,134 @@ static int ctable_create(ECPSockCTable *conn, ECPContext *ctx) {
return ECP_OK;
}
-static void ctable_destroy(ECPSockCTable *conn, ECPContext *ctx) {
+static void conn_table_destroy(ECPConnTable *conn_table) {
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_destroy(&conn->mutex);
+ pthread_mutex_destroy(&conn_table->mutex);
#endif
#ifdef ECP_WITH_HTABLE
- ecp_ht_destroy(conn->htable);
+ ecp_ht_destroy(conn_table->addrs);
+ ecp_ht_destroy(conn_table->keys);
#endif
}
-static int ctable_insert(ECPConnection *conn) {
+static int conn_table_insert(ECPConnection *conn) {
ECPSocket *sock = conn->sock;
#ifdef ECP_WITH_HTABLE
int i, rv = ECP_OK;
if (ecp_conn_is_outb(conn)) {
+ if (!ecp_conn_is_open(conn)) rv = ecp_ht_insert(sock->conn_table.addrs, &conn->remote.addr, conn);
+ if (rv) return rv;
+
for (i=0; i<ECP_MAX_CONN_KEY; i++) {
- if (conn->key[i].valid) rv = ecp_ht_insert(sock->conn.htable, ecp_cr_dh_pub_get_buf(&conn->key[i].public), conn);
+ if (conn->key[i].valid) rv = ecp_ht_insert(sock->conn_table.keys, &conn->key[i].public, conn);
if (rv) {
int j;
- for (j=0; j<i; j++) if (conn->key[j].valid) ecp_ht_remove(sock->conn.htable, ecp_cr_dh_pub_get_buf(&conn->key[j].public));
+
+ for (j=0; j<i; j++) {
+ if (conn->key[j].valid) ecp_ht_remove(sock->conn_table.keys, &conn->key[j].public);
+ }
+ if (!ecp_conn_is_open(conn)) ecp_ht_remove(sock->conn_table.addrs, &conn->remote.addr);
return rv;
}
}
} else {
- ECPDHRKeyBucket *remote = &conn->remote;
-
for (i=0; i<ECP_MAX_NODE_KEY; i++) {
- if (remote->key[i].idx != ECP_ECDH_IDX_INV) rv = ecp_ht_insert(sock->conn.htable, ecp_cr_dh_pub_get_buf(&remote->key[i].public), conn);
+ if (conn->rkey[i].valid) rv = ecp_ht_insert(sock->conn_table.keys, &conn->rkey[i].public, conn);
if (rv) {
int j;
- for (j=0; j<i; j++) if (remote->key[j].idx != ECP_ECDH_IDX_INV) ecp_ht_remove(sock->conn.htable, ecp_cr_dh_pub_get_buf(&remote->key[j].public));
+
+ for (j=0; j<i; j++) {
+ if (conn->rkey[j].valid) ecp_ht_remove(sock->conn_table.keys, &conn->rkey[j].public);
+ }
return rv;
}
}
}
#else
- if (sock->conn.size == ECP_MAX_SOCK_CONN) return ECP_ERR_MAX_SOCK_CONN;
- sock->conn.array[sock->conn.size] = conn;
- sock->conn.size++;
+ if (sock->conn_table.size == ECP_MAX_SOCK_CONN) return ECP_ERR_FULL;
+ sock->conn_table.arr[sock->conn_table.size] = conn;
+ sock->conn_table.size++;
#endif
return ECP_OK;
}
-static void ctable_remove(ECPConnection *conn) {
- int i;
+static void conn_table_remove(ECPConnection *conn) {
ECPSocket *sock = conn->sock;
+ int i;
#ifdef ECP_WITH_HTABLE
if (ecp_conn_is_outb(conn)) {
- for (i=0; i<ECP_MAX_CONN_KEY; i++) if (conn->key[i].valid) ecp_ht_remove(sock->conn.htable, ecp_cr_dh_pub_get_buf(&conn->key[i].public));
+ for (i=0; i<ECP_MAX_CONN_KEY; i++) {
+ if (conn->key[i].valid) ecp_ht_remove(sock->conn_table.keys, &conn->key[i].public);
+ }
+ if (!ecp_conn_is_open(conn)) ecp_ht_remove(sock->conn_table.addrs, &conn->remote.addr);
} else {
- ECPDHRKeyBucket *remote = &conn->remote;
- for (i=0; i<ECP_MAX_NODE_KEY; i++) if (remote->key[i].idx != ECP_ECDH_IDX_INV) ecp_ht_remove(sock->conn.htable, ecp_cr_dh_pub_get_buf(&remote->key[i].public));
+ for (i=0; i<ECP_MAX_NODE_KEY; i++) {
+ if (conn->rkey[i].valid) ecp_ht_remove(sock->conn_table.keys, &conn->rkey[i].public);
+ }
}
#else
- for (i=0; i<sock->conn.size; i++) {
- if (conn == sock->conn.array[i]) {
- sock->conn.array[i] = sock->conn.array[sock->conn.size-1];
- sock->conn.array[sock->conn.size-1] = NULL;
- sock->conn.size--;
+ for (i=0; i<sock->conn_table.size; i++) {
+ if (conn == sock->conn_table.arr[i]) {
+ while (i < (sock->conn_table.size-1)) {
+ sock->conn_table.arr[i] = sock->conn_table.arr[i+1];
+ i++;
+ }
+ sock->conn_table.arr[i] = NULL;
+ sock->conn_table.size--;
return;
}
}
#endif
}
-static ECPConnection *ctable_search(ECPSocket *sock, unsigned char c_idx, unsigned char *c_public, ECPNetAddr *addr) {
+static void conn_table_remove_addr(ECPConnection *conn) {
+ ECPSocket *sock = conn->sock;
+
+#ifdef ECP_WITH_HTABLE
+ ecp_ht_remove(sock->conn_table.addrs, &conn->remote.addr);
+#endif
+}
+
+static ECPConnection *conn_table_search(ECPSocket *sock, unsigned char c_idx, ecp_ecdh_public_t *c_public, ecp_tr_addr_t *addr) {
#ifdef ECP_WITH_HTABLE
- return ecp_ht_search(sock->conn.htable, c_public);
+ if (c_public) {
+ return ecp_ht_search(sock->conn_table.keys, c_public);
+ } else if (addr) {
+ return ecp_ht_search(sock->conn_table.addrs, addr);
+ } else {
+ return NULL;
+ }
#else
- ECPConnection *conn = NULL;
+ ECPConnection *conn;
int i;
if (c_public) {
- for (i=0; i<sock->conn.size; i++) {
- conn = sock->conn.array[i];
- if (ecp_conn_is_outb(conn)) {
- if ((c_idx < ECP_MAX_CONN_KEY) && conn->key[c_idx].valid && ecp_cr_dh_pub_eq(c_public, &conn->key[c_idx].public))
- return conn;
- } else {
- if ((c_idx < ECP_MAX_SOCK_KEY) && (conn->remote.key_idx_map[c_idx] != ECP_ECDH_IDX_INV) && ecp_cr_dh_pub_eq(c_public, &conn->remote.key[conn->remote.key_idx_map[c_idx]].public))
- return conn;
+ if (ecp_conn_is_outb(conn)) {
+ if (c_idx >= ECP_MAX_CONN_KEY) return ECP_ERR_ECDH_IDX;
+
+ for (i=0; i<sock->conn_table.size; i++) {
+ conn = sock->conn_table.arr[i];
+ if (conn->key[c_idx].valid && ecp_ecdh_pub_eq(c_public, &conn->key[c_idx].public)) return conn;
+ }
+ } else {
+ unsigned char *_c_idx;
+
+ if (c_idx & ~ECP_ECDH_IDX_MASK) return ECP_ERR_ECDH_IDX;
+
+ _c_idx = c_idx % ECP_MAX_NODE_KEY;
+ for (i=0; i<sock->conn_table.size; i++) {
+ conn = sock->conn_table.arr[i];
+ if (conn->rkey[_c_idx].valid && ecp_ecdh_pub_eq(c_public, &conn->rkey[_c_idx].public)) return conn;
}
}
} else if (addr) {
- /* in case server is not returning client's public key in packet */
- for (i=0; i<sock->conn.size; i++) {
- conn = sock->conn.array[i];
- if (ecp_conn_is_outb(conn) && ecp_tr_addr_eq(&conn->node.addr, addr)) return conn;
+ for (i=0; i<sock->conn_table.size; i++) {
+ conn = sock->conn_table.arr[i];
+ if (ecp_conn_is_outb(conn) && ecp_tr_addr_eq(&conn->remote.addr, addr)) return conn;
}
}
@@ -194,32 +246,26 @@ static ECPConnection *ctable_search(ECPSocket *sock, unsigned char c_idx, unsign
}
int ecp_sock_init(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) {
- if (sock == NULL) return ECP_ERR;
- if (ctx == NULL) return ECP_ERR;
-
memset(sock, 0, sizeof(ECPSocket));
sock->ctx = ctx;
- sock->poll_timeout = ECP_POLL_TIMEOUT;
sock->key_curr = 0;
if (key) sock->key_perma = *key;
- sock->handler[ECP_MTYPE_OPEN] = ecp_sock_handle_open;
- sock->handler[ECP_MTYPE_KGET] = ecp_sock_handle_kget;
-#ifdef ECP_WITH_DIRSRV
- sock->handler[ECP_MTYPE_DIR] = ecp_dir_handle_req;
-#endif
- return ecp_dhkey_gen(sock->ctx, &sock->key[sock->key_curr]);
+ return ecp_dhkey_gen(&sock->key[sock->key_curr]);
}
-int ecp_sock_create(ECPSocket *sock) {
+int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) {
int rv;
- rv = ctable_create(&sock->conn, sock->ctx);
+ rv = ecp_sock_init(sock, ctx, key);
+ if (rv) return rv;
+
+ rv = conn_table_create(&sock->conn_table);
if (rv) return rv;
rv = ecp_timer_create(&sock->timer);
if (rv) {
- ctable_destroy(&sock->conn, sock->ctx);
+ conn_table_destroy(&sock->conn_table);
return rv;
}
@@ -227,28 +273,25 @@ int ecp_sock_create(ECPSocket *sock) {
rv = pthread_mutex_init(&sock->mutex, NULL);
if (rv) {
ecp_timer_destroy(&sock->timer);
- ctable_destroy(&sock->conn, sock->ctx);
+ conn_table_destroy(&sock->conn_table);
return ECP_ERR;
}
#endif
+ arc4random_buf(&sock->nonce_out, sizeof(sock->nonce_out));
return ECP_OK;
}
void ecp_sock_destroy(ECPSocket *sock) {
ecp_timer_destroy(&sock->timer);
- ctable_destroy(&sock->conn, sock->ctx);
+ conn_table_destroy(&sock->conn_table);
+
#ifdef ECP_WITH_PTHREAD
pthread_mutex_destroy(&sock->mutex);
#endif
}
int ecp_sock_open(ECPSocket *sock, void *myaddr) {
- int rv;
-
- rv = ecp_sock_create(sock);
- if (rv) return rv;
-
return ecp_tr_open(sock, myaddr);
}
@@ -257,77 +300,158 @@ void ecp_sock_close(ECPSocket *sock) {
ecp_tr_close(sock);
}
-ecp_sock_msg_handler_t ecp_sock_get_msg_handler(ECPSocket *sock, unsigned char mtype) {
- return sock->handler[mtype];
+int ecp_sock_dhkey_new(ECPSocket *sock) {
+ ECPDHKey new_key;
+ int rv;
+
+ rv = ecp_dhkey_gen(&new_key);
+ if (rv) return rv;
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&sock->mutex);
+#endif
+
+ sock->key_curr = (sock->key_curr + 1) % ECP_MAX_SOCK_KEY;
+ sock->key[sock->key_curr] = new_key;
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&sock->mutex);
+#endif
+
+ return ECP_OK;
+}
+
+int ecp_sock_dhkey_get(ECPSocket *sock, unsigned char idx, ECPDHKey *key) {
+ int rv = ECP_OK;
+
+ if (idx == ECP_ECDH_IDX_PERMA) {
+ *key = sock->key_perma;
+ } else {
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&sock->mutex);
+#endif
+
+ if (idx < ECP_MAX_SOCK_KEY) {
+ *key = sock->key[idx];
+ } else {
+ rv = ECP_ERR_ECDH_IDX;
+ }
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&sock->mutex);
+#endif
+
+ }
+
+ if (!rv && !key->valid) rv = ECP_ERR_ECDH_IDX;
+ return rv;
}
-int ecp_sock_dhkey_get_curr(ECPSocket *sock, unsigned char *idx, unsigned char *public) {
+int ecp_sock_dhkey_get_pub(ECPSocket *sock, unsigned char *idx, ecp_ecdh_public_t *public) {
+ ECPDHKey *key;
unsigned char _idx;
+ int rv = ECP_OK;
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&sock->mutex);
#endif
_idx = sock->key_curr;
- if (_idx != ECP_ECDH_IDX_INV) ecp_cr_dh_pub_to_buf(public, &sock->key[_idx].public);
+ if (_idx == ECP_ECDH_IDX_INV) rv = ECP_ERR_ECDH_IDX;
+
+ if (!rv) {
+ key = &sock->key[_idx];
+ if (!key->valid) rv = ECP_ERR_ECDH_IDX;
+ }
+ if (!rv) memcpy(public, &key->public, sizeof(key->public));
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&sock->mutex);
#endif
- if (_idx == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX;
+ if (rv) return rv;
if (idx) *idx = _idx;
return ECP_OK;
}
-int ecp_sock_dhkey_new(ECPSocket *sock) {
- ECPDHKey new_key;
- int rv;
-
- rv = ecp_dhkey_gen(sock->ctx, &new_key);
- if (rv) return rv;
-
+void ecp_sock_get_nonce(ECPSocket *sock, ecp_nonce_t *nonce) {
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&sock->mutex);
#endif
- sock->key_curr = (sock->key_curr + 1) % ECP_MAX_SOCK_KEY;
- sock->key[sock->key_curr] = new_key;
- sock->key[(sock->key_curr + 1) % ECP_MAX_SOCK_KEY].valid = 0;
+
+ *nonce = sock->nonce_out;
+ sock->nonce_out++;
+
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&sock->mutex);
#endif
+}
- return ECP_OK;
+ECPConnection *ecp_sock_keys_search(ECPSocket *sock, ecp_ecdh_public_t *public) {
+ ECPConnection *conn;
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&sock->conn_table.mutex);
+#endif
+
+ conn = ecp_ht_search(sock->conn_table.keys, public);
+ if (conn) ecp_conn_refcount_inc(conn);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&sock->conn_table.mutex);
+#endif
+
+ return conn;
}
-static ECPDHKey *conn_dhkey_get(ECPConnection *conn, unsigned char idx) {
- if (conn->key_curr == ECP_ECDH_IDX_INV) {
- if (idx < ECP_MAX_SOCK_KEY) return &conn->sock->key[idx];
- } else {
- if (idx < ECP_MAX_CONN_KEY) return &conn->key[idx];
- }
- return NULL;
+int ecp_sock_keys_insert(ECPSocket *sock, ecp_ecdh_public_t *public, ECPConnection *conn) {
+ int rv;
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&sock->conn_table.mutex);
+#endif
+
+ rv = ecp_ht_insert(sock->conn_table.keys, public, conn);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&sock->conn_table.mutex);
+#endif
+
+ return rv;
+}
+
+void ecp_sock_keys_remove(ECPSocket *sock, ecp_ecdh_public_t *public) {
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&sock->conn_table.mutex);
+#endif
+
+ ecp_ht_remove(sock->conn_table.keys, public);
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&sock->conn_table.mutex);
+#endif
}
-static int conn_dhkey_new_pair(ECPConnection *conn, ECPDHKey *key) {
+static int conn_dhkey_new(ECPConnection *conn, unsigned char idx, ECPDHKey *key) {
ECPSocket *sock = conn->sock;
- conn->key_curr = conn->key_curr == ECP_ECDH_IDX_INV ? 0 : (conn->key_curr+1) % ECP_MAX_CONN_KEY;
+ if (idx >= ECP_MAX_CONN_KEY) return ECP_ERR_ECDH_IDX;
+
#ifdef ECP_WITH_HTABLE
- if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn) && conn->key[conn->key_curr].valid) {
- ecp_ht_remove(sock->conn.htable, ecp_cr_dh_pub_get_buf(&conn->key[conn->key_curr].public));
+ if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn) && conn->key[idx].valid) {
+ ecp_ht_remove(sock->conn_table.keys, &conn->key[idx].public);
}
#endif
- conn->key[conn->key_curr] = *key;
- conn->key_idx_map[conn->key_curr] = ECP_ECDH_IDX_INV;
+ conn->key[idx] = *key;
#ifdef ECP_WITH_HTABLE
if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn)) {
int rv;
- rv = ecp_ht_insert(sock->conn.htable, ecp_cr_dh_pub_get_buf(&conn->key[conn->key_curr].public), conn);
+ rv = ecp_ht_insert(sock->conn_table.keys, &conn->key[idx].public, conn);
if (rv) return rv;
}
#endif
@@ -335,172 +459,219 @@ static int conn_dhkey_new_pair(ECPConnection *conn, ECPDHKey *key) {
return ECP_OK;
}
-static void conn_dhkey_del_pair(ECPConnection *conn, unsigned char idx) {
+static void conn_dhkey_del(ECPConnection *conn, unsigned char idx) {
ECPSocket *sock = conn->sock;
+ if (idx >= ECP_MAX_CONN_KEY) return;
+
#ifdef ECP_WITH_HTABLE
if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn) && conn->key[idx].valid) {
- ecp_ht_remove(sock->conn.htable, ecp_cr_dh_pub_get_buf(&conn->key[idx].public));
+ ecp_ht_remove(sock->conn_table.keys, &conn->key[idx].public);
}
#endif
memset(&conn->key[idx], 0, sizeof(conn->key[idx]));
- conn->key_idx_map[idx] = ECP_ECDH_IDX_INV;
}
-/* remote client obtained our key */
-static int conn_dhkey_new_pub_local(ECPConnection *conn, unsigned char idx) {
- unsigned char new = conn->key_idx_curr == ECP_ECDH_IDX_INV ? 0 : (conn->key_idx_curr+1) % ECP_MAX_NODE_KEY;
+static ECPDHKey *conn_dhkey_get(ECPConnection *conn, unsigned char idx) {
+ ECPDHKey *key = NULL;
+
+ /* always outbound */
+ if (idx < ECP_MAX_CONN_KEY) {
+ key = &conn->key[idx];
+ }
+
+ if (key && key->valid) return key;
+ return NULL;
+}
+
+static ECPDHPub *conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx) {
+ ECPDHPub *key = NULL;
+
+ if (ecp_conn_is_outb(conn) && (idx == ECP_ECDH_IDX_PERMA)) {
+ key = &conn->remote.key_perma;
+ } else if ((idx & ECP_ECDH_IDX_MASK) == idx) {
+ key = &conn->rkey[idx % ECP_MAX_NODE_KEY];
+ }
+
+ if (key && key->valid) return key;
+ return NULL;
+}
+
+/* node will send public key */
+static void conn_dhkey_get_pub(ECPConnection *conn, unsigned char idx) {
+ unsigned char _idx;
int i;
- if (idx >= ECP_MAX_SOCK_KEY) return ECP_ERR_ECDH_IDX;
+ _idx = idx % ECP_MAX_NODE_KEY;
+ if (ecp_conn_is_outb(conn)) {
+ if (idx == conn->key_curr) return;
- if (conn->key_idx[new] != ECP_ECDH_IDX_INV) conn->key_idx_map[conn->key_idx[new]] = ECP_ECDH_IDX_INV;
- conn->key_idx_map[idx] = new;
- conn->key_idx[new] = idx;
- conn->key_idx_curr = new;
+ for (i=0; i<ECP_MAX_NODE_KEY; i++) {
+ conn->shkey[i][_idx].valid = 0;
+ }
+ } else {
+ if (idx == conn->rkey_curr) return;
- for (i=0; i<ECP_MAX_NODE_KEY; i++) {
- conn->shared[new][i].valid = 0;
+ for (i=0; i<ECP_MAX_NODE_KEY; i++) {
+ conn->shkey[_idx][i].valid = 0;
+ }
}
- return ECP_OK;
}
-/* this client obtained remote key */
-static int conn_dhkey_new_pub_remote(ECPConnection *conn, unsigned char idx, unsigned char *public) {
+/* node received public key */
+static int conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_public_t *public) {
+ unsigned char _idx;
+ ECPDHPub *key;
ECPSocket *sock = conn->sock;
- ECPDHRKeyBucket *remote = &conn->remote;
- unsigned char new = remote->key_curr == ECP_ECDH_IDX_INV ? 0 : (remote->key_curr+1) % ECP_MAX_NODE_KEY;
int i;
- if (idx >= ECP_MAX_SOCK_KEY) return ECP_ERR_ECDH_IDX;
- if ((remote->key_idx_map[idx] != ECP_ECDH_IDX_INV) && ecp_cr_dh_pub_eq(public, &remote->key[remote->key_idx_map[idx]].public)) return ECP_ERR_ECDH_KEY_DUP;
+ if (idx & ~ECP_ECDH_IDX_MASK) return ECP_ERR_ECDH_IDX;
+
+ _idx = idx % ECP_MAX_NODE_KEY;
+ key = &conn->rkey[_idx];
+ if (key->valid && (memcmp(public, &key->public, sizeof(key->public)) == 0)) return ECP_ERR_ECDH_KEY_DUP;
#ifdef ECP_WITH_HTABLE
- if (ecp_conn_is_inb(conn) && ecp_conn_is_reg(conn) && (remote->key[new].idx != ECP_ECDH_IDX_INV)) {
- ecp_ht_remove(sock->conn.htable, ecp_cr_dh_pub_get_buf(&remote->key[new].public));
+ if (ecp_conn_is_inb(conn) && ecp_conn_is_reg(conn) && (key->valid)) {
+ ecp_ht_remove(sock->conn_table.keys, &key->public);
}
#endif
- if (remote->key[new].idx != ECP_ECDH_IDX_INV) remote->key_idx_map[remote->key[new].idx] = ECP_ECDH_IDX_INV;
- remote->key_idx_map[idx] = new;
- ecp_cr_dh_pub_from_buf(&remote->key[new].public, public);
- remote->key[new].idx = idx;
- remote->key_curr = new;
+ memcpy(&key->public, public, sizeof(key->public));
+ key->valid = 1;
#ifdef ECP_WITH_HTABLE
if (ecp_conn_is_inb(conn) && ecp_conn_is_reg(conn)) {
int rv;
- rv = ecp_ht_insert(sock->conn.htable, ecp_cr_dh_pub_get_buf(&remote->key[new].public), conn);
+ rv = ecp_ht_insert(sock->conn_table.keys, &key->public, conn);
if (rv) return rv;
}
#endif
- for (i=0; i<ECP_MAX_NODE_KEY; i++) {
- conn->shared[i][new].valid = 0;
+ if (ecp_conn_is_outb(conn)) {
+ conn->rkey_curr = idx;
+ for (i=0; i<ECP_MAX_NODE_KEY; i++) {
+ conn->shkey[_idx][i].valid = 0;
+ }
+ } else {
+ for (i=0; i<ECP_MAX_NODE_KEY; i++) {
+ conn->shkey[i][_idx].valid = 0;
+ }
}
return ECP_OK;
}
-static int conn_shsec_get(ECPConnection *conn, unsigned char s_idx, unsigned char c_idx, ecp_aead_key_t *shsec) {
- if (s_idx == ECP_ECDH_IDX_PERMA) {
- ECPDHKey *priv = NULL;
- ecp_dh_public_t *public_p = NULL;
-
- if (ecp_conn_is_outb(conn)) {
- public_p = &conn->node.public;
- priv = conn_dhkey_get(conn, c_idx);
- } else {
-#if 0
- ECPDHRKey *pub = NULL;
+static int conn_shkey_get(ECPConnection *conn, unsigned char s_idx, unsigned char c_idx, ecp_aead_key_t *shkey) {
+ ECPDHPub *pub;
+ ECPDHKey *priv;
+ int rv;
- if (c_idx >= ECP_MAX_SOCK_KEY) return ECP_ERR_ECDH_IDX;
- if (conn->remote.key_idx_map[c_idx] == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX_REMOTE;
+ if (ecp_conn_is_outb(conn) && (s_idx == ECP_ECDH_IDX_PERMA)) {
+ pub = conn_dhkey_get_remote(conn, s_idx);
+ priv = conn_dhkey_get(conn, c_idx);
- pub = &conn->remote.key[conn->remote.key_idx_map[c_idx]];
- public_p = pub->idx != ECP_ECDH_IDX_INV ? &pub->public : NULL;
- priv = &conn->sock->key_perma;
-#endif
- }
- if (public_p == NULL) return ECP_ERR_ECDH_IDX;
- if ((priv == NULL) || !priv->valid) return ECP_ERR_ECDH_IDX;
- ecp_cr_dh_shsec(shsec, public_p, &priv->private);
+ if ((pub == NULL) || (priv == NULL)) return ECP_ERR_ECDH_IDX;
+ ecp_ecdh_shkey(shkey, &pub->public, &priv->private);
} else {
- unsigned char l_idx = ecp_conn_is_outb(conn) ? c_idx : s_idx;
- unsigned char r_idx = ecp_conn_is_outb(conn) ? s_idx : c_idx;
- ECPDHShared *shared = NULL;
+ ECPDHShkey *_shkey;
- if ((l_idx >= ECP_MAX_SOCK_KEY) || (r_idx >= ECP_MAX_SOCK_KEY)) return ECP_ERR_ECDH_IDX;
+ if (s_idx & ~ECP_ECDH_IDX_MASK) return ECP_ERR_ECDH_IDX;
+ if (c_idx & ~ECP_ECDH_IDX_MASK) return ECP_ERR_ECDH_IDX;
- if (conn->key_idx_map[l_idx] == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX_LOCAL;
- if (conn->remote.key_idx_map[r_idx] == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX_REMOTE;
+ _shkey = &conn->shkey[s_idx % ECP_MAX_NODE_KEY][c_idx % ECP_MAX_NODE_KEY];
+ if (!_shkey->valid) {
+ if (ecp_conn_is_inb(conn)) {
+ ECPSocket *sock = conn->sock;
+ ECPDHKey priv;
- shared = &conn->shared[conn->key_idx_map[l_idx]][conn->remote.key_idx_map[r_idx]];
+ pub = conn_dhkey_get_remote(conn, c_idx);
+ if (pub == NULL) return ECP_ERR_ECDH_IDX;
- if (!shared->valid) {
- ECPDHRKeyBucket *remote = &conn->remote;
- ECPDHRKey *pub = &remote->key[conn->remote.key_idx_map[r_idx]];
- ECPDHKey *priv = conn_dhkey_get(conn, l_idx);
+ rv = ecp_sock_dhkey_get(sock, s_idx, &priv);
+ if (rv) return rv;
- if ((pub == NULL) || (pub->idx == ECP_ECDH_IDX_INV)) return ECP_ERR_ECDH_IDX;
- if ((priv == NULL) || !priv->valid) return ECP_ERR_ECDH_IDX;
- ecp_cr_dh_shsec(&shared->secret, &pub->public, &priv->private);
- shared->valid = 1;
- }
+ ecp_ecdh_shkey(&_shkey->key, &pub->public, &priv.private);
+ conn->key_curr = s_idx;
+ conn->rkey_curr = c_idx;
+ } else {
+ pub = conn_dhkey_get_remote(conn, s_idx);
+ priv = conn_dhkey_get(conn, c_idx);
- memcpy(shsec, &shared->secret, sizeof(shared->secret));
+ if ((pub == NULL) || (priv == NULL)) return ECP_ERR_ECDH_IDX;
+ ecp_ecdh_shkey(&_shkey->key, &pub->public, &priv->private);
+ }
+ _shkey->valid = 1;
+ }
+ memcpy(shkey, &_shkey->key, sizeof(_shkey->key));
}
return ECP_OK;
}
-static int conn_shsec_set(ECPConnection *conn, unsigned char s_idx, unsigned char c_idx, ecp_aead_key_t *shsec) {
- unsigned char l_idx = ecp_conn_is_outb(conn) ? c_idx : s_idx;
- unsigned char r_idx = ecp_conn_is_outb(conn) ? s_idx : c_idx;
- ECPDHShared *shared = NULL;
+static int conn_shkey_set(ECPConnection *conn, unsigned char s_idx, unsigned char c_idx, ecp_aead_key_t *shkey) {
+ ECPDHShkey *_shkey;
- if ((l_idx >= ECP_MAX_SOCK_KEY) || (r_idx >= ECP_MAX_SOCK_KEY)) return ECP_ERR_ECDH_IDX;
+ if (s_idx & ~ECP_ECDH_IDX_MASK) return ECP_ERR_ECDH_IDX;
+ if (c_idx & ~ECP_ECDH_IDX_MASK) return ECP_ERR_ECDH_IDX;
- if (conn->key_idx_map[l_idx] == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX_LOCAL;
- if (conn->remote.key_idx_map[r_idx] == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX_REMOTE;
+ _shkey = &conn->shkey[s_idx % ECP_MAX_NODE_KEY][c_idx % ECP_MAX_NODE_KEY];
+ memcpy(_shkey->key, shkey, sizeof(_shkey->key));
+ _shkey->valid = 1;
- shared = &conn->shared[conn->key_idx_map[l_idx]][conn->remote.key_idx_map[r_idx]];
- memcpy(&shared->secret, shsec, sizeof(shared->secret));
- shared->valid = 1;
+ return ECP_OK;
+}
+int ecp_conn_alloc(ECPSocket *sock, unsigned char ctype, ECPConnection **_conn) {
+ ECPContext *ctx = sock->ctx;
+ ECPConnection *conn;
+ int rv;
+
+ if (ctx->conn_alloc == NULL) return ECP_ERR_ALLOC;
+
+ conn = ctx->conn_alloc(sock, ctype);
+ if (conn == NULL) return ECP_ERR_ALLOC;
+
+ *_conn = conn;
return ECP_OK;
}
-int ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) {
- int i;
+void ecp_conn_free(ECPConnection *conn) {
+ ECPContext *ctx = conn->sock->ctx;
- if (conn == NULL) return ECP_ERR;
- if (sock == NULL) return ECP_ERR;
+ if (ctx->conn_free) ctx->conn_free(conn);
+}
- memset(conn, 0, sizeof(ECPConnection));
+void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) {
+ int i;
- if (ctype >= ECP_MAX_CTYPE) return ECP_ERR_MAX_CTYPE;
+ memset(conn, 0, sizeof(ECPConnection));
- ecp_conn_set_new(conn);
conn->sock = sock;
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;
- memset(conn->key_idx, ECP_ECDH_IDX_INV, sizeof(conn->key_idx));
- memset(conn->key_idx_map, ECP_ECDH_IDX_INV, sizeof(conn->key_idx_map));
- for (i=0; i<ECP_MAX_NODE_KEY; i++) {
- conn->remote.key[i].idx = ECP_ECDH_IDX_INV;
- }
- memset(conn->remote.key_idx_map, ECP_ECDH_IDX_INV, sizeof(conn->remote.key_idx_map));
+ conn->key_next = ECP_ECDH_IDX_INV;
+ conn->rkey_curr = ECP_ECDH_IDX_INV;
+ arc4random_buf(&conn->nonce_out, sizeof(conn->nonce_out));
+}
- return ECP_OK;
+void ecp_conn_reinit(ECPConnection *conn) {
+ conn->flags = 0;
+ conn->key_curr = ECP_ECDH_IDX_INV;
+ conn->key_next = ECP_ECDH_IDX_INV;
+ conn->rkey_curr = ECP_ECDH_IDX_INV;
+ memset(&conn->key, 0, sizeof(conn->key));
+ memset(&conn->rkey, 0, sizeof(conn->rkey));
+ memset(&conn->shkey, 0, sizeof(conn->shkey));
+ arc4random_buf(&conn->nonce_out, sizeof(conn->nonce_out));
}
-int ecp_conn_create(ECPConnection *conn) {
+int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) {
int rv;
+ ecp_conn_init(conn, sock, ctype);
+
#ifdef ECP_WITH_PTHREAD
rv = pthread_mutex_init(&conn->mutex, NULL);
if (rv) return ECP_ERR;
@@ -509,207 +680,223 @@ int ecp_conn_create(ECPConnection *conn) {
return ECP_OK;
}
+int ecp_conn_create_inb(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) {
+ int rv;
+
+ rv = ecp_conn_create(conn, sock, ctype);
+ if (rv) return rv;
+
+ ecp_conn_set_inb(conn);
+
+#ifdef ECP_WITH_VCONN
+ if (conn->parent) {
+ ecp_conn_refcount_inc(conn->parent);
+ }
+#endif
+
+ return ECP_OK;
+}
+
void ecp_conn_destroy(ECPConnection *conn) {
+#ifdef ECP_WITH_VCONN
+ if (ecp_conn_is_inb(conn) && conn->parent) {
+ ecp_conn_refcount_dec(conn->parent);
+ }
+#endif
+
+ ecp_ext_conn_destroy(conn);
+
#ifdef ECP_WITH_PTHREAD
pthread_mutex_destroy(&conn->mutex);
#endif
}
-int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char c_idx, unsigned char *public) {
- ECPContext *ctx = conn->sock->ctx;
+void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags) {
+ flags &= flags & ECP_CONN_FLAG_MASK;
+ conn->flags_im |= flags;
+}
+
+void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags) {
+ flags &= flags & ECP_CONN_FLAG_MASK;
+ conn->flags_im &= ~flags;
+}
+
+void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key) {
+ conn->remote.key_perma = *key;
+}
+
+void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr) {
+ conn->remote.addr = *addr;
+}
+
+int ecp_conn_init_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *remote_key, ecp_aead_key_t *shkey) {
+ ECPSocket *sock = conn->sock;
+ unsigned short pcount;
int rv;
- rv = ecp_conn_create(conn);
+#ifdef ECP_WITH_VCONN
+ pcount = (parent ? parent->pcount + 1 : 0);
+ if (pcount > ECP_MAX_PARENT) return ECP_ERR_MAX_PARENT;
+#endif
+
+ if (ecp_conn_has_vbox(conn) && ((remote_key == NULL) || !remote_key->valid)) return ECP_ERR_VBOX;
+
+ rv = conn_dhkey_set_pub(conn, c_idx, public);
if (rv) return rv;
- conn->refcount = 1;
- conn->parent = parent;
- conn->pcount = parent ? parent->pcount+1 : 0;
+ rv = conn_shkey_set(conn, s_idx, c_idx, shkey);
+ if (rv) return rv;
- rv = ctx->rng(&conn->seq_out, sizeof(conn->seq_out));
- if (!rv) rv = conn_dhkey_new_pub_remote(conn, c_idx, public);
+#ifdef ECP_WITH_VCONN
+ conn->parent = parent;
+ conn->pcount = pcount;
+#endif
- if (rv) {
- ecp_conn_destroy(conn);
- return rv;
- }
+ conn->refcount = 1;
+ conn->key_curr = s_idx;
+ conn->rkey_curr = c_idx;
+ if (remote_key && remote_key->valid) conn->remote.key_perma = *remote_key;
return ECP_OK;
}
-int ecp_conn_create_outb(ECPConnection *conn, ECPNode *node) {
- ECPContext *ctx = conn->sock->ctx;
+int ecp_conn_init_outb(ECPConnection *conn, ECPNode *node) {
ECPDHKey key;
int rv;
- if (node == NULL) return ECP_ERR;
-
- rv = ecp_conn_create(conn);
+ rv = ecp_dhkey_gen(&key);
if (rv) return rv;
- ecp_conn_set_outb(conn);
- conn->node = *node;
- rv = ecp_dhkey_gen(ctx, &key);
- if (!rv) rv = ctx->rng(conn->nonce, ECP_AEAD_SIZE_NONCE);
- if (!rv) rv = ctx->rng(&conn->seq_out, sizeof(conn->seq_out));
-
- if (!rv) rv = conn_dhkey_new_pair(conn, &key);
- if (!rv) rv = conn_dhkey_new_pub_local(conn, conn->key_curr);
+ rv = conn_dhkey_new(conn, 0, &key);
+ if (rv) return rv;
- if (rv) {
- ecp_conn_destroy(conn);
- return rv;
- }
+ if (node) conn->remote = *node;
+ conn->key_curr = 0;
return ECP_OK;
}
int ecp_conn_insert(ECPConnection *conn) {
- ecp_conn_clr_new(conn);
- return ecp_conn_register(conn);
-}
-
-int ecp_conn_register(ECPConnection *conn) {
ECPSocket *sock = conn->sock;
int rv;
ecp_conn_set_reg(conn);
+
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&sock->conn.mutex);
+ pthread_mutex_lock(&sock->conn_table.mutex);
#endif
- rv = ctable_insert(conn);
+
+ rv = conn_table_insert(conn);
+
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&sock->conn.mutex);
+ pthread_mutex_unlock(&sock->conn_table.mutex);
#endif
+
if (rv) ecp_conn_clr_reg(conn);
return rv;
}
-void ecp_conn_unregister(ECPConnection *conn, unsigned short *refcount) {
+void ecp_conn_remove(ECPConnection *conn, unsigned short *refcount) {
ECPSocket *sock = conn->sock;
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&sock->conn.mutex);
+ pthread_mutex_lock(&sock->conn_table.mutex);
pthread_mutex_lock(&conn->mutex);
#endif
+
if (ecp_conn_is_reg(conn)) {
- ctable_remove(conn);
+ conn_table_remove(conn);
ecp_conn_clr_reg(conn);
}
if (refcount) *refcount = conn->refcount;
+
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&conn->mutex);
- pthread_mutex_unlock(&sock->conn.mutex);
+ pthread_mutex_unlock(&sock->conn_table.mutex);
#endif
}
-int ecp_conn_get_dirlist(ECPConnection *conn, ECPNode *node) {
- int rv;
- ssize_t _rv;
+void ecp_conn_remove_addr(ECPConnection *conn) {
+ ECPSocket *sock = conn->sock;
- rv = ecp_conn_create_outb(conn, node);
- if (rv) return rv;
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&sock->conn_table.mutex);
+ pthread_mutex_lock(&conn->mutex);
+#endif
- rv = ecp_conn_insert(conn);
- if (rv) {
- ecp_conn_destroy(conn);
- return rv;
- }
+ conn_table_remove_addr(conn);
- _rv = ecp_conn_send_dir(conn);
- if (_rv < 0) {
- ecp_conn_close(conn);
- return _rv;
- }
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&sock->conn_table.mutex);
+ pthread_mutex_lock(&conn->mutex);
+#endif
- return ECP_OK;
}
int ecp_conn_open(ECPConnection *conn, ECPNode *node) {
int rv;
ssize_t _rv;
- rv = ecp_conn_create_outb(conn, node);
+ rv = ecp_conn_init_outb(conn, node);
if (rv) return rv;
rv = ecp_conn_insert(conn);
- if (rv) {
- ecp_conn_destroy(conn);
- return rv;
- }
+ if (rv) return rv;
- _rv = ecp_conn_send_kget(conn);
+ _rv = ecp_send_init_req(conn);
if (_rv < 0) {
- ecp_conn_close(conn);
+ ecp_timer_remove(conn);
+ ecp_conn_remove(conn, NULL);
return _rv;
}
return ECP_OK;
}
-static void conn_close(ECPConnection *conn) {
- ECPContext *ctx = conn->sock->ctx;
-
- if (ecp_conn_is_inb(conn) && conn->parent) {
- ecp_conn_refcount_dec(conn->parent);
- }
-
- ecp_conn_destroy(conn);
+int ecp_conn_reset(ECPConnection *conn) {
+ unsigned short refcount = 0;
+ int i;
+ int rv;
- if (ecp_conn_is_inb(conn) && ctx->conn_free) ctx->conn_free(conn);
-}
+ /* timer holds one reference to this connection */
+ ecp_conn_remove(conn, &refcount);
+ if (refcount > 1) return ECP_ERR_BUSY;
-int ecp_conn_close(ECPConnection *conn) {
- unsigned short refcount = 0;
- ecp_conn_close_t handler;
+ ecp_conn_reinit(conn);
+ if (rv) return rv;
- ecp_conn_unregister(conn, &refcount);
- ecp_timer_remove(conn);
- handler = ecp_conn_get_close_handler(conn);
- if (handler) handler(conn);
+ rv = ecp_conn_init_outb(conn, NULL);
+ if (rv) return rv;
- if (refcount) return ECP_ERR_BUSY;
+ rv = ecp_conn_insert(conn);
+ if (rv) return rv;
- conn_close(conn);
return ECP_OK;
}
-int ecp_conn_reset(ECPConnection *conn) {
- ECPDHKey key;
- ECPSocket *sock = conn->sock;
- ECPContext *ctx = sock->ctx;
- int rv;
- int i;
+void _ecp_conn_close(ECPConnection *conn) {
- rv = ecp_dhkey_gen(ctx, &key);
- if (rv) return rv;
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&sock->conn.mutex);
- pthread_mutex_lock(&conn->mutex);
-#endif
+ if (ecp_conn_is_open(conn)) {
+ ecp_close_handler_t handler;
- for (i=0; i<ECP_MAX_CONN_KEY; i++) {
- conn_dhkey_del_pair(conn, i);
+ ecp_conn_clr_open(conn);
+ handler = ecp_get_close_handler(conn);
+ if (handler) handler(conn);
}
- conn->key_curr = 0;
- rv = conn_dhkey_new_pair(conn, &key);
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&sock->conn.mutex);
-#endif
+ ecp_conn_destroy(conn);
+ if (ecp_conn_is_inb(conn)) ecp_conn_free(conn);
+}
- if (!rv) rv = conn_dhkey_new_pub_local(conn, conn->key_curr);
- if (!rv) rv = ctx->rng(conn->nonce, ECP_AEAD_SIZE_NONCE);
- if (!rv) rv = ctx->rng(&conn->seq_out, sizeof(conn->seq_out));
- ecp_conn_clr_open(conn);
+int ecp_conn_close(ECPConnection *conn) {
+ unsigned short refcount = 0;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
-#endif
+ ecp_timer_remove(conn);
+ ecp_conn_remove(conn, &refcount);
+ if (refcount) return ECP_ERR_BUSY;
- return rv;
+ _ecp_conn_close(conn);
+ return ECP_OK;
}
void ecp_conn_refcount_inc(ECPConnection *conn) {
@@ -736,1210 +923,1396 @@ void ecp_conn_refcount_dec(ECPConnection *conn) {
pthread_mutex_unlock(&conn->mutex);
#endif
- if (!is_reg && (refcount == 0)) conn_close(conn);
-}
-
-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;
-#ifdef ECP_WITH_DIRSRV
- handler->msg[ECP_MTYPE_DIR] = ecp_dir_handle_update;
-#endif
-#ifdef ECP_WITH_RBUF
- handler->msg[ECP_MTYPE_RBACK] = ecp_rbuf_handle_ack;
- handler->msg[ECP_MTYPE_RBFLUSH] = ecp_rbuf_handle_flush;
- handler->msg[ECP_MTYPE_RBTIMER] = ecp_rbuf_handle_timer;
-#endif
- return ECP_OK;
+ if (!is_reg && (refcount == 0)) _ecp_conn_close(conn);
}
-ecp_conn_msg_handler_t ecp_conn_get_msg_handler(ECPConnection *conn, unsigned char mtype) {
- ECPContext *ctx = conn->sock->ctx;
- return ctx->handler[conn->type] ? ctx->handler[conn->type]->msg[mtype] : NULL;
-}
-
-ecp_conn_close_t ecp_conn_get_close_handler(ECPConnection *conn) {
- ECPContext *ctx = conn->sock->ctx;
- return ctx->handler[conn->type] ? ctx->handler[conn->type]->conn_close : NULL;
-}
-
-
int ecp_conn_dhkey_new(ECPConnection *conn) {
ECPSocket *sock = conn->sock;
ECPDHKey new_key;
+ unsigned char idx;
int rv;
ssize_t _rv;
- rv = ecp_dhkey_gen(sock->ctx, &new_key);
+ rv = ecp_dhkey_gen(&new_key);
if (rv) return rv;
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&sock->conn.mutex);
+ if (ecp_conn_is_outb(conn)) pthread_mutex_lock(&sock->conn_table.mutex);
pthread_mutex_lock(&conn->mutex);
#endif
- rv = conn_dhkey_new_pair(conn, &new_key);
+
+ idx = conn->key_curr;
+ if (idx != ECP_ECDH_IDX_INV) {
+ idx = (idx + 1) % ECP_MAX_CONN_KEY;
+ rv = conn_dhkey_new(conn, idx, &new_key);
+ conn->key_next = idx;
+ }
+
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&conn->mutex);
- pthread_mutex_unlock(&sock->conn.mutex);
+ if (ecp_conn_is_outb(conn)) pthread_mutex_unlock(&sock->conn_table.mutex);
#endif
-
+ if (idx == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX;
if (rv) return rv;
- _rv = ecp_conn_send_kput(conn);
+ _rv = ecp_send_keyx_req(conn);
if (_rv < 0) return _rv;
return ECP_OK;
}
-int ecp_conn_dhkey_new_pub(ECPConnection *conn, unsigned char idx, unsigned char *public) {
+int ecp_conn_dhkey_get(ECPSocket *sock, unsigned char idx, ECPDHKey *key) {
+ int rv = ECP_OK;
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&sock->mutex);
+#endif
+
+ if (idx < ECP_MAX_CONN_KEY) {
+ *key = sock->key[idx];
+ } else {
+ rv = ECP_ERR_ECDH_IDX;
+ }
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&sock->mutex);
+#endif
+
+ if (!rv && !key->valid) rv = ECP_ERR_ECDH_IDX;
+ return rv;
+}
+
+int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_public_t *public, int will_send) {
+ int rv = ECP_OK;
+ unsigned char _idx;
+
+ if (ecp_conn_is_inb(conn)) {
+ ECPSocket *sock = conn->sock;
+
+ rv = ecp_sock_dhkey_get_pub(sock, &_idx, public);
+ if (rv) return rv;
+
+#ifdef ECP_WITH_PTHREAD
+ if (will_send) pthread_mutex_lock(&conn->mutex);
+#endif
+
+ } else {
+ ECPDHKey *key;
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&conn->mutex);
+#endif
+
+ if (will_send) {
+ _idx = conn->key_next;
+ } else {
+ _idx = conn->key_curr;
+ }
+ if (_idx == ECP_ECDH_IDX_INV) rv = ECP_ERR_ECDH_IDX;
+
+ if (!rv) {
+ key = &conn->key[_idx];
+ if (!key->valid) rv = ECP_ERR_ECDH_IDX;
+ }
+ if (!rv) memcpy(public, &key->public, sizeof(key->public));
+ }
+
+ if (!rv && will_send) conn_dhkey_get_pub(conn, _idx);
+
+#ifdef ECP_WITH_PTHREAD
+ if (will_send || ecp_conn_is_outb(conn)) pthread_mutex_unlock(&conn->mutex);
+#endif
+
+ if (rv) return rv;
+
+ if (idx) *idx = _idx;
+ return ECP_OK;
+}
+
+int ecp_conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_public_t *public) {
ECPSocket *sock = conn->sock;
int rv;
- if (conn == NULL) return ECP_ERR;
- if (public == NULL) return ECP_ERR;
-
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&sock->conn.mutex);
+ if (ecp_conn_is_inb(conn)) pthread_mutex_lock(&sock->conn_table.mutex);
pthread_mutex_lock(&conn->mutex);
#endif
- rv = conn_dhkey_new_pub_remote(conn, idx, public);
+ rv = conn_dhkey_set_pub(conn, idx, public);
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&conn->mutex);
- pthread_mutex_unlock(&sock->conn.mutex);
+ if (ecp_conn_is_inb(conn)) pthread_mutex_unlock(&sock->conn_table.mutex);
#endif
if (rv == ECP_ERR_ECDH_KEY_DUP) rv = ECP_OK;
return rv;
}
-int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned char *public) {
- unsigned char _idx;
- ECPSocket *sock = conn->sock;
-
+void ecp_conn_dhkey_set_curr(ECPConnection *conn) {
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&conn->mutex);
#endif
- _idx = conn->key_curr;
- if (_idx != ECP_ECDH_IDX_INV) ecp_cr_dh_pub_to_buf(public, &conn->key[_idx].public);
+ if (conn->key_next != ECP_ECDH_IDX_INV) {
+ conn->key_curr = conn->key_next;
+ conn->key_next = ECP_ECDH_IDX_INV;
+ }
#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);
+void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_open_send_t send_open) {
+ memset(handler, 0, sizeof(ECPConnHandler));
+ handler->handle_msg = handle_msg;
+ handler->handle_open = handle_open;
+ handler->handle_close = handle_close;
+ handler->send_open = send_open;
+}
- if (idx) *idx = _idx;
- return ECP_OK;
+ecp_msg_handler_t ecp_get_msg_handler(ECPConnection *conn) {
+ ECPContext *ctx = conn->sock->ctx;
+ unsigned char ctype;
+
+ ctype = conn->type;
+ if (ecp_conn_is_sys(conn)) {
+ switch (ctype) {
+#ifdef ECP_WITH_DIR
+ case ECP_CTYPE_DIR:
+ return ecp_dir_handle_msg;
+#endif
+
+#ifdef ECP_WITH_VCONN
+ case ECP_CTYPE_VCONN:
+ case ECP_CTYPE_VLINK:
+ return ecp_vconn_handle_msg;
+#endif
+
+ default:
+ return NULL;
+ }
+ }
+
+ if (ctype >= ECP_MAX_CTYPE) return NULL;
+ return ctx->handler[ctype] ? ctx->handler[ctype]->handle_msg : NULL;
}
-static ssize_t _conn_send_open(ECPConnection *conn, ECPTimerItem *ti) {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(1, ECP_MTYPE_OPEN_REQ, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(1, ECP_MTYPE_OPEN_REQ, conn)];
- unsigned char *buf;
+ecp_open_handler_t ecp_get_open_handler(ECPConnection *conn) {
+ ECPContext *ctx = conn->sock->ctx;
+ unsigned char ctype;
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(1, ECP_MTYPE_OPEN_REQ, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(1, ECP_MTYPE_OPEN_REQ, conn);
+ ctype = conn->type;
+ if (ecp_conn_is_sys(conn)) {
+ switch (ctype) {
+#ifdef ECP_WITH_DIR
+ case ECP_CTYPE_DIR:
+ return ecp_dir_handle_open;
+#endif
+
+#ifdef ECP_WITH_VCONN
+ case ECP_CTYPE_VCONN:
+ case ECP_CTYPE_VLINK:
+ return ecp_vconn_handle_open;
+#endif
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_OPEN_REQ);
- buf = ecp_pld_get_buf(payload.buffer, payload.size);
- buf[0] = conn->type;
+ default:
+ return NULL;
+ }
+ }
- return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(1, ECP_MTYPE_OPEN_REQ), 0, ti);
+ if (ctype >= ECP_MAX_CTYPE) return NULL;
+ return ctx->handler[ctype] ? ctx->handler[ctype]->handle_open : NULL;
}
-static ssize_t _conn_send_kget(ECPConnection *conn, ECPTimerItem *ti) {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KGET_REQ, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn)];
+ecp_close_handler_t ecp_get_close_handler(ECPConnection *conn) {
+ ECPContext *ctx = conn->sock->ctx;
+ unsigned char ctype;
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KGET_REQ, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn);
+ ctype = conn->type;
+ if (ecp_conn_is_sys(conn)) {
+ switch (ctype) {
+#ifdef ECP_WITH_DIR
+ case ECP_CTYPE_DIR:
+ return NULL;
+#endif
+
+#ifdef ECP_WITH_VCONN
+ case ECP_CTYPE_VCONN:
+ case ECP_CTYPE_VLINK:
+ return ecp_vconn_handle_close;
+#endif
+
+ default:
+ return NULL;
+ }
+ }
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KGET_REQ);
- return _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti);
+ if (ctype >= ECP_MAX_CTYPE) return NULL;
+ return ctx->handler[ctype] ? ctx->handler[ctype]->handle_close : NULL;
}
-static ssize_t _conn_send_kput(ECPConnection *conn, ECPTimerItem *ti) {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn)];
- unsigned char *buf;
- int rv;
+ecp_dir_handler_t ecp_get_dir_handler(ECPConnection *conn) {
+ ECPContext *ctx = conn->sock->ctx;
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ, conn);
+ return ctx->handle_dir;
+}
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KPUT_REQ);
- buf = ecp_pld_get_buf(payload.buffer, payload.size);
- rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1);
- if (rv) return rv;
+void ecp_err_handle(ECPConnection *conn, unsigned char mtype, int err) {
+ ECPContext *ctx = conn->sock->ctx;
+ int rv;
+
+ rv = ecp_ext_err_handle(conn, mtype, err);
+ if (rv != ECP_PASS) return;
- return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KPUT_REQ), 0, ti);
+ if (ctx->handle_err) ctx->handle_err(conn, mtype, err);
}
-static ssize_t _conn_send_dir(ECPConnection *conn, ECPTimerItem *ti) {
+static ssize_t _send_ireq(ECPConnection *conn, ECPTimerItem *ti) {
ECPBuffer packet;
ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_DIR_REQ, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_DIR_REQ, conn)];
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_INIT_REQ, conn)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_INIT_REQ, conn)];
packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_DIR_REQ, conn);
+ packet.size = sizeof(pkt_buf);
payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_DIR_REQ, conn);
+ payload.size = sizeof(pld_buf);
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_DIR_REQ);
- return _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_DIR_REQ), 0, ti);
-}
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_INIT_REQ);
-ssize_t ecp_conn_send_open(ECPConnection *conn) {
- return ecp_timer_send(conn, _conn_send_open, ECP_MTYPE_OPEN_REP, 3, 500);
+ return _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, NULL, NULL, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_INIT_REQ), 0, ti);
}
-ssize_t ecp_conn_send_kget(ECPConnection *conn) {
- return ecp_timer_send(conn, _conn_send_kget, ECP_MTYPE_KGET_REP, 3, 500);
+static ssize_t _retry_ireq(ECPConnection *conn, ECPTimerItem *ti) {
+ int rv;
+
+ rv = ecp_conn_reset(conn);
+ if (rv) return rv;
+
+ return _send_ireq(conn, ti);
}
-ssize_t ecp_conn_send_kput(ECPConnection *conn) {
- return ecp_timer_send(conn, _conn_send_kput, ECP_MTYPE_KPUT_REP, 3, 500);
+ssize_t ecp_send_init_req(ECPConnection *conn) {
+ ECPTimerItem ti;
+
+ ecp_timer_item_init(&ti, conn, ECP_MTYPE_OPEN_REP, _retry_ireq, ECP_SEND_TRIES-1, ECP_SEND_TIMEOUT);
+
+ return _send_ireq(conn, &ti);
}
-ssize_t ecp_conn_send_dir(ECPConnection *conn) {
- return ecp_timer_send(conn, _conn_send_dir, ECP_MTYPE_DIR_REP, 3, 500);
+ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char *public_buf, ecp_aead_key_t *shkey) {
+ ssize_t rv;
+
+ rv = ecp_send_init_rep(sock, parent, addr, public_buf, shkey);
+ if (rv < 0) return rv;
+
+ return 0;
}
-ssize_t _ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b, int *was_open) {
+ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char *public_buf, ecp_aead_key_t *shkey) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ ECPPktMeta pkt_meta;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF_IREP(1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE, ECP_MTYPE_INIT_REP, parent)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF_IREP(1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE, ECP_MTYPE_INIT_REP, parent)];
+ unsigned char cookie[ECP_SIZE_COOKIE];
+ unsigned char *msg;
+ ecp_nonce_t nonce;
ssize_t rv;
int _rv;
- if (mtype & ECP_MTYPE_FLAG_REP) {
- int is_open;
+ packet.buffer = pkt_buf;
+ packet.size = sizeof(pkt_buf);
+ payload.buffer = pld_buf;
+ payload.size = sizeof(pld_buf);
- if (ecp_conn_is_inb(conn)) return ECP_ERR;
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_INIT_REP);
+ msg = ecp_pld_get_msg(payload.buffer, payload.size);
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&conn->mutex);
-#endif
- is_open = ecp_conn_is_open(conn);
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
-#endif
+ _rv = ecp_cookie_gen(sock, cookie, public_buf);
+ if (_rv) return _rv;
- if (is_open && size == ECP_ERR_TIMEOUT) {
- _rv = ecp_conn_reset(conn);
- if (_rv) return _rv;
- return 0;
- }
+ _rv = ecp_sock_dhkey_get_pub(sock, msg, (ecp_ecdh_public_t *)(msg+1));
+ if (_rv) return _rv;
+ memcpy(msg+1+ECP_SIZE_ECDH_PUB, cookie, ECP_SIZE_COOKIE);
+
+ ecp_sock_get_nonce(sock, &nonce);
+ pkt_meta.cookie = NULL;
+ pkt_meta.public = NULL;
+ pkt_meta.shkey = shkey;
+ pkt_meta.nonce = &nonce;
+ pkt_meta.ntype = ECP_NTYPE_INB;
+ pkt_meta.s_idx = 0xf;
+ pkt_meta.c_idx = 0xf;
+
+ rv = ecp_pld_send_irep(sock, parent, addr, &packet, &pkt_meta, &payload, ECP_SIZE_PLD(1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE, ECP_MTYPE_INIT_REP), 0);
+ return rv;
+}
- if (size < 0) return size;
+ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size) {
+ ecp_open_send_t send_open_f;
+ unsigned char ctype;
+ unsigned char *cookie;
+ ssize_t rv;
+ int _rv;
- if (was_open) *was_open = is_open;
+ if (msg_size < 1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE) return ECP_ERR_SIZE;
- if (!is_open) {
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&conn->mutex);
-#endif
- ecp_conn_set_open(conn);
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
+ _rv = ecp_conn_dhkey_set_pub(conn, msg[0], (ecp_ecdh_public_t *)(msg+1));
+ if (_rv) return _rv;
+
+ ctype = conn->type;
+ send_open_f = NULL;
+ cookie = msg+1+ECP_SIZE_ECDH_PUB;
+ if (ecp_conn_is_sys(conn)) {
+ switch (ctype) {
+#ifdef ECP_WITH_VCONN
+ case ECP_CTYPE_VCONN:
+ case ECP_CTYPE_VLINK:
+ send_open_f = ecp_vconn_send_open_req;
+ break;
#endif
- }
- rv = 0;
+ default:
+ break;
+ }
} else {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_OPEN_REP, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_OPEN_REP, conn)];
- unsigned char ctype;
- int is_new;
-
- if (size < 0) return size;
- if (size < 1) return ECP_ERR;
- if (ecp_conn_is_outb(conn)) return ECP_ERR;
+ ECPContext *ctx = conn->sock->ctx;
- is_new = ecp_conn_is_new(conn);
- if (is_new) {
- ecp_conn_set_open(conn);
- _rv = ecp_conn_insert(conn);
- if (_rv) return rv;
- }
+ if (ctype >= ECP_MAX_CTYPE) return ECP_ERR_CTYPE;
+ send_open_f = ctx->handler[ctype] ? ctx->handler[ctype]->send_open : NULL;
+ }
+ if (send_open_f == NULL) send_open_f = ecp_send_open_req;
+
+ rv = send_open_f(conn, cookie);
+ if (rv < 0) return rv;
- if (was_open) *was_open = !is_new;
+ return 1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE;
+}
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_OPEN_REP, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_OPEN_REP, conn);
+ssize_t ecp_write_open_req(ECPConnection *conn, ECPBuffer *payload) {
+ unsigned char *msg;
+ unsigned char vbox;
+ ssize_t rv;
+ int _rv;
+
+ if (payload->size < ECP_SIZE_PLD(2, ECP_MTYPE_OPEN_REQ)) return ECP_ERR_SIZE;
+
+ ecp_pld_set_type(payload->buffer, payload->size, ECP_MTYPE_OPEN_REQ);
+ msg = ecp_pld_get_msg(payload->buffer, payload->size);
+ *msg = conn->type;
+ msg++;
+
+ vbox = ecp_conn_has_vbox(conn);
+ *msg = vbox;
+ msg++;
+
+ rv = 0;
+ if (vbox) {
+ ECPSocket *sock = conn->sock;
+ ECPDHKey key;
+ ECPDHPub *remote_key;
+ ecp_ecdh_public_t public;
+ ecp_aead_key_t vbox_shkey;
+ ecp_nonce_t vbox_nonce;
+
+ remote_key = &conn->remote.key_perma;
+ if (payload->size < ECP_SIZE_PLD(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ)) _rv = ECP_ERR_SIZE;
+ if (!_rv && !remote_key->valid) _rv = ECP_ERR;
+ if (!_rv) _rv = ecp_sock_dhkey_get(sock, ECP_ECDH_IDX_PERMA, &key);
+ if (!_rv) _rv = ecp_conn_dhkey_get_pub(conn, NULL, &public, 0);
+ if (_rv) return _rv;
+
+ memcpy(msg, &key.public, ECP_SIZE_ECDH_PUB);
+ msg += ECP_SIZE_ECDH_PUB;
- ctype = msg[0];
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_OPEN_REP);
- rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_OPEN_REP), 0);
+ arc4random_buf(&vbox_nonce, sizeof(vbox_nonce));
+ ecp_nonce2buf(msg, &vbox_nonce);
+ msg += ECP_SIZE_NONCE;
- rv = 1;
+ ecp_ecdh_shkey(&vbox_shkey, &remote_key->public, &key.private);
+ rv = ecp_aead_enc(msg, payload->size - (msg - payload->buffer), (unsigned char *)&public, ECP_SIZE_ECDH_PUB, &vbox_shkey, &vbox_nonce, ECP_NTYPE_VBOX);
+ if (rv < 0) return rv;
}
- return rv;
+ return ECP_SIZE_PLD(2+rv, ECP_MTYPE_OPEN_REQ);
}
-ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- return _ecp_conn_handle_open(conn, seq, mtype, msg, size, b, NULL);
+ssize_t ecp_send_open_req(ECPConnection *conn, unsigned char *cookie) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF_WCOOKIE(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ, conn)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ, conn)];
+ ssize_t rv;
+
+ packet.buffer = pkt_buf;
+ packet.size = sizeof(pkt_buf);
+ payload.buffer = pld_buf;
+ payload.size = sizeof(pld_buf);
+
+ rv = ecp_write_open_req(conn, &payload);
+ if (rv < 0) return rv;
+
+ rv = ecp_pld_send_wcookie(conn, &packet, &payload, rv, 0, cookie);
+ return rv;
}
-ssize_t _ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b, ecp_conn_open_t conn_open) {
+ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, unsigned char *public_buf, unsigned char *msg, size_t msg_size, ecp_aead_key_t *shkey, ECPConnection **_conn) {
+ ECPConnection *conn;
+ ECPDHPub remote_key;
+ unsigned char ctype;
+ unsigned char vbox;
ssize_t rv;
int _rv;
- if (mtype & ECP_MTYPE_FLAG_REP) {
- ECPContext *ctx = conn->sock->ctx;
- int is_open;
-
- if (ecp_conn_is_inb(conn)) return ECP_ERR;
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&conn->mutex);
-#endif
- is_open = ecp_conn_is_open(conn);
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
-#endif
+ if (msg_size < 2) return ECP_ERR_SIZE;
+ ctype = *msg;
+ msg++;
- if ((size < 0) && !is_open) {
- ecp_conn_msg_handler_t handler;
+ vbox = *msg;
+ msg++;
- handler = ecp_conn_get_msg_handler(conn, ECP_MTYPE_OPEN);
- return handler ? handler(conn, seq, mtype, msg, size, b) : size;
- }
+ msg_size -= 2;
+ remote_key.valid = 0;
+ if (vbox) {
+ ECPDHKey key;
+ ecp_ecdh_public_t public;
+ ecp_aead_key_t vbox_shkey;
+ ecp_nonce_t vbox_nonce;
- if (size < 0) return size;
- if (size < ECP_ECDH_SIZE_KEY+1) return ECP_ERR;
+ if (msg_size < ECP_SIZE_VBOX) return ECP_ERR_SIZE;
- _rv = ecp_conn_dhkey_new_pub(conn, msg[0], msg+1);
+ _rv = ecp_sock_dhkey_get(sock, ECP_ECDH_IDX_PERMA, &key);
if (_rv) return _rv;
- if (!is_open && conn_open) {
- rv = conn_open(conn);
- }
-
- rv = ECP_ECDH_SIZE_KEY+1;
- } else {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, conn)];
- unsigned char *buf;
+ memcpy(&remote_key.public, msg, ECP_SIZE_ECDH_PUB);
+ msg+= ECP_SIZE_ECDH_PUB;
+ msg_size -= ECP_SIZE_ECDH_PUB;
- if (ecp_conn_is_outb(conn)) return ECP_ERR;
- if (size < 0) return size;
+ ecp_buf2nonce(&vbox_nonce, msg);
+ msg+= ECP_SIZE_NONCE;
+ msg_size -= ECP_SIZE_NONCE;
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, conn);
+ ecp_ecdh_shkey(&vbox_shkey, &remote_key.public, &key.private);
+ rv = ecp_aead_dec((unsigned char *)&public, ECP_SIZE_ECDH_PUB, msg, msg_size, &vbox_shkey, &vbox_nonce, ECP_NTYPE_VBOX);
+ if (rv != ECP_SIZE_ECDH_PUB) return ECP_ERR_VBOX;
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KGET_REP);
- buf= ecp_pld_get_buf(payload.buffer, payload.size);
+ if (memcmp(&public, public_buf, ECP_SIZE_ECDH_PUB) != 0) return ECP_ERR_VBOX;
+ remote_key.valid = 1;
+ }
- _rv = ecp_conn_dhkey_get_curr(conn, buf, buf+1);
- if (_rv) return _rv;
- rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0);
+ _rv = ecp_conn_alloc(sock, ctype, &conn);
+ if (_rv) return _rv;
- rv = 0;
+ _rv = ecp_conn_init_inb(conn, parent, s_idx, c_idx, (ecp_ecdh_public_t *)public_buf, remote_key.valid ? &remote_key : NULL, shkey);
+ if (!_rv) _rv = ecp_conn_insert(conn);
+ if (_rv) {
+ ecp_conn_destroy(conn);
+ ecp_conn_free(conn);
+ return _rv;
}
- return rv;
-}
+ *_conn = conn;
-ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- return _ecp_conn_handle_kget(conn, seq, mtype, msg, size, b, ecp_conn_send_open);
+ /* handle_open will be called later from msg handler */
+ return 2+(vbox ? ECP_SIZE_VBOX : 0);
}
-ssize_t ecp_conn_handle_kput(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
+ssize_t ecp_send_open_rep(ECPConnection *conn) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_OPEN_REP, conn)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_OPEN_REP, conn)];
ssize_t rv;
- int _rv;
- if (size < 0) return size;
+ packet.buffer = pkt_buf;
+ packet.size = sizeof(pkt_buf);
+ payload.buffer = pld_buf;
+ payload.size = sizeof(pld_buf);
- if (mtype & ECP_MTYPE_FLAG_REP) {
- if (ecp_conn_is_inb(conn)) return ECP_ERR;
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_OPEN_REP);
+ rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_OPEN_REP), 0);
+ return rv;
+}
- rv = 0;
- } else {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KPUT_REP, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KPUT_REP, conn)];
+ssize_t ecp_handle_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
+ size_t rsize;
+ ecp_open_handler_t handler;
+ int rv = ECP_OK;
+ if (mtype == ECP_MTYPE_OPEN_REQ) {
if (ecp_conn_is_outb(conn)) return ECP_ERR;
- if (size < ECP_ECDH_SIZE_KEY+1) return ECP_ERR;
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KPUT_REP, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KPUT_REP, conn);
+ rsize = 2;
+ if (msg_size < rsize) return ECP_ERR_SIZE;
- _rv = ecp_conn_dhkey_new_pub(conn, msg[0], msg+1);
- if (_rv) return _rv;
+ if (msg[1]) rsize += ECP_SIZE_VBOX;
+ if (msg_size < rsize) return ECP_ERR_SIZE;
+ } else {
+ if (ecp_conn_is_inb(conn)) return ECP_ERR;
+ rsize = 0;
+ }
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KPUT_REP);
- rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KPUT_REP), 0);
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&conn->mutex);
+#endif
- rv = ECP_ECDH_SIZE_KEY+1;
- }
+ if (ecp_conn_is_open(conn)) rv = ECP_ERR;
+ if (!rv) rv = ecp_ext_conn_open(conn);
+ if (!rv) ecp_conn_set_open(conn);
- return rv;
-}
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&conn->mutex);
+#endif
-ssize_t ecp_conn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
- ecp_conn_msg_handler_t handler;
- unsigned char mtype = 0;
- unsigned char *content = NULL;
- size_t rem_size = msg_size;
- ssize_t rv;
- int _rv;
+ if (rv) return rv;
- while (rem_size) {
- _rv = ecp_msg_get_type(msg, rem_size, &mtype);
- if (_rv) return ECP_ERR;
- if ((mtype & ECP_MTYPE_MASK) >= ECP_MAX_MTYPE) return ECP_ERR_MAX_MTYPE;
+ handler = ecp_get_open_handler(conn);
+ if (handler) rv = handler(conn, bufs);
+ if (rv) {
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&conn->mutex);
+#endif
- ecp_timer_pop(conn, mtype);
+ ecp_conn_clr_open(conn);
- if (mtype & ECP_MTYPE_FLAG_FRAG) {
-#ifdef ECP_WITH_RBUF
- ECPFragIter *iter = ecp_rbuf_get_frag_iter(conn);
- if (iter) {
- _rv = ecp_msg_defrag(iter, seq, mtype, msg, msg_size, &msg, &rem_size);
- if (_rv == ECP_ITER_NEXT) break;
- if (_rv < 0) return _rv;
- } else {
- return ECP_ERR_ITER;
- }
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&conn->mutex);
#endif
- }
- content = ecp_msg_get_content(msg, rem_size);
- if (content == NULL) return ECP_ERR;
- rem_size -= content - msg;
+ if (ecp_conn_is_inb(conn)) ecp_conn_close(conn);
+ return rv;
+ }
- handler = ecp_conn_get_msg_handler(conn, mtype & ECP_MTYPE_MASK);
- if (handler) {
- rv = handler(conn, seq, mtype, content, rem_size, bufs);
- if (rv < 0) return rv;
- if (rv > rem_size) return ECP_ERR;
- if (mtype & ECP_MTYPE_FLAG_FRAG) break;
+ if (ecp_conn_is_inb(conn)) {
+ ssize_t _rv;
- rem_size -= rv;
- msg = content + rv;
- } else {
- return msg_size - rem_size - 1;
+ _rv = ecp_send_open_rep(conn);
+ if (_rv < 0) {
+ ecp_conn_close(conn);
+ return _rv;
}
+ } else {
+ ecp_conn_remove_addr(conn);
}
-
- return msg_size;
+ return rsize;
}
-ssize_t ecp_sock_handle_open(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn) {
- ECPConnection *conn = NULL;
- unsigned char c_idx = pkt_meta->c_idx;
- unsigned char ctype;
- int rv;
-
- if (msg_size < 0) return msg_size;
- if (msg_size < 1) return ECP_ERR;
+static ssize_t _send_keyx_req(ECPConnection *conn, ECPTimerItem *ti) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF(1+ECP_SIZE_ECDH_PUB, ECP_MTYPE_KEYX_REQ, conn)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(1+ECP_SIZE_ECDH_PUB, ECP_MTYPE_KEYX_REQ, conn)];
+ unsigned char *msg;
+ ssize_t rv;
+ int _rv;
- ctype = msg[0];
+ packet.buffer = pkt_buf;
+ packet.size = sizeof(pkt_buf);
+ payload.buffer = pld_buf;
+ payload.size = sizeof(pld_buf);
- conn = sock->ctx->conn_alloc ? sock->ctx->conn_alloc(sock, ctype) : NULL;
- if (conn == NULL) return ECP_ERR_ALLOC;
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KEYX_REQ);
+ msg = ecp_pld_get_msg(payload.buffer, payload.size);
- rv = ecp_conn_create_inb(conn, parent, c_idx, pkt_meta->public);
- if (rv) {
- if (sock->ctx->conn_free) sock->ctx->conn_free(conn);
- return rv;
- }
+ _rv = ecp_conn_dhkey_get_pub(conn, msg, (ecp_ecdh_public_t *)(msg+1), 1);
+ if (_rv) return _rv;
- if (parent) {
- ecp_conn_refcount_inc(parent);
- }
+ rv = ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(1+ECP_SIZE_ECDH_PUB, ECP_MTYPE_KEYX_REQ), 0, ti);
+ return rv;
+}
- *_conn = conn;
- return 1;
+ssize_t ecp_send_keyx_req(ECPConnection *conn) {
+ return ecp_timer_send(conn, _send_keyx_req, ECP_MTYPE_KEYX_REP, ECP_SEND_TRIES, ECP_SEND_TIMEOUT);
}
-ssize_t ecp_sock_handle_kget(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn) {
+ssize_t ecp_send_keyx_rep(ECPConnection *conn) {
ECPBuffer packet;
ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent)];
- unsigned char *buf;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF(1+ECP_SIZE_ECDH_PUB, ECP_MTYPE_KEYX_REP, conn)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(1+ECP_SIZE_ECDH_PUB, ECP_MTYPE_KEYX_REP, conn)];
+ unsigned char *msg;
ssize_t rv;
int _rv;
- if (msg_size < 0) return msg_size;
-
packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent);
+ packet.size = sizeof(pkt_buf);
payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF_TR(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP, parent);
+ payload.size = sizeof(pld_buf);
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KGET_REP);
- buf = ecp_pld_get_buf(payload.buffer, payload.size);
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KEYX_REP);
+ msg = ecp_pld_get_msg(payload.buffer, payload.size);
- _rv = ecp_sock_dhkey_get_curr(sock, buf, buf+1);
+ _rv = ecp_conn_dhkey_get_pub(conn, msg, (ecp_ecdh_public_t *)(msg+1), 1);
if (_rv) return _rv;
- rv = ecp_pld_send_tr(sock, addr, parent, &packet, pkt_meta, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_KGET_REP), 0);
- if (rv < 0) return rv;
-
- return msg_size;
+ rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(1+ECP_SIZE_ECDH_PUB, ECP_MTYPE_KEYX_REP), 0);
+ return rv;
}
-ssize_t _ecp_pack(ECPContext *ctx, unsigned char *packet, size_t pkt_size, ECPPktMeta *pkt_meta, unsigned char *payload, size_t pld_size) {
+ssize_t ecp_handle_keyx(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size) {
ssize_t rv;
- unsigned char s_idx, c_idx;
+ int _rv;
- if (pkt_size < ECP_SIZE_PKT_HDR) return ECP_ERR;
+ if (msg_size < 1+ECP_SIZE_ECDH_PUB) return ECP_ERR_SIZE;
- // ECP_SIZE_PROTO
- packet[0] = 0;
- packet[1] = 0;
- s_idx = pkt_meta->s_idx & 0x0F;
- c_idx = pkt_meta->c_idx & 0x0F;
- packet[ECP_SIZE_PROTO] = (s_idx << 4) | c_idx;
- memcpy(packet+ECP_SIZE_PROTO+1, pkt_meta->public, ECP_ECDH_SIZE_KEY);
- memcpy(packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY, pkt_meta->nonce, ECP_AEAD_SIZE_NONCE);
-
- payload[0] = (pkt_meta->seq & 0xFF000000) >> 24;
- payload[1] = (pkt_meta->seq & 0x00FF0000) >> 16;
- payload[2] = (pkt_meta->seq & 0x0000FF00) >> 8;
- payload[3] = (pkt_meta->seq & 0x000000FF);
- rv = ecp_cr_aead_enc(packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, payload, pld_size, &pkt_meta->shsec, pkt_meta->nonce);
- if (rv < 0) return ECP_ERR_ENCRYPT;
+ _rv = ecp_conn_dhkey_set_pub(conn, msg[0], (ecp_ecdh_public_t *)(msg+1));
+ if (_rv) return _rv;
- memcpy(pkt_meta->nonce, packet+ECP_SIZE_PKT_HDR, ECP_AEAD_SIZE_NONCE);
+ if (mtype == ECP_MTYPE_KEYX_REP) {
+ if (ecp_conn_is_inb(conn)) return ECP_ERR;
- return rv+ECP_SIZE_PKT_HDR;
-}
+ ecp_conn_dhkey_set_curr(conn);
+ } else {
+ if (ecp_conn_is_outb(conn)) return ECP_ERR;
-#ifndef ECP_WITH_VCONN
-ssize_t ecp_pack(ECPContext *ctx, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) {
- if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR;
- if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR;
+ rv = ecp_send_keyx_rep(conn);
+ if (rv < 0) return rv;
+ }
- return _ecp_pack(ctx, packet->buffer, packet->size, pkt_meta, payload->buffer, pld_size);
+ return 1+ECP_SIZE_ECDH_PUB;
}
-#endif
-ssize_t _ecp_pack_conn(ECPConnection *conn, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, unsigned char *payload, size_t pld_size, ECPNetAddr *addr, ECPSeqItem *si) {
- ECPPktMeta pkt_meta;
- int rv;
- ssize_t _rv;
+ssize_t ecp_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
+ if (mtype & ECP_MTYPE_FLAG_SYS) {
+ switch (mtype) {
+ case ECP_MTYPE_OPEN_REQ:
+ case ECP_MTYPE_OPEN_REP:
+ return ecp_handle_open(conn, mtype, msg, msg_size, bufs);
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&conn->mutex);
-#endif
+ case ECP_MTYPE_KEYX_REQ:
+ case ECP_MTYPE_KEYX_REP:
+ return ecp_handle_keyx(conn, mtype, msg, msg_size);
- if (s_idx == ECP_ECDH_IDX_INV) {
- if (ecp_conn_is_outb(conn)) {
- if (conn->remote.key_curr != ECP_ECDH_IDX_INV) s_idx = conn->remote.key[conn->remote.key_curr].idx;
- } else {
- if (conn->key_idx_curr != ECP_ECDH_IDX_INV) s_idx = conn->key_idx[conn->key_idx_curr];
- }
- }
- if (c_idx == ECP_ECDH_IDX_INV) {
- if (ecp_conn_is_outb(conn)) {
- if (conn->key_idx_curr != ECP_ECDH_IDX_INV) c_idx = conn->key_idx[conn->key_idx_curr];
- } else {
- if (conn->remote.key_curr != ECP_ECDH_IDX_INV) c_idx = conn->remote.key[conn->remote.key_curr].idx;
+ default:
+ return ecp_ext_msg_handle(conn, seq, mtype, msg, msg_size, bufs);
}
- }
- rv = conn_shsec_get(conn, s_idx, c_idx, &pkt_meta.shsec);
- if (!rv) memcpy(pkt_meta.nonce, conn->nonce, sizeof(pkt_meta.nonce));
- if (!rv) {
- if (ecp_conn_is_outb(conn)) {
- ECPDHKey *key = conn_dhkey_get(conn, c_idx);
+ } else {
+ ecp_msg_handler_t handler;
- if ((key == NULL) || !key->valid) rv = ECP_ERR_ECDH_IDX;
- if (!rv) memcpy(&pkt_meta.public, &key->public, sizeof(pkt_meta.public));
+ handler = ecp_get_msg_handler(conn);
+ if (handler) {
+ return handler(conn, seq, mtype, msg, msg_size, bufs);
} else {
- memcpy(&pkt_meta.public, &conn->remote.key[conn->remote.key_curr].public, sizeof(pkt_meta.public));
+ return ECP_ERR_HANDLER;
}
}
- if (!rv) {
- if (si) {
- if (si->seq_w) {
- pkt_meta.seq = si->seq;
- } else {
- pkt_meta.seq = conn->seq_out + 1;
- si->seq = pkt_meta.seq;
- }
-
-#ifdef ECP_WITH_RBUF
- if (conn->rbuf.send) {
- rv = ecp_rbuf_set_seq(conn, si, payload, pld_size);
- }
-#endif
+}
- if (!rv && !si->seq_w) conn->seq_out = pkt_meta.seq;
- } else {
- pkt_meta.seq = conn->seq_out + 1;
- conn->seq_out = pkt_meta.seq;
- }
- if (!rv && addr) *addr = conn->node.addr;
- }
+ssize_t ecp_pld_handle_one(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs) {
+ unsigned char mtype;
+ unsigned char *msg;
+ size_t hdr_size, msg_size;
+ ssize_t rv;
+ int _rv;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
-#endif
+ _rv = ecp_pld_get_type(payload, pld_size, &mtype);
+ if (_rv) return _rv;
- if (rv) return rv;
+ ecp_timer_pop(conn, mtype);
- pkt_meta.s_idx = s_idx;
- pkt_meta.c_idx = c_idx;
- _rv = _ecp_pack(conn->sock->ctx, packet, pkt_size, &pkt_meta, payload, pld_size);
- if (_rv < 0) return _rv;
+ msg = ecp_pld_get_msg(payload, pld_size);
+ if (msg == NULL) return ECP_ERR;
+ hdr_size = msg - payload;
+ msg_size = pld_size - hdr_size;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&conn->mutex);
-#endif
- memcpy(conn->nonce, pkt_meta.nonce, sizeof(conn->nonce));
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
-#endif
+ rv = ecp_msg_handle(conn, seq, mtype, msg, msg_size, bufs);
+ if (rv < 0) return rv;
- return _rv;
+ rv += hdr_size;
+ if (rv > pld_size) return ECP_ERR_SIZE;
+ return rv;
}
-#ifndef ECP_WITH_VCONN
-ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr, ECPSeqItem *si) {
- if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR;
- if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR;
+ssize_t ecp_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t _pld_size, ECP2Buffer *bufs) {
+ size_t pld_size = _pld_size;
+ ssize_t rv;
+
+ rv = ecp_ext_pld_handle(conn, seq, payload, pld_size, bufs);
+ if (rv < 0) return rv;
+
+ payload += rv;
+ pld_size -= rv;
+
+ while (pld_size) {
+ rv = ecp_pld_handle_one(conn, seq, payload, pld_size, bufs);
+ if (rv == ECP_ERR_HANDLER) return _pld_size - pld_size;
+ if (rv < 0) return rv;
+
+ payload += rv;
+ pld_size -= rv;
+ }
- return _ecp_pack_conn(conn, packet->buffer, packet->size, s_idx, c_idx, payload->buffer, pld_size, addr, si);
+ return _pld_size;
}
-#endif
-ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size, ECPConnection **_conn, ecp_seq_t *_seq) {
+ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t _pkt_size, ECPConnection **_conn, unsigned char **_payload, ecp_seq_t *_seq) {
+ ECPConnection *conn = NULL;
+ unsigned char idx;
unsigned char s_idx;
unsigned char c_idx;
- unsigned char l_idx = ECP_ECDH_IDX_INV;
- unsigned char *payload = bufs->payload->buffer;
- unsigned char *packet = bufs->packet->buffer;
- size_t pld_size = bufs->payload->size;
- ssize_t dec_size;
- ecp_aead_key_t shsec;
- ecp_dh_public_t public;
- ecp_dh_private_t private;
- unsigned char *public_buf;
- unsigned char *nonce;
- unsigned char nonce_next[ECP_AEAD_SIZE_NONCE];
- ECPConnection *conn = NULL;
- ECPDHKey *key = NULL;
- unsigned char mtype;
+ unsigned char *payload;
+ unsigned char *packet;
+ ssize_t pld_size;
+ size_t pkt_size = _pkt_size;
+ ecp_aead_key_t shkey;
+ unsigned char *public_buf = NULL;
+ unsigned char *nonce_buf = NULL;
unsigned char is_open = 0;
- unsigned char seq_check;
- unsigned char seq_reset;
- ecp_seq_t seq_pkt, seq_conn, seq_last;
- ecp_ack_t seq_map;
- int rv = ECP_OK;
+ unsigned char is_inb = 0;
+ ecp_nonce_t nonce_pkt, nonce_conn, nonce_in;
+ ecp_ack_t nonce_map;
+ ssize_t rv;
+ int _rv = ECP_OK;
+
+ if (pkt_size < ECP_MIN_PKT) return ECP_ERR_SIZE;
*_conn = NULL;
+ *_payload = NULL;
*_seq = 0;
- s_idx = (packet[ECP_SIZE_PROTO] & 0xF0) >> 4;
- c_idx = (packet[ECP_SIZE_PROTO] & 0x0F);
-
- public_buf = packet+ECP_SIZE_PROTO+1;
- nonce = packet+ECP_SIZE_PROTO+1+ECP_ECDH_SIZE_KEY;
+ packet = bufs->packet->buffer;
+ idx = packet[ECP_SIZE_PROTO];
+ s_idx = (idx & 0xF0) >> 4;
+ c_idx = (idx & 0x0F);
+ if (idx != ECP_ECDH_IDX_INV) {
+ public_buf = packet+ECP_SIZE_PROTO+1;
+ }
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&sock->conn.mutex);
+ pthread_mutex_lock(&sock->conn_table.mutex);
#endif
- conn = ctable_search(sock, c_idx, public_buf, NULL);
- if (conn && ecp_conn_is_inb(conn) && (s_idx == ECP_ECDH_IDX_PERMA)) conn = NULL;
+ conn = conn_table_search(sock, c_idx, (ecp_ecdh_public_t *)public_buf, addr);
#ifdef ECP_WITH_PTHREAD
if (conn) pthread_mutex_lock(&conn->mutex);
- pthread_mutex_unlock(&sock->conn.mutex);
+ pthread_mutex_unlock(&sock->conn_table.mutex);
#endif
if (conn) {
- rv = conn_shsec_get(conn, s_idx, c_idx, &shsec);
- if (rv == ECP_ERR_ECDH_IDX_LOCAL) {
- rv = ECP_OK;
- l_idx = ecp_conn_is_outb(conn) ? c_idx : s_idx;
- key = conn_dhkey_get(conn, l_idx);
- if ((key == NULL) || !key->valid) rv = ECP_ERR_ECDH_IDX;
- }
- } else {
- if (s_idx == ECP_ECDH_IDX_PERMA) {
- key = &sock->key_perma;
- } else {
- l_idx = s_idx;
- if (l_idx < ECP_MAX_SOCK_KEY) key = &sock->key[l_idx];
- }
- if ((key == NULL) || !key->valid) rv = ECP_ERR_ECDH_IDX;
- }
-
- if (!rv && key) memcpy(&private, &key->private, sizeof(private));
-
- if (!rv && conn) {
- conn->refcount++;
+ is_inb = ecp_conn_is_inb(conn);
is_open = ecp_conn_is_open(conn);
+
if (is_open) {
- seq_conn = conn->seq_in;
- seq_map = conn->seq_in_map;
+ nonce_buf = packet+ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB;
+ packet += ECP_SIZE_PKT_HDR;
+ pkt_size -= ECP_SIZE_PKT_HDR;
+
+ nonce_conn = conn->nonce_in;
+ nonce_map = conn->nonce_map;
+ } else if (!is_inb && (idx == ECP_ECDH_IDX_INV)) {
+ nonce_buf = packet+ECP_SIZE_PROTO+1;
+ packet += ECP_SIZE_PROTO+1+ECP_SIZE_NONCE;
+ pkt_size -= ECP_SIZE_PROTO+1+ECP_SIZE_NONCE;
+
+ s_idx = ECP_ECDH_IDX_PERMA;
+ c_idx = conn->key_curr;
+ } else {
+ _rv = ECP_ERR;
}
- }
+ if (!_rv) _rv = conn_shkey_get(conn, s_idx, c_idx, &shkey);
+ if (!_rv) conn->refcount++;
#ifdef ECP_WITH_PTHREAD
- if (conn) pthread_mutex_unlock(&conn->mutex);
+ pthread_mutex_unlock(&conn->mutex);
#endif
- if (rv) return rv;
+ if (_rv) return _rv;
+ } else {
+ ECPDHKey key;
- if (key) {
- ecp_cr_dh_pub_from_buf(&public, public_buf);
- ecp_cr_dh_shsec(&shsec, &public, &private);
- memset(&private, 0, sizeof(private));
- }
+ is_inb = 1;
+ public_buf = packet+ECP_SIZE_PROTO+1;
- dec_size = ecp_cr_aead_dec(payload, pld_size, packet+ECP_SIZE_PKT_HDR, pkt_size-ECP_SIZE_PKT_HDR, &shsec, nonce);
- if (dec_size < ECP_SIZE_PLD_HDR+1) rv = ECP_ERR_DECRYPT;
- if (rv) goto ecp_unpack_err;
+ if (s_idx == ECP_ECDH_IDX_PERMA) {
+ nonce_buf = public_buf+ECP_SIZE_ECDH_PUB;
+ packet += ECP_SIZE_PKT_HDR;
+ pkt_size -= ECP_SIZE_PKT_HDR;
- seq_pkt = \
- (payload[0] << 24) | \
- (payload[1] << 16) | \
- (payload[2] << 8) | \
- (payload[3]);
+ _rv = ecp_sock_dhkey_get(sock, s_idx, &key);
+ if (_rv) return _rv;
- mtype = payload[ECP_SIZE_PLD_HDR];
- memcpy(nonce_next, packet+ECP_SIZE_PKT_HDR, sizeof(nonce_next));
- // XXX!
- // if ((mtype & ECP_MTYPE_MASK) < ECP_MAX_MTYPE_SYS) ecp_tr_release(bufs->packet, 1);
- if (conn == NULL) {
- ECPPktMeta pkt_meta;
- unsigned char *msg = payload+ECP_SIZE_PLD_HDR+1;
- size_t msg_size = dec_size-ECP_SIZE_PLD_HDR-1;
- ecp_sock_msg_handler_t handler;
-
- if (key == NULL) return ECP_ERR;
- if ((mtype & ECP_MTYPE_MASK) >= ECP_MAX_MTYPE_SOCK) return ECP_ERR_MAX_MTYPE;
- if (mtype & ECP_MTYPE_FLAG_REP) return ECP_ERR;
-
- memcpy(pkt_meta.public, public_buf, sizeof(pkt_meta.public));
- memcpy(pkt_meta.nonce, nonce_next, sizeof(pkt_meta.nonce));
- memcpy(&pkt_meta.shsec, &shsec, sizeof(pkt_meta.shsec));
- pkt_meta.seq = seq_pkt;
- pkt_meta.s_idx = s_idx;
- pkt_meta.c_idx = c_idx;
-
- handler = ecp_sock_get_msg_handler(sock, mtype & ECP_MTYPE_MASK);
- if (handler) {
- ssize_t _rv;
+ ecp_ecdh_shkey(&shkey, (ecp_ecdh_public_t *)public_buf, &key.private);
+ } else if (pkt_size >= (ECP_MIN_PKT+ECP_SIZE_COOKIE)) {
+ unsigned char *cookie_buf;
+
+ cookie_buf = public_buf+ECP_SIZE_ECDH_PUB;
+ nonce_buf = cookie_buf+ECP_SIZE_COOKIE;
+ packet += ECP_SIZE_PKT_HDR+ECP_SIZE_COOKIE;
+ pkt_size -= ECP_SIZE_PKT_HDR+ECP_SIZE_COOKIE;
+
+ _rv = ecp_cookie_verify(sock, cookie_buf, public_buf);
+ if (_rv) return _rv;
- _rv = handler(sock, addr, parent, msg, msg_size, &pkt_meta, bufs, &conn);
- if (_rv < 0) return _rv;
+ _rv = ecp_sock_dhkey_get(sock, s_idx, &key);
+ if (_rv) return _rv;
+
+ ecp_ecdh_shkey(&shkey, (ecp_ecdh_public_t *)public_buf, &key.private);
+ } else {
+ return ECP_ERR;
}
}
- if (conn == NULL) return dec_size;
+ ecp_buf2nonce(&nonce_pkt, nonce_buf);
+ if (conn && is_open) {
+ if (ECP_NONCE_LTE(nonce_pkt, nonce_conn)) {
+ ecp_nonce_t nonce_offset = nonce_conn - nonce_pkt;
- seq_check = 1;
- seq_reset = 0;
+ if (nonce_offset < ECP_SIZE_ACKB) {
+ ecp_ack_t nonce_mask = ((ecp_ack_t)1 << nonce_offset);
- if (is_open) {
-#ifdef ECP_WITH_RBUF
- if (ecp_rbuf_handle_seq(conn, mtype)) seq_check = 0;
-#endif
+ if (nonce_mask & nonce_map) _rv = ECP_ERR_SEQ;
+ if (!_rv) nonce_in = nonce_conn;
+ } else {
+ _rv = ECP_ERR_SEQ;
+ }
+ } else {
+ ecp_nonce_t nonce_offset = nonce_pkt - nonce_conn;
- if (seq_check) {
- if (ECP_SEQ_LTE(seq_pkt, seq_conn)) {
- ecp_seq_t seq_offset = seq_conn - seq_pkt;
- if (seq_offset < ECP_SIZE_ACKB) {
- ecp_ack_t ack_mask = ((ecp_ack_t)1 << seq_offset);
- if (ack_mask & seq_map) rv = ECP_ERR_SEQ;
- if (!rv) seq_last = seq_conn;
+ if (nonce_offset < ECP_MAX_SEQ_FWD) {
+ if (nonce_offset < ECP_SIZE_ACKB) {
+ nonce_map = nonce_map << nonce_offset;
} else {
- rv = ECP_ERR_SEQ;
+ nonce_map = 0;
}
+ nonce_map |= 1;
+ nonce_in = nonce_pkt;
} else {
- ecp_seq_t seq_offset = seq_pkt - seq_conn;
- if (seq_offset < ECP_MAX_SEQ_FWD) {
- if (seq_offset < ECP_SIZE_ACKB) {
- seq_map = seq_map << seq_offset;
- } else {
- seq_map = 0;
- }
- seq_map |= 1;
- seq_last = seq_pkt;
- } else {
- rv = ECP_ERR_SEQ;
- }
+ _rv = ECP_ERR_SEQ;
+ }
+ }
+ if (_rv) {
+ rv = _rv;
+ goto unpack_err;
+ }
+ }
+
+ payload = bufs->payload->buffer;
+ rv = ecp_aead_dec(payload, bufs->payload->size, packet, pkt_size, &shkey, &nonce_pkt, is_inb ? ECP_NTYPE_INB : ECP_NTYPE_OUTB);
+ if (rv < 0) goto unpack_err;
+
+ pld_size = rv;
+ if (pld_size < ECP_MIN_PLD) {
+ rv = ECP_ERR_SIZE;
+ goto unpack_err;
+ }
+
+ if (conn == NULL) {
+ unsigned char mtype;
+ unsigned char *msg;
+ size_t hdr_size, msg_size;
+
+ _rv = ecp_pld_get_type(payload, pld_size, &mtype);
+ if (_rv) return _rv;
+
+ msg = ecp_pld_get_msg(payload, pld_size);
+ if (msg == NULL) return ECP_ERR;
+ hdr_size = msg - payload;
+ msg_size = pld_size - hdr_size;
+
+ switch (mtype) {
+ case ECP_MTYPE_INIT_REQ: {
+ rv = ecp_handle_init_req(sock, parent, addr, public_buf, &shkey);
+ if (rv < 0) return rv;
+
+ rv += hdr_size;
+ break;
}
- if ((rv == ECP_ERR_SEQ) && (mtype == ECP_MTYPE_OPEN_REQ) && key) {
- rv = ECP_OK;
- seq_reset = 1;
+ case ECP_MTYPE_OPEN_REQ: {
+ rv = ecp_handle_open_req(sock, parent, s_idx, c_idx, public_buf, msg, msg_size, &shkey, &conn);
+ if (rv < 0) return rv;
+
+ /* pass to payload handler */
+ nonce_in = nonce_pkt;
+ nonce_map = ECP_ACK_FULL;
+ is_open = 1;
+ rv = 0;
+ break;
}
- if (rv) goto ecp_unpack_err;
+
+ default:
+ return ECP_ERR_MTYPE;
}
- }
- if (!is_open || seq_reset) {
- seq_last = seq_pkt;
- seq_map = 1;
+ payload += rv;
+ pld_size -= rv;
+ } else if (!is_open) {
+ unsigned char mtype;
+ unsigned char *msg;
+ size_t hdr_size, msg_size;
+
+ _rv = ecp_pld_get_type(payload, pld_size, &mtype);
+ if (_rv) {
+ rv = _rv;
+ goto unpack_err;
+ }
-#ifdef ECP_WITH_RBUF
- if (conn->rbuf.recv) {
- rv = ecp_rbuf_recv_start(conn, seq_pkt);
- if (rv) goto ecp_unpack_err;
+ msg = ecp_pld_get_msg(payload, pld_size);
+ if (msg == NULL) {
+ rv = ECP_ERR;
+ goto unpack_err;
}
-#endif
+ hdr_size = msg - payload;
+ msg_size = pld_size - hdr_size;
+
+ switch (mtype) {
+ case ECP_MTYPE_INIT_REP: {
+ rv = ecp_handle_init_rep(conn, msg, msg_size);
+ if (rv < 0) goto unpack_err;
+
+ rv += hdr_size;
+ break;
+ }
+
+ case ECP_MTYPE_OPEN_REP: {
+ /* pass to payload handler */
+ nonce_in = nonce_pkt;
+ nonce_map = ECP_ACK_FULL;
+ is_open = 1;
+ rv = 0;
+ break;
+ }
+
+ default:
+ rv = ECP_ERR_MTYPE;
+ goto unpack_err;
+ }
+
+ payload += rv;
+ pld_size -= rv;
}
+ if (conn && is_open) {
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&conn->mutex);
+ pthread_mutex_lock(&conn->mutex);
#endif
- memcpy(conn->nonce, nonce_next, sizeof(conn->nonce));
- if (addr) conn->node.addr = *addr;
- if (seq_check) {
- conn->seq_in = seq_last;
- conn->seq_in_map = seq_map;
- }
- if (key) {
- if (!rv) rv = conn_dhkey_new_pub_local(conn, l_idx);
- if (!rv) rv = conn_shsec_set(conn, s_idx, c_idx, &shsec);
- }
+
+ conn->nonce_in = nonce_in;
+ conn->nonce_map = nonce_map;
+ if (is_inb && addr) conn->remote.addr = *addr;
+
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
+ pthread_mutex_unlock(&conn->mutex);
#endif
- if (rv) goto ecp_unpack_err;
+ *_conn = conn;
+ *_payload = payload;
+ *_seq = (ecp_seq_t)nonce_pkt;
+ }
- *_conn = conn;
- *_seq = seq_pkt;
- return dec_size;
+ return _pkt_size - pld_size;
-ecp_unpack_err:
- if (conn == NULL) return rv;
- ecp_conn_refcount_dec(conn);
+unpack_err:
+ if (conn) ecp_conn_refcount_dec(conn);
return rv;
}
-ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size) {
- ECPConnection *conn;
+ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t pkt_size) {
+ ECPConnection *conn = NULL;
+ unsigned char *payload;
ecp_seq_t seq;
- ssize_t pld_size;
- ssize_t rv = 0;
+ size_t pld_size;
+ ssize_t rv;
- pld_size = ecp_unpack(sock, addr, parent, bufs, pkt_size, &conn, &seq);
- if (pld_size < 0) return pld_size;
- if (pld_size < ECP_SIZE_PLD_HDR) return ECP_ERR;
+ rv = ecp_unpack(sock, parent, addr, bufs, pkt_size, &conn, &payload, &seq);
+ if (rv < 0) return rv;
- if (conn) {
-#ifdef ECP_WITH_RBUF
- if (conn->rbuf.recv) {
- rv = ecp_rbuf_store(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR, bufs);
- }
-#endif
- if (rv == 0) rv = ecp_conn_handle_msg(conn, seq, bufs->payload->buffer+ECP_SIZE_PLD_HDR, pld_size-ECP_SIZE_PLD_HDR, bufs);
- ecp_conn_refcount_dec(conn);
- } else {
- rv = pld_size-ECP_SIZE_PLD_HDR;
+ pld_size = pkt_size - rv;
+ if (conn == NULL) {
+ if (pld_size) return ECP_ERR;
+ return pkt_size;
}
- if (rv < 0) return rv;
- return ECP_SIZE_PKT_HDR+ECP_AEAD_SIZE_TAG+ECP_SIZE_PLD_HDR+rv;
-}
+ if (pld_size) {
+ rv = ecp_ext_pld_store(conn, seq, payload, pld_size, bufs);
+ if (rv < 0) goto pkt_handle_fin;
-ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags) {
- ssize_t rv;
+ payload += rv;
+ pld_size -= rv;
+ }
- rv = ecp_tr_send(sock, packet, pkt_size, addr, flags);
- if (rv < 0) return rv;
- if (rv < ECP_MIN_PKT) return ECP_ERR_SEND;
+ if (pld_size) {
+ rv = ecp_pld_handle(conn, seq, payload, pld_size, bufs);
+ if (rv < 0) goto pkt_handle_fin;
- return rv;
-}
+ payload += rv;
+ pld_size -= rv;
+ }
-int ecp_msg_get_type(unsigned char *msg, size_t msg_size, unsigned char *mtype) {
- if (msg_size == 0) ECP_ERR;
+ rv = pkt_size - pld_size;
- *mtype = msg[0];
- return ECP_OK;
+pkt_handle_fin:
+ ecp_conn_refcount_dec(conn);
+ return rv;
}
-int ecp_msg_set_type(unsigned char *msg, size_t msg_size, unsigned char type) {
- if (msg_size == 0) ECP_ERR;
+ssize_t ecp_pkt_send(ECPSocket *sock, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ecp_tr_addr_t *addr) {
+ ssize_t rv;
- msg[0] = type;
- return ECP_OK;
-}
+ if (ti) {
+ int _rv;
-int ecp_msg_get_frag(unsigned char *msg, size_t msg_size, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_size) {
- if (msg_size < 3) return ECP_ERR;
- if (!(msg[0] & ECP_MTYPE_FLAG_FRAG)) return ECP_ERR;
- if (msg[2] == 0) return ECP_ERR;
+ _rv = ecp_timer_push(ti);
+ if (_rv) return _rv;
+ }
- *frag_cnt = msg[1];
- *frag_tot = msg[2];
- *frag_size = \
- (msg[3] << 8) | \
- (msg[4]);
+ rv = ecp_tr_send(sock, packet, pkt_size, addr, flags);
+ if (rv < 0) return rv;
- return ECP_OK;
+ return rv;
}
-int ecp_msg_set_frag(unsigned char *msg, size_t msg_size, unsigned char frag_cnt, unsigned char frag_tot, uint16_t frag_size) {
- if (msg_size < 3) return ECP_ERR;
- if (!(msg[0] & ECP_MTYPE_FLAG_FRAG)) return ECP_ERR;
-
- msg[1] = frag_cnt;
- msg[2] = frag_tot;
- msg[3] = (frag_size & 0xFF00) >> 8;
- msg[4] = (frag_size & 0x00FF);
-
- return ECP_OK;
+void ecp_nonce2buf(unsigned char *b, ecp_nonce_t *n) {
+ b[0] = *n >> 56;
+ b[1] = *n >> 48;
+ b[2] = *n >> 40;
+ b[3] = *n >> 32;
+ b[4] = *n >> 24;
+ b[5] = *n >> 16;
+ b[6] = *n >> 8;
+ b[7] = *n;
}
-int ecp_msg_get_pts(unsigned char *msg, size_t msg_size, ecp_pts_t *pts) {
- unsigned char mtype;
- size_t offset;
-
- if (msg_size == 0) ECP_ERR;
-
- mtype = msg[0];
- if (!(mtype & ECP_MTYPE_FLAG_PTS)) return ECP_ERR;
-
- offset = 1 + ECP_SIZE_MT_FRAG(mtype);
- if (msg_size < offset + sizeof(ecp_pts_t)) return ECP_ERR;
-
- *pts = \
- (msg[offset] << 24) | \
- (msg[offset + 1] << 16) | \
- (msg[offset + 2] << 8) | \
- (msg[offset + 3]);
-
- return ECP_OK;
+void ecp_buf2nonce(ecp_nonce_t *n, unsigned char *b) {
+ *n = (ecp_nonce_t)b[0] << 56;
+ *n |= (ecp_nonce_t)b[1] << 48;
+ *n |= (ecp_nonce_t)b[2] << 40;
+ *n |= (ecp_nonce_t)b[3] << 32;
+ *n |= (ecp_nonce_t)b[4] << 24;
+ *n |= (ecp_nonce_t)b[5] << 16;
+ *n |= (ecp_nonce_t)b[6] << 8;
+ *n |= (ecp_nonce_t)b[7];
}
-int ecp_msg_set_pts(unsigned char *msg, size_t msg_size, ecp_pts_t pts) {
- unsigned char mtype;
- size_t offset;
-
- if (msg_size == 0) ECP_ERR;
-
- mtype = msg[0];
- if (!(mtype & ECP_MTYPE_FLAG_PTS)) return ECP_ERR;
+int ecp_pkt_get_seq(unsigned char *pkt, size_t pkt_size, ecp_seq_t *s) {
+ *s = 0;
- offset = 1 + ECP_SIZE_MT_FRAG(mtype);
- if (msg_size < offset + sizeof(ecp_pts_t)) return ECP_ERR;
+ if (pkt_size < ECP_MIN_PKT) return ECP_ERR_SIZE;
- msg[offset] = (pts & 0xFF000000) >> 24;
- msg[offset + 1] = (pts & 0x00FF0000) >> 16;
- msg[offset + 2] = (pts & 0x0000FF00) >> 8;
- msg[offset + 3] = (pts & 0x000000FF);
+ pkt += ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB;
+ *s |= (ecp_seq_t)pkt[4] << 24;
+ *s |= (ecp_seq_t)pkt[5] << 16;
+ *s |= (ecp_seq_t)pkt[6] << 8;
+ *s |= (ecp_seq_t)pkt[7];
return ECP_OK;
}
-unsigned char *ecp_msg_get_content(unsigned char *msg, size_t msg_size) {
- unsigned char mtype;
- size_t offset;
+static ssize_t _pack(ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size) {
+ ssize_t rv;
+ unsigned char s_idx, c_idx;
+ unsigned char *pkt_buf;
+ size_t pkt_size;
+ size_t hdr_size;
- if (msg_size == 0) ECP_ERR;
+ pkt_size = ECP_MIN_PKT;
+ if (pkt_meta->public == NULL) pkt_size -= ECP_SIZE_ECDH_PUB;
+ if (pkt_meta->cookie) pkt_size += ECP_SIZE_COOKIE;
- mtype = msg[0];
- offset = 1 + ECP_SIZE_MT_FLAG(mtype);
- if (msg_size < offset) return NULL;
+ if (packet->size < pkt_size) return ECP_ERR_SIZE;
- return msg + offset;
-}
+ pkt_buf = packet->buffer;
+ pkt_size = packet->size;
-int ecp_msg_defrag(ECPFragIter *iter, ecp_seq_t seq, unsigned char mtype, unsigned char *msg_in, size_t msg_in_size, unsigned char **msg_out, size_t *msg_out_size) {
- unsigned char *content;
- unsigned char frag_cnt, frag_tot;
- uint16_t frag_size;
- size_t msg_size;
- size_t buf_offset;
- int rv;
+ // ECP_SIZE_PROTO
+ pkt_buf[0] = 0;
+ pkt_buf[1] = 0;
+ pkt_buf[ECP_SIZE_PROTO] = (pkt_meta->s_idx << 4) | pkt_meta->c_idx;
+ pkt_buf += 3;
+
+ if (pkt_meta->public) {
+ memcpy(pkt_buf, &pkt_meta->public, ECP_SIZE_ECDH_PUB);
+ pkt_buf += ECP_SIZE_ECDH_PUB;
+ }
+ if (pkt_meta->cookie) {
+ memcpy(pkt_buf, pkt_meta->cookie, ECP_SIZE_COOKIE);
+ pkt_buf += ECP_SIZE_COOKIE;
+ }
+ ecp_nonce2buf(pkt_buf, pkt_meta->nonce);
+ pkt_buf += ECP_SIZE_NONCE;
- rv = ecp_msg_get_frag(msg_in, msg_in_size, &frag_cnt, &frag_tot, &frag_size);
- if (rv) return ECP_ERR;
+ hdr_size = pkt_buf - packet->buffer;
+ rv = ecp_aead_enc(pkt_buf, packet->size-hdr_size, payload->buffer, pld_size, pkt_meta->shkey, pkt_meta->nonce, pkt_meta->ntype);
+ if (rv < 0) return rv;
- content = ecp_msg_get_content(msg_in, msg_in_size);
- if (content == NULL) return ECP_ERR;
+ return rv+hdr_size;
+}
- msg_size = msg_in_size - (content - msg_in);
- if (msg_size == 0) return ECP_ERR;
+static ssize_t _pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, unsigned char *cookie, ecp_nonce_t *_nonce, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr) {
+ ECPPktMeta pkt_meta;
+ ecp_ecdh_public_t public;
+ ecp_aead_key_t shkey;
+ ecp_nonce_t nonce;
+ int rv = ECP_OK;
- if (iter->msg_size && (iter->seq + frag_cnt != seq)) ecp_frag_iter_reset(iter);
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&conn->mutex);
+#endif
- if (iter->msg_size == 0) {
- iter->seq = seq - frag_cnt;
- iter->frag_cnt = 0;
+ if (s_idx == ECP_ECDH_IDX_INV) {
+ if (ecp_conn_is_inb(conn)) {
+ s_idx = conn->key_curr;
+ } else {
+ s_idx = conn->rkey_curr;
+ }
+ }
+ if (c_idx == ECP_ECDH_IDX_INV) {
+ if (ecp_conn_is_outb(conn)) {
+ c_idx = conn->key_curr;
+ } else {
+ c_idx = conn->rkey_curr;
+ }
}
+ rv = conn_shkey_get(conn, s_idx, c_idx, &shkey);
+ if (rv) goto pack_conn_fin;
- mtype &= (~ECP_MTYPE_FLAG_FRAG);
- buf_offset = 1 + ECP_SIZE_MT_FLAG(mtype) + frag_size * frag_cnt;
- if (buf_offset + msg_size > iter->buf_size) return ECP_ERR_SIZE;
- memcpy(iter->buffer + buf_offset, content, msg_size);
+ if (ecp_conn_is_outb(conn)) {
+ ECPDHKey *key = conn_dhkey_get(conn, c_idx);
- if (frag_cnt == 0) {
- if (1 + ECP_SIZE_MT_FLAG(mtype) > iter->buf_size) return ECP_ERR_SIZE;
+ if (key) {
+ memcpy(&public, &key->public, sizeof(public));
+ } else {
+ rv = ECP_ERR_ECDH_IDX;
+ }
+ } else {
+ ECPDHPub *key = conn_dhkey_get_remote(conn, c_idx);
- iter->buffer[0] = mtype;
- if (ECP_SIZE_MT_FLAG(mtype)) {
- memcpy(iter->buffer + 1, msg_in + 1, ECP_SIZE_MT_FLAG(mtype));
+ if (key) {
+ memcpy(&public, &key->public, sizeof(public));
+ } else {
+ rv = ECP_ERR_ECDH_IDX;
}
- msg_size += 1 + ECP_SIZE_MT_FLAG(mtype);
+ memcpy(&public, &key->public, sizeof(public));
}
+ if (rv) goto pack_conn_fin;
- iter->frag_cnt++;
- iter->msg_size += msg_size;
- if (iter->frag_cnt == frag_tot) {
- *msg_out = iter->buffer;
- *msg_out_size = iter->msg_size;
- return ECP_OK;
+ if (_nonce) {
+ nonce = *_nonce;
} else {
- return ECP_ITER_NEXT;
+ nonce = conn->nonce_out;
+ conn->nonce_out++;
}
-}
+#ifdef ECP_WITH_VCONN
+ if ((conn->parent == NULL) && addr) *addr = conn->remote.addr;
+#else
+ if (addr) *addr = conn->remote.addr;
+#endif
-int ecp_pld_get_type(unsigned char *payload, size_t pld_size, unsigned char *mtype) {
- if (pld_size < ECP_SIZE_PLD_HDR) return ECP_ERR;
+pack_conn_fin:
- payload += ECP_SIZE_PLD_HDR;
- pld_size -= ECP_SIZE_PLD_HDR;
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&conn->mutex);
+#endif
+ if (rv) return rv;
- return ecp_msg_get_type(payload, pld_size, mtype);
+ pkt_meta.cookie = cookie;
+ pkt_meta.public = &public;
+ pkt_meta.shkey = &shkey;
+ pkt_meta.nonce = &nonce;
+ pkt_meta.ntype = (ecp_conn_is_inb(conn) ? ECP_NTYPE_INB : ECP_NTYPE_OUTB);
+ pkt_meta.s_idx = s_idx;
+ pkt_meta.c_idx = c_idx;
+ return _pack(packet, &pkt_meta, payload, pld_size);
}
-int ecp_pld_set_type(unsigned char *payload, size_t pld_size, unsigned char mtype) {
- if (pld_size < ECP_SIZE_PLD_HDR) return ECP_ERR;
+ssize_t ecp_pack(ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr) {
+ ssize_t rv;
- payload += ECP_SIZE_PLD_HDR;
- pld_size -= ECP_SIZE_PLD_HDR;
+ rv = _pack(packet, pkt_meta, payload, pld_size);
+ if (rv < 0) return rv;
- return ecp_msg_set_type(payload, pld_size, mtype);
+#ifdef ECP_WITH_VCONN
+ if (parent) {
+ rv = ecp_vconn_pack_parent(parent, packet, payload, rv, addr);
+ }
+#endif
+
+ return rv;
}
-int ecp_pld_get_frag(unsigned char *payload, size_t pld_size, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_size) {
- if (pld_size < ECP_SIZE_PLD_HDR) return ECP_ERR;
+ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, unsigned char *cookie, ecp_nonce_t *nonce, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr) {
+ ssize_t rv;
+
+ rv = _pack_conn(conn, packet, s_idx, c_idx, cookie, nonce, payload, pld_size, addr);
+ if (rv < 0) return rv;
- payload += ECP_SIZE_PLD_HDR;
- pld_size -= ECP_SIZE_PLD_HDR;
+#ifdef ECP_WITH_VCONN
+ if (conn->parent) {
+ rv = ecp_vconn_pack_parent(conn->parent, packet, payload, rv, addr);
+ }
+#endif
- return ecp_msg_get_frag(payload, pld_size, frag_cnt, frag_tot, frag_size);
+ return rv;
}
-int ecp_pld_set_frag(unsigned char *payload, size_t pld_size, unsigned char frag_cnt, unsigned char frag_tot, uint16_t frag_size) {
- if (pld_size < ECP_SIZE_PLD_HDR) return ECP_ERR;
+int ecp_pld_get_type(unsigned char *pld, size_t pld_size, unsigned char *mtype) {
+ if (pld_size < ECP_SIZE_MTYPE) return ECP_ERR_SIZE;
- payload += ECP_SIZE_PLD_HDR;
- pld_size -= ECP_SIZE_PLD_HDR;
-
- return ecp_msg_set_frag(payload, pld_size, frag_cnt, frag_tot, frag_size);
+ *mtype = pld[0];
+ return ECP_OK;
}
-int ecp_pld_get_pts(unsigned char *payload, size_t pld_size, ecp_pts_t *pts) {
- if (pld_size < ECP_SIZE_PLD_HDR) return ECP_ERR;
+int ecp_pld_set_type(unsigned char *pld, size_t pld_size, unsigned char mtype) {
+ if (pld_size < ECP_SIZE_MTYPE) return ECP_ERR_SIZE;
- payload += ECP_SIZE_PLD_HDR;
- pld_size -= ECP_SIZE_PLD_HDR;
-
- return ecp_msg_get_pts(payload, pld_size, pts);
+ pld[0] = mtype;
+ return ECP_OK;
}
-int ecp_pld_set_pts(unsigned char *payload, size_t pld_size, ecp_pts_t pts) {
- if (pld_size < ECP_SIZE_PLD_HDR) return ECP_ERR;
+int ecp_pld_get_frag(unsigned char *pld, size_t pld_size, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_size) {
+ if (pld_size < ECP_SIZE_MTYPE) return ECP_ERR_SIZE;
- payload += ECP_SIZE_PLD_HDR;
- pld_size -= ECP_SIZE_PLD_HDR;
+ if (!(pld[0] & ECP_MTYPE_FLAG_FRAG)) return ECP_ERR;
+ if (pld_size < (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(pld[0]))) return ECP_ERR_SIZE;
+ if (pld[2] == 0) return ECP_ERR;
- return ecp_msg_set_pts(payload, pld_size, pts);
+ *frag_cnt = pld[1];
+ *frag_tot = pld[2];
+ *frag_size = \
+ (pld[3] << 8) | \
+ (pld[4]);
+
+ return ECP_OK;
}
-unsigned char *ecp_pld_get_buf(unsigned char *payload, size_t pld_size) {
- if (pld_size < ECP_SIZE_PLD_HDR) return NULL;
+int ecp_pld_set_frag(unsigned char *pld, size_t pld_size, unsigned char frag_cnt, unsigned char frag_tot, uint16_t frag_size) {
+ if (pld_size < ECP_SIZE_MTYPE) return ECP_ERR_SIZE;
- payload += ECP_SIZE_PLD_HDR;
- pld_size -= ECP_SIZE_PLD_HDR;
+ if (!(pld[0] & ECP_MTYPE_FLAG_FRAG)) return ECP_ERR;
+ if (pld_size < (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(pld[0]))) return ECP_ERR_SIZE;
- return ecp_msg_get_content(payload, pld_size);
-}
+ pld[1] = frag_cnt;
+ pld[2] = frag_tot;
+ pld[3] = frag_size >> 8;
+ pld[4] = frag_size;
-ssize_t __ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti, ECPSeqItem *si) {
- ECPSocket *sock = conn->sock;
- ECPNetAddr addr;
- ssize_t rv;
+ return ECP_OK;
+}
- rv = ecp_pack_conn(conn, packet, s_idx, c_idx, payload, pld_size, &addr, si);
- if (rv < 0) return rv;
+int ecp_pld_get_pts(unsigned char *pld, size_t pld_size, ecp_pts_t *pts) {
+ size_t offset;
-#ifdef ECP_WITH_RBUF
- if (conn->rbuf.send) {
- return ecp_rbuf_pkt_send(conn, conn->sock, &addr, packet, rv, flags, ti, si);
- }
-#endif
+ if (pld_size < ECP_SIZE_MTYPE) return ECP_ERR_SIZE;
- if (ti) {
- int _rv;
+ if (!(pld[0] & ECP_MTYPE_FLAG_PTS)) return ECP_ERR;
+ if (pld_size < (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(pld[0]))) return ECP_ERR_SIZE;
- _rv = ecp_timer_push(ti);
- if (_rv) return _rv;
- }
+ offset = ECP_SIZE_MTYPE + ECP_SIZE_MT_FRAG(pld[0]);
+ *pts = \
+ ((ecp_pts_t)pld[offset] << 24) | \
+ ((ecp_pts_t)pld[offset + 1] << 16) | \
+ ((ecp_pts_t)pld[offset + 2] << 8) | \
+ ((ecp_pts_t)pld[offset + 3]);
- return ecp_pkt_send(sock, &addr, packet, rv, flags);
+ return ECP_OK;
}
-#ifdef ECP_WITH_RBUF
+int ecp_pld_set_pts(unsigned char *pld, size_t pld_size, ecp_pts_t pts) {
+ size_t offset;
-ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) {
- if (conn->rbuf.send) {
- ECPSeqItem seq_item;
- int rv;
+ if (pld_size < ECP_SIZE_MTYPE) return ECP_ERR_SIZE;
- rv = ecp_seq_item_init(&seq_item);
- if (rv) return rv;
+ if (!(pld[0] & ECP_MTYPE_FLAG_PTS)) return ECP_ERR;
+ if (pld_size < (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(pld[0]))) return ECP_ERR_SIZE;
- return __ecp_pld_send(conn, packet, s_idx, c_idx, payload, pld_size, flags, ti, &seq_item);
- }
+ offset = ECP_SIZE_MTYPE + ECP_SIZE_MT_FRAG(pld[0]);
+ pld[offset] = pts >> 24;
+ pld[offset + 1] = pts >> 16;
+ pld[offset + 2] = pts >> 8;
+ pld[offset + 3] = pts;
- return __ecp_pld_send(conn, packet, s_idx, c_idx, payload, pld_size, flags, ti, NULL);
+ return ECP_OK;
}
-#else
+unsigned char *ecp_pld_get_msg(unsigned char *pld, size_t pld_size) {
+ size_t offset;
-ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) {
- return __ecp_pld_send(conn, packet, s_idx, c_idx, payload, pld_size, flags, ti, NULL);
+ if (pld_size < ECP_SIZE_MTYPE) return NULL;
+ if (pld_size < (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(pld[0]))) return NULL;
+
+ return pld + ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(pld[0]);
}
-#endif
+ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, unsigned char *cookie, ecp_nonce_t *n, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) {
+ ecp_tr_addr_t addr;
+ size_t pkt_size;
+ ssize_t rv;
+
+ rv = ecp_pack_conn(conn, packet, s_idx, c_idx, cookie, n, payload, pld_size, &addr);
+ if (rv < 0) return rv;
+
+ pkt_size = rv;
+ rv = ecp_ext_pld_send(conn, payload, pld_size, packet, pkt_size, flags, ti, &addr);
+ if (rv) return rv;
+
+ rv = ecp_pkt_send(conn->sock, packet, pkt_size, flags, ti, &addr);
+ if (rv < 0) return rv;
+
+ return pld_size;
+}
ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags) {
- return _ecp_pld_send(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, flags, NULL);
+ return _ecp_pld_send(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, NULL, NULL, payload, pld_size, flags, NULL);
}
ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti) {
- return _ecp_pld_send(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, flags, ti);
+ return _ecp_pld_send(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, NULL, NULL, payload, pld_size, flags, ti);
}
-ssize_t ecp_pld_send_tr(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, unsigned char flags) {
- ECPNetAddr _addr;
+ssize_t ecp_pld_send_wcookie(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, unsigned char *cookie) {
+ return _ecp_pld_send(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, cookie, NULL, payload, pld_size, flags, NULL);
+}
+
+ssize_t ecp_pld_send_wnonce(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_nonce_t *nonce) {
+ return _ecp_pld_send(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, NULL, nonce, payload, pld_size, flags, NULL);
+}
+
+ssize_t ecp_pld_send_irep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, unsigned char flags) {
+ ecp_tr_addr_t _addr;
ssize_t rv;
- rv = ecp_pack(sock->ctx, parent, packet, pkt_meta, payload, pld_size, addr ? NULL : &_addr);
+ rv = ecp_pack(parent, packet, pkt_meta, payload, pld_size, addr ? NULL : &_addr);
if (rv < 0) return rv;
- return ecp_pkt_send(sock, addr ? addr : &_addr, packet, rv, flags);
+ rv = ecp_pkt_send(sock, packet, rv, flags, NULL, addr ? addr : &_addr);
+ if (rv < 0) return rv;
+
+ return pld_size;
}
-ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *content, size_t content_size) {
+ssize_t ecp_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size) {
ECPBuffer packet;
ECPBuffer payload;
unsigned char pkt_buf[ECP_MAX_PKT];
unsigned char pld_buf[ECP_MAX_PLD];
- unsigned char *content_buf;
- ssize_t rv = 0;
- int pkt_cnt = 0;
- int vc_cnt = conn->pcount;
- size_t pld_max = ECP_MAX_PKT - (ECP_SIZE_PKT_HDR + ECP_AEAD_SIZE_TAG + ECP_SIZE_PLD_HDR + 1) * vc_cnt - (ECP_SIZE_PKT_HDR + ECP_AEAD_SIZE_TAG);
+ unsigned char *msg_buf;
+ ssize_t rv;
packet.buffer = pkt_buf;
packet.size = ECP_MAX_PKT;
payload.buffer = pld_buf;
payload.size = ECP_MAX_PLD;
- if (ECP_SIZE_PLD(content_size, mtype) > pld_max) {
- size_t frag_size, frag_size_final;
- ecp_seq_t seq_start;
- ECPSeqItem seq_item;
- int i;
- int _rv;
-
- _rv = ecp_seq_item_init(&seq_item);
- if (_rv) return _rv;
-
- mtype |= ECP_MTYPE_FLAG_FRAG;
- frag_size = pld_max - ECP_SIZE_PLD(0, mtype);
- pkt_cnt = content_size / frag_size;
- frag_size_final = content_size - frag_size * pkt_cnt;
- if (frag_size_final) pkt_cnt++;
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&conn->mutex);
-#endif
-
- seq_start = conn->seq_out + 1;
- conn->seq_out += pkt_cnt;
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
-#endif
-
- seq_item.seq_w = 1;
- for (i=0; i<pkt_cnt; i++) {
- ssize_t _rv;
-
- ecp_pld_set_type(pld_buf, ECP_MAX_PLD, mtype);
- ecp_pld_set_frag(pld_buf, ECP_MAX_PLD, i, pkt_cnt, frag_size);
- content_buf = ecp_pld_get_buf(pld_buf, ECP_MAX_PLD);
-
- if ((i == pkt_cnt - 1) && frag_size_final) frag_size = frag_size_final;
- memcpy(content_buf, content, frag_size);
- content += frag_size;
- seq_item.seq = seq_start + i;
-
- _rv = __ecp_pld_send(conn, &packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(frag_size, mtype), 0, NULL, &seq_item);
- if (_rv < 0) return _rv;
+ rv = ecp_ext_msg_send(conn, mtype, msg, msg_size, &packet, &payload);
+ if (rv) return rv;
- rv += _rv;
- }
- } else {
+ if (ECP_SIZE_PKT_BUF(msg_size, mtype, conn) <= ECP_MAX_PKT) {
ecp_pld_set_type(pld_buf, ECP_MAX_PLD, mtype);
- content_buf = ecp_pld_get_buf(pld_buf, ECP_MAX_PLD);
+ msg_buf = ecp_pld_get_msg(pld_buf, ECP_MAX_PLD);
- memcpy(content_buf, content, content_size);
- rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(content_size, mtype), 0);
+ memcpy(msg_buf, msg, msg_size);
+ rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(msg_size, mtype), 0);
+ if (rv < 0) return rv;
+ } else {
+ return ECP_ERR_SIZE;
}
- return rv;
-}
-#if defined(ECP_WITH_RBUF) && defined(ECP_WITH_MSGQ)
-ssize_t ecp_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ecp_cts_t timeout) {
- ssize_t rv;
-
- pthread_mutex_lock(&conn->rbuf.recv->msgq.mutex);
- rv = ecp_conn_msgq_pop(conn, mtype, msg, msg_size, timeout);
- pthread_mutex_unlock(&conn->rbuf.recv->msgq.mutex);
-
- return rv;
-}
-#else
-ssize_t ecp_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ecp_cts_t timeout) {
- return ECP_ERR_NOT_IMPLEMENTED;
+ return msg_size;
}
-#endif
-static int recv_p(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t size) {
+static int recv_p(ECPSocket *sock, ecp_tr_addr_t *addr, ECPBuffer *packet, size_t size) {
ECP2Buffer bufs;
ECPBuffer payload;
unsigned char pld_buf[ECP_MAX_PLD];
@@ -1951,17 +2324,17 @@ static int recv_p(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t s
payload.buffer = pld_buf;
payload.size = ECP_MAX_PLD;
- rv = ecp_pkt_handle(sock, addr, NULL, &bufs, size);
+ rv = ecp_pkt_handle(sock, NULL, addr, &bufs, size);
if (rv < 0) return rv;
return ECP_OK;
}
int ecp_receiver(ECPSocket *sock) {
- ECPNetAddr addr;
+ ecp_tr_addr_t addr;
ECPBuffer packet;
unsigned char pkt_buf[ECP_MAX_PKT];
- ecp_cts_t next = 0;
+ ecp_sts_t next = 0;
ssize_t rv;
int _rv;
@@ -1970,12 +2343,12 @@ int ecp_receiver(ECPSocket *sock) {
packet.buffer = pkt_buf;
packet.size = ECP_MAX_PKT;
- rv = ecp_tr_recv(sock, &packet, &addr, next ? next : sock->poll_timeout);
+ rv = ecp_tr_recv(sock, &packet, &addr, next ? next : ECP_POLL_TIMEOUT);
if (rv > 0) {
_rv = recv_p(sock, &addr, &packet, rv);
#ifdef ECP_DEBUG
if (_rv) {
- printf("RECEIVER ERR:%d\n", _rv);
+ printf("RCV ERR:%d\n", _rv);
}
#endif
}
@@ -2007,12 +2380,4 @@ int ecp_stop_receiver(ECPSocket *sock) {
if (rv) return ECP_ERR;
return ECP_OK;
}
-#else
-int ecp_start_receiver(ECPSocket *sock) {
- return ECP_ERR_NOT_IMPLEMENTED;
-}
-
-int ecp_stop_receiver(ECPSocket *sock) {
- return ECP_ERR_NOT_IMPLEMENTED;
-}
#endif
diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h
index b126430..b5c260f 100644
--- a/ecp/src/ecp/core.h
+++ b/ecp/src/ecp/core.h
@@ -1,16 +1,13 @@
#include <sys/types.h>
#include <stddef.h>
#include <stdint.h>
-#include <string.h>
#ifdef ECP_WITH_PTHREAD
#include <pthread.h>
#endif
-#define ECP_MEM_TINY 1
-
#define ECP_OK 0
-#define ECP_ITER_NEXT 1
+#define ECP_PASS 1
#define ECP_ERR -1
#define ECP_ERR_TIMEOUT -2
@@ -20,104 +17,138 @@
#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_MAX_SOCK_CONN -10
-#define ECP_ERR_MAX_CTYPE -11
-#define ECP_ERR_MAX_MTYPE -12
-#define ECP_ERR_NET_ADDR -13
+#define ECP_ERR_NET_ADDR -12
+#define ECP_ERR_MAX_PARENT -13
#define ECP_ERR_ECDH_KEY_DUP -21
#define ECP_ERR_ECDH_IDX -22
-#define ECP_ERR_ECDH_IDX_LOCAL -23
-#define ECP_ERR_ECDH_IDX_REMOTE -24
-#define ECP_ERR_RNG -25
#define ECP_ERR_ENCRYPT -26
#define ECP_ERR_DECRYPT -27
-#define ECP_ERR_SEND -28
-#define ECP_ERR_RECV -29
-#define ECP_ERR_SEQ -30
-#define ECP_ERR_CLOSED -31
-#define ECP_ERR_NOT_IMPLEMENTED -99
-
-#define ECP_SIZE_PROTO 2
-#define ECP_SIZE_SEQ 4
-
-#define ECP_MAX_SOCK_CONN 16
-#define ECP_MAX_SOCK_KEY 8
+#define ECP_ERR_SIGN -28
+#define ECP_ERR_VERIFY -29
+#define ECP_ERR_SEND -30
+#define ECP_ERR_RECV -31
+#define ECP_ERR_SEQ -32
+#define ECP_ERR_VBOX -33
+#define ECP_ERR_CLOSED -34
+
+#define ECP_MAX_SOCK_CONN 4
+#define ECP_MAX_SOCK_KEY 2
#define ECP_MAX_CONN_KEY 2
#define ECP_MAX_NODE_KEY 2
#define ECP_MAX_CTYPE 8
#define ECP_MAX_MTYPE 16
-#define ECP_MAX_MTYPE_SYS 4
-#define ECP_MAX_MTYPE_SOCK ECP_MAX_MTYPE_SYS
+#define ECP_MAX_PARENT 3
#define ECP_MAX_SEQ_FWD 1024
-#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)
+#define ECP_SIZE_PROTO 2
+#define ECP_SIZE_NONCE 8
+#define ECP_SIZE_MTYPE 1
+#define ECP_SIZE_COOKIE (ECP_SIZE_ECDH_PUB)
+
+#define ECP_SIZE_PKT_HDR (ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE)
#define ECP_MAX_PKT 1412
-#define ECP_MAX_PLD (ECP_MAX_PKT-ECP_SIZE_PKT_HDR-ECP_AEAD_SIZE_TAG)
-#define ECP_MAX_MSG (ECP_MAX_PLD-ECP_SIZE_PLD_HDR-1)
+#define ECP_MAX_PLD (ECP_MAX_PKT-ECP_SIZE_PKT_HDR-ECP_SIZE_AEAD_TAG)
+#define ECP_MAX_MSG (ECP_MAX_PLD-ECP_SIZE_MTYPE)
+
+#define ECP_MIN_PKT (ECP_SIZE_PKT_HDR+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG)
+#define ECP_MIN_PLD (ECP_SIZE_MTYPE)
+
+#define ECP_SIZE_VBOX (ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE+ECP_SIZE_ECDH_PUB+ECP_SIZE_AEAD_TAG)
+
+#define ECP_SIZE_MT_FRAG(T) ((T) & ECP_MTYPE_FLAG_FRAG ? 2 + sizeof(uint16_t) : 0)
+#define ECP_SIZE_MT_PTS(T) ((T) & ECP_MTYPE_FLAG_PTS ? sizeof(ecp_pts_t) : 0)
+#define ECP_SIZE_MT_FLAG(T) (ECP_SIZE_MT_FRAG(T)+ECP_SIZE_MT_PTS(T))
+#define ECP_SIZE_PLD(X,T) ((X)+ECP_SIZE_MTYPE+ECP_SIZE_MT_FLAG(T))
+#define ECP_SIZE_PKT(X,T) (ECP_SIZE_PKT_HDR+ECP_SIZE_PLD(X,T)+ECP_SIZE_AEAD_TAG)
-#define ECP_MIN_PKT (ECP_SIZE_PKT_HDR+ECP_SIZE_PLD_HDR+1+ECP_AEAD_SIZE_TAG)
+#ifdef ECP_WITH_VCONN
+#define ECP_SIZE_PLD_BUF(X,T,C) (ECP_SIZE_PLD(X,T)+(C)->pcount*(ECP_SIZE_PKT_HDR+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG))
+#else
+#define ECP_SIZE_PLD_BUF(X,T,C) (ECP_SIZE_PLD(X,T))
+#endif
+
+#define ECP_SIZE_PKT_BUF(X,T,C) (ECP_SIZE_PLD_BUF(X,T,C)+ECP_SIZE_PKT_HDR+ECP_SIZE_AEAD_TAG)
+#define ECP_SIZE_PKT_BUF_WCOOKIE(X,T,C) (ECP_SIZE_PKT_BUF(X,T,C)+ECP_SIZE_COOKIE)
+#ifdef ECP_WITH_VCONN
+#define ECP_SIZE_PLD_BUF_IREP(X,T,P) (ECP_SIZE_PLD(X,T)+((P) ? ((P)->pcount+1)*(ECP_SIZE_PKT_HDR+ECP_SIZE_MTYPE+ECP_SIZE_AEAD_TAG) : 0))
+#else
+#define ECP_SIZE_PLD_BUF_IREP(X,T,P) (ECP_SIZE_PLD(X,T))
+#endif
+
+#define ECP_SIZE_PKT_BUF_IREP(X,T,P) (ECP_SIZE_PLD_BUF_IREP(X,T,P)+ECP_SIZE_PKT_HDR-ECP_SIZE_ECDH_PUB+ECP_SIZE_AEAD_TAG)
+
+#define ECP_SEND_TRIES 3
+#define ECP_SEND_TIMEOUT 500
#define ECP_POLL_TIMEOUT 500
+
#define ECP_ECDH_IDX_INV 0xFF
#define ECP_ECDH_IDX_PERMA 0x0F
+#define ECP_ECDH_IDX_MASK 0x07
+
+#define ECP_NTYPE_INB 1
+#define ECP_NTYPE_OUTB 2
+#define ECP_NTYPE_VBOX 3
-#define ECP_MTYPE_FLAG_FRAG 0x80
-#define ECP_MTYPE_FLAG_PTS 0x40
-#define ECP_MTYPE_FLAG_REP 0x20
-#define ECP_MTYPE_MASK 0x1f
-
-#define ECP_MTYPE_OPEN 0x00
-#define ECP_MTYPE_KGET 0x01
-#define ECP_MTYPE_KPUT 0x02
-#define ECP_MTYPE_DIR 0x03
-
-#define ECP_MTYPE_OPEN_REQ (ECP_MTYPE_OPEN)
-#define ECP_MTYPE_OPEN_REP (ECP_MTYPE_OPEN | ECP_MTYPE_FLAG_REP)
-#define ECP_MTYPE_KGET_REQ (ECP_MTYPE_KGET)
-#define ECP_MTYPE_KGET_REP (ECP_MTYPE_KGET | ECP_MTYPE_FLAG_REP)
-#define ECP_MTYPE_KPUT_REQ (ECP_MTYPE_KPUT)
-#define ECP_MTYPE_KPUT_REP (ECP_MTYPE_KPUT | ECP_MTYPE_FLAG_REP)
-#define ECP_MTYPE_DIR_REQ (ECP_MTYPE_DIR)
-#define ECP_MTYPE_DIR_REP (ECP_MTYPE_DIR | ECP_MTYPE_FLAG_REP)
-
-#define ECP_CONN_FLAG_OUTB 0x01
-#define ECP_CONN_FLAG_NEW 0x02
+#define ECP_MTYPE_FLAG_SYS 0x80
+#define ECP_MTYPE_FLAG_FRAG 0x40
+#define ECP_MTYPE_FLAG_PTS 0x20
+#define ECP_MTYPE_MASK 0x1F
+
+#define ECP_MTYPE_INIT_REQ (0x00 | ECP_MTYPE_FLAG_SYS)
+#define ECP_MTYPE_INIT_REP (0x01 | ECP_MTYPE_FLAG_SYS)
+#define ECP_MTYPE_OPEN_REQ (0x02 | ECP_MTYPE_FLAG_SYS)
+#define ECP_MTYPE_OPEN_REP (0x03 | ECP_MTYPE_FLAG_SYS)
+#define ECP_MTYPE_KEYX_REQ (0x04 | ECP_MTYPE_FLAG_SYS)
+#define ECP_MTYPE_KEYX_REP (0x05 | ECP_MTYPE_FLAG_SYS)
+
+#define ECP_CTYPE_FLAG_SYS 0x80
+#define ECP_CTYPE_MASK 0x7F
+
+/* immutable flags */
+#define ECP_CONN_FLAG_INB 0x80
+#define ECP_CONN_FLAG_VBOX 0x01
+#define ECP_CONN_FLAG_RBUF 0x02
+
+#define ECP_CONN_FLAG_MASK 0x7F
+
+/* mutable flags */
#define ECP_CONN_FLAG_REG 0x04
#define ECP_CONN_FLAG_OPEN 0x08
#define ECP_SEND_FLAG_REPLY 0x01
#define ECP_SEND_FLAG_MORE 0x02
-#define ecp_conn_is_inb(conn) (!((conn)->flags_im & ECP_CONN_FLAG_OUTB))
-#define ecp_conn_is_outb(conn) ((conn)->flags_im & ECP_CONN_FLAG_OUTB)
-#define ecp_conn_is_new(conn) ((conn)->flags_im & ECP_CONN_FLAG_NEW)
+#define ecp_conn_has_vbox(conn) ((conn)->flags_im & ECP_CONN_FLAG_VBOX)
+#define ecp_conn_has_rbuf(conn) ((conn)->flags_im & ECP_CONN_FLAG_RBUF)
+#define ecp_conn_is_inb(conn) ((conn)->flags_im & ECP_CONN_FLAG_INB)
+#define ecp_conn_is_outb(conn) (!((conn)->flags_im & ECP_CONN_FLAG_INB))
#define ecp_conn_is_reg(conn) ((conn)->flags & ECP_CONN_FLAG_REG)
#define ecp_conn_is_open(conn) ((conn)->flags & ECP_CONN_FLAG_OPEN)
+#define ecp_conn_is_sys(conn) ((conn)->type & ECP_CTYPE_FLAG_SYS)
-#define ecp_conn_set_outb(conn) ((conn)->flags_im |= ECP_CONN_FLAG_OUTB)
-#define ecp_conn_set_new(conn) ((conn)->flags_im |= ECP_CONN_FLAG_NEW)
-#define ecp_conn_set_reg(conn) ((conn)->flags |= ECP_CONN_FLAG_REG)
-#define ecp_conn_set_open(conn) ((conn)->flags |= ECP_CONN_FLAG_OPEN)
+#define ecp_conn_set_inb(conn) ((conn)->flags_im |= ECP_CONN_FLAG_INB)
+#define ecp_conn_set_outb(conn) ((conn)->flags_im &= ~ECP_CONN_FLAG_INB)
+#define ecp_conn_set_reg(conn) ((conn)->flags |= ECP_CONN_FLAG_REG)
+#define ecp_conn_set_open(conn) ((conn)->flags |= ECP_CONN_FLAG_OPEN)
-#define ecp_conn_clr_outb(conn) ((conn)->flags_im &= ~ECP_CONN_FLAG_OUTB)
-#define ecp_conn_clr_new(conn) ((conn)->flags_im &= ~ECP_CONN_FLAG_NEW)
#define ecp_conn_clr_reg(conn) ((conn)->flags &= ~ECP_CONN_FLAG_REG)
#define ecp_conn_clr_open(conn) ((conn)->flags &= ~ECP_CONN_FLAG_OPEN)
-// typedef long ssize_t;
-
typedef uint32_t ecp_ack_t;
#define ECP_SIZE_ACKB (sizeof(ecp_ack_t)*8)
-#define ECP_ACK_FULL (~(ecp_ack_t)0)
+#define ECP_ACK_FULL (~((ecp_ack_t)0))
-typedef uint32_t ecp_cts_t;
-#define ECP_CTS_HALF ((ecp_cts_t)1 << (sizeof(ecp_cts_t) * 8 - 1))
-#define ECP_CTS_LT(a,b) ((ecp_cts_t)((ecp_cts_t)(a) - (ecp_cts_t)(b)) > ECP_CTS_HALF)
-#define ECP_CTS_LTE(a,b) ((ecp_cts_t)((ecp_cts_t)(b) - (ecp_cts_t)(a)) < ECP_CTS_HALF)
+typedef uint32_t ecp_sts_t;
+#define ECP_STS_HALF ((ecp_sts_t)1 << (sizeof(ecp_sts_t) * 8 - 1))
+#define ECP_STS_LT(a,b) ((ecp_sts_t)((ecp_sts_t)(a) - (ecp_sts_t)(b)) > ECP_STS_HALF)
+#define ECP_STS_LTE(a,b) ((ecp_sts_t)((ecp_sts_t)(b) - (ecp_sts_t)(a)) < ECP_STS_HALF)
typedef uint32_t ecp_pts_t;
#define ECP_PTS_HALF ((ecp_pts_t)1 << (sizeof(ecp_pts_t) * 8 - 1))
@@ -129,51 +160,32 @@ typedef uint32_t ecp_seq_t;
#define ECP_SEQ_LT(a,b) ((ecp_seq_t)((ecp_seq_t)(a) - (ecp_seq_t)(b)) > ECP_SEQ_HALF)
#define ECP_SEQ_LTE(a,b) ((ecp_seq_t)((ecp_seq_t)(b) - (ecp_seq_t)(a)) < ECP_SEQ_HALF)
+typedef uint64_t ecp_nonce_t;
+#define ECP_NONCE_HALF ((ecp_nonce_t)1 << (sizeof(ecp_nonce_t) * 8 - 1))
+#define ECP_NONCE_LT(a,b) ((ecp_nonce_t)((ecp_nonce_t)(a) - (ecp_nonce_t)(b)) > ECP_NONCE_HALF)
+#define ECP_NONCE_LTE(a,b) ((ecp_nonce_t)((ecp_nonce_t)(b) - (ecp_nonce_t)(a)) < ECP_NONCE_HALF)
-#define ECP_SIZE_MT_FRAG(F) ((F) & ECP_MTYPE_FLAG_FRAG ? 2 + sizeof(uint16_t) : 0)
-#define ECP_SIZE_MT_PTS(F) ((F) & ECP_MTYPE_FLAG_PTS ? sizeof(ecp_pts_t) : 0)
-#define ECP_SIZE_MT_FLAG(F) (ECP_SIZE_MT_FRAG(F)+ECP_SIZE_MT_PTS(F))
-#define ECP_SIZE_PLD(X,F) ((X) + ECP_SIZE_PLD_HDR+1+ECP_SIZE_MT_FLAG(F))
-#define ECP_SIZE_PKT(X,F) (ECP_SIZE_PKT_HDR+ECP_SIZE_PLD(X,F)+ECP_AEAD_SIZE_TAG)
-
-#define ECP_SIZE_MSG_BUF(T,P) ((P) && ecp_conn_is_outb(P) && (((T) == ECP_MTYPE_OPEN_REQ) || ((T) == ECP_MTYPE_KGET_REQ)) ? ECP_SIZE_PLD_HDR+3+2*ECP_ECDH_SIZE_KEY : ECP_SIZE_PLD_HDR+1)
-
-#define ECP_SIZE_PLD_BUF(X,T,C) (ECP_SIZE_PLD(X,T)+(C)->pcount*(ECP_SIZE_PKT_HDR+ECP_SIZE_MSG_BUF(T,(C)->parent)+ECP_AEAD_SIZE_TAG))
-#define ECP_SIZE_PKT_BUF(X,T,C) (ECP_SIZE_PLD_BUF(X,T,C)+ECP_SIZE_PKT_HDR+ECP_AEAD_SIZE_TAG)
-
-#define ECP_SIZE_PLD_BUF_TR(X,T,P) (ECP_SIZE_PLD(X,T)+((P) ? ((P)->pcount+1)*(ECP_SIZE_PKT_HDR+ECP_SIZE_MSG_BUF(T,P)+ECP_AEAD_SIZE_TAG) : 0))
-#define ECP_SIZE_PKT_BUF_TR(X,T,P) (ECP_SIZE_PLD_BUF_TR(X,T,P)+ECP_SIZE_PKT_HDR+ECP_AEAD_SIZE_TAG)
-
-#ifdef ECP_DEBUG
-#include <stdio.h>
-#endif
-
-struct ECPBuffer;
struct ECP2Buffer;
-struct ECPContext;
struct ECPSocket;
struct ECPConnection;
-struct ECPSeqItem;
-struct ECPPktMeta;
+
+#ifdef ECP_WITH_DIRSRV
struct ECPDirList;
+#endif
#include "crypto/crypto.h"
#include "transport.h"
#include "timer.h"
-#ifdef ECP_WITH_RBUF
-#include "rbuf.h"
-#endif
-
-typedef int (*ecp_rng_t) (void *, size_t);
+typedef void (*ecp_err_handler_t) (struct ECPConnection *conn, unsigned char mtype, int err);
+typedef ssize_t (*ecp_dir_handler_t) (struct ECPConnection *conn, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b);
+typedef struct ECPConnection * (*ecp_conn_alloc_t) (struct ECPSocket *sock, unsigned char type);
+typedef void (*ecp_conn_free_t) (struct ECPConnection *conn);
-typedef ssize_t (*ecp_sock_msg_handler_t) (struct ECPSocket *s, ECPNetAddr *a, struct ECPConnection *p, unsigned char *msg, size_t sz, struct ECPPktMeta *m, struct ECP2Buffer *b, struct ECPConnection **c);
-typedef ssize_t (*ecp_conn_msg_handler_t) (struct ECPConnection *c, ecp_seq_t s, unsigned char t, unsigned char *msg, ssize_t sz, struct ECP2Buffer *b);
-
-typedef struct ECPConnection * (*ecp_conn_alloc_t) (struct ECPSocket *s, unsigned char t);
-typedef void (*ecp_conn_free_t) (struct ECPConnection *c);
-typedef ssize_t (*ecp_conn_open_t) (struct ECPConnection *c);
-typedef void (*ecp_conn_close_t) (struct ECPConnection *c);
+typedef ssize_t (*ecp_msg_handler_t) (struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b);
+typedef int (*ecp_open_handler_t) (struct ECPConnection *conn, struct ECP2Buffer *b);
+typedef void (*ecp_close_handler_t) (struct ECPConnection *conn);
+typedef ssize_t (*ecp_open_send_t) (struct ECPConnection *conn, unsigned char *cookie);
typedef struct ECPBuffer {
unsigned char *buffer;
@@ -186,78 +198,46 @@ typedef struct ECP2Buffer {
} ECP2Buffer;
typedef struct ECPDHKey {
- ecp_dh_public_t public;
- ecp_dh_private_t private;
+ ecp_ecdh_public_t public;
+ ecp_ecdh_private_t private;
unsigned char valid;
} ECPDHKey;
-typedef struct ECPDHRKey {
- unsigned char idx;
- ecp_dh_public_t public;
-} ECPDHRKey;
-
-typedef struct ECPDHShared {
- ecp_aead_key_t secret;
+typedef struct ECPDHPub {
+ ecp_ecdh_public_t public;
unsigned char valid;
-} ECPDHShared;
-
-typedef struct ECPDHRKeyBucket {
- ECPDHRKey key[ECP_MAX_NODE_KEY];
- unsigned char key_curr;
- unsigned char key_idx_map[ECP_MAX_SOCK_KEY];
-} ECPDHRKeyBucket;
+} ECPDHPub;
typedef struct ECPNode {
- ECPNetAddr addr;
- ecp_dh_public_t public;
+ ecp_tr_addr_t addr;
+ ECPDHPub key_perma;
} ECPNode;
-typedef struct ECPSeqItem {
- ecp_seq_t seq;
- unsigned char seq_w;
-#ifdef ECP_WITH_RBUF
- unsigned char rb_pass;
- unsigned char rb_mtype;
- unsigned short rb_idx;
-#endif
-} ECPSeqItem;
-
-typedef struct ECPFragIter {
- ecp_seq_t seq;
- unsigned char frag_cnt;
- unsigned char *buffer;
- size_t buf_size;
- size_t msg_size;
-} ECPFragIter;
+typedef struct ECPDHShkey {
+ ecp_aead_key_t key;
+ unsigned char valid;
+} ECPDHShkey;
typedef struct ECPPktMeta {
- ecp_aead_key_t shsec;
- ecp_seq_t seq;
- unsigned char public[ECP_ECDH_SIZE_KEY];
- unsigned char nonce[ECP_AEAD_SIZE_NONCE];
+ unsigned char *cookie;
+ ecp_ecdh_public_t *public;
+ ecp_aead_key_t *shkey;
+ ecp_nonce_t *nonce;
+ unsigned char ntype;
unsigned char s_idx;
unsigned char c_idx;
} ECPPktMeta;
typedef struct ECPConnHandler {
- ecp_conn_msg_handler_t msg[ECP_MAX_MTYPE];
- ecp_conn_close_t conn_close;
+ ecp_msg_handler_t handle_msg;
+ ecp_open_handler_t handle_open;
+ ecp_close_handler_t handle_close;
+ ecp_open_send_t send_open;
} ECPConnHandler;
-typedef struct ECPSockCTable {
-#ifdef ECP_WITH_HTABLE
- void *htable;
-#else
- struct ECPConnection *array[ECP_MAX_SOCK_CONN];
- unsigned short size;
-#endif
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_t mutex;
-#endif
-} ECPSockCTable;
-
typedef struct ECPContext {
- ecp_rng_t rng;
+ ecp_err_handler_t handle_err;
+ ecp_dir_handler_t handle_dir;
ecp_conn_alloc_t conn_alloc;
ecp_conn_free_t conn_free;
ECPConnHandler *handler[ECP_MAX_CTYPE];
@@ -267,17 +247,29 @@ typedef struct ECPContext {
#endif
} ECPContext;
+typedef struct ECPConnTable {
+#ifdef ECP_WITH_HTABLE
+ void *keys;
+ void *addrs;
+#else
+ struct ECPConnection *arr[ECP_MAX_SOCK_CONN];
+ unsigned short size;
+#endif
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_t mutex;
+#endif
+} ECPConnTable;
+
typedef struct ECPSocket {
ECPContext *ctx;
unsigned char running;
- int poll_timeout;
- ECPNetSock sock;
+ ecp_tr_sock_t sock;
+ ecp_nonce_t nonce_out;
ECPDHKey key_perma;
ECPDHKey key[ECP_MAX_SOCK_KEY];
unsigned char key_curr;
- ECPSockCTable conn;
+ ECPConnTable conn_table;
ECPTimer timer;
- ecp_sock_msg_handler_t handler[ECP_MAX_MTYPE_SOCK];
#ifdef ECP_WITH_PTHREAD
pthread_t rcvr_thd;
pthread_mutex_t mutex;
@@ -289,120 +281,133 @@ typedef struct ECPConnection {
unsigned char flags;
unsigned char flags_im;
unsigned short refcount;
- ecp_seq_t seq_out;
- ecp_seq_t seq_in;
- ecp_ack_t seq_in_map;
+ ecp_nonce_t nonce_out;
+ ecp_nonce_t nonce_in;
+ ecp_ack_t nonce_map;
ECPSocket *sock;
- ECPNode node;
- ECPDHRKeyBucket remote;
+ ECPNode remote;
ECPDHKey key[ECP_MAX_CONN_KEY];
+ ECPDHPub rkey[ECP_MAX_NODE_KEY];
unsigned char key_curr;
- unsigned char key_idx[ECP_MAX_NODE_KEY];
- unsigned char key_idx_curr;
- 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];
-#ifdef ECP_WITH_RBUF
- ECPConnRBuffer rbuf;
-#endif
+ unsigned char key_next;
+ unsigned char rkey_curr;
+ ECPDHShkey shkey[ECP_MAX_NODE_KEY][ECP_MAX_NODE_KEY];
#ifdef ECP_WITH_PTHREAD
pthread_mutex_t mutex;
#endif
+#ifdef ECP_WITH_VCONN
struct ECPConnection *parent;
+ struct ECPConnection *next;
unsigned short pcount;
- void *conn_data;
+#endif
} ECPConnection;
int ecp_init(ECPContext *ctx);
-int ecp_ctx_init(ECPContext *ctx);
-int ecp_node_init(ECPNode *node, ecp_dh_public_t *public, void *addr);
-int ecp_seq_item_init(ECPSeqItem *seq_item);
-int ecp_frag_iter_init(ECPFragIter *iter, unsigned char *buffer, size_t buf_size);
-void ecp_frag_iter_reset(ECPFragIter *iter);
-int ecp_dhkey_gen(ECPContext *ctx, ECPDHKey *key);
+int ecp_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 ecp_ctx_set_handler(ECPContext *ctx, ECPConnHandler *handler, unsigned char ctype);
+int ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, void *addr);
+int ecp_dhkey_gen(ECPDHKey *key);
int ecp_sock_init(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key);
-int ecp_sock_create(ECPSocket *sock);
+int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key);
void ecp_sock_destroy(ECPSocket *sock);
int ecp_sock_open(ECPSocket *sock, void *myaddr);
void ecp_sock_close(ECPSocket *sock);
-ecp_sock_msg_handler_t ecp_sock_get_msg_handler(ECPSocket *sock, unsigned char mtype);
-int ecp_sock_dhkey_get_curr(ECPSocket *sock, unsigned char *idx, unsigned char *public);
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_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype);
-int ecp_conn_create(ECPConnection *conn);
+ECPConnection *ecp_sock_keys_search(ECPSocket *sock, ecp_ecdh_public_t *public);
+int ecp_sock_keys_insert(ECPSocket *sock, ecp_ecdh_public_t *public, ECPConnection *conn);
+void ecp_sock_keys_remove(ECPSocket *sock, ecp_ecdh_public_t *public);
+
+int ecp_conn_alloc(ECPSocket *sock, unsigned char ctype, ECPConnection **_conn);
+void ecp_conn_free(ECPConnection *conn);
+
+void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype);
+void ecp_conn_reinit(ECPConnection *conn);
+int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype);
+int ecp_conn_create_inb(ECPConnection *conn, ECPSocket *sock, unsigned char ctype);
void ecp_conn_destroy(ECPConnection *conn);
-int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char c_idx, unsigned char *public);
-int ecp_conn_create_outb(ECPConnection *conn, ECPNode *node);
+
+void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags);
+void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags);
+void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key);
+void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr);
+
+int ecp_conn_init_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *remote_key, ecp_aead_key_t *shkey);
+int ecp_conn_init_outb(ECPConnection *conn, ECPNode *node);
+
int ecp_conn_insert(ECPConnection *conn);
-int ecp_conn_register(ECPConnection *conn);
-void ecp_conn_unregister(ECPConnection *conn, unsigned short *refcount);
+void ecp_conn_remove(ECPConnection *conn, unsigned short *refcount);
+void ecp_conn_remove_addr(ECPConnection *conn);
-int ecp_conn_get_dirlist(ECPConnection *conn, ECPNode *node);
int ecp_conn_open(ECPConnection *conn, ECPNode *node);
-int ecp_conn_close(ECPConnection *conn);
int ecp_conn_reset(ECPConnection *conn);
+void _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);
-int ecp_conn_handler_init(ECPConnHandler *handler);
-ecp_conn_msg_handler_t ecp_conn_get_msg_handler(ECPConnection *conn, unsigned char mtype);
-ecp_conn_close_t ecp_conn_get_close_handler(ECPConnection *conn);
int ecp_conn_dhkey_new(ECPConnection *conn);
-int ecp_conn_dhkey_new_pub(ECPConnection *conn, unsigned char idx, unsigned char *public);
-int ecp_conn_dhkey_get_curr(ECPConnection *conn, unsigned char *idx, unsigned char *public);
-
-ssize_t ecp_conn_send_open(ECPConnection *conn);
-ssize_t ecp_conn_send_kget(ECPConnection *conn);
-ssize_t ecp_conn_send_kput(ECPConnection *conn);
-ssize_t ecp_conn_send_dir(ECPConnection *conn);
-
-ssize_t _ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b, int *was_open);
-ssize_t ecp_conn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b);
-ssize_t _ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b, ecp_conn_open_t conn_open);
-ssize_t ecp_conn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b);
-ssize_t ecp_conn_handle_kput(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b);
-ssize_t ecp_conn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs);
-ssize_t ecp_sock_handle_open(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn);
-ssize_t ecp_sock_handle_kget(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn);
-
-ssize_t _ecp_pack(ECPContext *ctx, unsigned char *packet, size_t pkt_size, ECPPktMeta *pkt_meta, unsigned char *payload, size_t pld_size);
-ssize_t ecp_pack(ECPContext *ctx, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) ;
-
-ssize_t _ecp_pack_conn(ECPConnection *conn, unsigned char *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, unsigned char *payload, size_t pld_size, ECPNetAddr *addr, ECPSeqItem *si);
-ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr, ECPSeqItem *si);
-
-ssize_t ecp_unpack(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size, ECPConnection **_conn, ecp_seq_t *_seq);
-ssize_t ecp_pkt_handle(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECP2Buffer *bufs, size_t pkt_size);
-ssize_t ecp_pkt_send(ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags);
-
-int ecp_msg_get_type(unsigned char *msg, size_t msg_size, unsigned char *mtype);
-int ecp_msg_set_type(unsigned char *msg, size_t msg_size, unsigned char mtype);
-int ecp_msg_get_frag(unsigned char *msg, size_t msg_size, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_size);
-int ecp_msg_set_frag(unsigned char *msg, size_t msg_size, unsigned char frag_cnt, unsigned char frag_tot, uint16_t frag_size);
-int ecp_msg_get_pts(unsigned char *msg, size_t msg_size, ecp_pts_t *pts);
-int ecp_msg_set_pts(unsigned char *msg, size_t msg_size, ecp_pts_t pts);
-unsigned char *ecp_msg_get_content(unsigned char *msg, size_t msg_size);
-int ecp_msg_defrag(ECPFragIter *iter, ecp_seq_t seq, unsigned char mtype, unsigned char *msg_in, size_t msg_in_size, unsigned char **msg_out, size_t *msg_out_size);
-
-int ecp_pld_get_type(unsigned char *payload, size_t pld_size, unsigned char *mtype);
-int ecp_pld_set_type(unsigned char *payload, size_t pld_size, unsigned char mtype);
-int ecp_pld_get_frag(unsigned char *payload, size_t pld_size, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_size);
-int ecp_pld_set_frag(unsigned char *payload, size_t pld_size, unsigned char frag_cnt, unsigned char frag_tot, uint16_t frag_size);
-int ecp_pld_get_pts(unsigned char *payload, size_t pld_size, ecp_pts_t *pts);
-int ecp_pld_set_pts(unsigned char *payload, size_t pld_size, ecp_pts_t pts);
-unsigned char *ecp_pld_get_buf(unsigned char *payload, size_t pld_size);
-
-ssize_t __ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti, ECPSeqItem *si);
-ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti);
+int ecp_conn_dhkey_get(ECPSocket *sock, unsigned char idx, ECPDHKey *key);
+int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_public_t *public, int will_send);
+int ecp_conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_public_t *public);
+void ecp_conn_dhkey_set_curr(ECPConnection *conn);
+
+void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_open_send_t send_open);
+ecp_msg_handler_t ecp_get_msg_handler(ECPConnection *conn);
+ecp_open_handler_t ecp_get_open_handler(ECPConnection *conn);
+ecp_close_handler_t ecp_get_close_handler(ECPConnection *conn);
+ecp_dir_handler_t ecp_get_dir_handler(ECPConnection *conn);
+void ecp_err_handle(ECPConnection *conn, unsigned char mtype, int err);
+
+ssize_t ecp_send_init_req(ECPConnection *conn);
+ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char *public_buf, ecp_aead_key_t *shkey);
+ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char *public_buf, ecp_aead_key_t *shkey);
+ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size);
+ssize_t ecp_write_open_req(ECPConnection *conn, ECPBuffer *payload);
+ssize_t ecp_send_open_req(ECPConnection *conn, unsigned char *cookie);
+ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, unsigned char *public_buf, unsigned char *msg, size_t msg_size, ecp_aead_key_t *shkey, ECPConnection **_conn);
+ssize_t ecp_send_open_rep(ECPConnection *conn);
+ssize_t ecp_handle_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs);
+
+ssize_t ecp_send_keyx_req(ECPConnection *conn);
+ssize_t ecp_send_keyx_rep(ECPConnection *conn);
+ssize_t ecp_handle_keyx(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size);
+
+ssize_t ecp_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs);
+ssize_t ecp_pld_handle_one(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs);
+ssize_t ecp_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t _pld_size, ECP2Buffer *bufs);
+
+ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t _pkt_size, ECPConnection **_conn, unsigned char **_payload, ecp_seq_t *_seq);
+ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t pkt_size);
+
+ssize_t ecp_pkt_send(ECPSocket *sock, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ecp_tr_addr_t *addr);
+
+void ecp_nonce2buf(unsigned char *b, ecp_nonce_t *n);
+void ecp_buf2nonce(ecp_nonce_t *n, unsigned char *b);
+int ecp_pkt_get_seq(unsigned char *pkt, size_t pkt_size, ecp_seq_t *s);
+ssize_t ecp_pack(ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr);
+ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, unsigned char *cookie, ecp_nonce_t *nonce, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr);
+
+int ecp_pld_get_type(unsigned char *pld, size_t pld_size, unsigned char *mtype);
+int ecp_pld_set_type(unsigned char *pld, size_t pld_size, unsigned char mtype);
+int ecp_pld_get_frag(unsigned char *pld, size_t pld_size, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_size);
+int ecp_pld_set_frag(unsigned char *pld, size_t pld_size, unsigned char frag_cnt, unsigned char frag_tot, uint16_t frag_size);
+int ecp_pld_get_pts(unsigned char *pld, size_t pld_size, ecp_pts_t *pts);
+int ecp_pld_set_pts(unsigned char *pld, size_t pld_size, ecp_pts_t pts);
+unsigned char *ecp_pld_get_msg(unsigned char *pld, size_t pld_size);
+
+ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, unsigned char *cookie, ecp_nonce_t *n, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti);
ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags);
ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti);
-ssize_t ecp_pld_send_tr(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, unsigned char flags);
-
-ssize_t ecp_send(ECPConnection *conn, unsigned char mtype, unsigned char *content, size_t content_size);
-ssize_t ecp_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ecp_cts_t timeout);
+ssize_t ecp_pld_send_wcookie(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, unsigned char *cookie);
+ssize_t ecp_pld_send_wnonce(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_nonce_t *nonce);
+ssize_t ecp_pld_send_irep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, unsigned char flags);
+ssize_t ecp_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size);
int ecp_receiver(ECPSocket *sock);
int ecp_start_receiver(ECPSocket *sock);
int ecp_stop_receiver(ECPSocket *sock);
diff --git a/ecp/src/ecp/cr.h b/ecp/src/ecp/cr.h
index a8d0dea..bcca318 100644
--- a/ecp/src/ecp/cr.h
+++ b/ecp/src/ecp/cr.h
@@ -1,13 +1,16 @@
-int ecp_cr_dh_mkpair(ecp_dh_public_t *pub, ecp_dh_private_t *priv, ecp_rng_t rand_buf);
-int ecp_cr_dh_shsec(ecp_aead_key_t *shared, ecp_dh_public_t *pub, ecp_dh_private_t *priv);
-unsigned char *ecp_cr_dh_pub_get_buf(ecp_dh_public_t *p);
-void ecp_cr_dh_pub_to_buf(unsigned char *b, ecp_dh_public_t *p);
-void ecp_cr_dh_pub_from_buf(ecp_dh_public_t *p, unsigned char *b) ;
-int ecp_cr_dh_pub_eq(unsigned char *p1, ecp_dh_public_t *p2) ;
-unsigned int ecp_cr_dh_pub_hash_fn(unsigned char *p);
-int ecp_cr_dh_pub_hash_eq(unsigned char *p1, unsigned char *p2);
-ssize_t ecp_cr_aead_enc(unsigned char *ct, size_t cl, unsigned char *pt, size_t pl, ecp_aead_key_t *k, unsigned char *n);
-ssize_t ecp_cr_aead_dec(unsigned char *pt, size_t pl, unsigned char *ct, size_t cl, ecp_aead_key_t *k, unsigned char *n) ;
-int ecp_cr_dsa_mkpair(ecp_dsa_public_t *pub, ecp_dsa_private_t *priv, ecp_rng_t rand_buf);
-int ecp_cr_dsa_sign(unsigned char *sig, unsigned char *m, size_t ml, ecp_dsa_public_t *p, ecp_dsa_private_t *s) ;
-int ecp_cr_dsa_verify(unsigned char *m, size_t ml, unsigned char *sig, ecp_dsa_public_t *p);
+uint32_t arc4random(void);
+void arc4random_buf(void *_buf, size_t n);
+uint32_t arc4random_uniform(uint32_t upper_bound);
+
+int ecp_ecdh_mkpair(ecp_ecdh_public_t *pub, ecp_ecdh_private_t *priv);
+int ecp_ecdh_shkey(ecp_aead_key_t *shared, ecp_ecdh_public_t *pub, ecp_ecdh_private_t *priv);
+
+unsigned int ecp_ecdh_pub_hash(ecp_ecdh_public_t *p);
+int ecp_ecdh_pub_eq(ecp_ecdh_public_t *p1, ecp_ecdh_public_t *p2);
+
+ssize_t ecp_aead_enc(unsigned char *ct, size_t cl, unsigned char *pt, size_t pl, ecp_aead_key_t *k, ecp_nonce_t *n, unsigned char nt);
+ssize_t ecp_aead_dec(unsigned char *pt, size_t pl, unsigned char *ct, size_t cl, ecp_aead_key_t *k, ecp_nonce_t *n, unsigned char nt);
+
+int ecp_ecdsa_mkpair(ecp_ecdsa_public_t *pub, ecp_ecdsa_private_t *priv);
+int ecp_ecdsa_sign(ecp_ecdsa_signature_t *sig, unsigned char *m, size_t ml, ecp_ecdsa_private_t *k);
+int ecp_ecdsa_verify(unsigned char *m, size_t ml, ecp_ecdsa_signature_t *sig, ecp_ecdsa_public_t *p);
diff --git a/ecp/src/ecp/crypto/crypto.c b/ecp/src/ecp/crypto/crypto.c
index e1d06b3..66ce524 100644
--- a/ecp/src/ecp/crypto/crypto.c
+++ b/ecp/src/ecp/crypto/crypto.c
@@ -1,14 +1,17 @@
+#include <stdlib.h>
+#include <string.h>
+
#include <core.h>
#include <cr.h>
#include <openssl/curve25519.h>
-int ecp_cr_dh_mkpair(ecp_dh_public_t *pub, ecp_dh_private_t *priv, ecp_rng_t rand_buf) {
+int ecp_ecdh_mkpair(ecp_ecdh_public_t *pub, ecp_ecdh_private_t *priv) {
X25519_keypair(*pub, *priv);
return ECP_OK;
}
-int ecp_cr_dh_shsec(ecp_aead_key_t *shared, ecp_dh_public_t *pub, ecp_dh_private_t *priv) {
+int ecp_ecdh_shkey(ecp_aead_key_t *shared, ecp_ecdh_public_t *pub, ecp_ecdh_private_t *priv) {
int rv;
rv = X25519(*shared, *priv, *pub);
@@ -16,78 +19,87 @@ int ecp_cr_dh_shsec(ecp_aead_key_t *shared, ecp_dh_public_t *pub, ecp_dh_private
return ECP_OK;
}
-unsigned char *ecp_cr_dh_pub_get_buf(ecp_dh_public_t *p) {
- return (unsigned char *)p;
+unsigned int ecp_ecdh_pub_hash(ecp_ecdh_public_t *p) {
+ return *((unsigned int *)p);
}
-void ecp_cr_dh_pub_to_buf(unsigned char *b, ecp_dh_public_t *p) {
- memcpy(b, p, ECP_ECDH_SIZE_KEY);
+int ecp_ecdh_pub_eq(ecp_ecdh_public_t *p1, ecp_ecdh_public_t *p2) {
+ return !memcmp(p1, p2, sizeof(ecp_ecdh_public_t));
}
-void ecp_cr_dh_pub_from_buf(ecp_dh_public_t *p, unsigned char *b) {
- memcpy(p, b, ECP_ECDH_SIZE_KEY);
-}
+ssize_t ecp_aead_enc(unsigned char *ct, size_t cl, unsigned char *pt, size_t pl, ecp_aead_key_t *k, ecp_nonce_t *n, unsigned char nt) {
+ ecp_aead_nonce_t nonce;
+ size_t ol;
+ int rv;
-int ecp_cr_dh_pub_eq(unsigned char *p1, ecp_dh_public_t *p2) {
- return !memcmp(p1, p2, ECP_ECDH_SIZE_KEY);
-}
+ switch (nt) {
+ case ECP_NTYPE_INB:
+ memcpy(&nonce, "SRVR", 4);
+ break;
-unsigned int ecp_cr_dh_pub_hash_fn(unsigned char *p) {
- return *((unsigned int *)p);
-}
+ case ECP_NTYPE_OUTB:
+ memcpy(&nonce, "CLNT", 4);
+ break;
-int ecp_cr_dh_pub_hash_eq(unsigned char *p1, unsigned char *p2) {
- return !memcmp(p1, p2, ECP_ECDH_SIZE_KEY);
-}
+ case ECP_NTYPE_VBOX:
+ memcpy(&nonce, "VBOX", 4);
+ break;
-ssize_t ecp_cr_aead_enc(unsigned char *ct, size_t cl, unsigned char *pt, size_t pl, ecp_aead_key_t *k, unsigned char *n) {
- uint8_t _n[ECP_AEAD_SIZE_NONCE + 4];
- size_t ol;
- int rv;
+ default:
+ return ECP_ERR_ENCRYPT;
+ }
+ ecp_nonce2buf((unsigned char *)&nonce + 4, n);
- memset(_n, 0, 4);
- memcpy(_n + 4, n, ECP_AEAD_SIZE_NONCE);
- rv = aead_chacha20_poly1305_seal(*k, ECP_AEAD_SIZE_TAG, ct, &ol, cl, _n, ECP_AEAD_SIZE_NONCE + 4, pt, pl, NULL, 0);
- if (!rv) return ECP_ERR;
+ rv = aead_chacha20_poly1305_seal(*k, ECP_SIZE_AEAD_TAG, ct, &ol, cl, (const unsigned char *)&nonce, sizeof(nonce), pt, pl, NULL, 0);
+ if (!rv) return ECP_ERR_ENCRYPT;
return ol;
}
-ssize_t ecp_cr_aead_dec(unsigned char *pt, size_t pl, unsigned char *ct, size_t cl, ecp_aead_key_t *k, unsigned char *n) {
- uint8_t _n[ECP_AEAD_SIZE_NONCE + 4];
+ssize_t ecp_aead_dec(unsigned char *pt, size_t pl, unsigned char *ct, size_t cl, ecp_aead_key_t *k, ecp_nonce_t *n, unsigned char nt) {
+ ecp_aead_nonce_t nonce;
size_t ol;
int rv;
- memset(_n, 0, 4);
- memcpy(_n + 4, n, ECP_AEAD_SIZE_NONCE);
- rv = aead_chacha20_poly1305_open(*k, ECP_AEAD_SIZE_TAG, pt, &ol, pl, _n, ECP_AEAD_SIZE_NONCE + 4, ct, cl, NULL, 0);
- if (!rv) return ECP_ERR;
+ switch (nt) {
+ case ECP_NTYPE_INB:
+ memcpy(&nonce, "CLNT", 4);
+ break;
+
+ case ECP_NTYPE_OUTB:
+ memcpy(&nonce, "SRVR", 4);
+ break;
+
+ case ECP_NTYPE_VBOX:
+ memcpy(&nonce, "VBOX", 4);
+ break;
+
+ default:
+ return ECP_ERR_DECRYPT;
+ }
+ ecp_nonce2buf((unsigned char *)&nonce + 4, n);
+
+ rv = aead_chacha20_poly1305_open(*k, ECP_SIZE_AEAD_TAG, pt, &ol, pl, (const unsigned char *)&nonce, sizeof(nonce), ct, cl, NULL, 0);
+ if (!rv) return ECP_ERR_DECRYPT;
return ol;
}
-int ecp_cr_dsa_mkpair(ecp_dsa_public_t *pub, ecp_dsa_private_t *priv, ecp_rng_t rand_buf) {
- unsigned char key[2*ECP_DSA_SIZE_KEY];
-
- ED25519_keypair(*pub, key);
- memcpy(priv, key, ECP_DSA_SIZE_KEY);
+int ecp_ecdsa_mkpair(ecp_ecdsa_public_t *pub, ecp_ecdsa_private_t *priv) {
+ ED25519_keypair(*pub, *priv);
return ECP_OK;
}
-int ecp_cr_dsa_sign(unsigned char *sig, unsigned char *m, size_t ml, ecp_dsa_public_t *p, ecp_dsa_private_t *s) {
- unsigned char key[2*ECP_DSA_SIZE_KEY];
+int ecp_ecdsa_sign(ecp_ecdsa_signature_t *sig, unsigned char *m, size_t ml, ecp_ecdsa_private_t *k) {
int rv;
- memcpy(key, s, ECP_DSA_SIZE_KEY);
- memcpy(key+ECP_DSA_SIZE_KEY, p, ECP_DSA_SIZE_KEY);
-
- rv = ED25519_sign(sig, m, ml, key);
- if (!rv) return ECP_ERR;
+ rv = ED25519_sign(*sig, m, ml, *k);
+ if (!rv) return ECP_ERR_SIGN;
return ECP_OK;
}
-int ecp_cr_dsa_verify(unsigned char *m, size_t ml, unsigned char *sig, ecp_dsa_public_t *p) {
+int ecp_ecdsa_verify(unsigned char *m, size_t ml, ecp_ecdsa_signature_t *sig, ecp_ecdsa_public_t *p) {
int rv;
- rv = ED25519_verify(m, ml, sig, *p);
+ rv = ED25519_verify(m, ml, *sig, *p);
if (rv == 1) return ECP_OK;
- return ECP_ERR;
+ return ECP_ERR_VERIFY;
}
diff --git a/ecp/src/ecp/crypto/crypto.h b/ecp/src/ecp/crypto/crypto.h
index 378500c..863b25b 100644
--- a/ecp/src/ecp/crypto/crypto.h
+++ b/ecp/src/ecp/crypto/crypto.h
@@ -1,21 +1,25 @@
#define CURVE25519_SIZE_KEY 32
#define CHACHA20_SIZE_KEY 32
#define POLY1305_SIZE_TAG 16
-#define CHACHA20_SIZE_NONCE 8
+#define CHACHA20_SIZE_NONCE 12
-#define ECP_ECDH_SIZE_KEY 32
-#define ECP_AEAD_SIZE_KEY 32
-#define ECP_AEAD_SIZE_TAG 16
-#define ECP_AEAD_SIZE_NONCE 8
+#define ECP_SIZE_ECDH_PUB 32
+#define ECP_SIZE_ECDH_SEC 32
+#define ECP_SIZE_AEAD_KEY 32
+#define ECP_SIZE_AEAD_TAG 16
+#define ECP_SIZE_AEAD_NONCE 12
-#define ECP_DSA_SIZE_KEY 32
-#define ECP_DSA_SIZE_SIGNATURE 32
+#define ECP_SIZE_ECDSA_PUB 32
+#define ECP_SIZE_ECDSA_SEC 64
+#define ECP_SIZE_ECDSA_SIG 32
-typedef uint8_t ecp_dh_public_t[ECP_ECDH_SIZE_KEY];
-typedef uint8_t ecp_dh_private_t[ECP_ECDH_SIZE_KEY];
-typedef uint8_t ecp_aead_key_t[ECP_AEAD_SIZE_KEY];
-typedef uint8_t ecp_dsa_public_t[ECP_DSA_SIZE_KEY];
-typedef uint8_t ecp_dsa_private_t[ECP_DSA_SIZE_KEY];
+typedef uint8_t ecp_ecdh_public_t[ECP_SIZE_ECDH_PUB];
+typedef uint8_t ecp_ecdh_private_t[ECP_SIZE_ECDH_SEC];
+typedef uint8_t ecp_aead_key_t[ECP_SIZE_AEAD_KEY];
+typedef uint8_t ecp_aead_nonce_t[ECP_SIZE_AEAD_NONCE];
+typedef uint8_t ecp_ecdsa_public_t[ECP_SIZE_ECDSA_PUB];
+typedef uint8_t ecp_ecdsa_private_t[ECP_SIZE_ECDSA_SEC];
+typedef uint8_t ecp_ecdsa_signature_t[ECP_SIZE_ECDSA_SIG];
int
aead_chacha20_poly1305_seal(unsigned char key[32], unsigned char tag_len,
diff --git a/ecp/src/ecp/dir.c b/ecp/src/ecp/dir.c
index 46d152e..0e07486 100644
--- a/ecp/src/ecp/dir.c
+++ b/ecp/src/ecp/dir.c
@@ -1,3 +1,6 @@
+#include <stdlib.h>
+#include <string.h>
+
#include "core.h"
#include "cr.h"
@@ -8,7 +11,7 @@ static int dir_update(ECPDirList *list, ECPDirItem *item) {
int i;
for (i=0; i<list->count; i++) {
- if (memcmp(ecp_cr_dh_pub_get_buf(&list->item[i].node.public), ecp_cr_dh_pub_get_buf(&item->node.public), ECP_ECDH_SIZE_KEY) == 0) {
+ if (memcmp(&list->item[i].node.key_perma.public, &item->node.key_perma.public, sizeof(item->node.key_perma.public)) == 0) {
return ECP_OK;
}
}
@@ -23,45 +26,65 @@ static int dir_update(ECPDirList *list, ECPDirItem *item) {
ssize_t ecp_dir_parse(ECPDirList *list, unsigned char *buf, size_t buf_size) {
ECPDirItem item;
- size_t size;
+ size_t rsize;
+ uint16_t count;
+ int i;
int rv;
- size = buf_size;
- while (size >= ECP_SIZE_DIR_ITEM) {
+ if (buf_size < sizeof(uint16_t)) return ECP_ERR_SIZE;
+
+ count = \
+ (buf[0] << 8) | \
+ (buf[1]);
+
+ rsize = sizeof(uint16_t) + count * ECP_SIZE_DIR_ITEM;
+ if (buf_size < rsize) return ECP_ERR_SIZE;
+
+ buf += sizeof(uint16_t);
+ for (i=0; i<count; i++) {
ecp_dir_item_parse(&item, buf);
rv = dir_update(list, &item);
if (rv) return rv;
buf += ECP_SIZE_DIR_ITEM;
- size -= ECP_SIZE_DIR_ITEM;
- };
+ }
- return buf_size - size;
+ return rsize;
}
-int ecp_dir_serialize(ECPDirList *list, unsigned char *buf, size_t buf_size) {
+ssize_t ecp_dir_serialize(ECPDirList *list, unsigned char *buf, size_t buf_size) {
+ size_t rsize;
int i;
- for (i=0; i<list->count; i++) {
- if (buf_size < ECP_SIZE_DIR_ITEM) return ECP_ERR_SIZE;
+ rsize = sizeof(uint16_t) + list->count * ECP_SIZE_DIR_ITEM;
+ if (buf_size < rsize) return ECP_ERR_SIZE;
+ buf[0] = (list->count & 0xFF00) >> 8;
+ buf[1] = (list->count & 0x00FF);
+ buf += sizeof(uint16_t);
+ for (i=0; i<list->count; i++) {
ecp_dir_item_serialize(&list->item[i], buf);
buf += ECP_SIZE_DIR_ITEM;
- buf_size -= ECP_SIZE_DIR_ITEM;
}
- return ECP_OK;
+ return rsize;
}
void ecp_dir_item_parse(ECPDirItem *item, unsigned char *buf) {
- ecp_cr_dh_pub_from_buf(&item->node.public, buf);
- buf += ECP_ECDH_SIZE_KEY;
+ ECPDHPub *key;
+ ecp_tr_addr_t *addr;
- memcpy(&item->node.addr.host, buf, sizeof(item->node.addr));
- buf += ECP_IPv4_ADDR_SIZE;
+ key = &item->node.key_perma;
+ addr = &item->node.addr;
- item->node.addr.port = \
+ memcpy(&key->public, buf, sizeof(key->public));
+ buf += sizeof(key->public);
+
+ memcpy(&addr->host, buf, sizeof(addr->host));
+ buf += sizeof(addr->host);
+
+ addr->port = \
(buf[0] << 8) | \
(buf[1]);
buf += sizeof(uint16_t);
@@ -73,17 +96,108 @@ void ecp_dir_item_parse(ECPDirItem *item, unsigned char *buf) {
}
void ecp_dir_item_serialize(ECPDirItem *item, unsigned char *buf) {
- ecp_cr_dh_pub_to_buf(buf, &item->node.public);
- buf += ECP_ECDH_SIZE_KEY;
+ ECPDHPub *key;
+ ecp_tr_addr_t *addr;
+
+ key = &item->node.key_perma;
+ addr = &item->node.addr;
- memcpy(buf, &item->node.addr.host, sizeof(item->node.addr));
- buf += ECP_IPv4_ADDR_SIZE;
+ memcpy(buf, &key->public, sizeof(key->public));
+ buf += sizeof(key->public);
- buf[0] = (item->node.addr.port & 0xFF00) >> 8;
- buf[1] = (item->node.addr.port & 0x00FF);
+ memcpy(buf, &addr->host, sizeof(addr->host));
+ buf += sizeof(addr->host);
+
+ buf[0] = (addr->port & 0xFF00) >> 8;
+ buf[1] = (addr->port & 0x00FF);
buf += sizeof(uint16_t);
buf[0] = (item->capabilities & 0xFF00) >> 8;
buf[1] = (item->capabilities & 0x00FF);
buf += sizeof(uint16_t);
}
+
+ssize_t ecp_dir_handle(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
+ ecp_dir_handler_t handler;
+
+ handler = ecp_get_dir_handler(conn);
+ if (handler) {
+ return handler(conn, msg, msg_size, b);
+ } else {
+ return ECP_ERR_HANDLER;
+ }
+}
+
+int ecp_dir_handle_open(ECPConnection *conn, ECP2Buffer *b) {
+ ssize_t rv;
+
+ if (ecp_conn_is_inb(conn)) return ECP_OK;
+
+#ifdef ECP_WITH_DIRSRV
+ rv = ecp_dir_send_upd(conn);
+#else
+ rv = ecp_dir_send_req(conn);
+#endif
+ if (rv < 0) return rv;
+
+ return ECP_OK;
+}
+
+ssize_t ecp_dir_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
+ switch (mtype) {
+#ifdef ECP_WITH_DIRSRV
+ case ECP_MTYPE_DIR_UPD: {
+ return ecp_dir_handle_upd(conn, msg, msg_size);
+ }
+
+ case ECP_MTYPE_DIR_REQ: {
+ return ecp_dir_handle_req(conn, msg, msg_size);
+ }
+#endif
+
+ case ECP_MTYPE_DIR_REP: {
+#ifdef ECP_WITH_DIRSRV
+ return ecp_dir_handle_rep(conn, msg, msg_size);
+#else
+ return ecp_dir_handle(conn, msg, msg_size, b);
+#endif
+ }
+
+ default:
+ return ECP_ERR_MTYPE;
+ }
+}
+
+// iterator for client
+
+static ssize_t _dir_send_req(ECPConnection *conn, ECPTimerItem *ti) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_DIR_REQ, conn)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_DIR_REQ, conn)];
+
+ packet.buffer = pkt_buf;
+ packet.size = sizeof(pkt_buf);
+ payload.buffer = pld_buf;
+ payload.size = sizeof(pld_buf);
+
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_DIR_REQ);
+ return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_DIR_REQ), 0, ti);
+}
+
+ssize_t ecp_dir_send_req(ECPConnection *conn) {
+ return ecp_timer_send(conn, _dir_send_req, ECP_MTYPE_DIR_REP, ECP_SEND_TRIES, ECP_SEND_TIMEOUT);
+}
+
+int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ECPNode *node) {
+ int rv;
+ ssize_t _rv;
+
+ rv = ecp_conn_create(conn, sock, ECP_CTYPE_DIR);
+ if (rv) return rv;
+
+ rv = ecp_conn_open(conn, node);
+ if (rv) return rv;
+
+ return ECP_OK;
+}
diff --git a/ecp/src/ecp/dir.h b/ecp/src/ecp/dir.h
index 2fcc50f..e9f8e1e 100644
--- a/ecp/src/ecp/dir.h
+++ b/ecp/src/ecp/dir.h
@@ -1,5 +1,11 @@
-#define ECP_MAX_DIR_ITEM 30
-#define ECP_SIZE_DIR_ITEM 40
+#define ECP_MAX_DIR_ITEM 30
+#define ECP_SIZE_DIR_ITEM 40
+
+#define ECP_MTYPE_DIR_UPD 0x00
+#define ECP_MTYPE_DIR_REQ 0x01
+#define ECP_MTYPE_DIR_REP 0x02
+
+#define ECP_CTYPE_DIR (0x00 | ECP_CTYPE_FLAG_SYS)
typedef struct ECPDirItem {
ECPNode node;
@@ -12,7 +18,15 @@ typedef struct ECPDirList {
} ECPDirList;
ssize_t ecp_dir_parse(ECPDirList *list, unsigned char *buf, size_t buf_size);
-int ecp_dir_serialize(ECPDirList *list, unsigned char *buf, size_t buf_size);
+ssize_t ecp_dir_serialize(ECPDirList *list, unsigned char *buf, size_t buf_size);
void ecp_dir_item_parse(ECPDirItem *item, unsigned char *buf);
void ecp_dir_item_serialize(ECPDirItem *item, unsigned char *buf);
+
+ssize_t ecp_dir_handle(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *b);
+
+int ecp_dir_handle_open(ECPConnection *conn, ECP2Buffer *b);
+ssize_t ecp_dir_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b);
+
+ssize_t ecp_dir_send_req(ECPConnection *conn);
+int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ECPNode *node); \ No newline at end of file
diff --git a/ecp/src/ecp/dir_srv.c b/ecp/src/ecp/dir_srv.c
index 563326d..952d393 100644
--- a/ecp/src/ecp/dir_srv.c
+++ b/ecp/src/ecp/dir_srv.c
@@ -1,11 +1,11 @@
+#include <stdlib.h>
+
#include "core.h"
#include "cr.h"
#include "dir.h"
#include "dir_srv.h"
-#ifdef ECP_WITH_DIRSRV
-
int ecp_dir_init(ECPContext *ctx, ECPDirList *dir_online, ECPDirList *dir_shadow) {
ctx->dir_online = dir_online;
ctx->dir_shadow = dir_shadow;
@@ -13,38 +13,76 @@ int ecp_dir_init(ECPContext *ctx, ECPDirList *dir_online, ECPDirList *dir_shadow
return ECP_OK;
}
-ssize_t ecp_dir_handle_update(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
+ssize_t ecp_dir_send_list(ECPConnection *conn, unsigned char mtype, ECPDirList *list) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_MAX_PKT];
+ unsigned char pld_buf[ECP_MAX_PLD];
+ unsigned char *msg;
+ size_t hdr_size;
+ size_t msg_size;
+ ssize_t rv;
+
+ packet.buffer = pkt_buf;
+ packet.size = ECP_MAX_PKT;
+ payload.buffer = pld_buf;
+ payload.size = ECP_MAX_PLD;
+
+ ecp_pld_set_type(payload.buffer, payload.size, mtype);
+ msg = ecp_pld_get_msg(payload.buffer, payload.size);
+ hdr_size = msg - payload.buffer;
+ msg_size = payload.size - hdr_size;
+
+ rv = ecp_dir_serialize(list, msg, msg_size);
+ if (rv < 0) return rv;
+
+ rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(rv, mtype), 0);
+ return rv;
+}
+
+ssize_t ecp_dir_send_upd(ECPConnection *conn) {
ECPContext *ctx = conn->sock->ctx;
- ECPDirList *dir_shadow = ctx->dir_shadow;
+ ssize_t rv;
- if (mtype == ECP_MTYPE_DIR_REQ) {
- return ecp_dir_parse(dir_shadow, msg, size);
- } else {
- return ECP_ERR;
- }
+ rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_UPD, ctx->dir_shadow);
+ return rv;
}
-ssize_t ecp_dir_handle_req(ECPSocket *sock, ECPNetAddr *addr, ECPConnection *parent, unsigned char *msg, size_t msg_size, ECPPktMeta *pkt_meta, ECP2Buffer *bufs, ECPConnection **_conn) {
- ECPContext *ctx = sock->ctx;
- ECPBuffer *packet = bufs->packet;
- ECPBuffer *payload = bufs->payload;
- ECPDirList *dir_online = ctx->dir_online;
+ssize_t ecp_dir_handle_upd(ECPConnection *conn, unsigned char *msg, size_t msg_size) {
+ ECPContext *ctx = conn->sock->ctx;
+ ssize_t rsize;
ssize_t rv;
- int _rv;
- if (msg_size < 0) return msg_size;
+ rsize = ecp_dir_parse(ctx->dir_shadow, msg, msg_size);
+ if (rsize < 0) return rsize;
- ecp_pld_set_type(payload->buffer, payload->size, ECP_MTYPE_DIR_REP);
- msg = ecp_pld_get_buf(payload->buffer, payload->size);
- msg_size = payload->size - (msg - payload->buffer);
+ rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_REP, ctx->dir_shadow);
+ if (rv < 0) return rv;
+
+ return rsize;
+}
- _rv = ecp_dir_serialize(dir_online, msg, msg_size);
- if (_rv) return _rv;
+ssize_t ecp_dir_handle_req(ECPConnection *conn, unsigned char *msg, size_t msg_size) {
+ ssize_t rv;
- rv = ecp_pld_send_tr(sock, addr, parent, packet, pkt_meta, payload, ECP_SIZE_PLD(dir_online->count * ECP_SIZE_DIR_ITEM, ECP_MTYPE_DIR_REP), 0);
+ rv = ecp_dir_send_rep(conn);
if (rv < 0) return rv;
- return msg_size;
+ return 0;
+}
+
+ssize_t ecp_dir_send_rep(ECPConnection *conn) {
+ ECPContext *ctx = conn->sock->ctx;
+ ssize_t rv;
+
+ rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_REP, ctx->dir_online);
+ return rv;
}
-#endif /* ECP_WITH_DIRSRV */ \ No newline at end of file
+ssize_t ecp_dir_handle_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size) {
+ ECPContext *ctx = conn->sock->ctx;
+ ssize_t rv;
+
+ rv = ecp_dir_parse(ctx->dir_shadow, msg, msg_size);
+ return rv;
+} \ No newline at end of file
diff --git a/ecp/src/ecp/dir_srv.h b/ecp/src/ecp/dir_srv.h
index 3fc14ee..85606c8 100644
--- a/ecp/src/ecp/dir_srv.h
+++ b/ecp/src/ecp/dir_srv.h
@@ -1,7 +1,10 @@
-#ifdef ECP_WITH_DIRSRV
+int ecp_dir_init(ECPContext *ctx, ECPDirList *dir_online, ECPDirList *dir_shadow);
+ssize_t ecp_dir_send_list(ECPConnection *conn, unsigned char mtype, ECPDirList *list);
-int ecp_dir_init(struct ECPContext *ctx, struct ECPDirList *dir_online, struct ECPDirList *dir_shadow);
-ssize_t ecp_dir_handle_update(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b);
-ssize_t ecp_dir_handle_req(struct ECPSocket *sock, struct ECPNetAddr *addr, struct ECPConnection *parent, unsigned char *msg, size_t msg_size, struct ECPPktMeta *pkt_meta, struct ECP2Buffer *bufs, struct ECPConnection **_conn);
+ssize_t ecp_dir_send_upd(ECPConnection *conn);
+ssize_t ecp_dir_handle_upd(ECPConnection *conn, unsigned char *msg, size_t msg_size);
-#endif /* ECP_WITH_DIRSRV */ \ No newline at end of file
+ssize_t ecp_dir_handle_req(ECPConnection *conn, unsigned char *msg, size_t msg_size);
+
+ssize_t ecp_dir_send_rep(ECPConnection *conn);
+ssize_t ecp_dir_handle_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size);
diff --git a/ecp/src/ecp/ht.h b/ecp/src/ecp/ht.h
index 13bf1d7..cf33454 100644
--- a/ecp/src/ecp/ht.h
+++ b/ecp/src/ecp/ht.h
@@ -1,5 +1,7 @@
-void *ecp_ht_create(ECPContext *ctx);
+void *ecp_ht_create_keys(void);
+void *ecp_ht_create_addrs(void);
+
void ecp_ht_destroy(void *h);
-int ecp_ht_insert(void *h, unsigned char *k, ECPConnection *v);
-ECPConnection *ecp_ht_remove(void *h, unsigned char *k);
-ECPConnection *ecp_ht_search(void *h, unsigned char *k);
+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);
diff --git a/ecp/src/ecp/htable/htable.c b/ecp/src/ecp/htable/htable.c
index 104d2aa..bd8ab2d 100644
--- a/ecp/src/ecp/htable/htable.c
+++ b/ecp/src/ecp/htable/htable.c
@@ -1,28 +1,34 @@
+#include <stdlib.h>
+
#include <core.h>
-#include <ht.h>
#include <cr.h>
+#include <tr.h>
+#include <ht.h>
#include "hashtable.h"
-void *ecp_ht_create(ECPContext *ctx) {
- return hashtable_create(1000, (unsigned int (*)(void *))ecp_cr_dh_pub_hash_fn, (int (*)(void *, void *))ecp_cr_dh_pub_hash_eq);
+void *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) {
+ return hashtable_create(1000, (unsigned int (*)(void *))ecp_tr_addr_hash, (int (*)(void *, void *))ecp_tr_addr_eq);
}
void ecp_ht_destroy(void *h) {
hashtable_destroy(h, 0);
}
-int ecp_ht_insert(void *h, unsigned char *k, ECPConnection *v) {
+int ecp_ht_insert(void *h, void *k, ECPConnection *v) {
int rv = hashtable_insert(h, k, v);
if (!rv) return ECP_ERR;
return ECP_OK;
}
-ECPConnection *ecp_ht_remove(void *h, unsigned char *k) {
+ECPConnection *ecp_ht_remove(void *h, void *k) {
return hashtable_remove(h, k);
}
-ECPConnection *ecp_ht_search(void *h, unsigned char *k) {
+ECPConnection *ecp_ht_search(void *h, void *k) {
return hashtable_search(h, k);
}
-
diff --git a/ecp/src/ecp/msgq.c b/ecp/src/ecp/msgq.c
index 8f81d8a..8a5408b 100644
--- a/ecp/src/ecp/msgq.c
+++ b/ecp/src/ecp/msgq.c
@@ -1,12 +1,14 @@
-#include "core.h"
-
-#ifdef ECP_WITH_MSGQ
-
#include <sys/time.h>
+#include <stdlib.h>
+#include <string.h>
-#define MSG_IDX_MASK(idx) ((idx) & ((ECP_MSGQ_MAX_MSG) - 1))
+#include "core.h"
+#include "rbuf.h"
+#include "msgq.h"
-static struct timespec *abstime_ts(struct timespec *ts, ecp_cts_t msec) {
+#define MSGQ_IDX_MASK(idx) ((idx) & ((ECP_MSGQ_MAX_MSG) - 1))
+
+static struct timespec *abstime_ts(struct timespec *ts, ecp_sts_t msec) {
struct timeval tv;
uint64_t us_start;
@@ -18,16 +20,15 @@ static struct timespec *abstime_ts(struct timespec *ts, ecp_cts_t msec) {
return ts;
}
-int ecp_conn_msgq_create(ECPConnMsgQ *msgq) {
+int ecp_msgq_create(ECPRBConn *conn, ECPMsgQ *msgq) {
int i;
int rv;
- memset(msgq, 0, sizeof(ECPConnMsgQ));
+ if (conn->recv == NULL) return ECP_ERR;
- rv = pthread_mutex_init(&msgq->mutex, NULL);
- if (rv) return ECP_ERR;
+ memset(msgq, 0, sizeof(ECPMsgQ));
- for (i=0; i<ECP_MAX_MTYPE; i++) {
+ for (i=0; i<ECP_MSGQ_MAX_MTYPE; i++) {
rv = pthread_cond_init(&msgq->cond[i], NULL);
if (rv) {
int j;
@@ -35,40 +36,42 @@ int ecp_conn_msgq_create(ECPConnMsgQ *msgq) {
for (j=0; j<i; j++) {
pthread_cond_destroy(&msgq->cond[j]);
}
- pthread_mutex_destroy(&msgq->mutex);
return ECP_ERR;
}
}
+ conn->recv->msgq = msgq;
return ECP_OK;
}
-void ecp_conn_msgq_destroy(ECPConnMsgQ *msgq) {
+void ecp_msgq_destroy(ECPRBConn *conn) {
+ ECPMsgQ *msgq = conn->recv->msgq;
int i;
- for (i=0; i<ECP_MAX_MTYPE; i++) {
+ for (i=0; i<ECP_MSGQ_MAX_MTYPE; i++) {
pthread_cond_destroy(&msgq->cond[i]);
}
- pthread_mutex_destroy(&msgq->mutex);
+
+ conn->recv->msgq = NULL;
}
-int ecp_conn_msgq_start(ECPConnMsgQ *msgq, ecp_seq_t seq) {
+void ecp_msgq_start(ECPRBConn *conn, ecp_seq_t seq) {
+ ECPMsgQ *msgq = conn->recv->msgq;
+
msgq->seq_max = seq;
msgq->seq_start = seq + 1;
-
- return ECP_OK;
}
-int ecp_conn_msgq_push(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype) {
- ECPRBRecv *buf = conn->rbuf.recv;
- ECPConnMsgQ *msgq = &buf->msgq;
+int ecp_msgq_push(ECPRBConn *conn, ecp_seq_t seq, unsigned char mtype) {
+ ECPRBRecv *buf = conn->recv;
+ ECPMsgQ *msgq = buf->msgq;
- if (mtype >= ECP_MAX_MTYPE) return ECP_ERR_MAX_MTYPE;
+ if (mtype >= ECP_MSGQ_MAX_MTYPE) return ECP_ERR_MTYPE;
if ((unsigned short)(msgq->idx_w[mtype] - msgq->idx_r[mtype]) == ECP_MSGQ_MAX_MSG) return ECP_ERR_FULL;
if (msgq->idx_w[mtype] == msgq->idx_r[mtype]) pthread_cond_signal(&msgq->cond[mtype]);
- msgq->seq_msg[mtype][MSG_IDX_MASK(msgq->idx_w[mtype])] = seq;
+ msgq->seq_msg[mtype][MSGQ_IDX_MASK(msgq->idx_w[mtype])] = seq;
msgq->idx_w[mtype]++;
if (ECP_SEQ_LT(msgq->seq_max, seq)) msgq->seq_max = seq;
@@ -76,68 +79,72 @@ int ecp_conn_msgq_push(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype)
return ECP_OK;
}
-ssize_t ecp_conn_msgq_pop(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ecp_cts_t timeout) {
- ECPRBRecv *buf = conn->rbuf.recv;
- ECPConnMsgQ *msgq = &buf->msgq;
+ssize_t ecp_msgq_pop(ECPRBConn *conn, unsigned char mtype, unsigned char *msg, size_t _msg_size, ecp_sts_t timeout) {
+ ECPRBRecv *buf = conn->recv;
+ ECPMsgQ *msgq = buf->msgq;
ECPRBuffer *rbuf = &buf->rbuf;
- ecp_seq_t seq;
+ unsigned char *pld_buf;
unsigned char *msg_buf;
- unsigned char *content;
+ size_t pld_size, hdr_size, msg_size;
+ ecp_seq_t seq;
unsigned short idx;
- int _rv;
- ssize_t rv;
+ int rv;
- if (mtype >= ECP_MAX_MTYPE) return ECP_ERR_MAX_MTYPE;
+ if (mtype >= ECP_MSGQ_MAX_MTYPE) return ECP_ERR_MTYPE;
if (msgq->idx_r[mtype] == msgq->idx_w[mtype]) {
if (timeout == -1) {
- pthread_cond_wait(&msgq->cond[mtype], &msgq->mutex);
+ pthread_cond_wait(&msgq->cond[mtype], &buf->mutex);
} else {
struct timespec ts;
- _rv = pthread_cond_timedwait(&msgq->cond[mtype], &msgq->mutex, abstime_ts(&ts, timeout));
- if (_rv) return ECP_ERR_TIMEOUT;
+ rv = pthread_cond_timedwait(&msgq->cond[mtype], &buf->mutex, abstime_ts(&ts, timeout));
+ if (rv) return ECP_ERR_TIMEOUT;
}
}
- seq = msgq->seq_msg[mtype][MSG_IDX_MASK(msgq->idx_r[mtype])];
-
- _rv = _ecp_rbuf_msg_idx(rbuf, seq, &idx);
- if (_rv) return ECP_ERR;
+ seq = msgq->seq_msg[mtype][MSGQ_IDX_MASK(msgq->idx_r[mtype])];
- msg_buf = rbuf->arr.msg[idx].buf;
- rv = rbuf->arr.msg[idx].size;
-
- content = ecp_msg_get_content(msg_buf, rv);
- if (content == NULL) {
- rv = ECP_ERR;
- goto msgq_pop_fin;
- }
+ rv = _ecp_rbuf_msg_idx(rbuf, seq, &idx);
+ if (rv) return ECP_ERR;
- rv -= content - msg_buf;
- if (msg_size < rv) {
- rv = ECP_ERR_FULL;
- goto msgq_pop_fin;
- }
+ pld_buf = rbuf->arr.pld[idx].buf;
+ pld_size = rbuf->arr.pld[idx].size;
- memcpy(msg, content, rv);
+ msg_buf = ecp_pld_get_msg(pld_buf, pld_size);
+ if (msg_buf == NULL) return ECP_ERR;
+ hdr_size = msg_buf - pld_buf;
+ msg_size = pld_size - hdr_size;
- rbuf->arr.msg[idx].flags &= ~ECP_RBUF_FLAG_IN_MSGQ;
- // if (rbuf->arr.msg[idx].flags == 0);
+ rbuf->arr.pld[idx].flags &= ~ECP_RBUF_FLAG_IN_MSGQ;
+ // if (rbuf->arr.pld[idx].flags == 0);
-msgq_pop_fin:
msgq->idx_r[mtype]++;
if (msgq->seq_start == seq) {
int i;
unsigned short msg_cnt = msgq->seq_max - msgq->seq_start + 1;
for (i=0; i<msg_cnt; i++) {
- if (rbuf->arr.msg[idx].flags & ECP_RBUF_FLAG_IN_MSGQ) break;
+ if (rbuf->arr.pld[idx].flags & ECP_RBUF_FLAG_IN_MSGQ) break;
idx = ECP_RBUF_IDX_MASK(idx + 1, rbuf->arr_size);
}
msgq->seq_start += i;
}
- return rv;
+ if (_msg_size < msg_size) return ECP_ERR_FULL;
+ if (msg_size) memcpy(msg, msg_buf, msg_size);
+ return msg_size;
}
-#endif /* ECP_WITH_MSGQ */ \ No newline at end of file
+ssize_t ecp_msg_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ecp_sts_t timeout) {
+ ECPRBConn *_conn;
+ ssize_t rv;
+
+ _conn = ecp_rbuf_get_rbconn(conn);
+ if (_conn == NULL) return ECP_ERR;
+
+ pthread_mutex_lock(&_conn->recv->mutex);
+ rv = ecp_msgq_pop(_conn, mtype, msg, msg_size, timeout);
+ pthread_mutex_unlock(&_conn->recv->mutex);
+
+ return rv;
+}
diff --git a/ecp/src/ecp/msgq.h b/ecp/src/ecp/msgq.h
index 394209f..dddb6e7 100644
--- a/ecp/src/ecp/msgq.h
+++ b/ecp/src/ecp/msgq.h
@@ -1,22 +1,19 @@
-#ifdef ECP_WITH_MSGQ
-
#define ECP_MSGQ_MAX_MSG 32
-typedef struct ECPConnMsgQ {
- unsigned short idx_w[ECP_MAX_MTYPE];
- unsigned short idx_r[ECP_MAX_MTYPE];
+#define ECP_MSGQ_MAX_MTYPE (ECP_MAX_MTYPE)
+
+typedef struct ECPMsgQ {
+ unsigned short idx_w[ECP_MSGQ_MAX_MTYPE];
+ unsigned short idx_r[ECP_MSGQ_MAX_MTYPE];
ecp_seq_t seq_start;
ecp_seq_t seq_max;
- ecp_seq_t seq_msg[ECP_MAX_MTYPE][ECP_MSGQ_MAX_MSG];
- pthread_cond_t cond[ECP_MAX_MTYPE];
- pthread_mutex_t mutex;
-} ECPConnMsgQ;
-
-int ecp_conn_msgq_create(ECPConnMsgQ *msgq);
-void ecp_conn_msgq_destroy(ECPConnMsgQ *msgq);
-int ecp_conn_msgq_start(ECPConnMsgQ *msgq, ecp_seq_t seq);
-
-int ecp_conn_msgq_push(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype);
-ssize_t ecp_conn_msgq_pop(struct ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ecp_cts_t timeout);
+ ecp_seq_t seq_msg[ECP_MSGQ_MAX_MTYPE][ECP_MSGQ_MAX_MSG];
+ pthread_cond_t cond[ECP_MSGQ_MAX_MTYPE];
+} ECPMsgQ;
-#endif /* ECP_WITH_MSGQ */ \ No newline at end of file
+int ecp_msgq_create(ECPRBConn *conn, ECPMsgQ *msgq);
+void ecp_msgq_destroy(ECPRBConn *conn);
+void ecp_msgq_start(ECPRBConn *conn, ecp_seq_t seq);
+int ecp_msgq_push(ECPRBConn *conn, ecp_seq_t seq, unsigned char mtype);
+ssize_t ecp_msgq_pop(ECPRBConn *conn, unsigned char mtype, unsigned char *msg, size_t _msg_size, ecp_sts_t timeout);
+ssize_t ecp_msg_receive(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ecp_sts_t timeout); \ No newline at end of file
diff --git a/ecp/src/ecp/rbuf.c b/ecp/src/ecp/rbuf.c
index be8e9f3..d2e6e28 100644
--- a/ecp/src/ecp/rbuf.c
+++ b/ecp/src/ecp/rbuf.c
@@ -1,10 +1,20 @@
+#include <stdlib.h>
+
#include "core.h"
+#include "rbuf.h"
+
+ECPRBConn *ecp_rbuf_get_rbconn(ECPConnection *conn) {
+ if (ecp_conn_has_rbuf(conn)) return (ECPRBConn *)conn;
+ return NULL;
+}
-int _ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq) {
+ECPConnection *ecp_rbuf_get_conn(ECPRBConn *conn) {
+ return &conn->b;
+}
+
+void _ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq) {
rbuf->seq_max = seq;
rbuf->seq_start = seq + 1;
-
- return ECP_OK;
}
int _ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq, unsigned short *idx) {
@@ -13,198 +23,90 @@ int _ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq, unsigned short *idx) {
/* This also checks for seq_start <= seq if seq type range >> rbuf->arr_size */
if (seq_offset >= rbuf->arr_size) return ECP_ERR_FULL;
- *idx = ECP_RBUF_IDX_MASK(rbuf->idx_start + seq_offset, rbuf->arr_size);
+ if (idx) *idx = ECP_RBUF_IDX_MASK(rbuf->idx_start + seq_offset, rbuf->arr_size);
return ECP_OK;
}
-int ecp_rbuf_create(ECPConnection *conn, ECPRBSend *buf_s, ECPRBPacket *msg_s, unsigned int msg_s_size, ECPRBRecv *buf_r, ECPRBMessage *msg_r, unsigned int msg_r_size) {
- int rv;
+void ecp_rbuf_conn_init(ECPRBConn *conn) {
+ ECPConnection *_conn = ecp_rbuf_get_conn(conn);
- if (buf_s) {
- rv = ecp_rbuf_send_create(conn, buf_s, msg_s, msg_s_size);
- if (rv) return rv;
+ ecp_conn_set_flags(_conn, ECP_CONN_FLAG_RBUF);
+ conn->send = NULL;
+ conn->recv = NULL;
+ conn->iter = NULL;
+}
- rv = ecp_rbuf_send_start(conn);
- if (rv) {
- ecp_rbuf_send_destroy(conn);
- return rv;
- }
- }
+int ecp_rbuf_conn_create(ECPRBConn *conn, ECPSocket *sock, unsigned char type) {
+ ECPConnection *_conn = ecp_rbuf_get_conn(conn);
+ int rv;
- if (buf_r) {
- rv = ecp_rbuf_recv_create(conn, buf_r, msg_r, msg_r_size);
- if (rv) {
- if (buf_s) ecp_rbuf_send_destroy(conn);
- return rv;
- }
- }
+ rv = ecp_conn_create(_conn, sock, type);
+ if (rv) return rv;
+ ecp_rbuf_conn_init(conn);
return ECP_OK;
}
-void ecp_rbuf_destroy(ECPConnection *conn) {
- ecp_rbuf_send_destroy(conn);
- ecp_rbuf_recv_destroy(conn);
-}
-
-int ecp_rbuf_handle_seq(ECPConnection *conn, unsigned char mtype) {
- if (conn->rbuf.recv || (mtype == ECP_MTYPE_RBACK) || (mtype == ECP_MTYPE_RBFLUSH)) return 1;
- return 0;
-}
-
-int ecp_rbuf_set_seq(ECPConnection *conn, ECPSeqItem *si, unsigned char *payload, size_t pld_size) {
- ECPRBSend *buf = conn->rbuf.send;
- ECPRBuffer *rbuf = &buf->rbuf;
- unsigned char mtype;
- unsigned short idx;
+int ecp_rbuf_conn_create_inb(ECPRBConn *conn, ECPSocket *sock, unsigned char type) {
+ ECPConnection *_conn = ecp_rbuf_get_conn(conn);
int rv;
- if (si->rb_pass) return ECP_OK;
-
- buf = conn->rbuf.send;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&buf->mutex);
-#endif
- rv = _ecp_rbuf_msg_idx(rbuf, si->seq, &idx);
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&buf->mutex);
-#endif
+ rv = ecp_conn_create_inb(_conn, sock, type);
if (rv) return rv;
- rv = ecp_pld_get_type(payload, pld_size, &mtype);
- if (rv) return rv;
-
- si->rb_mtype = mtype;
- si->rb_idx = idx;
- rbuf->arr.pkt[idx].size = 0;
- rbuf->arr.pkt[idx].flags = 0;
-
+ ecp_rbuf_conn_init(conn);
return ECP_OK;
}
-ssize_t ecp_rbuf_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_seq_t seq) {
- ECPSocket *sock = conn->sock;
- ECPContext *ctx = sock->ctx;
- ECPNetAddr addr;
- ECPSeqItem seq_item;
- int _rv;
- ssize_t rv;
+void ecp_rbuf_destroy(ECPRBConn *conn) {
+ if (conn->send) ecp_rbsend_destroy(conn);
+ if (conn->recv) ecp_rbrecv_destroy(conn);
+ conn->iter = NULL;
+}
- _rv = ecp_seq_item_init(&seq_item);
- if (_rv) return _rv;
+void ecp_rbuf_start(ECPRBConn *conn) {
+ ECPConnection *_conn = ecp_rbuf_get_conn(conn);
- seq_item.seq = seq;
- seq_item.seq_w = 1;
- seq_item.rb_pass = 1;
+ if (conn->send) {
+ ecp_seq_t seq_out;
- rv = ecp_pack_conn(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, pld_size, &addr, &seq_item);
- if (rv < 0) return rv;
+ seq_out = (ecp_seq_t)(_conn->nonce_out);
+ ecp_rbsend_start(conn, seq_out);
+ }
- rv = ecp_pkt_send(sock, &addr, packet, rv, flags);
- if (rv < 0) return rv;
+ if (conn->recv) {
+ ecp_seq_t seq_in;
- return rv;
+ seq_in = (ecp_seq_t)(_conn->nonce_in);
+ ecp_rbrecv_start(conn, seq_in);
+ }
}
-ssize_t ecp_rbuf_pkt_send(ECPConnection *conn, ECPSocket *sock, ECPNetAddr *addr, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ECPSeqItem *si) {
- ECPRBSend *buf = conn->rbuf.send;
- ECPRBuffer *rbuf = &buf->rbuf;
- ecp_seq_t seq = si->seq;
- unsigned short idx = si->rb_idx;
- unsigned char mtype = si->rb_mtype & ECP_MTYPE_MASK;
- unsigned char _flags;
- int rb_rel;
- int rb_cc;
- int do_send;
- int do_skip;
- int _rv = ECP_OK;
- ssize_t rv = 0;
-
- if (pkt_size == 0) return ECP_ERR;
-
- do_send = 1;
- do_skip = ecp_rbuf_skip(mtype);
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&buf->mutex);
-#endif
-
- rb_rel = (buf->flags & ECP_RBUF_FLAG_RELIABLE);
- rb_cc = ((buf->flags & ECP_RBUF_FLAG_CCONTROL) && (buf->cnt_cc || (buf->in_transit >= buf->win_size)));
-
- if (rb_rel || rb_cc) {
- ECPRBTimer *rb_timer = NULL;
- ECPRBTimerItem *rb_ti = NULL;
-
- _flags = ECP_RBUF_FLAG_IN_RBUF;
- if (do_skip) {
- _flags |= ECP_RBUF_FLAG_SKIP;
- } else {
- do_send = 0;
- }
-
- if (rbuf->arr.pkt[idx].flags) _rv = ECP_ERR_RBUF_DUP;
-
- if (!_rv && !do_send && ti) {
- rb_timer = buf->timer;
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&rb_timer->mutex);
-#endif
-
- rb_ti = &rb_timer->item[rb_timer->idx_w];
- if (rb_ti->empty) {
- rb_ti->empty = 0;
- rb_ti->item = *ti;
- rb_timer->idx_w = (rb_timer->idx_w + 1) % ECP_MAX_TIMER;
- } else {
- _rv = ECP_ERR_MAX_TIMER;
- }
-
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&rb_timer->mutex);
-#endif
- }
-
- if (_rv) {
- rv = _rv;
- goto pkt_send_fin;
- }
-
- if (!do_send) {
- memcpy(rbuf->arr.pkt[idx].buf, packet->buffer, pkt_size);
- rbuf->arr.pkt[idx].size = pkt_size;
- rbuf->arr.pkt[idx].timer = rb_ti;
- rv = pkt_size;
- }
- rbuf->arr.pkt[idx].flags = _flags;
-
- if (ECP_SEQ_LT(rbuf->seq_max, seq)) rbuf->seq_max = seq;
-
- if (rb_cc && !do_send) {
- if (buf->cnt_cc == 0) buf->seq_cc = seq;
- buf->cnt_cc++;
- }
- }
+ssize_t ecp_rbuf_msg_handle(ECPRBConn *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) {
+ switch (mtype) {
+ case ECP_MTYPE_RBACK:
+ if (conn->send) return ecp_rbuf_handle_ack(conn, msg, msg_size);
+ break;
- if ((buf->flags & ECP_RBUF_FLAG_CCONTROL) && !do_skip && do_send) {
- buf->in_transit++;
- }
+ case ECP_MTYPE_RBNOP:
+ if (conn->recv) return ecp_rbuf_handle_nop(conn, msg, msg_size);
+ break;
-pkt_send_fin:
+ case ECP_MTYPE_RBFLUSH:
+ if (conn->recv) return ecp_rbuf_handle_flush(conn);
+ break;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&buf->mutex);
-#endif
+ default:
+ break;
+ }
- if (rv < 0) return rv;
+ return ECP_ERR_MTYPE;
+}
- if (do_send) {
- if (ti) {
- _rv = ecp_timer_push(ti);
- if (_rv) return _rv;
- }
- rv = ecp_pkt_send(sock, addr, packet, pkt_size, flags);
+int ecp_rbuf_err_handle(ECPRBConn *conn, unsigned char mtype, int err) {
+ if (conn->recv && (mtype == ECP_MTYPE_RBTIMER)) {
+ ecp_rbuf_handle_timer(conn);
+ return ECP_OK;
}
- return rv;
+ return ECP_PASS;
}
diff --git a/ecp/src/ecp/rbuf.h b/ecp/src/ecp/rbuf.h
index 31aeb39..36ff963 100644
--- a/ecp/src/ecp/rbuf.h
+++ b/ecp/src/ecp/rbuf.h
@@ -5,49 +5,36 @@
#define ECP_RBUF_FLAG_CCONTROL 0x01
#define ECP_RBUF_FLAG_RELIABLE 0x02
-#define ECP_RBUF_FLAG_MSGQ 0x04
-#define ECP_MTYPE_RBACK 0x04
-#define ECP_MTYPE_RBFLUSH 0x05
-#define ECP_MTYPE_RBTIMER 0x06
-#define ECP_MTYPE_NOP 0x07
+
+#define ECP_MTYPE_RBNOP (0x08 | ECP_MTYPE_FLAG_SYS)
+#define ECP_MTYPE_RBACK (0x09 | ECP_MTYPE_FLAG_SYS)
+#define ECP_MTYPE_RBFLUSH (0x0a | ECP_MTYPE_FLAG_SYS)
+#define ECP_MTYPE_RBTIMER (0x0b | ECP_MTYPE_FLAG_SYS)
#define ECP_ERR_RBUF_DUP -100
+#define ECP_ERR_RBUF_TIMER -101
-typedef uint32_t ecp_win_t;
+#define ecp_rbuf_skip(mtype) (mtype & ECP_MTYPE_FLAG_SYS)
/* size must be power of 2 */
#define ECP_RBUF_IDX_MASK(idx, size) ((idx) & ((size) - 1))
-#define ecp_rbuf_skip(mtype) ((mtype & ECP_MTYPE_MASK) < ECP_MTYPE_NOP ? 1 : 0)
-#ifdef ECP_WITH_MSGQ
-#include "msgq.h"
-#endif
+typedef uint32_t ecp_win_t;
-typedef struct ECPRBTimerItem {
- ECPTimerItem item;
- unsigned char empty;
-} ECPRBTimerItem;
+struct ECPMsgQ;
+struct ECPFragIter;
-typedef struct ECPRBTimer {
- ECPRBTimerItem item[ECP_MAX_TIMER];
- unsigned short idx_w;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_t mutex;
-#endif
-} ECPRBTimer;
-
-typedef struct ECPRBMessage {
- unsigned char buf[ECP_MAX_MSG];
+typedef struct ECPRBPayload {
+ unsigned char buf[ECP_MAX_PLD];
size_t size;
unsigned char flags;
-} ECPRBMessage;
+} ECPRBPayload;
typedef struct ECPRBPacket {
unsigned char buf[ECP_MAX_PKT];
size_t size;
unsigned char flags;
- ECPRBTimerItem *timer;
} ECPRBPacket;
typedef struct ECPRBuffer {
@@ -56,27 +43,31 @@ typedef struct ECPRBuffer {
unsigned short arr_size;
unsigned short idx_start;
union {
- ECPRBMessage *msg;
+ ECPRBPayload *pld;
ECPRBPacket *pkt;
} arr;
} ECPRBuffer;
typedef struct ECPRBRecv {
+ unsigned char start;
unsigned char flags;
- ecp_cts_t deliver_delay;
+ ecp_sts_t deliver_delay;
unsigned short hole_max;
unsigned short ack_rate;
unsigned short ack_pkt;
ecp_seq_t seq_ack;
ecp_ack_t ack_map;
ECPRBuffer rbuf;
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_t mutex;
+#endif
#ifdef ECP_WITH_MSGQ
- ECPConnMsgQ msgq;
+ struct ECPMsgQ *msgq;
#endif
- struct ECPFragIter *frag_iter;
} ECPRBRecv;
typedef struct ECPRBSend {
+ unsigned char start;
unsigned char flags;
ecp_win_t win_size;
ecp_win_t in_transit;
@@ -87,42 +78,46 @@ typedef struct ECPRBSend {
unsigned char flush;
unsigned int nack_rate;
ECPRBuffer rbuf;
- ECPRBTimer *timer;
#ifdef ECP_WITH_PTHREAD
pthread_mutex_t mutex;
#endif
} ECPRBSend;
-typedef struct ECPConnRBuffer {
+typedef struct ECPRBConn {
+ ECPConnection b;
ECPRBRecv *recv;
ECPRBSend *send;
-} ECPConnRBuffer;
+ struct ECPFragIter *iter;
+} ECPRBConn;
-int _ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq);
+ECPRBConn *ecp_rbuf_get_rbconn(ECPConnection *conn);
+ECPConnection *ecp_rbuf_get_conn(ECPRBConn *conn);
+void _ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq);
int _ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq, unsigned short *idx);
-
-int ecp_rbuf_create(struct ECPConnection *conn, ECPRBSend *buf_s, ECPRBPacket *msg_s, unsigned int msg_s_size, ECPRBRecv *buf_r, ECPRBMessage *msg_r, unsigned int msg_r_size);
-void ecp_rbuf_destroy(struct ECPConnection *conn);
-ssize_t ecp_rbuf_pld_send(struct ECPConnection *conn, struct ECPBuffer *packet, struct ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_seq_t seq);
-int ecp_rbuf_handle_seq(struct ECPConnection *conn, unsigned char mtype);
-int ecp_rbuf_set_seq(struct ECPConnection *conn, struct ECPSeqItem *si, unsigned char *payload, size_t pld_size);
-ssize_t ecp_rbuf_pkt_send(struct ECPConnection *conn, struct ECPSocket *sock, ECPNetAddr *addr, struct ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, struct ECPSeqItem *si);
-
-int ecp_rbuf_recv_create(struct ECPConnection *conn, ECPRBRecv *buf, ECPRBMessage *msg, unsigned short msg_size);
-void ecp_rbuf_recv_destroy(struct ECPConnection *conn);
-int ecp_rbuf_recv_start(struct ECPConnection *conn, ecp_seq_t seq);
-int ecp_rbuf_set_hole(struct ECPConnection *conn, unsigned short hole_max);
-int ecp_rbuf_set_delay(struct ECPConnection *conn, ecp_cts_t delay);
-
-ssize_t ecp_rbuf_store(struct ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b);
-struct ECPFragIter *ecp_rbuf_get_frag_iter(struct ECPConnection *conn);
-
-int ecp_rbuf_send_create(struct ECPConnection *conn, ECPRBSend *buf, ECPRBPacket *msg, unsigned short msg_size);
-void ecp_rbuf_send_destroy(struct ECPConnection *conn);
-int ecp_rbuf_send_start(struct ECPConnection *conn);
-int ecp_rbuf_flush(struct ECPConnection *conn);
-int ecp_rbuf_set_wsize(struct ECPConnection *conn, ecp_win_t size);
-
-ssize_t ecp_rbuf_handle_ack(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b);
-ssize_t ecp_rbuf_handle_flush(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b);
-ssize_t ecp_rbuf_handle_timer(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, struct ECP2Buffer *b);
+void ecp_rbuf_conn_init(ECPRBConn *conn);
+int ecp_rbuf_conn_create(ECPRBConn *conn, ECPSocket *sock, unsigned char type);
+int ecp_rbuf_conn_create_inb(ECPRBConn *conn, ECPSocket *sock, unsigned char type);
+void ecp_rbuf_destroy(ECPRBConn *conn);
+void ecp_rbuf_start(ECPRBConn *conn);
+ssize_t ecp_rbuf_msg_handle(ECPRBConn *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs);
+int ecp_rbuf_err_handle(ECPRBConn *conn, unsigned char mtype, int err);
+
+/* send */
+ssize_t ecp_rbuf_send_flush(ECPRBConn *conn);
+ssize_t ecp_rbuf_handle_ack(ECPRBConn *conn, unsigned char *msg, size_t msg_size);
+int ecp_rbsend_create(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigned short pkt_size);
+void ecp_rbsend_destroy(ECPRBConn *conn);
+void ecp_rbsend_start(ECPRBConn *conn, ecp_seq_t seq);
+int ecp_rbuf_set_wsize(ECPRBConn *conn, ecp_win_t size);
+int ecp_rbuf_flush(ECPRBConn *conn);
+ssize_t ecp_rbuf_pld_send(ECPRBConn *conn, ECPBuffer *payload, size_t pld_size, ECPBuffer *packet, size_t pkt_size, ECPTimerItem *ti);
+
+ssize_t ecp_rbuf_handle_nop(ECPRBConn *conn, unsigned char *msg, size_t msg_size);
+ssize_t ecp_rbuf_handle_flush(ECPRBConn *conn);
+void ecp_rbuf_handle_timer(ECPRBConn *conn) ;
+int ecp_rbrecv_create(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsigned short pld_size);
+void ecp_rbrecv_destroy(ECPRBConn *conn);
+void ecp_rbrecv_start(ECPRBConn *conn, ecp_seq_t seq);
+int ecp_rbuf_set_hole(ECPRBConn *conn, unsigned short hole_max);
+int ecp_rbuf_set_delay(ECPRBConn *conn, ecp_sts_t delay);
+ssize_t ecp_rbuf_store(ECPRBConn *conn, ecp_seq_t seq, unsigned char *pld, size_t pld_size);
diff --git a/ecp/src/ecp/rbuf_recv.c b/ecp/src/ecp/rbuf_recv.c
index a3f2345..1d50494 100644
--- a/ecp/src/ecp/rbuf_recv.c
+++ b/ecp/src/ecp/rbuf_recv.c
@@ -1,12 +1,21 @@
+#include <stdlib.h>
+#include <string.h>
+
#include "core.h"
-#include "tr.h"
#include "tm.h"
+#include "rbuf.h"
+
+#ifdef ECP_WITH_MSGQ
+#include "msgq.h"
+#endif
+
#define ACK_RATE 8
#define ACK_MASK_FIRST ((ecp_ack_t)1 << (ECP_SIZE_ACKB - 1))
-static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, unsigned char mtype) {
- ECPRBRecv *buf = conn->rbuf.recv;
+static ssize_t msg_store(ECPRBConn *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *pld, size_t pld_size) {
+ ECPConnection *_conn = ecp_rbuf_get_conn(conn);
+ ECPRBRecv *buf = conn->recv;
ECPRBuffer *rbuf = &buf->rbuf;
unsigned short idx;
unsigned char flags;
@@ -16,18 +25,22 @@ static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg,
rv = _ecp_rbuf_msg_idx(rbuf, seq, &idx);
if (rv) return rv;
- if (rbuf->arr.msg[idx].flags) return ECP_ERR_RBUF_DUP;
+ if (rbuf->arr.pld[idx].flags) return ECP_ERR_RBUF_DUP;
#ifdef ECP_WITH_MSGQ
- if (buf->flags & ECP_RBUF_FLAG_MSGQ) {
+ if (buf->msgq) {
ecp_seq_t seq_offset;
- pthread_mutex_lock(&buf->msgq.mutex);
+#ifndef ECP_WITH_RTHD
+ pthread_mutex_lock(&buf->mutex);
+#endif
- seq_offset = seq - buf->msgq.seq_start;
+ seq_offset = seq - buf->msgq->seq_start;
if (seq_offset >= rbuf->arr_size) rv = ECP_ERR_FULL;
- pthread_mutex_unlock(&buf->msgq.mutex);
+#ifndef ECP_WITH_RTHD
+ pthread_mutex_unlock(&buf->mutex);
+#endif
if (rv) return rv;
}
@@ -36,75 +49,80 @@ static ssize_t msg_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg,
skip = ecp_rbuf_skip(mtype);
flags = ECP_RBUF_FLAG_IN_RBUF;
if (skip) flags |= ECP_RBUF_FLAG_SKIP;
- rbuf->arr.msg[idx].flags = flags;
+ rbuf->arr.pld[idx].flags = flags;
- if (skip) return 0;
+ if ((mtype == ECP_MTYPE_RBNOP) && pld) {
+ return ecp_pld_handle_one(_conn, seq, pld, pld_size, NULL);
+ } else if (skip) {
+ return 0;
+ }
- memcpy(rbuf->arr.msg[idx].buf, msg, msg_size);
- rbuf->arr.msg[idx].size = msg_size;
+ if (pld && pld_size) memcpy(rbuf->arr.pld[idx].buf, pld, pld_size);
+ rbuf->arr.pld[idx].size = pld_size;
if (ECP_SEQ_LT(rbuf->seq_max, seq)) rbuf->seq_max = seq;
- return msg_size;
+ return pld_size;
}
-static void msg_flush(ECPConnection *conn, ECP2Buffer *b) {
- ECPRBRecv *buf = conn->rbuf.recv;
+static void msg_flush(ECPRBConn *conn) {
+ ECPConnection *_conn = ecp_rbuf_get_conn(conn);
+ ECPRBRecv *buf = conn->recv;
ECPRBuffer *rbuf = &buf->rbuf;
ecp_seq_t seq;
unsigned short idx;
int i;
#ifdef ECP_WITH_MSGQ
- if (buf->flags & ECP_RBUF_FLAG_MSGQ) pthread_mutex_lock(&buf->msgq.mutex);
+#ifndef ECP_WITH_RTHD
+ if (buf->msgq) pthread_mutex_lock(&buf->mutex);
+#endif
#endif
seq = rbuf->seq_start;
idx = rbuf->idx_start;
- unsigned short msg_cnt = rbuf->seq_max - rbuf->seq_start + 1;
-
while (ECP_SEQ_LTE(seq, rbuf->seq_max)) {
- if (rbuf->arr.msg[idx].flags & ECP_RBUF_FLAG_IN_RBUF) {
- if (!(rbuf->arr.msg[idx].flags & ECP_RBUF_FLAG_SKIP)) {
+ if (rbuf->arr.pld[idx].flags & ECP_RBUF_FLAG_IN_RBUF) {
+ if (!(rbuf->arr.pld[idx].flags & ECP_RBUF_FLAG_SKIP)) {
ecp_pts_t msg_pts;
int rv;
- rv = ecp_msg_get_pts(rbuf->arr.msg[idx].buf, rbuf->arr.msg[idx].size, &msg_pts);
+ rv = ecp_pld_get_pts(rbuf->arr.pld[idx].buf, rbuf->arr.pld[idx].size, &msg_pts);
if (!rv && buf->deliver_delay) {
- ecp_cts_t now = ecp_tm_abstime_ms(0);
+ ecp_sts_t now = ecp_tm_abstime_ms(0);
msg_pts += buf->deliver_delay;
if (ECP_PTS_LT(now, msg_pts)) {
- if (!(rbuf->arr.msg[idx].flags & ECP_RBUF_FLAG_IN_TIMER)) {
+ if (!(rbuf->arr.pld[idx].flags & ECP_RBUF_FLAG_IN_TIMER)) {
ECPTimerItem ti;
- rv = ecp_timer_item_init(&ti, conn, ECP_MTYPE_RBTIMER, 0, msg_pts - now);
- if (!rv) rv = ecp_timer_push(&ti);
- if (!rv) rbuf->arr.msg[idx].flags |= ECP_RBUF_FLAG_IN_TIMER;
+ ecp_timer_item_init(&ti, _conn, ECP_MTYPE_RBTIMER, NULL, 0, msg_pts - now);
+ rv = ecp_timer_push(&ti);
+ if (!rv) rbuf->arr.pld[idx].flags |= ECP_RBUF_FLAG_IN_TIMER;
}
break;
- } else if (rbuf->arr.msg[idx].flags & ECP_RBUF_FLAG_IN_TIMER) {
- rbuf->arr.msg[idx].flags &= ~ECP_RBUF_FLAG_IN_TIMER;
+ } else if (rbuf->arr.pld[idx].flags & ECP_RBUF_FLAG_IN_TIMER) {
+ rbuf->arr.pld[idx].flags &= ~ECP_RBUF_FLAG_IN_TIMER;
}
}
#ifdef ECP_WITH_MSGQ
- if (buf->flags & ECP_RBUF_FLAG_MSGQ) {
+ if (buf->msgq) {
unsigned char mtype;
- rv = ecp_msg_get_type(rbuf->arr.msg[idx].buf, rbuf->arr.msg[idx].size, &mtype);
- if (!rv) rv = ecp_conn_msgq_push(conn, seq, mtype & ECP_MTYPE_MASK);
+ rv = ecp_pld_get_type(rbuf->arr.pld[idx].buf, rbuf->arr.pld[idx].size, &mtype);
+ if (!rv) rv = ecp_msgq_push(conn, seq, mtype & ECP_MTYPE_MASK);
if (rv) break;
- rbuf->arr.msg[idx].flags |= ECP_RBUF_FLAG_IN_MSGQ;
+ rbuf->arr.pld[idx].flags |= ECP_RBUF_FLAG_IN_MSGQ;
} else
#endif
- ecp_conn_handle_msg(conn, seq, rbuf->arr.msg[idx].buf, rbuf->arr.msg[idx].size, b);
+ ecp_pld_handle(_conn, seq, rbuf->arr.pld[idx].buf, rbuf->arr.pld[idx].size, NULL);
} else {
- rbuf->arr.msg[idx].flags &= ~ECP_RBUF_FLAG_SKIP;
+ rbuf->arr.pld[idx].flags &= ~ECP_RBUF_FLAG_SKIP;
}
- rbuf->arr.msg[idx].flags &= ~ECP_RBUF_FLAG_IN_RBUF;
- // if (rbuf->arr.msg[idx].flags == 0);
+ rbuf->arr.pld[idx].flags &= ~ECP_RBUF_FLAG_IN_RBUF;
+ // if (rbuf->arr.pld[idx].flags == 0);
} else {
if (buf->flags & ECP_RBUF_FLAG_RELIABLE) break;
if (!ECP_SEQ_LT(seq, rbuf->seq_max - buf->hole_max)) break;
@@ -116,45 +134,14 @@ static void msg_flush(ECPConnection *conn, ECP2Buffer *b) {
rbuf->idx_start = idx;
#ifdef ECP_WITH_MSGQ
- if (buf->flags & ECP_RBUF_FLAG_MSGQ) pthread_mutex_unlock(&buf->msgq.mutex);
+#ifndef ECP_WITH_RTHD
+ if (buf->msgq) pthread_mutex_unlock(&buf->mutex);
+#endif
#endif
-
-}
-
-static int ack_send(ECPConnection *conn, ecp_seq_t seq_ack, ecp_seq_t ack_map) {
- ECPRBRecv *buf = conn->rbuf.recv;
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK, conn)];
- unsigned char *_buf;
- ssize_t rv;
-
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK, conn);
-
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_RBACK);
- _buf = ecp_pld_get_buf(payload.buffer, payload.size);
- _buf[0] = (seq_ack & 0xFF000000) >> 24;
- _buf[1] = (seq_ack & 0x00FF0000) >> 16;
- _buf[2] = (seq_ack & 0x0000FF00) >> 8;
- _buf[3] = (seq_ack & 0x000000FF);
- _buf[4] = (ack_map & 0xFF000000) >> 24;
- _buf[5] = (ack_map & 0x00FF0000) >> 16;
- _buf[6] = (ack_map & 0x0000FF00) >> 8;
- _buf[7] = (ack_map & 0x000000FF);
-
- rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK), 0);
- if (rv < 0) return rv;
-
- buf->ack_pkt = 0;
-
- return ECP_OK;
}
-static int ack_shift(ECPRBRecv *buf) {
+static int ack_shift(ECPRBConn *conn) {
+ ECPRBRecv *buf = conn->recv;
ECPRBuffer *rbuf = &buf->rbuf;
unsigned short idx;
int do_ack = 0;
@@ -168,7 +155,7 @@ static int ack_shift(ECPRBRecv *buf) {
buf->seq_ack++;
rv = _ecp_rbuf_msg_idx(rbuf, buf->seq_ack, &idx);
if (!rv) {
- in_rbuf = rbuf->arr.msg[idx].flags & ECP_RBUF_FLAG_IN_RBUF;
+ in_rbuf = rbuf->arr.pld[idx].flags & ECP_RBUF_FLAG_IN_RBUF;
} else {
in_rbuf = 1;
}
@@ -190,100 +177,194 @@ static int ack_shift(ECPRBRecv *buf) {
return do_ack;
}
-ssize_t ecp_rbuf_handle_flush(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- ECPRBRecv *buf = conn->rbuf.recv;
+static int ack_send(ECPRBConn *conn, ecp_seq_t seq_ack, ecp_seq_t ack_map) {
+ ECPConnection *_conn = ecp_rbuf_get_conn(conn);
+ ECPRBRecv *buf = conn->recv;
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK, _conn)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK, _conn)];
+ unsigned char *_buf;
+ ssize_t rv;
+
+ packet.buffer = pkt_buf;
+ packet.size = sizeof(pkt_buf);
+ payload.buffer = pld_buf;
+ payload.size = sizeof(pld_buf);
+
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_RBACK);
+ _buf = ecp_pld_get_msg(payload.buffer, payload.size);
+ _buf[0] = seq_ack >> 24;
+ _buf[1] = seq_ack >> 16;
+ _buf[2] = seq_ack >> 8;
+ _buf[3] = seq_ack;
+ _buf[4] = ack_map >> 24;
+ _buf[5] = ack_map >> 16;
+ _buf[6] = ack_map >> 8;
+ _buf[7] = ack_map;
+
+ rv = ecp_pld_send(_conn, &packet, &payload, ECP_SIZE_PLD(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBACK), 0);
+ if (rv < 0) return rv;
+
+ buf->ack_pkt = 0;
+
+ return ECP_OK;
+}
+
+ssize_t ecp_rbuf_handle_nop(ECPRBConn *conn, unsigned char *msg, size_t msg_size) {
+ ECPRBRecv *buf = conn->recv;
+ ECPRBuffer *rbuf = &buf->rbuf;
+ ecp_seq_t seq_ack;
+ ecp_ack_t ack_map;
+ ecp_ack_t ack_mask = (ecp_ack_t)1 << (ECP_SIZE_ACKB - 1);
+ size_t rsize = sizeof(ecp_seq_t) + sizeof(ecp_ack_t);
+ int i;
- if (buf == NULL) return ECP_ERR;
- if (size < 0) return size;
+ if (msg_size < rsize) return ECP_ERR_SIZE;
+
+ seq_ack = \
+ ((ecp_seq_t)msg[0] << 24) | \
+ ((ecp_seq_t)msg[1] << 16) | \
+ ((ecp_seq_t)msg[2] << 8) | \
+ ((ecp_seq_t)msg[3]);
+ ack_map = \
+ ((ecp_ack_t)msg[4] << 24) | \
+ ((ecp_ack_t)msg[5] << 16) | \
+ ((ecp_ack_t)msg[6] << 8) | \
+ ((ecp_ack_t)msg[7]);
+
+ seq_ack -= (ECP_SIZE_ACKB - 1);
+ for (i=0; i<ECP_SIZE_ACKB; i++) {
+ if (ack_map & ack_mask) {
+ msg_store(conn, seq_ack, ECP_MTYPE_RBNOP, NULL, 0);
+ }
+ seq_ack++;
+ ack_mask = ack_mask >> 1;
+ }
+
+ return rsize;
+}
+
+ssize_t ecp_rbuf_handle_flush(ECPRBConn *conn) {
+ ECPRBRecv *buf = conn->recv;
+
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_lock(&buf->mutex);
+#endif
- ecp_tr_release(b->packet, 1);
ack_send(conn, buf->seq_ack, buf->ack_map);
+
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_unlock(&buf->mutex);
+#endif
+
return 0;
}
-ssize_t ecp_rbuf_handle_timer(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- ECPRBRecv *buf = conn->rbuf.recv;
+void ecp_rbuf_handle_timer(ECPRBConn *conn) {
+ ECPRBRecv *buf = conn->recv;
+
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_lock(&buf->mutex);
+#endif
- if (buf == NULL) return ECP_ERR;
+ msg_flush(conn);
- msg_flush(conn, b);
- return 0;
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_unlock(&buf->mutex);
+#endif
}
-int ecp_rbuf_recv_create(ECPConnection *conn, ECPRBRecv *buf, ECPRBMessage *msg, unsigned short msg_size) {
+int ecp_rbrecv_create(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsigned short pld_size) {
ECPRBuffer *rbuf = &buf->rbuf;
int rv;
- if (msg == NULL) return ECP_ERR;
-
memset(buf, 0, sizeof(ECPRBRecv));
- memset(msg, 0, sizeof(ECPRBMessage) * msg_size);
+ memset(pld, 0, sizeof(ECPRBPayload) * pld_size);
buf->ack_map = ECP_ACK_FULL;
buf->ack_rate = ACK_RATE;
- rbuf->arr.msg = msg;
- rbuf->arr_size = msg_size;
+ rbuf->arr.pld = pld;
+ rbuf->arr_size = pld_size;
-#ifdef ECP_WITH_MSGQ
- rv = ecp_conn_msgq_create(&buf->msgq);
- if (rv) return rv;
+#ifdef ECP_WITH_PTHREAD
+ rv = pthread_mutex_init(&buf->mutex, NULL);
+ if (rv) return ECP_ERR;
#endif
- conn->rbuf.recv = buf;
+ conn->recv = buf;
return ECP_OK;
}
-void ecp_rbuf_recv_destroy(ECPConnection *conn) {
- ECPRBRecv *buf = conn->rbuf.recv;
+void ecp_rbrecv_destroy(ECPRBConn *conn) {
+ ECPRBRecv *buf = conn->recv;
- if (buf == NULL) return;
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_destroy(&buf->mutex);
+#endif
#ifdef ECP_WITH_MSGQ
- ecp_conn_msgq_destroy(&buf->msgq);
+ if (buf->msgq) ecp_msgq_destroy(conn);
#endif
- conn->rbuf.recv = NULL;
+
+ conn->recv = NULL;
}
-int ecp_rbuf_recv_start(ECPConnection *conn, ecp_seq_t seq) {
- ECPRBRecv *buf = conn->rbuf.recv;
+void ecp_rbrecv_start(ECPRBConn *conn, ecp_seq_t seq) {
+ ECPRBRecv *buf = conn->recv;
ECPRBuffer *rbuf = &buf->rbuf;
- int rv;
- if (buf == NULL) return ECP_ERR;
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_lock(&buf->mutex);
+#endif
- seq--;
+ buf->start = 1;
buf->seq_ack = seq;
- rv = _ecp_rbuf_start(rbuf, seq);
- if (rv) return rv;
+ _ecp_rbuf_start(rbuf, seq);
#ifdef ECP_WITH_MSGQ
- if (buf->flags & ECP_RBUF_FLAG_MSGQ) {
- rv = ecp_conn_msgq_start(&buf->msgq, seq);
- if (rv) return rv;
- }
+ if (buf->msgq) ecp_msgq_start(conn, seq);
#endif
- return ECP_OK;
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_unlock(&buf->mutex);
+#endif
}
-int ecp_rbuf_set_hole(ECPConnection *conn, unsigned short hole_max) {
- ECPRBRecv *buf = conn->rbuf.recv;
+int ecp_rbuf_set_hole(ECPRBConn *conn, unsigned short hole_max) {
+ ECPRBRecv *buf = conn->recv;
+
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_lock(&buf->mutex);
+#endif
buf->hole_max = hole_max;
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_unlock(&buf->mutex);
+#endif
+
return ECP_OK;
}
-int ecp_rbuf_set_delay(ECPConnection *conn, ecp_cts_t delay) {
- ECPRBRecv *buf = conn->rbuf.recv;
+int ecp_rbuf_set_delay(ECPRBConn *conn, ecp_sts_t delay) {
+ ECPRBRecv *buf = conn->recv;
+
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_lock(&buf->mutex);
+#endif
buf->deliver_delay = delay;
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_unlock(&buf->mutex);
+#endif
+
return ECP_OK;
}
-ssize_t ecp_rbuf_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
- ECPRBRecv *buf = conn->rbuf.recv;
+ssize_t ecp_rbuf_store(ECPRBConn *conn, ecp_seq_t seq, unsigned char *pld, size_t pld_size) {
+ ECPRBRecv *buf = conn->recv;
ECPRBuffer *rbuf = &buf->rbuf;
unsigned char mtype;
unsigned short ack_pkt = 0;
@@ -291,9 +372,18 @@ ssize_t ecp_rbuf_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, s
int _rv;
ssize_t rv;
- _rv = ecp_msg_get_type(msg, msg_size, &mtype);
+ _rv = ecp_pld_get_type(pld, pld_size, &mtype);
if (_rv) return _rv;
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_lock(&buf->mutex);
+#endif
+
+ if (!buf->start) {
+ rv = 0;
+ goto rbuf_store_fin;
+ }
+
if (ECP_SEQ_LT(rbuf->seq_max, seq)) {
ack_pkt = seq - rbuf->seq_max;
}
@@ -302,42 +392,51 @@ ssize_t ecp_rbuf_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, s
if (seq_offset < ECP_SIZE_ACKB) {
ecp_ack_t ack_bit = ((ecp_ack_t)1 << seq_offset);
- if (ack_bit & buf->ack_map) return ECP_ERR_RBUF_DUP;
+ if (ack_bit & buf->ack_map) {
+ rv = ECP_ERR_RBUF_DUP;
+ goto rbuf_store_fin;
+ }
- rv = msg_store(conn, seq, msg, msg_size, mtype);
- if (rv < 0) return rv;
+ rv = msg_store(conn, seq, mtype, pld, pld_size);
+ if (rv < 0) goto rbuf_store_fin;
buf->ack_map |= ack_bit;
/* reliable transport can prevent seq_ack from reaching seq_max */
if (ECP_SEQ_LT(buf->seq_ack, rbuf->seq_max)) {
- do_ack = ack_shift(buf);
+ do_ack = ack_shift(conn);
}
} else {
- return ECP_ERR_RBUF_DUP;
+ rv = ECP_ERR_RBUF_DUP;
+ goto rbuf_store_fin;
}
} else {
unsigned short msg_cnt = rbuf->seq_max - rbuf->seq_start + 1;
if ((msg_cnt == 0) && (seq == (ecp_seq_t)(buf->seq_ack + 1))) {
- if ((buf->flags & ECP_RBUF_FLAG_MSGQ) || buf->deliver_delay) {
- rv = msg_store(conn, seq, msg, msg_size, mtype);
- if (rv < 0) return rv;
- } else {
+ int deliver = 1;
+#ifdef ECP_WITH_MSGQ
+ if (buf->msgq) deliver = 0;
+#endif
+ if (buf->deliver_delay) deliver = 0;
+ if (deliver) {
/* receive buffer is empty, so no need for msgq mutex lock */
rv = 0;
rbuf->seq_max++;
rbuf->seq_start++;
rbuf->idx_start = ECP_RBUF_IDX_MASK(rbuf->idx_start + 1, rbuf->arr_size);
+ } else {
+ rv = msg_store(conn, seq, mtype, pld, pld_size);
+ if (rv < 0) goto rbuf_store_fin;
}
buf->seq_ack++;
} else {
- rv = msg_store(conn, seq, msg, msg_size, mtype);
- if (rv < 0) return rv;
+ rv = msg_store(conn, seq, mtype, pld, pld_size);
+ if (rv < 0) goto rbuf_store_fin;
- do_ack = ack_shift(buf);
+ do_ack = ack_shift(conn);
}
}
- msg_flush(conn, b);
+ msg_flush(conn);
if (ack_pkt) {
buf->ack_pkt += ack_pkt;
if (!do_ack && (buf->ack_pkt > buf->ack_rate)) do_ack = 1;
@@ -358,13 +457,17 @@ ssize_t ecp_rbuf_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *msg, s
}
}
_rv = ack_send(conn, seq_ack, ack_map);
- if (_rv) return _rv;
+ if (_rv) {
+ rv = _rv;
+ goto rbuf_store_fin;
+ }
}
- return rv;
-}
+rbuf_store_fin:
-ECPFragIter *ecp_rbuf_get_frag_iter(ECPConnection *conn) {
- if (conn->rbuf.recv) return conn->rbuf.recv->frag_iter;
- return NULL;
+#ifdef ECP_WITH_RTHD
+ pthread_mutex_unlock(&buf->mutex);
+#endif
+
+ return rv;
}
diff --git a/ecp/src/ecp/rbuf_send.c b/ecp/src/ecp/rbuf_send.c
index 9f29010..4a7cb2c 100644
--- a/ecp/src/ecp/rbuf_send.c
+++ b/ecp/src/ecp/rbuf_send.c
@@ -1,39 +1,17 @@
+#include <stdlib.h>
+#include <string.h>
+
#include "core.h"
-#include "tr.h"
+#include "rbuf.h"
#define NACK_RATE_UNIT 10000
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
-static ssize_t flush_send(ECPConnection *conn, ECPTimerItem *ti) {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_RBFLUSH, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_RBFLUSH, conn)];
-
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_RBFLUSH, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_RBFLUSH, conn);
-
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_RBFLUSH);
- if (ti == NULL) {
- ECPTimerItem _ti;
- int rv;
-
- rv = ecp_timer_item_init(&_ti, conn, ECP_MTYPE_RBACK, 3, 500);
- if (rv) return rv;
-
- _ti.retry = flush_send;
- rv = ecp_timer_push(&_ti);
- if (rv) return rv;
- }
- return ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_RBFLUSH), 0);
-}
-
-static void cc_flush(ECPConnection *conn, unsigned char flags) {
- ECPRBSend *buf = conn->rbuf.send;
+static void cc_flush(ECPRBConn *conn, unsigned char flags) {
+ ECPConnection *_conn = ecp_rbuf_get_conn(conn);
+ ECPRBSend *buf = conn->send;
ECPRBuffer *rbuf = &buf->rbuf;
unsigned short idx;
int rv;
@@ -42,7 +20,6 @@ static void cc_flush(ECPConnection *conn, unsigned char flags) {
if (rv) return;
while (ECP_SEQ_LTE(buf->seq_cc, rbuf->seq_max)) {
- ECPRBTimerItem *ti;
ECPBuffer packet;
if ((buf->cnt_cc == 0) || (buf->in_transit >= buf->win_size)) break;
@@ -52,26 +29,14 @@ static void cc_flush(ECPConnection *conn, unsigned char flags) {
pthread_mutex_unlock(&buf->mutex);
#endif
- ti = rbuf->arr.pkt[idx].timer;
- if (ti) ecp_timer_push(&ti->item);
packet.buffer = rbuf->arr.pkt[idx].buf;
packet.size = ECP_MAX_PKT;
- ecp_pkt_send(conn->sock, &conn->node.addr, &packet, rbuf->arr.pkt[idx].size, flags);
+ ecp_pkt_send(_conn->sock, &packet, rbuf->arr.pkt[idx].size, flags, NULL, &_conn->remote.addr);
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&buf->mutex);
#endif
- if (ti) {
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&buf->timer->mutex);
-#endif
- ti->empty = 1;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&buf->timer->mutex);
-#endif
- }
-
buf->cnt_cc--;
buf->in_transit++;
}
@@ -88,39 +53,55 @@ static void cc_flush(ECPConnection *conn, unsigned char flags) {
}
}
-ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- ECPRBSend *buf;
- ECPRBuffer *rbuf;
- ssize_t rsize = sizeof(ecp_seq_t)+sizeof(ecp_ack_t);
- ecp_seq_t seq_ack = 0;
- ecp_ack_t ack_map = 0;
+static ssize_t _rbuf_send_flush(ECPConnection *_conn, ECPTimerItem *ti) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_RBFLUSH, _conn)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_RBFLUSH, _conn)];
+
+ packet.buffer = pkt_buf;
+ packet.size = sizeof(pkt_buf);
+ payload.buffer = pld_buf;
+ payload.size = sizeof(pld_buf);
+
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_RBFLUSH);
+
+ return ecp_pld_send_wtimer(_conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_RBFLUSH), 0, ti);
+}
+
+ssize_t ecp_rbuf_send_flush(ECPRBConn *conn) {
+ ECPConnection *_conn = ecp_rbuf_get_conn(conn);
+
+ return ecp_timer_send(_conn, _rbuf_send_flush, ECP_MTYPE_RBACK, 3, 500);
+}
+
+ssize_t ecp_rbuf_handle_ack(ECPRBConn *conn, unsigned char *msg, size_t msg_size) {
+ ECPConnection *_conn = ecp_rbuf_get_conn(conn);
+ ECPRBSend *buf = conn->send;
+ ECPRBuffer *rbuf = &buf->rbuf;
+ ssize_t rsize = sizeof(ecp_seq_t) + sizeof(ecp_ack_t);
ecp_seq_t seq_start;
ecp_seq_t seq_max;
+ ecp_seq_t seq_ack;
+ ecp_ack_t ack_map;
unsigned short idx;
unsigned short msg_cnt;
int do_flush = 0;
int i;
int rv;
- buf = conn->rbuf.send;
- if (buf == NULL) return size;
-
- rbuf = &buf->rbuf;
- if (size < 0) return size;
- if (size < rsize) return ECP_ERR;
+ if (msg_size < rsize) return ECP_ERR_SIZE;
seq_ack = \
- (msg[0] << 24) | \
- (msg[1] << 16) | \
- (msg[2] << 8) | \
- (msg[3]);
+ ((ecp_seq_t)msg[0] << 24) | \
+ ((ecp_seq_t)msg[1] << 16) | \
+ ((ecp_seq_t)msg[2] << 8) | \
+ ((ecp_seq_t)msg[3]);
ack_map = \
- (msg[4] << 24) | \
- (msg[5] << 16) | \
- (msg[6] << 8) | \
- (msg[7]);
-
- ecp_tr_release(b->packet, 1);
+ ((ecp_ack_t)msg[4] << 24) | \
+ ((ecp_ack_t)msg[5] << 16) | \
+ ((ecp_ack_t)msg[6] << 8) | \
+ ((ecp_ack_t)msg[7]);
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&buf->mutex);
@@ -130,7 +111,7 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt
if (ECP_SEQ_LT(seq_max, seq_ack)) return ECP_ERR;
if (buf->flags & ECP_RBUF_FLAG_RELIABLE) {
- rv = _ecp_rbuf_msg_idx(rbuf, seq_ack, &idx);
+ rv = _ecp_rbuf_msg_idx(rbuf, seq_ack, NULL);
if (rv) goto handle_ack_fin;
}
@@ -140,6 +121,7 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt
if (ack_map != ECP_ACK_FULL) {
ecp_ack_t ack_mask = (ecp_ack_t)1 << (ECP_SIZE_ACKB - 1);
+ ecp_ack_t ack_map_nop = 0;
unsigned short nack_cnt = 0;
int nack_first = 0;
@@ -162,24 +144,13 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt
if (buf->flags & ECP_RBUF_FLAG_RELIABLE) {
if (!(rbuf->arr.pkt[idx].flags & ECP_RBUF_FLAG_IN_RBUF) || (rbuf->arr.pkt[idx].flags & ECP_RBUF_FLAG_SKIP)) {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_NOP, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_NOP, conn)];
-
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_NOP, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_NOP, conn);
-
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_NOP);
- ecp_rbuf_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_NOP), ECP_SEND_FLAG_MORE, seq_ack);
+ ack_map_nop |= ack_mask;
} else {
ECPBuffer packet;
packet.buffer = rbuf->arr.pkt[idx].buf;
packet.size = ECP_MAX_PKT;
- ecp_pkt_send(conn->sock, &conn->node.addr, &packet, rbuf->arr.pkt[idx].size, ECP_SEND_FLAG_MORE);
+ ecp_pkt_send(_conn->sock, &packet, rbuf->arr.pkt[idx].size, ECP_SEND_FLAG_MORE, NULL, &_conn->remote.addr);
if (buf->flags & ECP_RBUF_FLAG_CCONTROL) {
buf->in_transit++;
}
@@ -195,6 +166,34 @@ ssize_t ecp_rbuf_handle_ack(ECPConnection *conn, ecp_seq_t seq, unsigned char mt
if (buf->flags & ECP_RBUF_FLAG_RELIABLE) idx = ECP_RBUF_IDX_MASK(idx + 1, rbuf->arr_size);
}
+ if ((buf->flags & ECP_RBUF_FLAG_RELIABLE) && ack_map_nop) {
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBNOP, _conn)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBNOP, _conn)];
+ unsigned char *_buf;
+
+ packet.buffer = pkt_buf;
+ packet.size = sizeof(pkt_buf);
+ payload.buffer = pld_buf;
+ payload.size = sizeof(pld_buf);
+
+ ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_RBNOP);
+ _buf = ecp_pld_get_msg(payload.buffer, payload.size);
+
+ seq_ack--;
+ _buf[0] = seq_ack >> 24;
+ _buf[1] = seq_ack >> 16;
+ _buf[2] = seq_ack >> 8;
+ _buf[3] = seq_ack;
+ _buf[4] = ack_map_nop >> 24;
+ _buf[5] = ack_map_nop >> 16;
+ _buf[6] = ack_map_nop >> 8;
+ _buf[7] = ack_map_nop;
+
+ ecp_pld_send(_conn, &packet, &payload, ECP_SIZE_PLD(sizeof(ecp_seq_t) + sizeof(ecp_ack_t), ECP_MTYPE_RBNOP), ECP_SEND_FLAG_MORE);
+ }
+
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&buf->mutex);
#endif
@@ -231,24 +230,18 @@ handle_ack_fin:
if (!rv && do_flush) {
ssize_t _rv;
- _rv = flush_send(conn, NULL);
+ _rv = ecp_rbuf_send_flush(conn);
if (_rv < 0) rv = _rv;
- } else {
- // ecp_tr_nomore();
}
- ecp_tr_release(b->packet, 0);
-
if (rv) return rv;
return rsize;
}
-int ecp_rbuf_send_create(ECPConnection *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigned short pkt_size) {
+int ecp_rbsend_create(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigned short pkt_size) {
ECPRBuffer *rbuf = &buf->rbuf;
int rv;
- if (pkt == NULL) return ECP_ERR;
-
memset(buf, 0, sizeof(ECPRBRecv));
memset(pkt, 0, sizeof(ECPRBPacket) * pkt_size);
@@ -260,36 +253,39 @@ int ecp_rbuf_send_create(ECPConnection *conn, ECPRBSend *buf, ECPRBPacket *pkt,
if (rv) return ECP_ERR;
#endif
- conn->rbuf.send = buf;
+ conn->send = buf;
return ECP_OK;
}
-void ecp_rbuf_send_destroy(ECPConnection *conn) {
- ECPRBSend *buf = conn->rbuf.send;
-
- if (buf == NULL) return;
+void ecp_rbsend_destroy(ECPRBConn *conn) {
+ ECPRBSend *buf = conn->send;
#ifdef ECP_WITH_PTHREAD
pthread_mutex_destroy(&buf->mutex);
#endif
- conn->rbuf.send = NULL;
+ conn->send = NULL;
}
-int ecp_rbuf_send_start(ECPConnection *conn) {
- ECPRBSend *buf = conn->rbuf.send;
+void ecp_rbsend_start(ECPRBConn *conn, ecp_seq_t seq) {
+ ECPRBSend *buf = conn->send;
ECPRBuffer *rbuf = &buf->rbuf;
- if (buf == NULL) return ECP_ERR;
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&buf->mutex);
+#endif
- buf->seq_nack = conn->seq_out;
- return _ecp_rbuf_start(rbuf, conn->seq_out);
-}
+ buf->start = 1;
+ buf->seq_nack = seq;
+ _ecp_rbuf_start(rbuf, seq);
-int ecp_rbuf_set_wsize(ECPConnection *conn, ecp_win_t size) {
- ECPRBSend *buf = conn->rbuf.send;
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&buf->mutex);
+#endif
+}
- if (buf == NULL) return ECP_ERR;
+int ecp_rbuf_set_wsize(ECPRBConn *conn, ecp_win_t size) {
+ ECPRBSend *buf = conn->send;
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&buf->mutex);
@@ -305,19 +301,18 @@ int ecp_rbuf_set_wsize(ECPConnection *conn, ecp_win_t size) {
return ECP_OK;
}
-int ecp_rbuf_flush(ECPConnection *conn) {
- ECPRBSend *buf = conn->rbuf.send;
+int ecp_rbuf_flush(ECPRBConn *conn) {
+ ECPConnection *_conn = ecp_rbuf_get_conn(conn);
+ ECPRBSend *buf = conn->send;
ecp_seq_t seq;
ssize_t rv;
- if (buf == NULL) return ECP_ERR;
-
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&conn->mutex);
+ pthread_mutex_lock(&_conn->mutex);
#endif
- seq = conn->seq_out;
+ seq = (ecp_seq_t)(_conn->nonce_out) - 1;
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
+ pthread_mutex_unlock(&_conn->mutex);
#endif
#ifdef ECP_WITH_PTHREAD
@@ -335,8 +330,89 @@ int ecp_rbuf_flush(ECPConnection *conn) {
pthread_mutex_unlock(&buf->mutex);
#endif
- rv = flush_send(conn, NULL);
+ rv = ecp_rbuf_send_flush(conn);
if (rv < 0) return rv;
return ECP_OK;
}
+
+ssize_t ecp_rbuf_pld_send(ECPRBConn *conn, ECPBuffer *payload, size_t pld_size, ECPBuffer *packet, size_t pkt_size, ECPTimerItem *ti) {
+ ECPRBSend *buf = conn->send;
+ ECPRBuffer *rbuf = &buf->rbuf;
+ unsigned char mtype;
+ int rb_rel;
+ int rb_cc;
+ int do_send;
+ int do_skip;
+ int _rv = ECP_OK;
+ ssize_t rv = 0;
+
+ _rv = ecp_pld_get_type(payload->buffer, pld_size, &mtype);
+ if (_rv) return _rv;
+
+ do_send = 1;
+ do_skip = ecp_rbuf_skip(mtype);
+ if (ti && !do_skip) return ECP_ERR_RBUF_TIMER;
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_lock(&buf->mutex);
+#endif
+
+ if (!buf->start) {
+ rv = 0;
+ goto pld_send_fin;
+ }
+
+ rb_rel = (buf->flags & ECP_RBUF_FLAG_RELIABLE);
+ rb_cc = ((buf->flags & ECP_RBUF_FLAG_CCONTROL) && (buf->cnt_cc || (buf->in_transit >= buf->win_size)));
+
+ if (rb_rel || rb_cc) {
+ ecp_seq_t seq;
+ unsigned short idx;
+ unsigned char _flags;
+
+ _rv = ecp_pkt_get_seq(packet->buffer, pkt_size, &seq);
+ if (_rv) {
+ rv = _rv;
+ goto pld_send_fin;
+ }
+
+ _rv = _ecp_rbuf_msg_idx(rbuf, seq, &idx);
+ if (_rv) rv = ECP_ERR_RBUF_DUP;
+ if (!rv && rbuf->arr.pkt[idx].flags) rv = ECP_ERR_RBUF_DUP;
+ if (rv) goto pld_send_fin;
+
+ _flags = ECP_RBUF_FLAG_IN_RBUF;
+ if (do_skip) {
+ _flags |= ECP_RBUF_FLAG_SKIP;
+ } else {
+ do_send = 0;
+ }
+
+ rbuf->arr.pkt[idx].flags = _flags;
+ if (!do_send) {
+ memcpy(rbuf->arr.pkt[idx].buf, packet->buffer, pkt_size);
+ rbuf->arr.pkt[idx].size = pkt_size;
+ rv = pld_size;
+ }
+
+ if (ECP_SEQ_LT(rbuf->seq_max, seq)) rbuf->seq_max = seq;
+
+ if (rb_cc && !do_send) {
+ if (buf->cnt_cc == 0) buf->seq_cc = seq;
+ buf->cnt_cc++;
+ }
+ }
+
+ if ((buf->flags & ECP_RBUF_FLAG_CCONTROL) && !do_skip && do_send) {
+ buf->in_transit++;
+ }
+
+pld_send_fin:
+
+#ifdef ECP_WITH_PTHREAD
+ pthread_mutex_unlock(&buf->mutex);
+#endif
+
+ return rv;
+}
diff --git a/ecp/src/ecp/timer.c b/ecp/src/ecp/timer.c
index 28d4cb1..445c343 100644
--- a/ecp/src/ecp/timer.c
+++ b/ecp/src/ecp/timer.c
@@ -1,3 +1,6 @@
+#include <stdlib.h>
+#include <string.h>
+
#include "core.h"
#include "tm.h"
@@ -20,20 +23,13 @@ void ecp_timer_destroy(ECPTimer *timer) {
#endif
}
-int ecp_timer_item_init(ECPTimerItem *ti, ECPConnection *conn, unsigned char mtype, short cnt, ecp_cts_t timeout) {
- if ((mtype & ECP_MTYPE_MASK) >= ECP_MAX_MTYPE) return ECP_ERR_MAX_MTYPE;
-
- if (ti == NULL) return ECP_ERR;
- if (conn == NULL) return ECP_ERR;
-
+void ecp_timer_item_init(ECPTimerItem *ti, ECPConnection *conn, unsigned char mtype, ecp_timer_retry_t retry_f, unsigned short cnt, ecp_sts_t timeout) {
ti->conn = conn;
ti->mtype = mtype;
- ti->cnt = cnt-1;
+ ti->retry = retry_f;
+ ti->cnt = cnt;
ti->timeout = timeout;
ti->abstime = 0;
- ti->retry = NULL;
-
- return ECP_OK;
}
int ecp_timer_push(ECPTimerItem *ti) {
@@ -58,7 +54,7 @@ int ecp_timer_push(ECPTimerItem *ti) {
if (!rv) {
for (i=timer->head; i>=0; i--) {
- if (ECP_CTS_LTE(ti->abstime, timer->item[i].abstime)) {
+ if (ECP_STS_LTE(ti->abstime, timer->item[i].abstime)) {
if (i != timer->head) memmove(timer->item+i+2, timer->item+i+1, sizeof(ECPTimerItem) * (timer->head-i));
timer->item[i+1] = *ti;
timer->head++;
@@ -106,7 +102,6 @@ void ecp_timer_pop(ECPConnection *conn, unsigned char mtype) {
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&timer->mutex);
#endif
-
}
void ecp_timer_remove(ECPConnection *conn) {
@@ -134,25 +129,24 @@ void ecp_timer_remove(ECPConnection *conn) {
#ifdef ECP_WITH_PTHREAD
pthread_mutex_unlock(&timer->mutex);
#endif
-
}
-ecp_cts_t ecp_timer_exe(ECPSocket *sock) {
+ecp_sts_t ecp_timer_exe(ECPSocket *sock) {
int i;
- ecp_cts_t ret = 0;
+ ecp_sts_t ret = 0;
ECPTimer *timer = &sock->timer;
ECPTimerItem to_exec[ECP_MAX_TIMER];
int to_exec_size = 0;
- ecp_cts_t now = ecp_tm_abstime_ms(0);
+ ecp_sts_t now = ecp_tm_abstime_ms(0);
#ifdef ECP_WITH_PTHREAD
pthread_mutex_lock(&timer->mutex);
#endif
for (i=timer->head; i>=0; i--) {
- ecp_cts_t abstime = timer->item[i].abstime;
+ ecp_sts_t abstime = timer->item[i].abstime;
- if (ECP_CTS_LT(now, abstime)) {
+ if (ECP_STS_LT(now, abstime)) {
ret = abstime - now;
break;
}
@@ -172,7 +166,6 @@ ecp_cts_t ecp_timer_exe(ECPSocket *sock) {
ECPConnection *conn = to_exec[i].conn;
unsigned char mtype = to_exec[i].mtype;
ecp_timer_retry_t retry = to_exec[i].retry;
- ecp_conn_msg_handler_t handler = ecp_conn_get_msg_handler(conn, mtype & ECP_MTYPE_MASK);
int rv = ECP_OK;
if (to_exec[i].cnt > 0) {
@@ -183,9 +176,9 @@ ecp_cts_t ecp_timer_exe(ECPSocket *sock) {
_rv = retry(conn, to_exec+i);
if (_rv < 0) rv = _rv;
}
- if (rv && (rv != ECP_ERR_CLOSED) && handler) handler(conn, 0, mtype, NULL, rv, NULL);
- } else if (handler) {
- handler(conn, 0, mtype, NULL, ECP_ERR_TIMEOUT, NULL);
+ if (rv && (rv != ECP_ERR_CLOSED)) ecp_err_handle(conn, mtype, rv);
+ } else {
+ ecp_err_handle(conn, mtype, ECP_ERR_TIMEOUT);
}
ecp_conn_refcount_dec(conn);
}
@@ -193,13 +186,12 @@ ecp_cts_t ecp_timer_exe(ECPSocket *sock) {
return ret;
}
-ssize_t ecp_timer_send(ECPConnection *conn, ecp_timer_retry_t send_f, unsigned char mtype, short cnt, ecp_cts_t timeout) {
+ssize_t ecp_timer_send(ECPConnection *conn, ecp_timer_retry_t send_f, unsigned char mtype, unsigned short cnt, ecp_sts_t timeout) {
ECPTimerItem ti;
- int rv;
- rv = ecp_timer_item_init(&ti, conn, mtype, cnt, timeout);
- if (rv) return rv;
+ if (cnt == 0) return ECP_ERR;
+
+ ecp_timer_item_init(&ti, conn, mtype, send_f, cnt-1, timeout);
- ti.retry = send_f;
return send_f(conn, &ti);
}
diff --git a/ecp/src/ecp/timer.h b/ecp/src/ecp/timer.h
index 5bccff1..9079a5e 100644
--- a/ecp/src/ecp/timer.h
+++ b/ecp/src/ecp/timer.h
@@ -9,9 +9,9 @@ typedef ssize_t (*ecp_timer_retry_t) (struct ECPConnection *, struct ECPTimerIte
typedef struct ECPTimerItem {
struct ECPConnection *conn;
unsigned char mtype;
- short cnt;
- ecp_cts_t abstime;
- ecp_cts_t timeout;
+ unsigned short cnt;
+ ecp_sts_t abstime;
+ ecp_sts_t timeout;
ecp_timer_retry_t retry;
} ECPTimerItem;
@@ -25,9 +25,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 mtype, short cnt, ecp_cts_t timeout);
+void ecp_timer_item_init(ECPTimerItem *ti, struct ECPConnection *conn, unsigned char mtype, ecp_timer_retry_t retry_f, unsigned short cnt, ecp_sts_t timeout);
int ecp_timer_push(ECPTimerItem *ti);
void ecp_timer_pop(struct ECPConnection *conn, unsigned char mtype);
void ecp_timer_remove(struct ECPConnection *conn);
-ecp_cts_t ecp_timer_exe(struct ECPSocket *sock);
-ssize_t ecp_timer_send(struct ECPConnection *conn, ecp_timer_retry_t send_f, unsigned char mtype, short cnt, ecp_cts_t timeout);
+ecp_sts_t ecp_timer_exe(struct ECPSocket *sock);
+ssize_t ecp_timer_send(struct ECPConnection *conn, ecp_timer_retry_t send_f, unsigned char mtype, unsigned short cnt, ecp_sts_t timeout);
diff --git a/ecp/src/ecp/tm.h b/ecp/src/ecp/tm.h
index 00c6fad..af84b66 100644
--- a/ecp/src/ecp/tm.h
+++ b/ecp/src/ecp/tm.h
@@ -1,4 +1,4 @@
int ecp_tm_init(ECPContext *ctx);
-ecp_cts_t ecp_tm_abstime_ms(ecp_cts_t msec);
-void ecp_tm_sleep_ms(ecp_cts_t msec);
-void ecp_tm_timer_set(ecp_cts_t next);
+ecp_sts_t ecp_tm_abstime_ms(ecp_sts_t msec);
+void ecp_tm_sleep_ms(ecp_sts_t msec);
+void ecp_tm_timer_set(ecp_sts_t next);
diff --git a/ecp/src/ecp/tr.h b/ecp/src/ecp/tr.h
index 116590b..5037b07 100644
--- a/ecp/src/ecp/tr.h
+++ b/ecp/src/ecp/tr.h
@@ -1,10 +1,11 @@
int ecp_tr_init(ECPContext *ctx);
-int ecp_tr_addr_eq(ECPNetAddr *addr1, ECPNetAddr *addr2);
-int ecp_tr_addr_set(ECPNetAddr *addr, void *addr_s);
+unsigned int ecp_tr_addr_hash(ecp_tr_addr_t *addr);
+int ecp_tr_addr_eq(ecp_tr_addr_t *addr1, ecp_tr_addr_t *addr2);
+int ecp_tr_addr_set(ecp_tr_addr_t *addr, void *addr_s);
int ecp_tr_open(ECPSocket *sock, void *addr_s);
void ecp_tr_close(ECPSocket *sock);
-ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t msg_size, ECPNetAddr *addr, unsigned char flags);
-ssize_t ecp_tr_recv(ECPSocket *sock, ECPBuffer *packet, ECPNetAddr *addr, int timeout);
+ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t msg_size, ecp_tr_addr_t *addr, unsigned char flags);
+ssize_t ecp_tr_recv(ECPSocket *sock, ECPBuffer *packet, ecp_tr_addr_t *addr, int timeout);
void ecp_tr_release(ECPBuffer *packet, unsigned char more);
void ecp_tr_flag_set(unsigned char flags);
void ecp_tr_flag_clear(unsigned char flags);
diff --git a/ecp/src/ecp/vconn/vconn.c b/ecp/src/ecp/vconn/vconn.c
index d3eec44..bbed3c3 100644
--- a/ecp/src/ecp/vconn/vconn.c
+++ b/ecp/src/ecp/vconn/vconn.c
@@ -1,620 +1,313 @@
-#include <core.h>
+#include <stdlib.h>
+#include <string.h>
-#ifdef ECP_WITH_HTABLE
-#include <ht.h>
-#endif
-#include <cr.h>
+#include <core.h>
#include "vconn.h"
-#ifdef ECP_WITH_HTABLE
-static void *key_perma_table;
-static void *key_next_table;
-#ifdef ECP_WITH_PTHREAD
-static pthread_mutex_t key_perma_mutex;
-static pthread_mutex_t key_next_mutex;
-#endif
-#endif
-
-static ECPConnHandler handler_vc;
-static ECPConnHandler handler_vl;
+ssize_t ecp_vconn_send_open_req(ECPConnection *conn, unsigned char *cookie) {
+ if (conn->type == ECP_CTYPE_VCONN) {
+ ECPDHPub *key;
+ ECPBuffer packet;
+ ECPBuffer payload;
+ unsigned char pkt_buf[ECP_SIZE_PKT_BUF_WCOOKIE(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ, conn)+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT)];
+ unsigned char pld_buf[ECP_SIZE_PLD_BUF(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ, conn)+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT)];
+ unsigned char *msg;
+ unsigned char *_pld_buf;
+ size_t _pld_size;
+ ssize_t rv;
+
+ if (conn->next == NULL) return ECP_ERR;
+
+ key = &conn->next->remote.key_perma;
+ if (!key->valid) return ECP_ERR;
+
+ packet.buffer = pkt_buf;
+ packet.size = sizeof(pkt_buf);
+ payload.buffer = pld_buf;
+ payload.size = sizeof(pld_buf);
+
+ rv = ecp_write_open_req(conn, &payload);
+ if (rv < 0) return rv;
-#ifdef ECP_WITH_HTABLE
+ _pld_buf = payload.buffer + rv;
+ _pld_size = payload.size - rv;
-static int key_is_null(unsigned char *key) {
- int i;
+ ecp_pld_set_type(_pld_buf, _pld_size, ECP_MTYPE_NEXT);
+ msg = ecp_pld_get_msg(_pld_buf, _pld_size);
+ memcpy(msg, &key->public, ECP_SIZE_ECDH_PUB);
- for (i=0; i<ECP_ECDH_SIZE_KEY; i++) {
- if (key[i] != 0) return 0;
+ rv = ecp_pld_send_wcookie(conn, &packet, &payload, rv+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT), 0, cookie);
+ return rv;
+ } else {
+ return ecp_send_open_req(conn, cookie);
}
- return 1;
}
-static void vconn_remove(ECPConnection *conn) {
- ECPVConnIn *conn_v = (ECPVConnIn *)conn;
- int i;
+static void insert_key_next(ECPConnection *conn, unsigned char idx, ecp_ecdh_public_t *public) {
+ ECPVConn *_conn = (ECPVConn *)conn;
+ ecp_ecdh_public_t to_remove;
+ unsigned char c_idx;
+ int do_insert = 0, do_remove = 0;
+
+ if (idx == ECP_ECDH_IDX_INV) return;
- if (conn->type != ECP_CTYPE_VCONN) return;
- if (ecp_conn_is_outb(conn)) return;
+ c_idx = (idx & 0x0F);
+ if (c_idx & ~ECP_ECDH_IDX_MASK) return;
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&key_next_mutex);
pthread_mutex_lock(&conn->mutex);
#endif
- for (i=0; i<ECP_MAX_NODE_KEY; i++) {
- if (!key_is_null(conn_v->key_next[i])) ecp_ht_remove(key_next_table, conn_v->key_next[i]);
- }
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
- pthread_mutex_unlock(&key_next_mutex);
-#endif
-}
-
-#endif /* ECP_WITH_HTABLE */
-
-static ssize_t _vconn_send_open(ECPConnection *conn, ECPTimerItem *ti) {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KGET_REQ, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn)];
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KGET_REQ, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn);
+ if (c_idx != _conn->key_next_curr) {
+ ECPDHPub *key;
+ unsigned char _c_idx;
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KGET_REQ);
- return _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti);
-}
+ _c_idx = c_idx % ECP_MAX_NODE_KEY;
+ key = &_conn->key_next[_c_idx];
-static ssize_t vconn_send_open(ECPConnection *conn) {
- ECPTimerItem ti;
- ECPVConnOut *conn_v = (ECPVConnOut *)conn;
- ECPConnection *conn_next;
- ssize_t rv;
-
- if (conn->type != ECP_CTYPE_VCONN) return ECP_ERR;
- if (ecp_conn_is_inb(conn)) return ECP_ERR;
-
- conn_next = conn_v->next;
- if (conn_next == NULL) return ECP_ERR;
-
- rv = ecp_timer_send(conn_next, _vconn_send_open, ECP_MTYPE_KGET_REP, 3, 1000);
- if (rv < 0) return rv;
-
- return rv;
-}
-
-static ssize_t vconn_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- return _ecp_conn_handle_kget(conn, seq, mtype, msg, size, b, vconn_send_open);
-}
-
-static ssize_t vconn_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- ssize_t rv;
- int _rv;
-
- if (conn->type != ECP_CTYPE_VCONN) return ECP_ERR;
-
- if (mtype & ECP_MTYPE_FLAG_REP) {
- if (ecp_conn_is_inb(conn)) return ECP_ERR;
- if (size < 0) {
- ecp_conn_msg_handler_t handler;
- while (conn && (conn->type == ECP_CTYPE_VCONN)) {
- ECPVConnOut *conn_v = (ECPVConnOut *)conn;
- conn = conn_v->next;
+ if (!key->valid || (memcmp(public, &key->public, sizeof(key->public)) != 0)) {
+ if (key->valid) {
+ memcpy(&to_remove, &key->public, sizeof(key->public));
+ do_remove = 1;
}
- if (conn) handler = ecp_conn_get_msg_handler(conn, ECP_MTYPE_OPEN);
- return handler ? handler(conn, seq, mtype, msg, size, b) : size;
- }
-
- rv = ecp_conn_handle_open(conn, seq, mtype, msg, size, b);
- } else {
+ memcpy(&key->public, public, sizeof(key->public));
+ key->valid = 1;
-#ifdef ECP_WITH_HTABLE
-
- ECPVConnIn *conn_v = (ECPVConnIn *)conn;
- unsigned char ctype;
- int is_new, do_ins;
-
- if (ecp_conn_is_outb(conn)) return ECP_ERR;
- if (size < 0) return size;
- if (size < 1+2*ECP_ECDH_SIZE_KEY) return ECP_ERR;
-
- ctype = msg[0];
- msg++;
-
- is_new = ecp_conn_is_new(conn);
- do_ins = 0;
- if (is_new) {
- conn_v->key_next_curr = 0;
- memset(conn_v->key_next, 0, sizeof(conn_v->key_next));
- memset(conn_v->key_out, 0, sizeof(conn_v->key_out));
- memcpy(conn_v->key_next[conn_v->key_next_curr], msg, ECP_ECDH_SIZE_KEY);
- memcpy(conn_v->key_out, msg+ECP_ECDH_SIZE_KEY, ECP_ECDH_SIZE_KEY);
- do_ins = 1;
-
- _rv = ecp_conn_insert(conn);
- if (_rv) return rv;
+ _conn->key_next_curr = c_idx;
+ do_insert = 1;
}
+ }
#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&key_next_mutex);
- pthread_mutex_lock(&conn->mutex);
+ pthread_mutex_unlock(&conn->mutex);
#endif
- _rv = ECP_OK;
- if (!is_new && memcmp(conn_v->key_next[conn_v->key_next_curr], msg, ECP_ECDH_SIZE_KEY)) {
- conn_v->key_next_curr = (conn_v->key_next_curr + 1) % ECP_MAX_NODE_KEY;
- if (!key_is_null(conn_v->key_next[conn_v->key_next_curr])) ecp_ht_remove(key_next_table, conn_v->key_next[conn_v->key_next_curr]);
- memcpy(conn_v->key_next[conn_v->key_next_curr], msg, ECP_ECDH_SIZE_KEY);
- do_ins = 1;
- }
- if (do_ins) _rv = ecp_ht_insert(key_next_table, conn_v->key_next[conn_v->key_next_curr], conn);
- if (!_rv && !ecp_conn_is_open(conn)) ecp_conn_set_open(conn);
+ if (do_remove) ecp_sock_keys_remove(conn->sock, &to_remove);
+ if (do_insert) ecp_sock_keys_insert(conn->sock, public, conn);
+}
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&conn->mutex);
- pthread_mutex_unlock(&key_next_mutex);
-#endif
+static ssize_t handle_next(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
+ ECPConnection *conn_next;
- if (_rv) {
- ecp_conn_close(conn);
- return _rv;
- }
+ if (msg_size < ECP_SIZE_ECDH_PUB) return ECP_ERR_SIZE;
- rv = 1+2*ECP_ECDH_SIZE_KEY;
+ conn_next = ecp_sock_keys_search(conn->sock, (ecp_ecdh_public_t *)msg);
+ if (conn_next == NULL) return ECP_ERR;
-#else /* ECP_WITH_HTABLE */
+ conn->next = conn_next;
- ecp_conn_close(conn);
- rv = ECP_ERR_NOT_IMPLEMENTED;
+ return ECP_SIZE_ECDH_PUB;
+}
-#endif /* ECP_WITH_HTABLE */
+static ssize_t handle_exec(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
+ ECPBuffer *packet;
- }
+ if (b == NULL) return ECP_ERR;
- return rv;
+ packet = b->packet;
+ if (packet->size < msg_size) return ECP_ERR_SIZE;
+
+ memcpy(packet->buffer, msg, msg_size);
+ return ecp_pkt_handle(conn->sock, conn, NULL, b, msg_size);
}
-#ifdef ECP_WITH_HTABLE
-static ssize_t vconn_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
+static ssize_t handle_relay(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
ECPBuffer payload;
- ECPConnection *conn_out = NULL;
- ECPVConnIn *conn_v = (ECPVConnIn *)conn;
+ ECPConnection *conn_next;
ssize_t rv;
- if (conn->type != ECP_CTYPE_VCONN) return ECP_ERR;
- if (ecp_conn_is_outb(conn)) return ECP_ERR;
- if (b == NULL) return ECP_ERR;
-
- if (size < 0) return size;
- if (size < ECP_MIN_PKT) return ECP_ERR;
+ if (msg_size < ECP_MIN_PKT) return ECP_ERR_SIZE;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&key_perma_mutex);
-#endif
- conn_out = ecp_ht_search(key_perma_table, conn_v->key_out);
- if (conn_out) {
- ecp_conn_refcount_inc(conn_out);
+ if (conn->type == ECP_CTYPE_VCONN) {
+ if (ecp_conn_is_outb(conn)) return ECP_ERR;
+ conn_next = conn->next;
+ insert_key_next(conn, msg[ECP_SIZE_PROTO], (ecp_ecdh_public_t *)(msg+ECP_SIZE_PROTO+1));
+ } else if (conn->type == ECP_CTYPE_VLINK) {
+ conn_next = ecp_sock_keys_search(conn->sock, (ecp_ecdh_public_t *)(msg+ECP_SIZE_PROTO+1));
}
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&key_perma_mutex);
-#endif
- if (conn_out == NULL) return ECP_ERR;
+ if (conn_next == NULL) return ECP_ERR;
- payload.buffer = msg - ECP_SIZE_PLD_HDR - 1;
+ payload.buffer = msg - ECP_SIZE_MTYPE;
payload.size = b->payload->size - (payload.buffer - b->payload->buffer);
ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_EXEC);
- rv = ecp_pld_send(conn_out, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size, ECP_SEND_FLAG_REPLY);
+ rv = ecp_pld_send(conn_next, b->packet, &payload, ECP_SIZE_MTYPE + msg_size, ECP_SEND_FLAG_REPLY);
- ecp_conn_refcount_dec(conn_out);
+ if (conn->type == ECP_CTYPE_VLINK) {
+ ecp_conn_refcount_dec(conn_next);
+ }
if (rv < 0) return rv;
- return size;
+ return msg_size;
}
-static int vlink_insert(ECPConnection *conn) {
+ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pkt_size, ecp_tr_addr_t *addr) {
+ unsigned char *msg;
+ size_t hdr_size;
int rv;
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&key_perma_mutex);
-#endif
- rv = ecp_ht_insert(key_perma_table, ecp_cr_dh_pub_get_buf(&conn->node.public), conn);
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&key_perma_mutex);
-#endif
-
- return rv;
-}
-
-static void vlink_remove(ECPConnection *conn) {
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&key_perma_mutex);
-#endif
- ecp_ht_remove(key_perma_table, ecp_cr_dh_pub_get_buf(&conn->node.public));
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&key_perma_mutex);
-#endif
-}
-
-#endif /* ECP_WITH_HTABLE */
+ rv = ecp_pld_set_type(payload->buffer, payload->size, ECP_MTYPE_RELAY);
+ if (rv) return rv;
-static ssize_t _vlink_send_open(ECPConnection *conn, ECPTimerItem *ti) {
- ECPSocket *sock = conn->sock;
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ, conn)];
- unsigned char *buf;
-
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ, conn);
-
- // XXX server should verify perma_key
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_OPEN_REQ);
- buf = ecp_pld_get_buf(payload.buffer, payload.size);
- buf[0] = conn->type;
- memcpy(buf+1, ecp_cr_dh_pub_get_buf(&sock->key_perma.public), ECP_ECDH_SIZE_KEY);
-
- return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(ECP_ECDH_SIZE_KEY+1, ECP_MTYPE_OPEN_REQ), 0, ti);
-}
+ msg = ecp_pld_get_msg(payload->buffer, payload->size);
+ if (msg == NULL) return ECP_ERR;
-static ssize_t vlink_send_open(ECPConnection *conn) {
- return ecp_timer_send(conn, _vlink_send_open, ECP_MTYPE_OPEN_REP, 3, 500);
-}
+ hdr_size = msg - payload->buffer;
+ if (payload->size < pkt_size+hdr_size) return ECP_ERR_SIZE;
-static ssize_t vlink_handle_kget(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- return _ecp_conn_handle_kget(conn, seq, mtype, msg, size, b, vlink_send_open);
+ memcpy(msg, packet->buffer, pkt_size);
+ return ecp_pack_conn(conn, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, NULL, NULL, payload, pkt_size+hdr_size, addr);
}
-static ssize_t vlink_handle_open(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- ssize_t rv;
- int _rv;
- int is_open;
+int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *b) {
+ if (conn->type == ECP_CTYPE_VCONN) {
+ if (ecp_conn_is_outb(conn)) {
+ if (conn->next) {
+ int rv;
- if (conn->type != ECP_CTYPE_VLINK) return ECP_ERR;
+ rv = ecp_conn_open(conn->next, NULL);
+ if (rv) ecp_err_handle(conn->next, ECP_MTYPE_INIT_REQ, rv);
+ }
+ }
+ } else if (conn->type == ECP_CTYPE_VLINK) {
+ ECPDHPub *key = &conn->remote.key_perma;
- if (size < 0) return size;
+ if (key->valid) {
+ int rv;
- if (ecp_conn_is_new(conn) && (size >= 1+ECP_ECDH_SIZE_KEY)) {
- // XXX we should verify perma_key
- ecp_cr_dh_pub_from_buf(&conn->node.public, msg+1);
+ rv = ecp_sock_keys_insert(conn->sock, &key->public, conn);
+ if (rv) return rv;
+ }
}
- rv = _ecp_conn_handle_open(conn, seq, mtype, msg, size, b, &is_open);
- if (rv < 0) return rv;
-
- if (mtype & ECP_MTYPE_FLAG_REP) {
-
-#ifdef ECP_WITH_HTABLE
+ return ECP_OK;
+}
- if (!is_open) {
- _rv = vlink_insert(conn);
- if (_rv) return _rv;
+void ecp_vconn_handle_close(ECPConnection *conn) {
+ if (conn->type == ECP_CTYPE_VCONN) {
+ if (ecp_conn_is_inb(conn)) {
+ ecp_vconn_destroy_inb((ECPVConn *)conn);
}
+ } else if (conn->type == ECP_CTYPE_VLINK) {
+ ECPDHPub *key = &conn->remote.key_perma;
-#endif /* ECP_WITH_HTABLE */
-
- } else {
- if (size < rv+ECP_ECDH_SIZE_KEY) return ECP_ERR;
-
-#ifdef ECP_WITH_HTABLE
-
- msg += rv;
-
- if (!is_open) {
- _rv = vlink_insert(conn);
- if (_rv) {
- ecp_conn_close(conn);
- return _rv;
- }
+ if (key->valid) {
+ ecp_sock_keys_remove(conn->sock, &key->public);
}
-
- rv = rv+ECP_ECDH_SIZE_KEY;
-
-#else /* ECP_WITH_HTABLE */
-
- ecp_conn_close(conn);
- rv = ECP_ERR_NOT_IMPLEMENTED;
-
-#endif /* ECP_WITH_HTABLE */
-
}
-
- return rv;
}
-#ifdef ECP_WITH_HTABLE
-static ssize_t vlink_handle_relay(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- ECPBuffer payload;
- ssize_t rv;
+ssize_t ecp_vconn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) {
+ switch (mtype) {
+ case ECP_MTYPE_NEXT:
+ return handle_next(conn, msg, msg_size, b);
- if (conn->type != ECP_CTYPE_VLINK) return ECP_ERR;
- if (b == NULL) return ECP_ERR;
+ case ECP_MTYPE_EXEC:
+ return handle_exec(conn, msg, msg_size, b);
- if (size < 0) return size;
- if (size < ECP_MIN_PKT) return ECP_ERR;
+ case ECP_MTYPE_RELAY:
+ return handle_relay(conn, msg, msg_size, b);
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_lock(&key_next_mutex);
-#endif
- conn = ecp_ht_search(key_next_table, msg+ECP_SIZE_PROTO+1);
- if (conn) {
- ecp_conn_refcount_inc(conn);
+ default:
+ return ECP_ERR_MTYPE;
}
-#ifdef ECP_WITH_PTHREAD
- pthread_mutex_unlock(&key_next_mutex);
-#endif
-
- if (conn == NULL) return ECP_ERR;
-
- payload.buffer = msg - ECP_SIZE_PLD_HDR - 1;
- payload.size = b->payload->size - (payload.buffer - b->payload->buffer);
-
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_EXEC);
- rv = ecp_pld_send(conn, b->packet, &payload, ECP_SIZE_PLD_HDR+1+size, ECP_SEND_FLAG_REPLY);
-
- ecp_conn_refcount_dec(conn);
-
- if (rv < 0) return rv;
- return size;
}
-#endif /* ECP_WITH_HTABLE */
-
-#ifdef ECP_MEM_TINY
-/* Memory limited version */
-
-static ssize_t vconn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- if (size < 0) return size;
- if (b == NULL) return ECP_ERR;
- if (b->packet->buffer == NULL) return ECP_ERR;
- memcpy(b->packet->buffer, msg, size);
- return ecp_pkt_handle(conn->sock, NULL, conn, b, size);
-}
-
-#else
-
-static ssize_t vconn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b) {
- if (size < 0) return size;
- if (b == NULL) return ECP_ERR;
-
- ECP2Buffer b2;
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pld_buf[ECP_MAX_PLD];
+int ecp_vconn_create_inb(ECPVConn *conn, ECPSocket *sock) {
+ ECPConnection *_conn = &conn->b;
+ int rv;
- b2.packet = &packet;
- b2.payload = &payload;
+ rv = ecp_conn_create_inb(_conn, sock, ECP_CTYPE_VCONN);
+ if (rv) return rv;
- packet.buffer = msg;
- packet.size = b->payload->size - (msg - b->payload->buffer);
- payload.buffer = pld_buf;
- payload.size = ECP_MAX_PLD;
+ memset(conn->key_next, 0, sizeof(conn->key_next));
+ conn->key_next_curr = ECP_ECDH_IDX_INV;
- return ecp_pkt_handle(conn->sock, NULL, conn, &b2, size);
+ return ECP_OK;
}
-#endif
-
-static ssize_t vconn_set_msg(ECPConnection *conn, ECPBuffer *payload, unsigned char mtype) {
- if (ecp_conn_is_outb(conn) && (conn->type == ECP_CTYPE_VCONN) && ((mtype == ECP_MTYPE_OPEN_REQ) || (mtype == ECP_MTYPE_KGET_REQ))) {
- ECPVConnOut *conn_v = (ECPVConnOut *)conn;
- ECPConnection *conn_next = conn_v->next;
- unsigned char *buf = NULL;
- int rv;
-
- if (payload->size < ECP_SIZE_PLD_HDR + 3 + 2 * ECP_ECDH_SIZE_KEY) return ECP_ERR;
- if (conn_next == NULL) return ECP_ERR;
-
- ecp_pld_set_type(payload->buffer, payload->size, ECP_MTYPE_OPEN_REQ);
- buf = ecp_pld_get_buf(payload->buffer, payload->size);
-
- buf[0] = ECP_CTYPE_VCONN;
- rv = ecp_conn_dhkey_get_curr(conn_next, NULL, buf+1);
- if (rv) return rv;
-
- memcpy(buf+1+ECP_ECDH_SIZE_KEY, ecp_cr_dh_pub_get_buf(&conn_next->node.public), ECP_ECDH_SIZE_KEY);
- buf[1+2*ECP_ECDH_SIZE_KEY] = ECP_MTYPE_RELAY;
-
- return ECP_SIZE_PLD_HDR + 3 + 2 * ECP_ECDH_SIZE_KEY;
- } else {
- if (payload->size < ECP_SIZE_PLD_HDR + 1) return ECP_ERR;
+void ecp_vconn_destroy_inb(ECPVConn *conn) {
+ ECPConnection *_conn = &conn->b;
+ int i;
- ecp_pld_set_type(payload->buffer, payload->size, ECP_MTYPE_RELAY);
+ for (i=0; i<ECP_MAX_NODE_KEY; i++) {
+ ECPDHPub *key;
- return ECP_SIZE_PLD_HDR + 1;
+ key = &conn->key_next[i];
+ if (key->valid) {
+ ecp_sock_keys_remove(_conn->sock, &key->public);
+ }
}
-
+ if (_conn->next) ecp_conn_refcount_dec(_conn->next);
}
-#ifdef ECP_MEM_TINY
-/* Memory limited version */
-
-ssize_t ecp_pack(ECPContext *ctx, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) {
- if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR;
- if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR;
-
- if (parent) {
- unsigned char mtype;
- ssize_t rv, hdr_size;
- int _rv;
-
- _rv = ecp_pld_get_type(payload->buffer, payload->size, &mtype);
- if (_rv) return _rv;
-
- hdr_size = vconn_set_msg(parent, packet, mtype);
- if (hdr_size < 0) return hdr_size;
-
- rv = _ecp_pack(ctx, packet->buffer+hdr_size, packet->size-hdr_size, pkt_meta, payload->buffer, pld_size);
- if (rv < 0) return rv;
-
- if (payload->size < rv+hdr_size) return ECP_ERR;
- memcpy(payload->buffer, packet->buffer, rv+hdr_size);
+static int vconn_create(ECPConnection vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPSocket *sock) {
+ ECPDHPub key;
+ int i, j;
+ int rv;
- return ecp_pack_conn(parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, rv+hdr_size, addr, NULL);
- } else {
- return _ecp_pack(ctx, packet->buffer, packet->size, pkt_meta, payload->buffer, pld_size);
+ key.valid = 1;
+ for (i=0; i<vconn_size; j++) {
+ rv = ecp_conn_create(&vconn[i], sock, ECP_CTYPE_VCONN);
+ if (rv) {
+ for (j=0; j<i; j++) {
+ ecp_conn_destroy(&vconn[j]);
+ }
+ return rv;
+ }
+ memcpy(&key.public, &keys[i], sizeof(keys[i]));
+ ecp_conn_set_remote_key(&vconn[i], &key);
}
-}
-
-#else
-
-ssize_t ecp_pack(ECPContext *ctx, ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr) {
- if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR;
- if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR;
-
- if (parent) {
- ECPBuffer _payload;
- unsigned char pld_buf[ECP_MAX_PLD];
- unsigned char mtype;
- ssize_t rv, hdr_size;
- int _rv;
-
- _payload.buffer = pld_buf;
- _payload.size = ECP_MAX_PLD;
-
- _rv = ecp_pld_get_type(payload->buffer, payload->size, &mtype);
- if (_rv) return _rv;
- hdr_size = vconn_set_msg(parent, &_payload, mtype);
- if (hdr_size < 0) return hdr_size;
-
- rv = _ecp_pack(ctx, _payload.buffer+hdr_size, _payload.size-hdr_size, pkt_meta, payload->buffer, pld_size);
- if (rv < 0) return rv;
-
- return ecp_pack_conn(parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &_payload, rv+hdr_size, addr, NULL);
- } else {
- return _ecp_pack(ctx, packet->buffer, packet->size, pkt_meta, payload->buffer, pld_size);
- }
+ return ECP_OK;
}
-#endif
-
-#ifdef ECP_MEM_TINY
-/* Memory limited version */
-
-ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr, ECPSeqItem *si) {
- if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR;
- if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR;
-
- if (conn->parent) {
- unsigned char mtype;
- ssize_t rv, hdr_size;
- int _rv;
+int ecp_vconn_create(ECPConnection vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPConnection *conn) {
+ ECPConnection *_conn;
+ unsigned short pcount;
+ int rv;
- _rv = ecp_pld_get_type(payload->buffer, payload->size, &mtype);
- if (_rv) return _rv;
+ _conn = conn;
+ pcount = vconn_size;
- hdr_size = vconn_set_msg(conn->parent, packet, mtype);
- if (hdr_size < 0) return hdr_size;
+ if (pcount >= ECP_MAX_PARENT) return ECP_ERR_MAX_PARENT;
- rv = _ecp_pack_conn(conn, packet->buffer+hdr_size, packet->size-hdr_size, s_idx, c_idx, payload->buffer, pld_size, NULL, si);
- if (rv < 0) return rv;
+ rv = vconn_create(vconn, keys, vconn_size, conn->sock);
+ if (rv) return rv;
- if (payload->size < rv+hdr_size) return ECP_ERR;
- memcpy(payload->buffer, packet->buffer, rv+hdr_size);
+ while (pcount) {
+ _conn->parent = &vconn[pcount-1];
+ _conn->parent->next = _conn;
+ _conn->pcount = pcount;
- return ecp_pack_conn(conn->parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, payload, rv+hdr_size, addr, NULL);
- } else {
- return _ecp_pack_conn(conn, packet->buffer, packet->size, s_idx, c_idx, payload->buffer, pld_size, addr, si);
+ _conn = _conn->parent;
+ pcount--;
}
-}
-
-#else
-
-ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, unsigned char s_idx, unsigned char c_idx, ECPBuffer *payload, size_t pld_size, ECPNetAddr *addr, ECPSeqItem *si) {
- if ((packet == NULL) || (packet->buffer == NULL)) return ECP_ERR;
- if ((payload == NULL) || (payload->buffer == NULL)) return ECP_ERR;
-
- if (conn->parent) {
- ECPBuffer _payload;
- unsigned char pld_buf[ECP_MAX_PLD];
- unsigned char mtype;
- ssize_t rv, hdr_size;
- int _rv;
-
- _payload.buffer = pld_buf;
- _payload.size = ECP_MAX_PLD;
-
- _rv = ecp_pld_get_type(payload->buffer, payload->size, &mtype);
- if (_rv) return _rv;
- hdr_size = vconn_set_msg(conn->parent, &_payload, mtype);
- if (hdr_size < 0) return hdr_size;
-
- rv = _ecp_pack_conn(conn, _payload.buffer+hdr_size, _payload.size-hdr_size, s_idx, c_idx, payload->buffer, pld_size, NULL, si);
- if (rv < 0) return rv;
-
- return ecp_pack_conn(conn->parent, packet, ECP_ECDH_IDX_INV, ECP_ECDH_IDX_INV, &_payload, rv+hdr_size, addr, NULL);
- } else {
- return _ecp_pack_conn(conn, packet->buffer, packet->size, s_idx, c_idx, payload->buffer, pld_size, addr, si);
- }
+ return ECP_OK;
}
-#endif
-
-int ecp_vconn_ctx_init(ECPContext *ctx) {
+int ecp_vconn_open(ECPConnection *conn, ECPNode *node) {
+ ECPConnection *vconn0;
int rv;
- rv = ecp_conn_handler_init(&handler_vc);
- if (rv) return rv;
-
- handler_vc.msg[ECP_MTYPE_OPEN] = vconn_handle_open;
- handler_vc.msg[ECP_MTYPE_KGET] = vconn_handle_kget;
- handler_vc.msg[ECP_MTYPE_EXEC] = vconn_handle_exec;
-#ifdef ECP_WITH_HTABLE
- handler_vc.msg[ECP_MTYPE_RELAY] = vconn_handle_relay;
- handler_vc.conn_close = vconn_remove;
-#endif /* ECP_WITH_HTABLE */
- ctx->handler[ECP_CTYPE_VCONN] = &handler_vc;
-
- rv = ecp_conn_handler_init(&handler_vl);
- if (rv) return rv;
-
- handler_vl.msg[ECP_MTYPE_OPEN] = vlink_handle_open;
- handler_vl.msg[ECP_MTYPE_KGET] = vlink_handle_kget;
- handler_vl.msg[ECP_MTYPE_EXEC] = vconn_handle_exec;
-#ifdef ECP_WITH_HTABLE
- handler_vl.msg[ECP_MTYPE_RELAY] = vlink_handle_relay;
- handler_vl.conn_close = vlink_remove;
-#endif /* ECP_WITH_HTABLE */
- ctx->handler[ECP_CTYPE_VLINK] = &handler_vl;
-
-#ifdef ECP_WITH_HTABLE
- key_perma_table = ecp_ht_create(ctx);
- if (key_perma_table == NULL) {
- return ECP_ERR;
- }
- key_next_table = ecp_ht_create(ctx);
- if (key_next_table == NULL) {
- ecp_ht_destroy(key_perma_table);
- return ECP_ERR;
+ vconn0 = conn;
+ while (vconn0->parent) {
+ vconn0 = vconn0->parent;
}
-#ifdef ECP_WITH_PTHREAD
- rv = pthread_mutex_init(&key_perma_mutex, NULL);
- if (rv) {
- ecp_ht_destroy(key_next_table);
- ecp_ht_destroy(key_perma_table);
- return ECP_ERR;
- }
- rv = pthread_mutex_init(&key_next_mutex, NULL);
- if (rv) {
- pthread_mutex_destroy(&key_perma_mutex);
- ecp_ht_destroy(key_next_table);
- ecp_ht_destroy(key_perma_table);
- return ECP_ERR;
+
+ if (node) {
+ ecp_conn_set_remote_key(conn, &node->key_perma);
+ ecp_conn_set_remote_addr(vconn0, &node->addr);
}
-#endif /* ECP_WITH_PTHREAD */
-#endif /* ECP_WITH_HTABLE */
- return ECP_OK;
+ rv = ecp_conn_open(vconn0, NULL);
+ return rv;
}
+/*
int ecp_vconn_create_parent(ECPConnection *conn, ECPNode *conn_node, ECPVConnOut vconn[], ECPNode vconn_node[], int size) {
ECPSocket *sock = conn->sock;
int i, j, rv;
@@ -650,21 +343,6 @@ int ecp_vconn_create_parent(ECPConnection *conn, ECPNode *conn_node, ECPVConnOut
return ECP_OK;
}
-static ssize_t _vconn_send_kget(ECPConnection *conn, ECPTimerItem *ti) {
- ECPBuffer packet;
- ECPBuffer payload;
- unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KGET_REQ, conn)];
- unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn)];
-
- packet.buffer = pkt_buf;
- packet.size = ECP_SIZE_PKT_BUF(0, ECP_MTYPE_KGET_REQ, conn);
- payload.buffer = pld_buf;
- payload.size = ECP_SIZE_PLD_BUF(0, ECP_MTYPE_KGET_REQ, conn);
-
- ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_KGET_REQ);
- return _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_KGET_REQ), 0, ti);
-}
-
int ecp_vconn_open(ECPConnection *conn, ECPNode *conn_node, ECPVConnOut vconn[], ECPNode vconn_node[], int size) {
int rv;
ssize_t _rv;
@@ -688,4 +366,5 @@ int ecp_vconn_open(ECPConnection *conn, ECPNode *conn_node, ECPVConnOut vconn[],
if (_rv < 0) return _rv;
return ECP_OK;
-} \ No newline at end of file
+}
+*/ \ No newline at end of file
diff --git a/ecp/src/ecp/vconn/vconn.h b/ecp/src/ecp/vconn/vconn.h
index 73d9fd6..eec13d4 100644
--- a/ecp/src/ecp/vconn/vconn.h
+++ b/ecp/src/ecp/vconn/vconn.h
@@ -1,22 +1,25 @@
-#define ECP_CTYPE_VCONN 1
-#define ECP_CTYPE_VLINK 2
+#define ECP_CTYPE_VCONN (0x01 | ECP_CTYPE_FLAG_SYS)
+#define ECP_CTYPE_VLINK (0x02 | ECP_CTYPE_FLAG_SYS)
-#define ECP_MTYPE_RELAY 0x08
-#define ECP_MTYPE_EXEC 0x09
+#define ECP_MTYPE_NEXT 0x00
+#define ECP_MTYPE_EXEC 0x02
+#define ECP_MTYPE_RELAY 0x01
-typedef struct ECPVConnOut {
+/* inbound only */
+typedef struct ECPVConn {
ECPConnection b;
- ECPConnection *next;
-} ECPVConnOut;
-
-typedef struct ECPVConnIn {
- ECPConnection b;
- unsigned char key_next[ECP_MAX_NODE_KEY][ECP_ECDH_SIZE_KEY];
+ ECPDHPub key_next[ECP_MAX_NODE_KEY];
unsigned char key_next_curr;
- unsigned char key_out[ECP_ECDH_SIZE_KEY];
-} ECPVConnIn;
+} ECPVConn;
+
+ssize_t ecp_vconn_send_open_req(ECPConnection *conn, unsigned char *cookie);
+ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pkt_size, ecp_tr_addr_t *addr);
+int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *b);
+void ecp_vconn_handle_close(ECPConnection *conn);
+ssize_t ecp_vconn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b);
+
+int ecp_vconn_create_inb(ECPVConn *conn, ECPSocket *sock);
+void ecp_vconn_destroy_inb(ECPVConn *conn);
-ssize_t ecp_vconn_handle_exec(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, ssize_t size, ECP2Buffer *b);
-int ecp_vconn_ctx_init(ECPContext *ctx);
-int ecp_vconn_create_parent(ECPConnection *conn, ECPNode *conn_node, ECPVConnOut vconn[], ECPNode vconn_node[], int size);
-int ecp_vconn_open(ECPConnection *conn, ECPNode *conn_node, ECPVConnOut vconn[], ECPNode vconn_node[], int size);
+int ecp_vconn_create(ECPConnection vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPConnection *conn);
+int ecp_vconn_open(ECPConnection *conn, ECPNode *node);
diff --git a/ecp/src/platform/fe310/time.c b/ecp/src/platform/fe310/time.c
index 3c74933..1e5eb17 100644
--- a/ecp/src/platform/fe310/time.c
+++ b/ecp/src/platform/fe310/time.c
@@ -1,3 +1,5 @@
+#include <stdlib.h>
+
#include <core.h>
#include <tr.h>
@@ -9,7 +11,7 @@
extern ECPSocket *_ecp_tr_sock;
static void timer_handler(unsigned char type) {
- ecp_cts_t next = ecp_timer_exe(_ecp_tr_sock);
+ ecp_sts_t next = ecp_timer_exe(_ecp_tr_sock);
if (next) {
eos_timer_set(next, EOS_TIMER_ETYPE_ECP);
}
@@ -21,15 +23,15 @@ int ecp_tm_init(ECPContext *ctx) {
return ECP_OK;
}
-ecp_cts_t ecp_tm_abstime_ms(ecp_cts_t msec) {
+ecp_sts_t ecp_tm_abstime_ms(ecp_sts_t msec) {
return eos_time_get_tick() * 1000 / EOS_TIMER_RTC_FREQ + msec;
}
-void ecp_tm_sleep_ms(ecp_cts_t msec) {
+void ecp_tm_sleep_ms(ecp_sts_t msec) {
eos_time_sleep(msec);
}
-void ecp_tm_timer_set(ecp_cts_t next) {
+void ecp_tm_timer_set(ecp_sts_t next) {
uint32_t _next = eos_timer_get(EOS_TIMER_ETYPE_ECP);
if ((_next == EOS_TIMER_NONE) || (next < _next)) eos_timer_set(next, EOS_TIMER_ETYPE_ECP);
}
diff --git a/ecp/src/platform/fe310/transport.c b/ecp/src/platform/fe310/transport.c
index 777a956..b551c51 100644
--- a/ecp/src/platform/fe310/transport.c
+++ b/ecp/src/platform/fe310/transport.c
@@ -1,4 +1,5 @@
#include <stdlib.h>
+#include <string.h>
#include <core.h>
#include <tr.h>
@@ -11,7 +12,7 @@ static unsigned char _flags = 0;
ECPSocket *_ecp_tr_sock = NULL;
static void packet_handler(unsigned char type, unsigned char *buffer, uint16_t len) {
- ECPNetAddr addr;
+ ecp_tr_addr_t addr;
ECP2Buffer bufs;
ECPBuffer packet;
@@ -49,13 +50,18 @@ int ecp_tr_init(ECPContext *ctx) {
return ECP_OK;
}
-int ecp_tr_addr_eq(ECPNetAddr *addr1, ECPNetAddr *addr2) {
+unsigned int ecp_tr_addr_hash(ecp_tr_addr_t *addr) {
+ unsigned int ret = *((unsigned int *)addr->host);
+ return ret ^ ((unsigned int)addr->port << 16);
+}
+
+int ecp_tr_addr_eq(ecp_tr_addr_t *addr1, ecp_tr_addr_t *addr2) {
if (addr1->port != addr2->port) return 0;
if (memcmp(addr1->host, addr2->host, sizeof(addr1->host)) != 0) return 0;
return 1;
}
-int ecp_tr_addr_set(ECPNetAddr *addr, void *addr_s) {
+int ecp_tr_addr_set(ecp_tr_addr_t *addr, void *addr_s) {
return ECP_ERR;
}
@@ -74,7 +80,7 @@ void ecp_tr_close(ECPSocket *sock) {
_ecp_tr_sock = NULL;
}
-ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t msg_size, ECPNetAddr *addr, unsigned char flags) {
+ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t msg_size, ecp_tr_addr_t *addr, unsigned char flags) {
unsigned char *buf = NULL;
int rv;
@@ -94,7 +100,7 @@ ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t msg_size, ECPNetA
return msg_size;
}
-ssize_t ecp_tr_recv(ECPSocket *sock, ECPBuffer *packet, ECPNetAddr *addr, int timeout) {
+ssize_t ecp_tr_recv(ECPSocket *sock, ECPBuffer *packet, ecp_tr_addr_t *addr, int timeout) {
return ECP_ERR;
}
diff --git a/ecp/src/platform/fe310/transport.h b/ecp/src/platform/fe310/transport.h
index 47ad482..213ca11 100644
--- a/ecp/src/platform/fe310/transport.h
+++ b/ecp/src/platform/fe310/transport.h
@@ -1,7 +1,4 @@
#include <eos/sock.h>
-#define ECP_IPv4_ADDR_SIZE 4
-
-typedef EOSNetAddr ECPNetAddr;
-typedef int ECPNetSock;
-
+typedef EOSNetAddr ecp_tr_addr_t;
+typedef int ecp_tr_sock_t;
diff --git a/ecp/src/platform/posix/platform.mk b/ecp/src/platform/posix/platform.mk
index 0370c58..9dcfe37 100644
--- a/ecp/src/platform/posix/platform.mk
+++ b/ecp/src/platform/posix/platform.mk
@@ -1,2 +1,2 @@
-CFLAGS += -O3 -DECP_WITH_PTHREAD=1 -DECP_WITH_HTABLE=1 -DECP_WITH_RBUF=1 -DECP_WITH_MSGQ=1 -DECP_WITH_VCONN=1 -DECP_WITH_DIRSRV -DECP_DEBUG=1
+CFLAGS += -O3 -DECP_WITH_PTHREAD=1 -DECP_WITH_HTABLE=1 -DECP_WITH_VCONN=1 -DECP_WITH_DIR -DECP_WITH_DIRSRV -DECP_WITH_MSGQ=1 -DECP_DEBUG=1
LDFLAGS += -lm -pthread
diff --git a/ecp/src/platform/posix/platform_obj.mk b/ecp/src/platform/posix/platform_obj.mk
index 6ca3b8d..4157ff4 100644
--- a/ecp/src/platform/posix/platform_obj.mk
+++ b/ecp/src/platform/posix/platform_obj.mk
@@ -1,2 +1,2 @@
-obj += rbuf.o rbuf_send.o rbuf_recv.o msgq.o
+obj += ext.o frag.o rbuf.o rbuf_send.o rbuf_recv.o msgq.o
subdirs += htable vconn
diff --git a/ecp/src/platform/posix/time.c b/ecp/src/platform/posix/time.c
index 111e598..efee4f8 100644
--- a/ecp/src/platform/posix/time.c
+++ b/ecp/src/platform/posix/time.c
@@ -1,3 +1,4 @@
+#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
@@ -8,17 +9,17 @@ int ecp_tm_init(ECPContext *ctx) {
return ECP_OK;
}
-ecp_cts_t ecp_tm_abstime_ms(ecp_cts_t msec) {
+ecp_sts_t ecp_tm_abstime_ms(ecp_sts_t msec) {
struct timeval tv;
- ecp_cts_t ms_now;
+ ecp_sts_t ms_now;
gettimeofday(&tv, NULL);
ms_now = tv.tv_sec * 1000 + tv.tv_usec / 1000;
return ms_now + msec;
}
-void ecp_tm_sleep_ms(ecp_cts_t msec) {
+void ecp_tm_sleep_ms(ecp_sts_t msec) {
usleep(msec*1000);
}
-void ecp_tm_timer_set(ecp_cts_t next) {} \ No newline at end of file
+void ecp_tm_timer_set(ecp_sts_t next) {}
diff --git a/ecp/src/platform/posix/transport.c b/ecp/src/platform/posix/transport.c
index c41f0df..30822b6 100644
--- a/ecp/src/platform/posix/transport.c
+++ b/ecp/src/platform/posix/transport.c
@@ -1,4 +1,5 @@
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -14,13 +15,18 @@ int ecp_tr_init(ECPContext *ctx) {
return ECP_OK;
}
-int ecp_tr_addr_eq(ECPNetAddr *addr1, ECPNetAddr *addr2) {
+unsigned int ecp_tr_addr_hash(ecp_tr_addr_t *addr) {
+ unsigned int ret = *((unsigned int *)addr->host);
+ return ret ^ ((unsigned int)addr->port << 16);
+}
+
+int ecp_tr_addr_eq(ecp_tr_addr_t *addr1, ecp_tr_addr_t *addr2) {
if (addr1->port != addr2->port) return 0;
if (memcmp(addr1->host, addr2->host, sizeof(addr1->host)) != 0) return 0;
return 1;
}
-int ecp_tr_addr_set(ECPNetAddr *addr, void *addr_s) {
+int ecp_tr_addr_set(ecp_tr_addr_t *addr, void *addr_s) {
int rv;
char addr_c[ADDR_S_MAX];
char *colon = NULL;
@@ -49,7 +55,7 @@ int ecp_tr_open(ECPSocket *sock, void *addr_s) {
memset((char *)&_myaddr, 0, sizeof(_myaddr));
_myaddr.sin_family = AF_INET;
if (addr_s) {
- ECPNetAddr addr;
+ ecp_tr_addr_t addr;
int rv = ecp_tr_addr_set(&addr, addr_s);
if (rv) return rv;
@@ -75,7 +81,7 @@ void ecp_tr_close(ECPSocket *sock) {
close(sock->sock);
}
-ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t msg_size, ECPNetAddr *addr, unsigned char flags) {
+ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t msg_size, ecp_tr_addr_t *addr, unsigned char flags) {
struct sockaddr_in servaddr;
memset((void *)&servaddr, 0, sizeof(servaddr));
@@ -85,7 +91,7 @@ ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t msg_size, ECPNetA
return sendto(sock->sock, packet->buffer, msg_size, 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
}
-ssize_t ecp_tr_recv(ECPSocket *sock, ECPBuffer *packet, ECPNetAddr *addr, int timeout) {
+ssize_t ecp_tr_recv(ECPSocket *sock, ECPBuffer *packet, ecp_tr_addr_t *addr, int timeout) {
struct sockaddr_in servaddr;
socklen_t addrlen = sizeof(servaddr);
struct pollfd fds[] = {
@@ -111,4 +117,3 @@ ssize_t ecp_tr_recv(ECPSocket *sock, ECPBuffer *packet, ECPNetAddr *addr, int ti
void ecp_tr_release(ECPBuffer *packet, unsigned char more) {}
void ecp_tr_flag_set(unsigned char flags) {}
void ecp_tr_flag_clear(unsigned char flags) {}
-
diff --git a/ecp/src/platform/posix/transport.h b/ecp/src/platform/posix/transport.h
index 155bd9c..736dbc1 100644
--- a/ecp/src/platform/posix/transport.h
+++ b/ecp/src/platform/posix/transport.h
@@ -1,7 +1,9 @@
#define ECP_IPv4_ADDR_SIZE 4
-typedef int ECPNetSock;
-typedef struct ECPNetAddr {
+struct ECPNetAddr {
unsigned char host[ECP_IPv4_ADDR_SIZE];
uint16_t port;
-} ECPNetAddr;
+};
+
+typedef struct ECPNetAddr ecp_tr_addr_t;
+typedef int ecp_tr_sock_t;
diff --git a/ecp/util/mknode.c b/ecp/util/mknode.c
index 0c262fe..885a4c0 100644
--- a/ecp/util/mknode.c
+++ b/ecp/util/mknode.c
@@ -12,26 +12,15 @@
static char fn_key[FN_LEN];
static char fn_node[FN_LEN];
-static int v_rng(void *buf, size_t bufsize) {
- int fd;
-
- if((fd = open("/dev/urandom", O_RDONLY)) < 0) return -1;
- size_t nb = read(fd, buf, bufsize);
- close(fd);
- if (nb != bufsize) return -1;
- return 0;
-}
-
static void usage(char *arg) {
fprintf(stderr, "Usage: %s <name> [address]\n", arg);
exit(1);
}
int main(int argc, char *argv[]) {
- int rv;
- ECPContext ctx;
ECPDHKey key;
ECPNode node;
+ int rv;
if ((argc < 2) || (argc > 3)) usage(argv[0]);
@@ -41,20 +30,16 @@ int main(int argc, char *argv[]) {
strcat(fn_key, ".priv");
strcat(fn_node, ".pub");
- rv = ecp_ctx_init(&ctx);
- if (rv) goto err;
- ctx.rng = v_rng;
-
- rv = ecp_dhkey_gen(&ctx, &key);
+ rv = ecp_dhkey_gen(&key);
if (rv) goto err;
rv = ecp_node_init(&node, &key.public, (argc == 3) ? argv[2] : NULL);
if (rv) goto err;
- rv = ecp_util_key_save(&ctx, &key, fn_key);
+ rv = ecp_util_key_save(&key, fn_key);
if (rv) goto err;
- rv = ecp_util_node_save(&ctx, &node, fn_node);
+ rv = ecp_util_node_save(&node, fn_node);
if (rv) goto err;
return 0;
diff --git a/ecp/util/util.c b/ecp/util/util.c
index 7ce8da5..ee51c73 100644
--- a/ecp/util/util.c
+++ b/ecp/util/util.c
@@ -7,13 +7,15 @@
#include "cr.h"
#include "util.h"
-int ecp_util_key_save(ECPContext *ctx, ECPDHKey *key, char *filename) {
+int ecp_util_key_save(ECPDHKey *key, char *filename) {
int fd;
ssize_t rv;
+ if (!key->valid) return ECP_ERR;
+
if ((fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) < 0) return ECP_ERR;
- rv = write(fd, ecp_cr_dh_pub_get_buf(&key->public), ECP_ECDH_SIZE_KEY);
- if (rv != ECP_ECDH_SIZE_KEY) {
+ rv = write(fd, &key->public, sizeof(key->public));
+ if (rv != sizeof(key->public)) {
close(fd);
return ECP_ERR;
}
@@ -26,14 +28,13 @@ int ecp_util_key_save(ECPContext *ctx, ECPDHKey *key, char *filename) {
return ECP_OK;
}
-int ecp_util_key_load(ECPContext *ctx, ECPDHKey *key, char *filename) {
+int ecp_util_key_load(ECPDHKey *key, char *filename) {
int fd;
ssize_t rv;
- unsigned char buf[ECP_ECDH_SIZE_KEY];
if ((fd = open(filename, O_RDONLY)) < 0) return ECP_ERR;
- rv = read(fd, buf, ECP_ECDH_SIZE_KEY);
- if (rv != ECP_ECDH_SIZE_KEY) {
+ rv = read(fd, &key->public, sizeof(key->public));
+ if (rv != sizeof(key->public)) {
close(fd);
return ECP_ERR;
}
@@ -44,19 +45,19 @@ int ecp_util_key_load(ECPContext *ctx, ECPDHKey *key, char *filename) {
}
close(fd);
- ecp_cr_dh_pub_from_buf(&key->public, buf);
-
key->valid = 1;
return ECP_OK;
}
-int ecp_util_node_save(ECPContext *ctx, ECPNode *node, char *filename) {
+int ecp_util_node_save(ECPNode *node, char *filename) {
int fd;
ssize_t rv;
+ if (!node->key_perma.valid) return ECP_ERR;
+
if ((fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) < 0) return ECP_ERR;
- rv = write(fd, ecp_cr_dh_pub_get_buf(&node->public), ECP_ECDH_SIZE_KEY);
- if (rv != ECP_ECDH_SIZE_KEY) {
+ rv = write(fd, &node->key_perma.public, sizeof(node->key_perma.public));
+ if (rv != sizeof(node->key_perma.public)) {
close(fd);
return ECP_ERR;
}
@@ -69,14 +70,13 @@ int ecp_util_node_save(ECPContext *ctx, ECPNode *node, char *filename) {
return ECP_OK;
}
-int ecp_util_node_load(ECPContext *ctx, ECPNode *node, char *filename) {
+int ecp_util_node_load(ECPNode *node, char *filename) {
int fd;
ssize_t rv;
- unsigned char buf[ECP_ECDH_SIZE_KEY];
if ((fd = open(filename, O_RDONLY)) < 0) return ECP_ERR;
- rv = read(fd, buf, ECP_ECDH_SIZE_KEY);
- if (rv != ECP_ECDH_SIZE_KEY) {
+ rv = read(fd, &node->key_perma.public, sizeof(node->key_perma.public));
+ if (rv != sizeof(node->key_perma.public)) {
close(fd);
return ECP_ERR;
}
@@ -87,7 +87,6 @@ int ecp_util_node_load(ECPContext *ctx, ECPNode *node, char *filename) {
}
close(fd);
- ecp_cr_dh_pub_from_buf(&node->public, buf);
-
+ node->key_perma.valid = 1;
return ECP_OK;
} \ No newline at end of file
diff --git a/ecp/util/util.h b/ecp/util/util.h
index 3d07588..631a808 100644
--- a/ecp/util/util.h
+++ b/ecp/util/util.h
@@ -1,5 +1,5 @@
-int ecp_util_key_save(ECPContext *ctx, ECPDHKey *key, char *filename);
-int ecp_util_key_load(ECPContext *ctx, ECPDHKey *key, char *filename);
+int ecp_util_key_save(ECPDHKey *key, char *filename);
+int ecp_util_key_load(ECPDHKey *key, char *filename);
-int ecp_util_node_save(ECPContext *ctx, ECPNode *node, char *filename);
-int ecp_util_node_load(ECPContext *ctx, ECPNode *node, char *filename); \ No newline at end of file
+int ecp_util_node_save(ECPNode *node, char *filename);
+int ecp_util_node_load(ECPNode *node, char *filename); \ No newline at end of file