summaryrefslogtreecommitdiff
path: root/ecp/src
diff options
context:
space:
mode:
Diffstat (limited to 'ecp/src')
-rw-r--r--ecp/src/ecp/core.c105
-rw-r--r--ecp/src/ecp/core.h21
-rw-r--r--ecp/src/ecp/cr.h1
-rw-r--r--ecp/src/ecp/crypto/crypto.c20
-rw-r--r--ecp/src/ecp/crypto/crypto.h1
-rw-r--r--ecp/src/ecp/dir/dir.c4
-rw-r--r--ecp/src/ecp/dir/dir.h2
-rw-r--r--ecp/src/ecp/dir/dir_client.c91
-rw-r--r--ecp/src/ecp/dir/dir_client.h8
-rw-r--r--ecp/src/ecp/vconn/vconn.c67
-rw-r--r--ecp/src/ecp/vconn/vconn.h6
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