diff options
Diffstat (limited to 'ecp/src/ecp/vconn/vconn.c')
-rw-r--r-- | ecp/src/ecp/vconn/vconn.c | 733 |
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 |