summaryrefslogtreecommitdiff
path: root/ecp/src/ecp/vconn/vconn.c
diff options
context:
space:
mode:
Diffstat (limited to 'ecp/src/ecp/vconn/vconn.c')
-rw-r--r--ecp/src/ecp/vconn/vconn.c733
1 files changed, 206 insertions, 527 deletions
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