diff options
author | Uros Majstorovic <majstor@majstor.org> | 2024-06-03 04:06:21 +0200 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2024-06-03 04:06:21 +0200 |
commit | 109f39e09630409a30a9f4e8183f539c499f07ba (patch) | |
tree | 4492b38e1840be67e9ffedadb30df8f8baf9a0a7 /ecp/src | |
parent | 4c2c25f80b3cc173f09f6113e0ee623866948b87 (diff) |
improved (v)conn init / open / init vlink / open vlink API; implemented randezvous hashing
Diffstat (limited to 'ecp/src')
-rw-r--r-- | ecp/src/ecp/core.c | 105 | ||||
-rw-r--r-- | ecp/src/ecp/core.h | 21 | ||||
-rw-r--r-- | ecp/src/ecp/cr.h | 1 | ||||
-rw-r--r-- | ecp/src/ecp/crypto/crypto.c | 20 | ||||
-rw-r--r-- | ecp/src/ecp/crypto/crypto.h | 1 | ||||
-rw-r--r-- | ecp/src/ecp/dir/dir.c | 4 | ||||
-rw-r--r-- | ecp/src/ecp/dir/dir.h | 2 | ||||
-rw-r--r-- | ecp/src/ecp/dir/dir_client.c | 91 | ||||
-rw-r--r-- | ecp/src/ecp/dir/dir_client.h | 8 | ||||
-rw-r--r-- | ecp/src/ecp/vconn/vconn.c | 67 | ||||
-rw-r--r-- | ecp/src/ecp/vconn/vconn.h | 6 |
11 files changed, 227 insertions, 99 deletions
diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c index b962278..60a346b 100644 --- a/ecp/src/ecp/core.c +++ b/ecp/src/ecp/core.c @@ -25,6 +25,51 @@ int ecp_dhkey_gen(ECPDHKey *key) { return ECP_OK; } +void ecp_dhkey_init(ECPDHKey *key, ecp_ecdh_public_t *public, ecp_ecdh_private_t *private) { + memcpy(&key->public, public, sizeof(key->public)); + memcpy(&key->private, private, sizeof(key->private)); + key->valid = 1; +} + +void ecp_dhpub_init(ECPDHPub *key, ecp_ecdh_public_t *public) { + memcpy(&key->public, public, sizeof(key->public)); + key->valid = 1; +} + +int ecp_addr_init(ecp_tr_addr_t *addr, void *addr_s) { + int rv; + + memset(addr, 0, sizeof(ecp_tr_addr_t)); + rv = ecp_tr_addr_set(addr, addr_s); + return rv; +} + +void ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr) { + memset(node, 0, sizeof(ECPNode)); + + if (public) { + ECPDHPub *key = &node->key_perma; + + memcpy(&key->public, public, sizeof(key->public)); + key->valid = 1; + } + + if (addr) { + node->addr = *addr; + } +} + +void ecp_node_set_pub(ECPNode *node, ecp_ecdh_public_t *public) { + ECPDHPub *key = &node->key_perma; + + memcpy(&key->public, public, sizeof(key->public)); + key->valid = 1; +} + +void ecp_node_set_addr(ECPNode *node, ecp_tr_addr_t *addr) { + node->addr = *addr; +} + int ecp_ctx_init(ECPContext *ctx, ecp_conn_auth_t conn_auth, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free, ecp_err_handler_t handle_err, ecp_logger_t logger) { int rv; @@ -70,43 +115,6 @@ ECPConnHandler *ecp_ctx_get_handler(ECPContext *ctx, unsigned char ctype) { return NULL; } -int ecp_addr_init(ecp_tr_addr_t *addr, void *addr_s) { - int rv; - - memset(addr, 0, sizeof(ecp_tr_addr_t)); - rv = ecp_tr_addr_set(addr, addr_s); - return rv; -} - -void ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr) { - memset(node, 0, sizeof(ECPNode)); - - if (public) { - ECPDHPub *key = &node->key_perma; - - memcpy(&key->public, public, sizeof(key->public)); - key->valid = 1; - } - - if (addr) { - node->addr = *addr; - } -} - -void ecp_node_set_pub(ECPNode *node, ecp_ecdh_public_t *public) { - ECPDHPub *key = &node->key_perma; - - memcpy(&key->public, public, sizeof(key->public)); - key->valid = 1; -} - -int ecp_node_set_addr(ECPNode *node, void *addr) { - int rv; - - rv = ecp_tr_addr_set(&node->addr, addr); - return rv; -} - static int conn_table_create(ECPConnTable *conn_table) { int rv; @@ -1189,8 +1197,8 @@ void *ecp_conn_get_param(ECPConnection *conn) { return r; } -void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key) { - conn->remote.key_perma = *key; +void ecp_conn_set_remote_key(ECPConnection *conn, ecp_ecdh_public_t *public) { + ecp_dhpub_init(&conn->remote.key_perma, public); } void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr) { @@ -1256,14 +1264,13 @@ int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned cha return rv; } -int ecp_conn_create_outb(ECPConnection *conn, ECPConnection *parent, ECPNode *node) { +int ecp_conn_create_outb(ECPConnection *conn, ECPConnection *parent) { ECPDHKey key; int rv; ecp_conn_set_outb(conn); conn->refcount = 1; - if (node) conn->remote = *node; rv = ecp_dhkey_gen(&key); if (rv) return rv; @@ -1456,11 +1463,11 @@ void ecp_conn_remove_gc(ECPConnection *conn) { } } -int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, ECPNode *node, int retry) { +int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, int retry) { int rv; ssize_t _rv; - rv = ecp_conn_create_outb(conn, parent, node); + rv = ecp_conn_create_outb(conn, parent); if (rv) return rv; rv = ecp_conn_insert(conn, 0); @@ -1492,17 +1499,21 @@ int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, ECPNode *node, in return ECP_OK; } -int ecp_conn_open(ECPConnection *conn, ECPNode *node) { +int ecp_conn_open(ECPConnection *conn, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr) { int rv; - rv = _ecp_conn_open(conn, NULL, node, 1); + if (public) ecp_conn_set_remote_key(conn, public); + if (addr) ecp_conn_set_remote_addr(conn, addr); + rv = _ecp_conn_open(conn, NULL, 1); return rv; } -int ecp_conn_try_open(ECPConnection *conn, ECPNode *node) { +int ecp_conn_try_open(ECPConnection *conn, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr) { int rv; - rv = _ecp_conn_open(conn, NULL, node, 0); + if (public) ecp_conn_set_remote_key(conn, public); + if (addr) ecp_conn_set_remote_addr(conn, addr); + rv = _ecp_conn_open(conn, NULL, 0); return rv; } diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h index e79eefc..5fa00a7 100644 --- a/ecp/src/ecp/core.h +++ b/ecp/src/ecp/core.h @@ -451,16 +451,15 @@ typedef struct ECPConnection { } ECPConnection; int ecp_dhkey_gen(ECPDHKey *key); - -int ecp_ctx_init(ECPContext *ctx, ecp_conn_auth_t conn_auth, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free, ecp_err_handler_t handle_err, ecp_logger_t logger); -int ecp_ctx_set_handler(ECPContext *ctx, unsigned char ctype, ECPConnHandler *handler); -ECPConnHandler *ecp_ctx_get_handler(ECPContext *ctx, unsigned char ctype); - int ecp_addr_init(ecp_tr_addr_t *addr, void *addr_s); void ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr); void ecp_node_set_pub(ECPNode *node, ecp_ecdh_public_t *public); -int ecp_node_set_addr(ECPNode *node, void *addr); +void ecp_node_set_addr(ECPNode *node, ecp_tr_addr_t *addr); + +int ecp_ctx_init(ECPContext *ctx, ecp_conn_auth_t conn_auth, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free, ecp_err_handler_t handle_err, ecp_logger_t logger); +int ecp_ctx_set_handler(ECPContext *ctx, unsigned char ctype, ECPConnHandler *handler); +ECPConnHandler *ecp_ctx_get_handler(ECPContext *ctx, unsigned char ctype); int ecp_sock_init(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key); int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key); @@ -495,11 +494,11 @@ int ecp_conn_set_closed(ECPConnection *conn); void ecp_conn_set_rdy(ECPConnection *conn); void *ecp_conn_set_param(ECPConnection *conn, void *param); void *ecp_conn_get_param(ECPConnection *conn); -void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key); +void ecp_conn_set_remote_key(ECPConnection *conn, ecp_ecdh_public_t *public); void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr); int ecp_conn_create(ECPConnection *conn, ECPConnection *parent); int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *rkey_perma, ecp_aead_key_t *shkey); -int ecp_conn_create_outb(ECPConnection *conn, ECPConnection *parent, ECPNode *node); +int ecp_conn_create_outb(ECPConnection *conn, ECPConnection *parent); void ecp_conn_destroy(ECPConnection *conn); void ecp_conn_free(ECPConnection *conn); @@ -510,9 +509,9 @@ void ecp_conn_remove(ECPConnection *conn); void ecp_conn_remove_addr(ECPConnection *conn); void ecp_conn_remove_gc(ECPConnection *conn); -int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, ECPNode *node, int retry); -int ecp_conn_open(ECPConnection *conn, ECPNode *node); -int ecp_conn_try_open(ECPConnection *conn, ECPNode *node); +int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, int retry); +int ecp_conn_open(ECPConnection *conn, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr); +int ecp_conn_try_open(ECPConnection *conn, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr); void _ecp_conn_close(ECPConnection *conn); void ecp_conn_close(ECPConnection *conn); diff --git a/ecp/src/ecp/cr.h b/ecp/src/ecp/cr.h index 84f9bf1..0ac09bf 100644 --- a/ecp/src/ecp/cr.h +++ b/ecp/src/ecp/cr.h @@ -16,6 +16,7 @@ int ecp_ecdsa_sign(ecp_ecdsa_signature_t *sig, unsigned char *m, size_t ml, ecp_ int ecp_ecdsa_verify(unsigned char *m, size_t ml, ecp_ecdsa_signature_t *sig, ecp_ecdsa_public_t *p); void ecp_hmac(unsigned char *hd, ecp_hmac_key_t *k, unsigned char *m, size_t ml); +void ecp_hash(unsigned char *hd, unsigned char *m, size_t ml); int ecp_str2key(uint8_t *key, char *str); void ecp_key2str(char *str, uint8_t *key); diff --git a/ecp/src/ecp/crypto/crypto.c b/ecp/src/ecp/crypto/crypto.c index 1b801ab..95598da 100644 --- a/ecp/src/ecp/crypto/crypto.c +++ b/ecp/src/ecp/crypto/crypto.c @@ -133,8 +133,16 @@ void ecp_hmac(unsigned char *hd, ecp_hmac_key_t *k, unsigned char *m, size_t ml) SHA1_Final(hd, &ctx); } +void ecp_hash(unsigned char *hd, unsigned char *m, size_t ml) { + SHA_CTX ctx; + + SHA1_Init(&ctx); + SHA1_Update(&ctx, m, ml); + SHA1_Final(hd, &ctx); +} + int ecp_str2key(uint8_t *key, char *str) { - unsigned int u[8]; + uint32_t u[8]; int i, rv; if (str[ECP_SIZE_ECDH_KEY_BUF - 1] != '\0') return ECP_ERR; @@ -154,14 +162,14 @@ int ecp_str2key(uint8_t *key, char *str) { } void ecp_key2str(char *str, uint8_t *key) { - unsigned int u[8]; + uint32_t u[8]; int i; for (i=0; i<8; i++) { - u[i] = (unsigned int)key[0] << 24; - u[i] |= (unsigned int)key[1] << 16; - u[i] |= (unsigned int)key[2] << 8; - u[i] |= (unsigned int)key[3]; + u[i] = (uint32_t)key[0] << 24; + u[i] |= (uint32_t)key[1] << 16; + u[i] |= (uint32_t)key[2] << 8; + u[i] |= (uint32_t)key[3]; key += 4; } diff --git a/ecp/src/ecp/crypto/crypto.h b/ecp/src/ecp/crypto/crypto.h index 1fd63a2..1eed243 100644 --- a/ecp/src/ecp/crypto/crypto.h +++ b/ecp/src/ecp/crypto/crypto.h @@ -17,6 +17,7 @@ #define ECP_SIZE_HMAC_KEY 32 #define ECP_SIZE_HMAC_DIGEST SHA_DIGEST_LENGTH +#define ECP_SIZE_HASH_DIGEST SHA_DIGEST_LENGTH #define ECP_SIZE_ECDH_KEY_BUF 72 diff --git a/ecp/src/ecp/dir/dir.c b/ecp/src/ecp/dir/dir.c index 59764bb..b997f5c 100644 --- a/ecp/src/ecp/dir/dir.c +++ b/ecp/src/ecp/dir/dir.c @@ -134,10 +134,10 @@ void ecp_dir_conn_init(ECPConnection *conn, ECPSocket *sock) { ecp_conn_init(conn, sock, ECP_CTYPE_DIR); } -int ecp_dir_request(ECPConnection *conn, ECPNode *node, unsigned char region) { +int ecp_dir_request(ECPConnection *conn, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr, unsigned char region) { int rv; ecp_conn_set_param(conn, (void *)region); - rv = ecp_conn_open(conn, node); + rv = ecp_conn_open(conn, public, addr); return rv; } diff --git a/ecp/src/ecp/dir/dir.h b/ecp/src/ecp/dir/dir.h index 5db33f1..e343ecc 100644 --- a/ecp/src/ecp/dir/dir.h +++ b/ecp/src/ecp/dir/dir.h @@ -24,4 +24,4 @@ int ecp_dir_handle_open(ECPConnection *conn, ECP2Buffer *b); ssize_t ecp_dir_send_req(ECPConnection *conn, unsigned char region); void ecp_dir_conn_init(ECPConnection *conn, ECPSocket *sock); -int ecp_dir_request(ECPConnection *conn, ECPNode *node, unsigned char region); +int ecp_dir_request(ECPConnection *conn, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr, unsigned char region); diff --git a/ecp/src/ecp/dir/dir_client.c b/ecp/src/ecp/dir/dir_client.c index defc202..7c34189 100644 --- a/ecp/src/ecp/dir/dir_client.c +++ b/ecp/src/ecp/dir/dir_client.c @@ -2,6 +2,7 @@ #include <string.h> #include <ecp/core.h> +#include <ecp/cr.h> #include <ecp/dir/dir.h> #include "dir_client.h" @@ -16,10 +17,19 @@ static int dir_list_create_items(ECPDirList *dir_list, uint16_t list_size) { return ECP_OK; } -static void dir_list_reset_items(ECPDirList *dir_list, uint16_t serial) { +static int dir_list_reset_items(ECPDirList *dir_list, uint16_t list_size, uint16_t serial) { + int rv; + dir_list->count = 0; dir_list->serial = serial; + if (dir_list->size != list_size) { + if (dir_list->items) free(dir_list->items); + rv = dir_list_create_items(dir_list, list_size); + if (rv) return rv; + } memset(dir_list->items, 0, dir_list->size * sizeof(ECPDirItem)); + + return ECP_OK; } static int dir_handle_open(ECPConnection *conn, ECP2Buffer *b) { @@ -28,7 +38,7 @@ static int dir_handle_open(ECPConnection *conn, ECP2Buffer *b) { rv = ecp_dir_handle_open(conn, b); if (rv) return rv; - conn->param = ecp_dir_list_create(); + conn->param = ecp_dir_list_create(0); if (conn->param == NULL) return ECP_ERR_ALLOC; return ECP_OK; @@ -65,11 +75,8 @@ static ssize_t dir_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char if (rv) goto handle_dir_msg_fin; if (is_first) { - if (dir_list->items == NULL) { - rv = dir_list_create_items(dir_list, frag_tot * ECP_MAX_DIR_ITEM_IN_MSG); - if (rv) goto handle_dir_msg_fin; - } - dir_list_reset_items(dir_list, serial); + rv = dir_list_reset_items(dir_list, frag_tot * ECP_MAX_DIR_ITEM_IN_MSG, serial); + if (rv) goto handle_dir_msg_fin; } if ((dir_list->items == NULL) || @@ -112,13 +119,22 @@ static void dir_handle_err(ECPConnection *conn, unsigned char mtype, int err) { ecp_conn_close(conn); } -ECPDirList *ecp_dir_list_create(void) { +ECPDirList *ecp_dir_list_create(uint16_t list_size) { ECPDirList *dir_list; dir_list = malloc(sizeof(ECPDirList)); if (dir_list == NULL) return NULL; memset(dir_list, 0, sizeof(ECPDirList)); + if (list_size) { + int rv; + + rv = dir_list_create_items(dir_list, list_size); + if (rv) { + free(dir_list); + return NULL; + } + } return dir_list; } @@ -147,10 +163,65 @@ int ecp_dir_set_handler(ECPContext *ctx, ECPConnHandler *handler, ecp_dir_result return rv; } -int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ECPNode *node, unsigned char region) { +int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr, unsigned char region) { int rv; ecp_dir_conn_init(conn, sock); - rv = ecp_dir_request(conn, node, region); + rv = ecp_dir_request(conn, public, addr, region); return rv; } + +#ifdef ECP_WITH_VCONN + +ssize_t ecp_dir_hrw_select(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, struct ECPNetAddr *addr) { + unsigned char tmp_hash[ECP_SIZE_HASH_DIGEST]; + unsigned char hrw_hash[ECP_SIZE_HASH_DIGEST]; + ecp_ecdh_public_t public[2]; + uint16_t sel[ECP_MAX_PARENT]; + uint16_t hrw_i, sel_cnt; + uint32_t rnd_i; + int i, j, k; + + if ((dir_list->count == 0) || (vconn_size == 0)) return ECP_ERR_EMPTY; + if (vconn_size > ECP_MAX_PARENT) vconn_size = ECP_MAX_PARENT; + + memset(hrw_hash, 0, sizeof(hrw_hash)); + memcpy(&public[0], srv_pub, sizeof(public[0])); + + for (i=0; i<dir_list->count; i++) { + memcpy(&public[1], &dir_list->items[i].node.key_perma.public, sizeof(public[1])); + ecp_hash(tmp_hash, (unsigned char *)public, sizeof(public)); + if (memcmp(hrw_hash, tmp_hash, sizeof(hrw_hash)) < 0) { + hrw_i = i; + memcpy(hrw_hash, tmp_hash, sizeof(hrw_hash)); + } + } + sel[0] = hrw_i; + sel_cnt = 1; + + for (i=0; i<vconn_size-1; i++) { + if ((dir_list->count - sel_cnt) == 0) goto dir_hrw_select_fin; + rnd_i = arc4random_uniform(dir_list->count - sel_cnt); + for (j=0; j<sel_cnt; j++) { + if (rnd_i >= sel[j]) { + rnd_i++; + } else { + for (k=sel_cnt; k>j; k--) { + sel[k] = sel[k-1]; + } + break; + } + } + sel[j] = rnd_i; + sel_cnt++; + memcpy(&vconn_keys[i], &dir_list->items[rnd_i].node.key_perma.public, sizeof(vconn_keys[i])); + if (i == 0) *addr = dir_list->items[rnd_i].node.addr; + } + +dir_hrw_select_fin: + memcpy(&vconn_keys[i], &dir_list->items[hrw_i].node.key_perma.public, sizeof(vconn_keys[i])); + if (i == 0) *addr = dir_list->items[hrw_i].node.addr; + return sel_cnt; +} + +#endif diff --git a/ecp/src/ecp/dir/dir_client.h b/ecp/src/ecp/dir/dir_client.h index d55b8f6..a1be56d 100644 --- a/ecp/src/ecp/dir/dir_client.h +++ b/ecp/src/ecp/dir/dir_client.h @@ -7,9 +7,13 @@ typedef struct ECPDirList { typedef void (*ecp_dir_result_t) (ECPSocket *sock, ECPDirList *dir_list, int err); -ECPDirList *ecp_dir_list_create(void); +ECPDirList *ecp_dir_list_create(uint16_t list_size); void ecp_dir_list_destroy(ECPDirList *dir_list); ECPDirList *ecp_dir_list_copy(ECPDirList *dir_list); int ecp_dir_set_handler(ECPContext *ctx, ECPConnHandler *handler, ecp_dir_result_t dir_result); -int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ECPNode *node, unsigned char region);
\ No newline at end of file +int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr, unsigned char region); + +#ifdef ECP_WITH_VCONN +ssize_t ecp_dir_hrw_select(ECPDirList *dir_list, ecp_ecdh_public_t *srv_pub, ecp_ecdh_public_t vconn_keys[], size_t vconn_size, struct ECPNetAddr *addr); +#endif diff --git a/ecp/src/ecp/vconn/vconn.c b/ecp/src/ecp/vconn/vconn.c index e8d9b35..615474c 100644 --- a/ecp/src/ecp/vconn/vconn.c +++ b/ecp/src/ecp/vconn/vconn.c @@ -249,17 +249,31 @@ ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *payload, ECPBuffer return rv; } -void ecp_vconn_init(ECPVConnOutb vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPSocket *sock) { - ECPDHPub key; +void ecp_vconn_init(ECPVConnOutb vconn[], size_t vconn_size, ECPConnection *conn, ECPSocket *sock) { int i; - key.valid = 1; for (i=0; i<vconn_size; i++) { - memcpy(&key.public, &keys[i], sizeof(keys[i])); ecp_conn_init(&vconn[i].b, sock, ECP_CTYPE_VCONN); if (i != 0) ecp_conn_set_flags(&vconn[i].b, ECP_CONN_FLAG_NOFREE); - ecp_conn_set_remote_key(&vconn[i].b, &key); - if (i < vconn_size - 1) { + if (i != vconn_size - 1) { + vconn[i].next = &vconn[i + 1].b; + } else { + vconn[i].next = conn; + } + } +} + +void ecp_vconn_init_vlink(ECPVConnOutb vconn[], size_t vconn_size, ECPSocket *sock) { + int i; + + for (i=0; i<vconn_size; i++) { + if (i != vconn_size - 1) { + ecp_conn_init(&vconn[i].b, sock, ECP_CTYPE_VCONN); + } else { + ecp_vlink_init(&vconn[i].b, sock); + } + if (i != 0) ecp_conn_set_flags(&vconn[i].b, ECP_CONN_FLAG_NOFREE); + if (i != vconn_size - 1) { vconn[i].next = &vconn[i + 1].b; } else { vconn[i].next = NULL; @@ -280,22 +294,39 @@ void ecp_vconn_init_inb(ECPVConnInb *vconn, ECPSocket *sock) { #endif /* ECP_WITH_HTABLE */ -int ecp_vconn_open(ECPVConnOutb *vconn, ECPConnection *conn, ECPNode *node) { - ECPVConnOutb *_vconn; - int rv; +int ecp_vconn_open(ECPVConnOutb *vconn, ecp_ecdh_public_t vconn_pub[], ecp_tr_addr_t *addr, ecp_ecdh_public_t *public) { + ECPConnection *conn; + int i, rv; - _vconn = vconn; - while (_vconn->next) { - _vconn = (ECPVConnOutb *)_vconn->next; + i = 0; + conn = &vconn->b; + while (conn->type == ECP_CTYPE_VCONN) { + ecp_conn_set_remote_key(conn, &vconn_pub[i]); + conn = ((ECPVConnOutb *)conn)->next; + i++; } + if (public) ecp_conn_set_remote_key(conn, public); + if (addr) ecp_conn_set_remote_addr(&vconn->b, addr); + + rv = _ecp_conn_open(&vconn->b, NULL, 1); + return rv; +} + +int ecp_vconn_open_vlink(ECPVConnOutb *vconn, ecp_ecdh_public_t vconn_pub[], ecp_tr_addr_t *addr) { + ECPConnection *conn; + int i, rv; - _vconn->next = conn; - if (node) { - ecp_conn_set_remote_key(conn, &node->key_perma); - ecp_conn_set_remote_addr(&vconn->b, &node->addr); + i = 0; + conn = &vconn->b; + while (conn->type == ECP_CTYPE_VCONN) { + ecp_conn_set_remote_key(conn, &vconn_pub[i]); + conn = ((ECPVConnOutb *)conn)->next; + i++; } + ecp_conn_set_remote_key(conn, &vconn_pub[i]); + if (addr) ecp_conn_set_remote_addr(&vconn->b, addr); - rv = _ecp_conn_open(&vconn->b, NULL, NULL, 1); + rv = _ecp_conn_open(&vconn->b, NULL, 1); return rv; } @@ -332,7 +363,7 @@ int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs) { /* we should release incoming packet before sending next open packet */ ecp_tr_release(bufs->packet, 1); - rv = _ecp_conn_open(vconn->next, conn, NULL, 1); + rv = _ecp_conn_open(vconn->next, conn, 1); /* err will be handled by ecp_vconn_handle_err */ return rv; diff --git a/ecp/src/ecp/vconn/vconn.h b/ecp/src/ecp/vconn/vconn.h index a0e076f..ab1d2d1 100644 --- a/ecp/src/ecp/vconn/vconn.h +++ b/ecp/src/ecp/vconn/vconn.h @@ -25,11 +25,13 @@ typedef struct ECPVConnOutb { ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *payload, ECPBuffer *packet, size_t pkt_size, ecp_tr_addr_t *addr); -void ecp_vconn_init(ECPVConnOutb vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPSocket *sock); +void ecp_vconn_init(ECPVConnOutb vconn[], size_t vconn_size, ECPConnection *conn, ECPSocket *sock); +void ecp_vconn_init_vlink(ECPVConnOutb vconn[], size_t vconn_size, ECPSocket *sock); #ifdef ECP_WITH_HTABLE void ecp_vconn_init_inb(ECPVConnInb *vconn, ECPSocket *sock); #endif -int ecp_vconn_open(ECPVConnOutb *vconn, ECPConnection *conn, ECPNode *node); +int ecp_vconn_open(ECPVConnOutb *vconn, ecp_ecdh_public_t vconn_pub[], ecp_tr_addr_t *addr, ecp_ecdh_public_t *public); +int ecp_vconn_open_vlink(ECPVConnOutb *vconn, ecp_ecdh_public_t vconn_pub[], ecp_tr_addr_t *addr); void ecp_vconn_close(ECPConnection *conn); int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs); #ifdef ECP_WITH_HTABLE |