diff options
author | Uros Majstorovic <majstor@majstor.org> | 2022-08-09 21:54:45 +0200 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2022-08-09 21:54:45 +0200 |
commit | 810dde21ee65653c15606917b19566cfbaaf165e (patch) | |
tree | 4cd84b109e06660a9c59f2487822905e5672681e /ecp | |
parent | aee853a208d6abec53ec81dc4ef110b63e13342f (diff) |
ecp server added
Diffstat (limited to 'ecp')
62 files changed, 2945 insertions, 1657 deletions
diff --git a/ecp/server/Makefile b/ecp/server/Makefile new file mode 100644 index 0000000..2105e9f --- /dev/null +++ b/ecp/server/Makefile @@ -0,0 +1,16 @@ +src_dir = ../src +include $(src_dir)/ecp/common.mk +CFLAGS += -Wno-int-to-void-pointer-cast + +obj = server.o dir.o vlink.o ht.o +dep = ../build-posix/*.a + +%.o: %.c + $(CC) $(CFLAGS) -c $< + +ecp_server: $(obj) + $(CC) -o $@ $(obj) $(dep) $(LDFLAGS) + +clean: + rm -f *.o + rm -f ecp_server diff --git a/ecp/server/dir.c b/ecp/server/dir.c new file mode 100644 index 0000000..0066bac --- /dev/null +++ b/ecp/server/dir.c @@ -0,0 +1,551 @@ +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include <ecp/core.h> +#include <ecp/dir/dir.h> +#include <ecp/ht.h> +#include <ecp/tm.h> + +#include "server.h" +#include "vlink.h" +#include "dir.h" +#include "ht.h" + +static ecp_ht_table_t *dir_shadow = NULL; +static pthread_rwlock_t dir_shadow_rwlock; +static pthread_rwlock_t dir_online_rwlock; +static pthread_t dir_announce_thd; + +static DirList dir_online; + +static SRVConfig *srv_config; + +ssize_t dir_send_ann(ECPConnection *conn) { + ECPBuffer packet; + ECPBuffer payload; + unsigned char pkt_buf[ECP_SIZE_PKT_BUF(sizeof(uint16_t), ECP_MTYPE_DIR_ANN, conn)]; + unsigned char pld_buf[ECP_SIZE_PLD_BUF(sizeof(uint16_t), ECP_MTYPE_DIR_ANN, conn)]; + unsigned char *msg; + + packet.buffer = pkt_buf; + packet.size = sizeof(pkt_buf); + payload.buffer = pld_buf; + payload.size = sizeof(pld_buf); + + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_DIR_ANN); + msg = ecp_pld_get_msg(payload.buffer, payload.size); + msg[0] = srv_config->capabilities >> 8; + msg[1] = srv_config->capabilities; + + return ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(sizeof(uint16_t), ECP_MTYPE_DIR_ANN), 0); +} + +ssize_t dir_send_shadow(ECPConnection *conn) { + ECPBuffer packet; + ECPBuffer payload; + unsigned char pkt_buf[ECP_MAX_PKT]; + unsigned char pld_buf[ECP_MAX_PLD]; + unsigned char *msg; + + struct hashtable_itr itr; + DirNode *node; + uint16_t count; + ecp_sts_t access_ts; + size_t msg_size; + + packet.buffer = pkt_buf; + packet.size = ECP_MAX_PKT; + payload.buffer = pld_buf; + payload.size = ECP_MAX_PLD; + + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_DIR_SHADOW); + msg = ecp_pld_get_msg(payload.buffer, payload.size); + msg_size = 0; + + pthread_rwlock_rdlock(&dir_shadow_rwlock); + + count = ecp_ht_count(dir_shadow); + msg[0] = count >> 8; + msg[1] = count; + msg += sizeof(uint16_t); + msg_size += sizeof(uint16_t); + + if (count > 0) { + size_t rv; + int _rv; + + ecp_ht_itr_create(&itr, dir_shadow); + do { + node = ecp_ht_itr_value(&itr); + + pthread_mutex_lock(&node->mutex); + access_ts = node->access_ts; + pthread_mutex_unlock(&node->mutex); + + rv = ecp_dir_item_serialize(&node->dir_item, msg); + msg += rv; + msg_size += rv; + + msg[0] = access_ts >> 24; + msg[1] = access_ts >> 16; + msg[2] = access_ts >> 8; + msg[3] = access_ts; + msg += sizeof(uint32_t); + msg_size += sizeof(uint32_t); + + _rv = ecp_ht_itr_advance(&itr); + } while (_rv == ECP_OK); + } + + pthread_rwlock_unlock(&dir_shadow_rwlock); + + return ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(msg_size, ECP_MTYPE_DIR_SHADOW), 0); +} + +ssize_t dir_send_online(ECPConnection *conn) { + ECPBuffer packet; + ECPBuffer payload; + unsigned char pkt_buf[ECP_MAX_PKT]; + unsigned char pld_buf[ECP_MAX_PLD]; + unsigned char *msg; + size_t msg_size; + + packet.buffer = pkt_buf; + packet.size = ECP_MAX_PKT; + payload.buffer = pld_buf; + payload.size = ECP_MAX_PLD; + + ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_DIR_REP); + msg = ecp_pld_get_msg(payload.buffer, payload.size); + + pthread_rwlock_rdlock(&dir_online_rwlock); + + msg[0] = dir_online.count >> 8; + msg[1] = dir_online.count; + msg += sizeof(uint16_t); + msg_size = sizeof(uint16_t) + dir_online.count * ECP_SIZE_DIR_ITEM; + memcpy(msg, dir_online.msg, dir_online.count * ECP_SIZE_DIR_ITEM); + + pthread_rwlock_unlock(&dir_online_rwlock); + + return ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(msg_size, ECP_MTYPE_DIR_REP), 0); +} + +ssize_t dir_handle_ann(ECPConnection *conn, unsigned char *msg, size_t msg_size) { + ECPDirItem dir_item; + int is_new; + uint16_t capabilities; + ecp_sts_t now; + ssize_t rsize; + ssize_t rv; + + rsize = sizeof(uint16_t); + if (msg_size < rsize) return ECP_ERR_SIZE; + + capabilities = \ + ((uint16_t)msg[0] << 8) | \ + ((uint16_t)msg[1]); + + memset(&dir_item, 0, sizeof(ECPDirItem)); + dir_item.node = conn->remote; + dir_item.capabilities = capabilities; + + now = ecp_tm_get_s(); + is_new = dir_process_item(&dir_item, now); + if (is_new) vlink_new_node(conn->sock, &dir_item); + + rv = dir_send_shadow(conn); + if (rv < 0) return rv; + + return rsize; +} + +ssize_t dir_handle_req(ECPConnection *conn, unsigned char *msg, size_t msg_size) { + ssize_t rv; + + rv = dir_send_online(conn); + if (rv < 0) return rv; + + return 0; +} + +ssize_t dir_handle_shadow(ECPConnection *conn, unsigned char *msg, size_t msg_size) { + ecp_sts_t now; + uint16_t count; + size_t rsize; + int i; + + if (msg_size < sizeof(uint16_t)) return ECP_ERR_SIZE; + + count = \ + ((uint16_t)msg[0] << 8) | \ + ((uint16_t)msg[1]); + + rsize = sizeof(uint16_t) + count * (ECP_SIZE_DIR_ITEM + sizeof(uint32_t)); + if (msg_size < rsize) return ECP_ERR_SIZE; + + msg += sizeof(uint16_t); + + now = ecp_tm_get_s(); + for (i=0; i<count; i++) { + ECPDirItem dir_item; + ecp_sts_t access_ts; + size_t rv; + + rv = ecp_dir_item_parse(&dir_item, msg); + msg += rv; + + access_ts = \ + ((uint32_t)msg[0] << 24) | \ + ((uint32_t)msg[1] << 16) | \ + ((uint32_t)msg[2] << 8) | \ + ((uint32_t)msg[3]); + msg += sizeof(uint32_t); + + if (ECP_STS_LT(now, access_ts) || (now - access_ts < (NODE_EXP_TIME / 2))) { + int is_new; + + is_new = dir_process_item(&dir_item, access_ts); + if (is_new) vlink_new_node(conn->sock, &dir_item); + } + } + + return rsize; +} + +ssize_t dir_handle_msg(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b) { + switch (mtype) { + case ECP_MTYPE_DIR_REQ: { + if (ecp_conn_is_outb(conn)) return ECP_ERR; + return dir_handle_req(conn, msg, msg_size); + } + + case ECP_MTYPE_DIR_ANN: { + if (ecp_conn_is_outb(conn)) return ECP_ERR; + if (!conn->remote.key_perma.valid) return ECP_ERR_VBOX; + return dir_handle_ann(conn, msg, msg_size); + } + + case ECP_MTYPE_DIR_SHADOW: { + if (ecp_conn_is_inb(conn)) return ECP_ERR; + return dir_handle_shadow(conn, msg, msg_size); + } + + default: + return ECP_ERR_MTYPE; + } +} + +int dir_handle_open(ECPConnection *conn, ECP2Buffer *bufs) { + ssize_t rv; + + if (ecp_conn_is_inb(conn)) return ECP_OK; + + rv = dir_send_ann(conn); + if (rv < 0) return rv; + + return ECP_OK; +} + +void dir_online_switch(void) { + struct hashtable_itr itr; + DirNode *node; + unsigned char *msg; + + pthread_rwlock_rdlock(&dir_shadow_rwlock); + pthread_rwlock_wrlock(&dir_online_rwlock); + + msg = dir_online.msg; + dir_online.count = ecp_ht_count(dir_shadow); + + if (dir_online.count > 0) { + size_t _rv; + int rv; + + ecp_ht_itr_create(&itr, dir_shadow); + do { + node = ecp_ht_itr_value(&itr); + + _rv = ecp_dir_item_serialize(&node->dir_item, msg); + msg += _rv; + + rv = ecp_ht_itr_advance(&itr); + } while (rv == ECP_OK); + } + + pthread_rwlock_unlock(&dir_online_rwlock); + pthread_rwlock_unlock(&dir_shadow_rwlock); +} + +int dir_process_item(ECPDirItem *dir_item, ecp_sts_t access_ts) { + DirNode *node; + int is_new = 0; + int rv = ECP_OK; + + pthread_rwlock_rdlock(&dir_shadow_rwlock); + + node = ht_search_item(dir_shadow, dir_item); + if (node) { + pthread_mutex_lock(&node->mutex); + if (!node->zombie) node->access_ts = access_ts; + pthread_mutex_unlock(&node->mutex); + + pthread_rwlock_unlock(&dir_shadow_rwlock); + } else { + pthread_rwlock_unlock(&dir_shadow_rwlock); + + LOG(LOG_DEBUG, "dir new node\n"); + + node = dir_create_node(dir_item, access_ts); + if (node == NULL) rv = ECP_ERR_ALLOC; + + if (!rv) { + pthread_rwlock_wrlock(&dir_shadow_rwlock); + if (ecp_ht_count(dir_shadow) > MAX_DIR_ITEM) rv = ECP_ERR_FULL; + if (!rv) { + if (ht_search_node(dir_shadow, node) == NULL) { + rv = ht_insert_node(dir_shadow, node); + } else { + rv = ECP_ERR_DUP; + } + } + pthread_rwlock_unlock(&dir_shadow_rwlock); + } + + if (!rv) { + is_new = 1; + /* always switch */ + dir_online_switch(); + } else { + if (node) dir_destroy_node(node); + LOG(LOG_ERR, "dir create node err:%d\n", rv); + } + } + + return is_new; +} + +DirNode *dir_create_node(ECPDirItem *dir_item, ecp_sts_t access_ts) { + DirNode *node; + int rv; + + node = malloc(sizeof(DirNode)); + if (node == NULL) return NULL; + + memset(node, 0, sizeof(DirNode)); + + rv = pthread_mutex_init(&node->mutex, NULL); + if (rv) { + free(node); + return NULL; + } + + node->dir_item = *dir_item; + node->access_ts = access_ts; + + return node; +} + +void dir_destroy_node(DirNode *node) { + pthread_mutex_destroy(&node->mutex); + free(node); +} + +int dir_open_conn(ECPSocket *sock, ECPNode *node) { + ECPConnection *conn; + int rv; + + conn = malloc(sizeof(ECPConnection)); + if (conn == NULL) return ECP_ERR_ALLOC; + + ecp_dir_conn_init(conn, sock); + ecp_conn_set_flags(conn, ECP_CONN_FLAG_GC | ECP_CONN_FLAG_VBOX); + rv = ecp_conn_try_open(conn, node); + return rv; +} + +DirNode *dir_search_conn(ECPConnection *conn) { + DirNode *node; + DirNode *ret = NULL; + + pthread_rwlock_rdlock(&dir_shadow_rwlock); + + node = ht_search_conn(dir_shadow, conn); + if (node) { + pthread_mutex_lock(&node->mutex); + if (!node->zombie) { + node->refcount++; + ret = node; + } else { + ret = NULL; + } + pthread_mutex_unlock(&node->mutex); + } + + pthread_rwlock_unlock(&dir_shadow_rwlock); + + return ret; +} + +void dir_announce(ECPSocket *sock) { + static DirNode *expire_node[MAX_EXPIRE_CNT]; + static int expire_node_z[MAX_EXPIRE_CNT]; + static int expire_cnt; + + struct hashtable_itr itr; + ecp_sts_t now; + DirNode *node; + DirNode *node_next; + DirNode *announce_node[MAX_ANNOUNCE_CNT]; + int announce_cnt; + int refcount; + int i; + int rv; + + now = ecp_tm_get_s(); + node_next = NULL; + do { + announce_cnt = 0; + pthread_rwlock_rdlock(&dir_shadow_rwlock); + + if (ecp_ht_count(dir_shadow) > 0) { + ecp_ht_itr_create(&itr, dir_shadow); + if (node_next) { + rv = ecp_ht_itr_search(&itr, node_next); + if (rv) { + LOG(LOG_ERR, "dir ann itr search err:%d\n", rv); + break; + } + node_next = NULL; + } + do { + node = ecp_ht_itr_value(&itr); + rv = ecp_ht_itr_advance(&itr); + + pthread_mutex_lock(&node->mutex); + if (ECP_STS_LT(node->access_ts, now) && (now - node->access_ts > NODE_EXP_TIME)) { + node->zombie = 1; + pthread_mutex_unlock(&node->mutex); + + if (expire_cnt < MAX_EXPIRE_CNT) { + expire_node[expire_cnt] = node; + expire_node_z[expire_cnt] = 1; + expire_cnt++; + } + } else { + pthread_mutex_unlock(&node->mutex); + + if ((node->dir_item.capabilities & ECP_DIR_CAP_DIR) && (memcmp(node->dir_item.node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) != 0)) { + announce_node[announce_cnt] = node; + announce_cnt++; + + if (announce_cnt == MAX_ANNOUNCE_CNT) { + if (!rv) { + node_next = ecp_ht_itr_key(&itr); + } else { + node_next = NULL; + } + break; + } + } + } + } while (rv == ECP_OK); + } + + pthread_rwlock_unlock(&dir_shadow_rwlock); + + if (expire_cnt) { + pthread_rwlock_wrlock(&dir_shadow_rwlock); + for (i=0; i<expire_cnt; i++) { + if (expire_node_z[i]) { + expire_node_z[i] = 0; + ht_remove_node(dir_shadow, expire_node[i]); + LOG(LOG_DEBUG, "dir remove node\n"); + } + } + pthread_rwlock_unlock(&dir_shadow_rwlock); + } + + for (i=0; i<announce_cnt; i++) { + rv = dir_open_conn(sock, &announce_node[i]->dir_item.node); + if (rv) LOG(LOG_ERR, "dir open connection err:%d\n", rv); + } + + i = expire_cnt - 1; + while (i >= 0) { + node = expire_node[i]; + + pthread_mutex_lock(&node->mutex); + refcount = node->refcount; + pthread_mutex_unlock(&node->mutex); + + if (refcount == 0) { + int j = i; + + expire_cnt--; + while (j < expire_cnt) { + expire_node[j] = expire_node[j+1]; + j++; + } + expire_node[j] = NULL; + dir_destroy_node(node); + } + i--; + } + } while (node_next); +} + +static void *_dir_announce(void *arg) { + ECPSocket *sock = arg; + + while (1) { + LOG(LOG_DEBUG, "dir announce...\n"); + dir_announce(sock); + sleep(10); + } + + return NULL; +} + +int dir_start_announce(ECPSocket *sock) { + int rv; + + rv = pthread_create(&dir_announce_thd, NULL, _dir_announce, sock); + if (rv) return ECP_ERR; + return ECP_OK; +} + +int dir_init(ECPContext *ctx) { + ECPConnHandler *handler; + int rv; + + srv_config = srv_get_config(); + + handler = malloc(sizeof(ECPConnHandler)); + if (handler == NULL) return ECP_ERR_ALLOC; + + ecp_conn_handler_init(handler, dir_handle_msg, dir_handle_open, NULL, NULL); + rv = ecp_ctx_set_handler(ctx, ECP_CTYPE_DIR, handler); + if (rv) return rv; + + rv = pthread_rwlock_init(&dir_shadow_rwlock, NULL); + if (rv) { + return ECP_ERR; + } + + rv = pthread_rwlock_init(&dir_online_rwlock, NULL); + if (rv) { + pthread_rwlock_destroy(&dir_shadow_rwlock); + return ECP_ERR; + } + + dir_shadow = ecp_ht_create_keys(); + if (dir_shadow == NULL) { + pthread_rwlock_destroy(&dir_shadow_rwlock); + pthread_rwlock_destroy(&dir_online_rwlock); + return ECP_ERR_ALLOC; + } + + return ECP_OK; +} diff --git a/ecp/server/dir.h b/ecp/server/dir.h new file mode 100644 index 0000000..cbc0c87 --- /dev/null +++ b/ecp/server/dir.h @@ -0,0 +1,35 @@ +#define MAX_DIR_ITEM 30 +#define MAX_EXPIRE_CNT 100 +#define MAX_ANNOUNCE_CNT 100 + +#define NODE_EXP_TIME 86400 + +typedef struct DirNode { + ECPDirItem dir_item; + int refcount; + int zombie; + ecp_sts_t access_ts; + pthread_mutex_t mutex; +} DirNode; + +typedef struct DirList { + unsigned char msg[ECP_MAX_PLD]; + uint16_t count; +} DirList; + +ssize_t dir_send_ann(ECPConnection *conn); +ssize_t dir_send_shadow(ECPConnection *conn); +ssize_t dir_send_online(ECPConnection *conn); +ssize_t dir_handle_ann(ECPConnection *conn, unsigned char *msg, size_t msg_size); +ssize_t dir_handle_req(ECPConnection *conn, unsigned char *msg, size_t msg_size); +ssize_t dir_handle_shadow(ECPConnection *conn, unsigned char *msg, size_t msg_size); +ssize_t dir_handle_msg(struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b); +int dir_handle_open(ECPConnection *conn, ECP2Buffer *bufs); +int dir_process_item(ECPDirItem *dir_item, ecp_sts_t access_ts); +DirNode *dir_create_node(ECPDirItem *dir_item, ecp_sts_t access_ts); +void dir_destroy_node(DirNode *node); +int dir_open_conn(ECPSocket *sock, ECPNode *node); +DirNode *dir_search_conn(ECPConnection *conn); +void dir_announce(ECPSocket *sock); +int dir_start_announce(ECPSocket *sock); +int dir_init(ECPContext *ctx); diff --git a/ecp/server/ht.c b/ecp/server/ht.c new file mode 100644 index 0000000..0daf8d5 --- /dev/null +++ b/ecp/server/ht.c @@ -0,0 +1,34 @@ +#include <ecp/core.h> +#include <ecp/dir/dir.h> +#include <ecp/ht.h> + +#include "dir.h" +#include "ht.h" + +int ht_insert_node(ecp_ht_table_t *table, DirNode *node) { + return ecp_ht_insert(table, &node->dir_item.node.key_perma.public, node); +} + +void ht_remove_node(ecp_ht_table_t *table, DirNode *node) { + ecp_ht_remove(table, &node->dir_item.node.key_perma.public); +} + +void *ht_search_node(ecp_ht_table_t *table, DirNode *node) { + return ecp_ht_search(table, &node->dir_item.node.key_perma.public); +} + +int ht_insert_conn(ecp_ht_table_t *table, ECPConnection *conn) { + return ecp_ht_insert(table, &conn->remote.key_perma.public, conn); +} + +void ht_remove_conn(ecp_ht_table_t *table, ECPConnection *conn) { + ecp_ht_remove(table, &conn->remote.key_perma.public); +} + +void *ht_search_conn(ecp_ht_table_t *table, ECPConnection *conn) { + return ecp_ht_search(table, &conn->remote.key_perma.public); +} + +void *ht_search_item(ecp_ht_table_t *table, ECPDirItem *dir_item) { + return ecp_ht_search(table, &dir_item->node.key_perma.public); +} diff --git a/ecp/server/ht.h b/ecp/server/ht.h new file mode 100644 index 0000000..cba4691 --- /dev/null +++ b/ecp/server/ht.h @@ -0,0 +1,7 @@ +int ht_insert_node(ecp_ht_table_t *table, DirNode *node); +void ht_remove_node(ecp_ht_table_t *table, DirNode *node); +void *ht_search_node(ecp_ht_table_t *table, DirNode *node); +int ht_insert_conn(ecp_ht_table_t *table, ECPConnection *conn); +void ht_remove_conn(ecp_ht_table_t *table, ECPConnection *conn); +void *ht_search_conn(ecp_ht_table_t *table, ECPConnection *conn); +void *ht_search_item(ecp_ht_table_t *table, ECPDirItem *dir_item);
\ No newline at end of file diff --git a/ecp/server/server.c b/ecp/server/server.c new file mode 100644 index 0000000..bbe7c4e --- /dev/null +++ b/ecp/server/server.c @@ -0,0 +1,204 @@ +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> + +#include <ecp/core.h> +#include <ecp/dir/dir.h> +#include <ecp/vconn/vconn.h> + +#include "dir.h" +#include "vlink.h" +#include "ht.h" + +#include "server.h" + +static SRVConfig srv_config; + +SRVConfig *srv_get_config(void) { + return &srv_config; +} + +static void usage(char *arg) { + fprintf(stderr, "Usage: %s <capabilities> <priv> <addr> [ <pub> <addr> ]\n", arg); + exit(1); +} + +static void handle_err(ECPConnection *conn, unsigned char mtype, int err) { + if (conn->type == ECP_CTYPE_VLINK) vlink_handle_err(conn, mtype, err); + LOG(LOG_ERR, "handle error ctype:%d mtype:%d err:%d\n", conn->type, mtype, err); +} + +static ECPConnection *conn_new(ECPSocket *sock, unsigned char type) { + ECPConnection *conn = NULL; + + switch (type) { + case ECP_CTYPE_VCONN: { + ECPVConnInb *_conn; + + _conn = malloc(sizeof(ECPVConnInb)); + if (_conn) { + ecp_vconn_init_inb(_conn, sock); + conn = &_conn->b; + } + break; + } + + case ECP_CTYPE_VLINK: { + conn = malloc(sizeof(ECPConnection)); + if (conn) ecp_vlink_init(conn, sock); + break; + } + + default: { + conn = malloc(sizeof(ECPConnection)); + if (conn) ecp_conn_init(conn, sock, type); + break; + } + } + + return conn; +} + +static void conn_free(ECPConnection *conn) { + free(conn); +} + +int ecp_init(ECPContext *ctx, ECPConnHandler *vconn_handler, ECPConnHandler *vlink_handler) { + int rv; + + rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free); + if (rv) return rv; + + rv = ecp_vconn_handler_init(ctx, vconn_handler); + if (rv) return rv; + + rv = ecp_vlink_handler_init(ctx, vlink_handler); + if (rv) return rv; + + return ECP_OK; +} + +int main(int argc, char *argv[]) { + ecp_tr_addr_t addr; + ECPContext ctx; + ECPSocket sock; + ECPConnHandler vconn_handler; + ECPConnHandler vlink_handler; + char *endptr; + int fd; + int rv; + + if ((argc < 4) || (argc > 6)) usage(argv[0]); + + srv_config.capabilities = (uint16_t)strtol(argv[1], &endptr, 16); + if (endptr[0] != '\0') { + fprintf(stderr, "Bad capabilities\n"); + exit(1); + } + + if ((fd = open(argv[2], O_RDONLY)) < 0) { + fprintf(stderr, "Unable to open %s\n", argv[2]); + exit(1); + } + if (read(fd, &srv_config.key_perma.public, sizeof(ecp_ecdh_public_t)) != sizeof(ecp_ecdh_public_t)) { + close(fd); + fprintf(stderr, "Unable to read public key from %s\n", argv[2]); + exit(1); + } + if (read(fd, &srv_config.key_perma.private, sizeof(ecp_ecdh_private_t)) != sizeof(ecp_ecdh_private_t)) { + close(fd); + fprintf(stderr, "Unable to read private key from %s\n", argv[2]); + exit(1); + } + close(fd); + srv_config.key_perma.valid = 1; + + rv = ecp_init(&ctx, &vconn_handler, &vlink_handler); + if (rv) { + fprintf(stderr, "ecp_init RV:%d\n", rv); + exit(1); + } + rv = ecp_sock_create(&sock, &ctx, &srv_config.key_perma); + if (rv) { + fprintf(stderr, "ecp_sock_create RV:%d\n", rv); + exit(1); + } + + + rv = ecp_addr_init(&addr, argv[3]); + if (rv) { + fprintf(stderr, "ecp_addr_init RV:%d\n", rv); + exit(1); + } + + rv = ecp_sock_open(&sock, &addr); + if (rv) { + fprintf(stderr, "ecp_sock_open RV:%d\n", rv); + exit(1); + } + + rv = dir_init(&ctx); + if (rv) { + fprintf(stderr, "dir_init RV:%d\n", rv); + exit(1); + } + + rv = vlink_init(&ctx); + if (rv) { + fprintf(stderr, "vlink_init RV:%d\n", rv); + exit(1); + } + + rv = dir_start_announce(&sock); + if (rv) { + fprintf(stderr, "dir_start_announce RV:%d\n", rv); + exit(1); + } + + rv = vlink_start_open(&sock); + if (rv) { + fprintf(stderr, "vlink_start_open RV:%d\n", rv); + exit(1); + } + + rv = vlink_start_keyx(); + if (rv) { + fprintf(stderr, "vlink_start_keyx RV:%d\n", rv); + exit(1); + } + + if (argc == 6) { + ECPNode node; + ecp_ecdh_public_t node_pub; + ecp_tr_addr_t node_addr; + + if ((fd = open(argv[4], O_RDONLY)) < 0) { + fprintf(stderr, "Unable to open %s\n", argv[4]); + exit(1); + } + if (read(fd, &node_pub, sizeof(ecp_ecdh_public_t)) != sizeof(ecp_ecdh_public_t)) { + close(fd); + fprintf(stderr, "Unable to read public key from %s\n", argv[4]); + exit(1); + } + close(fd); + + int rv; + + ecp_node_init(&node, &node_pub, NULL); + rv = ecp_node_set_addr(&node, argv[5]); + if (rv) { + fprintf(stderr, "ecp_node_set_addr RV:%d\n", rv); + exit(1); + } + + rv = dir_open_conn(&sock, &node); + if (rv) { + fprintf(stderr, "dir_open_conn RV:%d\n", rv); + exit(1); + } + } + + ecp_receiver(&sock); +}
\ No newline at end of file diff --git a/ecp/server/server.h b/ecp/server/server.h new file mode 100644 index 0000000..ff8e444 --- /dev/null +++ b/ecp/server/server.h @@ -0,0 +1,15 @@ +#include <stdio.h> + +#define LOG_DEBUG 1 +#define LOG_INFO 2 +#define LOG_ERR 3 + +#define LOG_LEVEL LOG_DEBUG +#define LOG(l, ...) (l >= LOG_LEVEL ? fprintf(stderr, __VA_ARGS__) : 0 ) + +typedef struct SRVConfig { + ECPDHKey key_perma; + uint16_t capabilities; +} SRVConfig; + +SRVConfig *srv_get_config(void); diff --git a/ecp/server/vlink.c b/ecp/server/vlink.c new file mode 100644 index 0000000..e98dacc --- /dev/null +++ b/ecp/server/vlink.c @@ -0,0 +1,321 @@ +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include <ecp/core.h> +#include <ecp/dir/dir.h> +#include <ecp/vconn/vconn.h> +#include <ecp/ht.h> +#include <ecp/tm.h> + +#include "server.h" +#include "dir.h" +#include "ht.h" + +#include "vlink.h" + +static ecp_ht_table_t *vlink_conn = NULL; +static ecp_ht_table_t *vlink_node = NULL; +static pthread_mutex_t vlink_conn_mutex; +static pthread_mutex_t vlink_node_mutex; +static pthread_t vlink_open_thd; +static pthread_t vlink_keyx_thd; + +static SRVConfig *srv_config; + +void vlink_handle_err(ECPConnection *conn, unsigned char mtype, int err) { + switch (mtype) { + case ECP_MTYPE_OPEN_REP: { + if (err == ECP_ERR_TIMEOUT) { + int rv; + + rv = vlink_insert_node(conn); + if (rv) LOG(LOG_ERR, "vlink insert node err:%d\n", rv); + } + ecp_conn_close(conn); + break; + } + } +} + +int vlink_handle_open(ECPConnection *conn, ECP2Buffer *bufs) { + int rv; + + rv = ecp_vlink_handle_open(conn, bufs); + if (rv) return rv; + + if (ecp_conn_is_inb(conn)) return ECP_OK; + + pthread_mutex_lock(&vlink_conn_mutex); + rv = ht_insert_conn(vlink_conn, conn); + pthread_mutex_unlock(&vlink_conn_mutex); + + if (rv) { + ecp_vlink_handle_close(conn); + return rv; + } + + return ECP_OK; +} + +void vlink_handle_close(ECPConnection *conn) { + int rv; + + ecp_vlink_handle_close(conn); + + if (ecp_conn_is_inb(conn)) return; + + rv = vlink_insert_node(conn); + if (rv) LOG(LOG_ERR, "vlink insert node err:%d\n", rv); +} + +int vlink_open_conn(ECPSocket *sock, ECPNode *node) { + ECPConnection *conn; + int rv; + + conn = malloc(sizeof(ECPConnection)); + if (conn == NULL) return ECP_ERR_ALLOC; + + ecp_vlink_init(conn, sock); + rv = ecp_conn_open(conn, node); + return rv; +} + +void vlink_new_node(ECPSocket *sock, ECPDirItem *dir_item) { + if ((dir_item->capabilities & ECP_DIR_CAP_VCONN) && (memcmp(&dir_item->node.key_perma.public, &srv_config->key_perma.public, sizeof(srv_config->key_perma.public)) < 0)) { + int rv; + + LOG(LOG_DEBUG, "vlink open connection\n"); + rv = vlink_open_conn(sock, &dir_item->node); + if (rv) LOG(LOG_ERR, "vlink open connection err:%d\n", rv); + } +} + +int vlink_insert_node(ECPConnection *conn) { + DirNode *node; + int rv = ECP_OK; + + node = dir_search_conn(conn); + if (node) { + pthread_mutex_lock(&vlink_node_mutex); + rv = ht_insert_node(vlink_node, node); + pthread_mutex_unlock(&vlink_node_mutex); + + if (rv) { + pthread_mutex_lock(&node->mutex); + node->refcount--; + pthread_mutex_unlock(&node->mutex); + } + } + + return rv; +} + +void vlink_open(ECPSocket *sock) { + struct hashtable_itr itr; + DirNode *node; + DirNode *node_next; + DirNode *open_node[MAX_OPEN_CNT]; + int open_cnt; + int i; + int rv; + + node_next = NULL; + do { + open_cnt = 0; + pthread_mutex_lock(&vlink_node_mutex); + + if (ecp_ht_count(vlink_node) > 0) { + ecp_ht_itr_create(&itr, vlink_node); + if (node_next) { + rv = ecp_ht_itr_search(&itr, node_next); + if (rv) { + LOG(LOG_ERR, "vlink open itr search err:%d\n", rv); + break; + } + node_next = NULL; + } + do { + node = ecp_ht_itr_value(&itr); + rv = ecp_ht_itr_remove(&itr); + + open_node[open_cnt] = node; + open_cnt++; + if (open_cnt == MAX_OPEN_CNT) { + if (!rv) { + node_next = ecp_ht_itr_key(&itr); + } else { + node_next = NULL; + } + } + } while (rv == ECP_OK); + } + + pthread_mutex_unlock(&vlink_node_mutex); + + for (i=0; i<open_cnt; i++) { + pthread_mutex_lock(&open_node[i]->mutex); + + if (open_node[i]->zombie) { + open_node[i]->refcount--; + + pthread_mutex_unlock(&open_node[i]->mutex); + } else { + pthread_mutex_unlock(&open_node[i]->mutex); + + LOG(LOG_DEBUG, "vlink open connection\n"); + rv = vlink_open_conn(sock, &open_node[i]->dir_item.node); + if (rv) LOG(LOG_ERR, "vlink open connection err:%d\n", rv); + } + } + } while (node_next); +} + +void vlink_keyx(void) { + struct hashtable_itr itr; + ecp_sts_t now; + ECPConnection *conn; + ECPConnection *keyx_next; + ECPConnection *keyx_conn[MAX_KEYX_CNT]; + int keyx_conn_z[MAX_KEYX_CNT]; + int keyx_cnt; + int is_zombie; + int i; + int rv; + + now = ecp_tm_get_s(); + keyx_next = NULL; + do { + keyx_cnt = 0; + pthread_mutex_lock(&vlink_conn_mutex); + + if (ecp_ht_count(vlink_conn) > 0) { + ecp_ht_itr_create(&itr, vlink_conn); + if (keyx_next) { + rv = ecp_ht_itr_search(&itr, keyx_next); + if (rv) { + LOG(LOG_ERR, "vlink keyx itr search err:%d\n", rv); + break; + } + keyx_next = NULL; + } + do { + conn = ecp_ht_itr_value(&itr); + + is_zombie = ecp_conn_is_zombie(conn, now, CONN_EXP_TIME); + if (is_zombie) { + rv = ecp_ht_itr_remove(&itr); + } else { + rv = ecp_ht_itr_advance(&itr); + } + + keyx_conn[keyx_cnt] = conn; + keyx_conn_z[keyx_cnt] = is_zombie; + keyx_cnt++; + + if (keyx_cnt == MAX_KEYX_CNT) { + if (!rv) { + keyx_next = ecp_ht_itr_key(&itr); + } else { + keyx_next = NULL; + } + } + } while (rv == ECP_OK); + } + + pthread_mutex_unlock(&vlink_conn_mutex); + + for (i=0; i<keyx_cnt; i++) { + if (keyx_conn_z[i]) { + LOG(LOG_DEBUG, "vlink close connection\n"); + ecp_conn_close(keyx_conn[i]); + } else { + ssize_t _rv; + + LOG(LOG_DEBUG, "vlink send keyx\n"); + _rv = ecp_send_keyx_req(keyx_conn[i], 1); + if (_rv < 0) LOG(LOG_ERR, "vlink send keyx err:%ld\n", _rv); + } + } + } while (keyx_next); +} + +static void *_vlink_open(void *arg) { + ECPSocket *sock = arg; + + while (1) { + LOG(LOG_DEBUG, "vlink open...\n"); + vlink_open(sock); + sleep(10); + } + + return NULL; +} + +static void *_vlink_keyx(void *arg) { + while (1) { + LOG(LOG_DEBUG, "vlink keyx...\n"); + vlink_keyx(); + sleep(10); + } + + return NULL; +} + +int vlink_start_open(ECPSocket *sock) { + int rv; + + rv = pthread_create(&vlink_open_thd, NULL, _vlink_open, sock); + if (rv) return ECP_ERR; + return ECP_OK; +} + +int vlink_start_keyx(void) { + int rv; + + rv = pthread_create(&vlink_keyx_thd, NULL, _vlink_keyx, NULL); + if (rv) return ECP_ERR; + return ECP_OK; +} + +int vlink_init(ECPContext *ctx) { + ECPConnHandler *handler; + int rv; + + srv_config = srv_get_config(); + + handler = ecp_ctx_get_handler(ctx, ECP_CTYPE_VLINK); + if (handler == NULL) return ECP_ERR; + + handler->handle_open = vlink_handle_open; + handler->handle_close = vlink_handle_close; + + rv = pthread_mutex_init(&vlink_conn_mutex, NULL); + if (rv) { + return ECP_ERR; + } + + rv = pthread_mutex_init(&vlink_node_mutex, NULL); + if (rv) { + pthread_mutex_destroy(&vlink_conn_mutex); + return ECP_ERR; + } + + rv = ECP_OK; + vlink_conn = ecp_ht_create_keys(); + if (vlink_conn == NULL) rv = ECP_ERR_ALLOC; + if (!rv) { + vlink_node = ecp_ht_create_keys(); + if (vlink_node == NULL) rv = ECP_ERR_ALLOC; + } + + if (rv) { + pthread_mutex_destroy(&vlink_node_mutex); + pthread_mutex_destroy(&vlink_conn_mutex); + if (vlink_node) ecp_ht_destroy(vlink_node); + if (vlink_conn) ecp_ht_destroy(vlink_conn); + return rv; + } + + return ECP_OK; +} diff --git a/ecp/server/vlink.h b/ecp/server/vlink.h new file mode 100644 index 0000000..78af6b1 --- /dev/null +++ b/ecp/server/vlink.h @@ -0,0 +1,17 @@ +#define MAX_KEYX_CNT 100 +#define MAX_OPEN_CNT 100 + +#define CONN_EXP_TIME 22 + +void vlink_handle_err(ECPConnection *conn, unsigned char mtype, int err); +int vlink_handle_open(ECPConnection *conn, ECP2Buffer *bufs); +void vlink_handle_close(ECPConnection *conn); +int vlink_open_conn(ECPSocket *sock, ECPNode *node); +void vlink_new_node(ECPSocket *sock, ECPDirItem *item); +int vlink_insert_node(ECPConnection *conn); + +void vlink_keyx(void); +void vlink_open(ECPSocket *sock); +int vlink_start_open(ECPSocket *sock); +int vlink_start_keyx(void); +int vlink_init(ECPContext *ctx); diff --git a/ecp/src/ecp/common.mk b/ecp/src/ecp/common.mk index a07b5c5..9380130 100644 --- a/ecp/src/ecp/common.mk +++ b/ecp/src/ecp/common.mk @@ -7,11 +7,7 @@ platform_dir = $(abspath $(src_dir)/platform/$(platform)) include $(platform_dir)/platform.mk include $(platform_dir)/features.mk -CFLAGS += -I$(src_dir)/ecp -I$(ssl_dir)/include -I$(platform_dir) - -ifeq ($(with_dirsrv),yes) -with_dir = yes -endif +CFLAGS += -I$(src_dir) -I$(platform_dir) -I$(ssl_dir)/include ifeq ($(with_pthread),yes) CFLAGS += -DECP_WITH_PTHREAD=1 @@ -27,24 +23,29 @@ CFLAGS += -DECP_WITH_VCONN=1 subdirs += vconn endif +ifeq ($(with_frag),yes) +CFLAGS += -DECP_WITH_FRAG=1 +ext_subdir = yes +endif + ifeq ($(with_rbuf),yes) CFLAGS += -DECP_WITH_RBUF=1 -subdirs += ext +ext_subdir = yes endif ifeq ($(with_msgq),yes) CFLAGS += -DECP_WITH_MSGQ=1 endif +ifdef ext_subdir +subdirs += ext +endif + ifeq ($(with_dir),yes) CFLAGS += -DECP_WITH_DIR=1 subdirs += dir endif -ifeq ($(with_dirsrv),yes) -CFLAGS += -DECP_WITH_DIRSRV=1 -endif - ifeq ($(with_debug),yes) CFLAGS += -DECP_DEBUG=1 endif diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c index 3d4342d..9585388 100644 --- a/ecp/src/ecp/core.c +++ b/ecp/src/ecp/core.c @@ -12,10 +12,6 @@ #include "vconn/vconn.h" #endif -#ifdef ECP_WITH_DIR -#include "dir/dir.h" -#endif - #include "cr.h" #include "tr.h" #include "tm.h" @@ -34,13 +30,12 @@ int ecp_dhkey_gen(ECPDHKey *key) { return ECP_OK; } -int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_dir_handler_t handle_dir, ecp_conn_alloc_t conn_alloc, ecp_conn_free_t conn_free) { +int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free) { int rv; memset(ctx, 0, sizeof(ECPContext)); ctx->handle_err = handle_err; - ctx->handle_dir = handle_dir; - ctx->conn_alloc = conn_alloc; + ctx->conn_new = conn_new; ctx->conn_free = conn_free; rv = ecp_tr_init(ctx); @@ -52,14 +47,44 @@ int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_dir_handler_ return ECP_OK; } -int ecp_ctx_set_handler(ECPContext *ctx, ECPConnHandler *handler, unsigned char ctype) { - if (ctype >= ECP_MAX_CTYPE) return ECP_ERR_CTYPE; +int ecp_ctx_set_handler(ECPContext *ctx, unsigned char ctype, ECPConnHandler *handler) { + unsigned char _ctype = ctype & ECP_CTYPE_MASK; - ctx->handler[ctype] = handler; + if (ctype & ECP_CTYPE_FLAG_SYS) { + if (_ctype >= ECP_MAX_CTYPE_SYS) return ECP_ERR_CTYPE; + ctx->handler_sys[_ctype] = handler; + } else { + if (_ctype >= ECP_MAX_CTYPE) return ECP_ERR_CTYPE; + ctx->handler[_ctype] = handler; + } return ECP_OK; } -int ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, void *addr) { +ECPConnHandler *ecp_ctx_get_handler(ECPContext *ctx, unsigned char ctype) { + unsigned char _ctype = ctype & ECP_CTYPE_MASK; + + if (ctype & ECP_CTYPE_FLAG_SYS) { + if (_ctype >= ECP_MAX_CTYPE_SYS) return NULL; + return ctx->handler_sys[_ctype]; + } else { + if (_ctype >= ECP_MAX_CTYPE) return NULL; + return ctx->handler[_ctype]; + } + return NULL; +} + +int ecp_addr_init(ecp_tr_addr_t *addr, void *addr_s) { + int rv = ECP_OK; + + memset(addr, 0, sizeof(ecp_tr_addr_t)); + if (addr_s) { + 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) { @@ -70,13 +95,8 @@ int ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, void *addr) { } if (addr) { - int rv; - - rv = ecp_tr_addr_set(&node->addr, addr); - if (rv) return ECP_ERR_NET_ADDR; + node->addr = *addr; } - - return ECP_OK; } void ecp_node_set_pub(ECPNode *node, ecp_ecdh_public_t *public) { @@ -106,7 +126,7 @@ static int conn_table_create(ECPConnTable *conn_table) { return ECP_ERR; } - rv = pthread_mutex_init(&conn_table->mutex_inb, NULL); + rv = pthread_mutex_init(&conn_table->mutex_gc, NULL); if (rv) { pthread_mutex_destroy(&conn_table->mutex); return ECP_ERR; @@ -120,8 +140,8 @@ static int conn_table_create(ECPConnTable *conn_table) { if (conn_table->keys == NULL) rv = ECP_ERR_ALLOC; if (!rv) { - conn_table->keys_inb = ecp_ht_create_keys(); - if (conn_table->keys_inb == NULL) rv = ECP_ERR_ALLOC; + conn_table->keys_gc = ecp_ht_create_keys(); + if (conn_table->keys_gc == NULL) rv = ECP_ERR_ALLOC; } if (!rv) { @@ -131,11 +151,11 @@ static int conn_table_create(ECPConnTable *conn_table) { if (rv) { #ifdef ECP_WITH_PTHREAD - pthread_mutex_destroy(&conn_table->mutex_inb); + pthread_mutex_destroy(&conn_table->mutex_gc); pthread_mutex_destroy(&conn_table->mutex); #endif if (conn_table->addrs) ecp_ht_destroy(conn_table->addrs); - if (conn_table->keys_inb) ecp_ht_destroy(conn_table->keys_inb); + if (conn_table->keys_gc) ecp_ht_destroy(conn_table->keys_gc); if (conn_table->keys) ecp_ht_destroy(conn_table->keys); } #endif @@ -145,12 +165,12 @@ static int conn_table_create(ECPConnTable *conn_table) { static void conn_table_destroy(ECPConnTable *conn_table) { #ifdef ECP_WITH_PTHREAD - pthread_mutex_destroy(&conn_table->mutex_inb); + pthread_mutex_destroy(&conn_table->mutex_gc); pthread_mutex_destroy(&conn_table->mutex); #endif #ifdef ECP_WITH_HTABLE ecp_ht_destroy(conn_table->addrs); - ecp_ht_destroy(conn_table->keys_inb); + ecp_ht_destroy(conn_table->keys_gc); ecp_ht_destroy(conn_table->keys); #endif } @@ -162,7 +182,7 @@ static int conn_table_insert(ECPConnection *conn) { int i, rv = ECP_OK; if (ecp_conn_is_outb(conn)) { - if (ecp_conn_is_root(conn) && !ecp_conn_is_open(conn)) { + if (ecp_conn_is_root(conn) && !_ecp_conn_is_open(conn)) { rv = ecp_ht_insert(sock->conn_table.addrs, &conn->remote.addr, conn); if (rv) return rv; } @@ -178,8 +198,8 @@ static int conn_table_insert(ECPConnection *conn) { ecp_ht_remove(sock->conn_table.keys, &conn->key[j].public); } } - if (ecp_conn_is_root(conn) && !ecp_conn_is_open(conn)) { - ecp_ht_remove(sock->conn_table.addrs, &conn->remote.addr); + if (ecp_conn_is_root(conn) && !_ecp_conn_is_open(conn)) { + ecp_ht_remove_kv(sock->conn_table.addrs, &conn->remote.addr, conn); } return rv; } @@ -214,16 +234,12 @@ static int conn_table_insert(ECPConnection *conn) { return ECP_OK; } -static int conn_table_insert_inb(ECPConnection *conn) { +static int conn_table_insert_gc(ECPConnection *conn) { ECPSocket *sock = conn->sock; int rv = ECP_OK; #ifdef ECP_WITH_HTABLE - unsigned char idx; - - idx = conn->rkey_curr % ECP_MAX_NODE_KEY; - - rv = ecp_ht_insert(sock->conn_table.keys_inb, &conn->rkey[idx].public, conn); + rv = ecp_ht_insert(sock->conn_table.keys_gc, &conn->remote.key_perma.public, conn); #endif return rv; @@ -241,8 +257,8 @@ static void conn_table_remove(ECPConnection *conn) { ecp_ht_remove(sock->conn_table.keys, &conn->key[i].public); } } - if (ecp_conn_is_root(conn) && !ecp_conn_is_open(conn)) { - ecp_ht_remove(sock->conn_table.addrs, &conn->remote.addr); + if (ecp_conn_is_root(conn) && !_ecp_conn_is_open(conn)) { + ecp_ht_remove_kv(sock->conn_table.addrs, &conn->remote.addr, conn); } } else { for (i=0; i<ECP_MAX_NODE_KEY; i++) { @@ -273,126 +289,168 @@ static void conn_table_remove_addr(ECPConnection *conn) { ECPSocket *sock = conn->sock; #ifdef ECP_WITH_HTABLE - ecp_ht_remove(sock->conn_table.addrs, &conn->remote.addr); + ecp_ht_remove_kv(sock->conn_table.addrs, &conn->remote.addr, conn); #endif } -static ECPConnection *conn_table_search(ECPSocket *sock, unsigned char c_idx, ecp_ecdh_public_t *c_public, ecp_tr_addr_t *addr, ECPConnection *parent) { -#ifdef ECP_WITH_VCONN - if ((c_public == NULL) && parent) { - return parent->next; - } -#endif - +static ECPConnection *conn_table_search_pub(ECPSocket *sock, unsigned char c_idx, ecp_ecdh_public_t *c_public) { #ifdef ECP_WITH_HTABLE + return ecp_ht_search(sock->conn_table.keys, c_public); +#else /* ECP_WITH_HTABLE */ + ECPConnection *conn = NULL; + int i; - if (c_public) { - return ecp_ht_search(sock->conn_table.keys, c_public); - } else if (addr) { - return ecp_ht_search(sock->conn_table.addrs, addr); - } else { - return NULL; + for (i=0; i<sock->conn_table.size; i++) { + conn = sock->conn_table.arr[i]; + if (ecp_conn_is_outb(conn)) { + if (c_idx >= ECP_MAX_CONN_KEY) continue; + + if (conn->key[c_idx].valid && ecp_ecdh_pub_eq(c_public, &conn->key[c_idx].public)) { + return conn; + } + } else { + unsigned char _c_idx; + + if (c_idx & ~ECP_ECDH_IDX_MASK) continue; + + _c_idx = c_idx % ECP_MAX_NODE_KEY; + if (conn->rkey[_c_idx].valid && ecp_ecdh_pub_eq(c_public, &conn->rkey[_c_idx].public)) { + return conn; + } + } } + return NULL; +#endif /* ECP_WITH_HTABLE */ +} +static ECPConnection *conn_table_search_addr(ECPSocket *sock, ecp_tr_addr_t *addr) { +#ifdef ECP_WITH_HTABLE + return ecp_ht_search(sock->conn_table.addrs, addr); #else /* ECP_WITH_HTABLE */ ECPConnection *conn = NULL; int i; - if (c_public) { - for (i=0; i<sock->conn_table.size; i++) { - conn = sock->conn_table.arr[i]; - if (ecp_conn_is_outb(conn)) { - if (c_idx >= ECP_MAX_CONN_KEY) continue; + for (i=0; i<sock->conn_table.size; i++) { + conn = sock->conn_table.arr[i]; + if (ecp_conn_is_root(conn) && ecp_conn_is_outb(conn) && ecp_tr_addr_eq(&conn->remote.addr, addr)) { + return conn; + } + } - if (conn->key[c_idx].valid && ecp_ecdh_pub_eq(c_public, &conn->key[c_idx].public)) { - return conn; - } - } else { - unsigned char _c_idx; + return NULL; +#endif /* ECP_WITH_HTABLE */ +} - if (c_idx & ~ECP_ECDH_IDX_MASK) continue; +static ECPConnection *conn_table_search_addr_next(ECPSocket *sock, ecp_tr_addr_t *addr, ECPConnection *_conn) { +#ifdef ECP_WITH_HTABLE + return ecp_ht_search_next(sock->conn_table.addrs, addr, _conn); +#else /* ECP_WITH_HTABLE */ + ECPConnection *conn = NULL; + int i, f; - _c_idx = c_idx % ECP_MAX_NODE_KEY; - if (conn->rkey[_c_idx].valid && ecp_ecdh_pub_eq(c_public, &conn->rkey[_c_idx].public)) { - return conn; - } - } - } - } else if (addr) { - for (i=0; i<sock->conn_table.size; i++) { - conn = sock->conn_table.arr[i]; + f = 0; + for (i=0; i<sock->conn_table.size; i++) { + conn = sock->conn_table.arr[i]; + if (f) if (ecp_conn_is_root(conn) && ecp_conn_is_outb(conn) && ecp_tr_addr_eq(&conn->remote.addr, addr)) { return conn; } + } else if (conn == _conn) { + f = 1; } } return NULL; - #endif /* ECP_WITH_HTABLE */ } -static void conn_table_expire_inb(ECPSocket *sock, ecp_sts_t to) { +static ECPConnection *conn_table_search(ECPSocket *sock, unsigned char c_idx, ecp_ecdh_public_t *c_public, ecp_tr_addr_t *addr, ECPConnection *parent) { +#ifdef ECP_WITH_VCONN + if ((c_public == NULL) && parent) { + if ((parent->type == ECP_CTYPE_VCONN) && ecp_conn_is_outb(parent)) { + ECPVConnOutb *_parent = (ECPVConnOutb *)parent; + + return _parent->next; + } + return NULL; + } +#endif + + if (c_public) { + return conn_table_search_pub(sock, c_idx, c_public); + } else if (addr) { + return conn_table_search_addr(sock, addr); + } + + return NULL; +} + +static void conn_table_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t conn_expired) { ECPConnection *conn; ECPConnection *to_remove[ECP_MAX_EXP]; - int i, remove_cnt; - ecp_sts_t access_ts, now = ecp_tm_get_tick(); + int i, remove_cnt, expired; + ecp_sts_t now = ecp_tm_get_s(); #ifdef ECP_WITH_HTABLE struct hashtable_itr itr; void *remove_next; int rv = ECP_OK; + remove_next = NULL; do { + ecp_ht_table_t *keys_gc = sock->conn_table.keys_gc; remove_cnt = 0; #ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&sock->conn_table.mutex_inb); + pthread_mutex_lock(&sock->conn_table.mutex_gc); #endif - ecp_ht_itr_create(&itr, sock->conn_table.keys_inb); - if (remove_next) { - ecp_ht_itr_search(&itr, remove_next); - remove_next = NULL; - } - do { - conn = ecp_ht_itr_value(&itr); - if (conn) { + if (ecp_ht_count(keys_gc) > 0) { + ecp_ht_itr_create(&itr, keys_gc); + if (remove_next) { + ecp_ht_itr_search(&itr, remove_next); + remove_next = NULL; + } + do { + conn = ecp_ht_itr_value(&itr); + #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); #endif - access_ts = conn->access_ts; + expired = conn_expired(conn, now, to); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); #endif - if (now - access_ts > to) { + if (expired) { + rv = ecp_ht_itr_remove(&itr); + to_remove[remove_cnt] = conn; remove_cnt++; - rv = ecp_ht_itr_remove(&itr); if (remove_cnt == ECP_MAX_EXP) { - if (!rv) remove_next = ecp_ht_itr_key(&itr); + if (!rv) { + remove_next = ecp_ht_itr_key(&itr); + } else { + remove_next = NULL; + } break; } } else { rv = ecp_ht_itr_advance(&itr); } - } else { - rv = ECP_ITR_END; - } - } while (rv == ECP_OK); + } while (rv == ECP_OK); + } #ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&sock->conn_table.mutex_inb); + pthread_mutex_unlock(&sock->conn_table.mutex_gc); #endif for (i=0; i<remove_cnt; i++) { _ecp_conn_close(to_remove[i]); } - } while (remove_next); #else /* ECP_WITH_HTABLE */ @@ -406,18 +464,18 @@ static void conn_table_expire_inb(ECPSocket *sock, ecp_sts_t to) { for (i=0; i<sock->conn_table.size; i++) { conn = sock->conn_table.arr[i]; - if (ecp_conn_is_inb(conn)) { + if (ecp_conn_is_gc(conn)) { #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); #endif - access_ts = conn->access_ts; + expired = conn_expired(conn, now, to); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); #endif - if (now - access_ts > to) { + if (expired) { to_remove[remove_cnt] = conn; remove_cnt++; if (remove_cnt == ECP_MAX_EXP) break; @@ -492,7 +550,7 @@ void ecp_sock_destroy(ECPSocket *sock) { #endif } -int ecp_sock_open(ECPSocket *sock, void *myaddr) { +int ecp_sock_open(ECPSocket *sock, ecp_tr_addr_t *myaddr) { return ecp_tr_open(sock, myaddr); } @@ -606,11 +664,20 @@ void ecp_sock_get_nonce(ECPSocket *sock, ecp_nonce_t *nonce) { #endif } +static int _conn_expired_inb(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to) { + if (ecp_conn_is_inb(conn) && _ecp_conn_expired(conn, now, to)) return 1; + return 0; +} + +void ecp_sock_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t conn_expired) { + conn_table_expire(sock, to, conn_expired); +} + int ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to) { int rv; rv = ecp_sock_minkey_new(sock); - if (!rv) conn_table_expire_inb(sock, to); + if (!rv) conn_table_expire(sock, to, _conn_expired_inb); return rv; } @@ -664,7 +731,7 @@ static int conn_dhkey_new(ECPConnection *conn, unsigned char idx, ECPDHKey *key) if (idx >= ECP_MAX_CONN_KEY) return ECP_ERR_ECDH_IDX; #ifdef ECP_WITH_HTABLE - if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn) && conn->key[idx].valid) { + if (ecp_conn_is_outb(conn) && _ecp_conn_is_reg(conn) && conn->key[idx].valid) { ecp_ht_remove(sock->conn_table.keys, &conn->key[idx].public); } #endif @@ -672,7 +739,7 @@ static int conn_dhkey_new(ECPConnection *conn, unsigned char idx, ECPDHKey *key) conn->key[idx] = *key; #ifdef ECP_WITH_HTABLE - if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn)) { + if (ecp_conn_is_outb(conn) && _ecp_conn_is_reg(conn)) { int rv; rv = ecp_ht_insert(sock->conn_table.keys, &conn->key[idx].public, conn); @@ -689,7 +756,7 @@ static void conn_dhkey_del(ECPConnection *conn, unsigned char idx) { if (idx >= ECP_MAX_CONN_KEY) return; #ifdef ECP_WITH_HTABLE - if (ecp_conn_is_outb(conn) && ecp_conn_is_reg(conn) && conn->key[idx].valid) { + if (ecp_conn_is_outb(conn) && _ecp_conn_is_reg(conn) && conn->key[idx].valid) { ecp_ht_remove(sock->conn_table.keys, &conn->key[idx].public); } #endif @@ -723,7 +790,7 @@ static ECPDHPub *conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx) { } /* node will send public key */ -static void conn_dhkey_get_pub(ECPConnection *conn, unsigned char idx) { +static void conn_dhkey_send_pub(ECPConnection *conn, unsigned char idx) { unsigned char _idx; int i; @@ -754,10 +821,10 @@ static int conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_p _idx = idx % ECP_MAX_NODE_KEY; key = &conn->rkey[_idx]; - if (key->valid && (memcmp(public, &key->public, sizeof(key->public)) == 0)) return ECP_ERR_ECDH_KEY_DUP; + if (key->valid && (memcmp(public, &key->public, sizeof(key->public)) == 0)) return ECP_ERR_DUP; #ifdef ECP_WITH_HTABLE - if (ecp_conn_is_inb(conn) && ecp_conn_is_reg(conn) && (key->valid)) { + if (ecp_conn_is_inb(conn) && _ecp_conn_is_reg(conn) && (key->valid)) { ecp_ht_remove(sock->conn_table.keys, &key->public); } #endif @@ -766,7 +833,7 @@ static int conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_p key->valid = 1; #ifdef ECP_WITH_HTABLE - if (ecp_conn_is_inb(conn) && ecp_conn_is_reg(conn)) { + if (ecp_conn_is_inb(conn) && _ecp_conn_is_reg(conn)) { int rv; rv = ecp_ht_insert(sock->conn_table.keys, &key->public, conn); @@ -847,24 +914,11 @@ static int conn_shkey_set(ECPConnection *conn, unsigned char s_idx, unsigned cha return ECP_OK; } -int ecp_conn_alloc(ECPSocket *sock, unsigned char ctype, ECPConnection **_conn) { +ECPConnection *ecp_conn_new_inb(ECPSocket *sock, unsigned char ctype) { ECPContext *ctx = sock->ctx; - ECPConnection *conn; - int rv; - if (ctx->conn_alloc == NULL) return ECP_ERR_ALLOC; - - conn = ctx->conn_alloc(sock, ctype); - if (conn == NULL) return ECP_ERR_ALLOC; - - *_conn = conn; - return ECP_OK; -} - -void ecp_conn_free(ECPConnection *conn) { - ECPContext *ctx = conn->sock->ctx; - - if (ctx->conn_free) ctx->conn_free(conn); + if (ctx->conn_new) return ctx->conn_new(sock, ctype); + return NULL; } void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) { @@ -878,138 +932,146 @@ void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) { conn->key_next = ECP_ECDH_IDX_INV; conn->rkey_curr = ECP_ECDH_IDX_INV; arc4random_buf(&conn->nonce_out, sizeof(conn->nonce_out)); + conn->access_ts = ecp_tm_get_s(); } -void ecp_conn_reinit(ECPConnection *conn) { - conn->flags = 0; +int ecp_conn_reset(ECPConnection *conn) { + if (conn->flags) return ECP_ERR; + + conn->key_curr = ECP_ECDH_IDX_INV; conn->key_next = ECP_ECDH_IDX_INV; conn->rkey_curr = ECP_ECDH_IDX_INV; memset(&conn->key, 0, sizeof(conn->key)); memset(&conn->rkey, 0, sizeof(conn->rkey)); memset(&conn->shkey, 0, sizeof(conn->shkey)); arc4random_buf(&conn->nonce_out, sizeof(conn->nonce_out)); + conn->nonce_in = 0; + conn->nonce_map = 0; + + return ECP_OK; } -int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) { +int ecp_conn_create(ECPConnection *conn, ECPConnection *parent) { int rv; +#ifdef ECP_WITH_VCONN + unsigned short pcount; - ecp_conn_init(conn, sock, ctype); + pcount = parent ? parent->pcount + 1 : 0; + if (pcount > ECP_MAX_PARENT) return ECP_ERR_MAX_PARENT; +#endif #ifdef ECP_WITH_PTHREAD rv = pthread_mutex_init(&conn->mutex, NULL); if (rv) return ECP_ERR; #endif - return ECP_OK; -} - -int ecp_conn_create_inb(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) { - int rv; - - rv = ecp_conn_create(conn, sock, ctype); - if (rv) return rv; - - ecp_conn_set_inb(conn); - -#ifdef ECP_WITH_VCONN - if (conn->parent) { - ecp_conn_refcount_inc(conn->parent); - } + rv = ecp_ext_conn_create(conn); + if (rv) { +#ifdef ECP_WITH_PTHREAD + pthread_mutex_destroy(&conn->mutex); #endif - return ECP_OK; -} - -void ecp_conn_destroy(ECPConnection *conn) { -#ifdef ECP_WITH_VCONN - if (ecp_conn_is_inb(conn) && conn->parent) { - ecp_conn_refcount_dec(conn->parent); + return ECP_ERR; } -#endif - ecp_ext_conn_destroy(conn); +#ifdef ECP_WITH_VCONN + if (parent) { + conn->parent = parent; + conn->pcount = pcount; -#ifdef ECP_WITH_PTHREAD - pthread_mutex_destroy(&conn->mutex); + ecp_conn_refcount_inc(parent); + } #endif -} - -void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags) { - flags &= flags & ECP_CONN_FLAG_MASK; - conn->flags_im |= flags; -} - -void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags) { - flags &= flags & ECP_CONN_FLAG_MASK; - conn->flags_im &= ~flags; -} - -void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key) { - conn->remote.key_perma = *key; -} -void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr) { - conn->remote.addr = *addr; + return ECP_OK; } -int ecp_conn_init_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *remote_key, ecp_aead_key_t *shkey) { +int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *remote_key, ecp_aead_key_t *shkey) { ECPSocket *sock = conn->sock; - unsigned short pcount; int rv; -#ifdef ECP_WITH_VCONN - pcount = (parent ? parent->pcount + 1 : 0); - if (pcount > ECP_MAX_PARENT) return ECP_ERR_MAX_PARENT; -#endif - if (ecp_conn_has_vbox(conn) && ((remote_key == NULL) || !remote_key->valid)) return ECP_ERR_VBOX; + ecp_conn_set_inb(conn); + rv = conn_dhkey_set_pub(conn, c_idx, public); if (rv) return rv; rv = conn_shkey_set(conn, s_idx, c_idx, shkey); if (rv) return rv; -#ifdef ECP_WITH_VCONN - conn->parent = parent; - conn->pcount = pcount; -#endif - + ecp_conn_set_flags(conn, ECP_CONN_FLAG_GC); conn->refcount = 1; conn->key_curr = s_idx; conn->rkey_curr = c_idx; - if (remote_key && remote_key->valid) conn->remote.key_perma = *remote_key; + if (remote_key && remote_key->valid) { + conn->remote.key_perma = *remote_key; + } else { + ECPDHPub *key_perma = &conn->remote.key_perma; + memcpy(&key_perma->public, public, sizeof(key_perma->public)); + } - return ECP_OK; + rv = ecp_conn_create(conn, parent); + return rv; +} + +int ecp_conn_create_outb(ECPConnection *conn, ECPConnection *parent, ECPNode *node) { + int rv; + + ecp_conn_set_outb(conn); + + conn->refcount = 1; + if (node) conn->remote = *node; + + rv = ecp_conn_reset_outb(conn); + if (rv) return rv; + + rv = ecp_conn_create(conn, parent); + return rv; } -int ecp_conn_init_outb(ECPConnection *conn, ECPNode *node) { +int ecp_conn_reset_outb(ECPConnection *conn) { ECPDHKey key; - unsigned char key_curr; int rv; - if (conn->key_curr == ECP_ECDH_IDX_INV) { - key_curr = 0; - } else { - key_curr = (conn->key_curr + 1) % ECP_MAX_CONN_KEY; - } + conn->key_curr = 0; + rv = ecp_dhkey_gen(&key); if (rv) return rv; - rv = conn_dhkey_new(conn, key_curr, &key); + rv = conn_dhkey_new(conn, conn->key_curr, &key); if (rv) return rv; - if (node) conn->remote = *node; - conn->key_curr = key_curr; - return ECP_OK; } +void ecp_conn_destroy(ECPConnection *conn) { +#ifdef ECP_WITH_VCONN + if (conn->parent) { + ecp_conn_refcount_dec(conn->parent); + } +#endif + + ecp_ext_conn_destroy(conn); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_destroy(&conn->mutex); +#endif + + ecp_conn_free(conn); +} + +void ecp_conn_free(ECPConnection *conn) { + ECPContext *ctx = conn->sock->ctx; + + if (ctx->conn_free) ctx->conn_free(conn); +} + int ecp_conn_insert(ECPConnection *conn) { ECPSocket *sock = conn->sock; int rv; - ecp_conn_set_reg(conn); + _ecp_conn_set_reg(conn); #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&sock->conn_table.mutex); @@ -1021,25 +1083,23 @@ int ecp_conn_insert(ECPConnection *conn) { pthread_mutex_unlock(&sock->conn_table.mutex); #endif - if (rv) ecp_conn_clr_reg(conn); + if (rv) _ecp_conn_clr_reg(conn); return rv; } -int ecp_conn_insert_inb(ECPConnection *conn) { +int ecp_conn_insert_gc(ECPConnection *conn) { ECPSocket *sock = conn->sock; int rv; #ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&sock->conn_table.mutex_inb); - pthread_mutex_lock(&conn->mutex); + pthread_mutex_lock(&sock->conn_table.mutex_gc); #endif - rv = conn_table_insert_inb(conn); + rv = conn_table_insert_gc(conn); #ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&conn->mutex); - pthread_mutex_unlock(&sock->conn_table.mutex_inb); + pthread_mutex_unlock(&sock->conn_table.mutex_gc); #endif return rv; @@ -1053,9 +1113,9 @@ void ecp_conn_remove(ECPConnection *conn, unsigned short *refcount) { pthread_mutex_lock(&conn->mutex); #endif - if (ecp_conn_is_reg(conn)) { + if (_ecp_conn_is_reg(conn)) { conn_table_remove(conn); - ecp_conn_clr_reg(conn); + _ecp_conn_clr_reg(conn); } if (refcount) *refcount = conn->refcount; @@ -1082,57 +1142,64 @@ void ecp_conn_remove_addr(ECPConnection *conn) { } -int ecp_conn_open(ECPConnection *conn, ECPNode *node) { +int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, ECPNode *node, int retry) { int rv; ssize_t _rv; - rv = ecp_conn_init_outb(conn, node); + rv = ecp_conn_create_outb(conn, parent, node); if (rv) return rv; rv = ecp_conn_insert(conn); - if (rv) return rv; + if (rv) { + ecp_conn_destroy(conn); + return rv; + } - _rv = ecp_send_init_req(conn); + if (ecp_conn_is_gc(conn)) { + rv = ecp_conn_insert_gc(conn); + if (rv) { + ecp_conn_refcount_dec(conn); + _ecp_conn_close(conn); + return rv; + } + } + + _rv = ecp_send_init_req(conn, retry); if (_rv < 0) { - ecp_timer_remove(conn); - ecp_conn_remove(conn, NULL); + ecp_conn_refcount_dec(conn); + ecp_conn_close(conn); return _rv; } + ecp_conn_refcount_dec(conn); + return ECP_OK; } -int ecp_conn_reset(ECPConnection *conn) { - unsigned short refcount = 0; - int i; +int ecp_conn_open(ECPConnection *conn, ECPNode *node) { int rv; - /* timer holds one reference to this connection */ - ecp_conn_remove(conn, &refcount); - if (refcount > 1) return ECP_ERR_BUSY; - - ecp_conn_reinit(conn); - if (rv) return rv; - - rv = ecp_conn_init_outb(conn, NULL); - if (rv) return rv; + rv = _ecp_conn_open(conn, NULL, node, 1); + return rv; +} - rv = ecp_conn_insert(conn); - if (rv) return rv; +int ecp_conn_try_open(ECPConnection *conn, ECPNode *node) { + int rv; - return ECP_OK; + rv = _ecp_conn_open(conn, NULL, node, 0); + return rv; } static void conn_close(ECPConnection *conn) { - if (ecp_conn_is_open(conn)) { + if (_ecp_conn_is_open(conn)) { ecp_close_handler_t handler; - ecp_conn_clr_open(conn); + _ecp_conn_clr_open(conn); handler = ecp_get_close_handler(conn); if (handler) handler(conn); + ecp_ext_conn_close(conn); } ecp_conn_destroy(conn); - if (ecp_conn_is_inb(conn)) ecp_conn_free(conn); } int _ecp_conn_close(ECPConnection *conn) { @@ -1147,8 +1214,49 @@ int _ecp_conn_close(ECPConnection *conn) { } int ecp_conn_close(ECPConnection *conn) { - if (ecp_conn_is_inb(conn)) return ECP_ERR; - return _ecp_conn_close(conn); + int rv; + + if (ecp_conn_is_gc(conn)) { + ecp_conn_mark_closed(conn); + rv = ECP_OK; + } else { + rv = _ecp_conn_close(conn); + } + + return rv; +} + +void ecp_conn_mark_closed(ECPConnection *conn) { +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + _ecp_conn_set_closed(conn); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif +} + +int _ecp_conn_expired(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to) { + if (_ecp_conn_is_closed(conn) || (ECP_STS_LT(conn->access_ts, now) && (now - conn->access_ts > to))) return 1; + return 0; +} + +int ecp_conn_is_zombie(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to) { + int z = 0; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + z = _ecp_conn_expired(conn, now, to); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif + + return z; } void ecp_conn_refcount_inc(ECPConnection *conn) { @@ -1173,7 +1281,7 @@ void ecp_conn_refcount_dec(ECPConnection *conn) { conn->refcount--; refcount = conn->refcount; - is_reg = ecp_conn_is_reg(conn); + is_reg = _ecp_conn_is_reg(conn); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); @@ -1182,6 +1290,24 @@ void ecp_conn_refcount_dec(ECPConnection *conn) { if (!is_reg && (refcount == 0)) conn_close(conn); } +void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags) { + flags &= ECP_CONN_FLAG_MASK; + conn->flags_im |= flags; +} + +void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags) { + flags &= ECP_CONN_FLAG_MASK; + conn->flags_im &= ~flags; +} + +void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key) { + conn->remote.key_perma = *key; +} + +void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr) { + conn->remote.addr = *addr; +} + int ecp_conn_dhkey_new(ECPConnection *conn) { ECPSocket *sock = conn->sock; ECPDHKey new_key; @@ -1208,13 +1334,9 @@ int ecp_conn_dhkey_new(ECPConnection *conn) { pthread_mutex_unlock(&conn->mutex); if (ecp_conn_is_outb(conn)) pthread_mutex_unlock(&sock->conn_table.mutex); #endif - if (idx == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX; - if (rv) return rv; - - _rv = ecp_send_keyx_req(conn); - if (_rv < 0) return _rv; - return ECP_OK; + if (idx == ECP_ECDH_IDX_INV) return ECP_ERR_ECDH_IDX; + return rv; } int ecp_conn_dhkey_get(ECPConnection *conn, unsigned char idx, ECPDHKey *key) { @@ -1274,7 +1396,6 @@ int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_pub #ifdef ECP_WITH_PTHREAD if (will_send) pthread_mutex_lock(&conn->mutex); #endif - } else { ECPDHKey *key; @@ -1282,7 +1403,7 @@ int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_pub pthread_mutex_lock(&conn->mutex); #endif - if (will_send) { + if (will_send && (conn->key_next != ECP_ECDH_IDX_INV)) { _idx = conn->key_next; } else { _idx = conn->key_curr; @@ -1296,7 +1417,7 @@ int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_pub if (!rv) memcpy(public, &key->public, sizeof(key->public)); } - if (!rv && will_send) conn_dhkey_get_pub(conn, _idx); + if (!rv && will_send) conn_dhkey_send_pub(conn, _idx); #ifdef ECP_WITH_PTHREAD if (will_send || ecp_conn_is_outb(conn)) pthread_mutex_unlock(&conn->mutex); @@ -1324,7 +1445,7 @@ int ecp_conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_publ if (ecp_conn_is_inb(conn)) pthread_mutex_unlock(&sock->conn_table.mutex); #endif - if (rv == ECP_ERR_ECDH_KEY_DUP) rv = ECP_OK; + if (rv == ECP_ERR_DUP) rv = ECP_OK; return rv; } @@ -1344,7 +1465,7 @@ void ecp_conn_dhkey_set_curr(ECPConnection *conn) { #endif } -void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_open_send_t send_open) { +void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_send_open_t send_open) { memset(handler, 0, sizeof(ECPConnHandler)); handler->handle_msg = handle_msg; handler->handle_open = handle_open; @@ -1356,87 +1477,56 @@ ecp_msg_handler_t ecp_get_msg_handler(ECPConnection *conn) { ECPContext *ctx = conn->sock->ctx; unsigned char ctype; - ctype = conn->type; + ctype = conn->type & ECP_CTYPE_MASK; if (ecp_conn_is_sys(conn)) { - switch (ctype) { -#ifdef ECP_WITH_DIR - case ECP_CTYPE_DIR: - return ecp_dir_handle_msg; -#endif - -#ifdef ECP_WITH_VCONN - case ECP_CTYPE_VCONN: - case ECP_CTYPE_VLINK: - return ecp_vconn_handle_msg; -#endif - - default: - return NULL; - } + if (ctype >= ECP_MAX_CTYPE_SYS) return NULL; + return ctx->handler_sys[ctype] ? ctx->handler_sys[ctype]->handle_msg : NULL; + } else { + if (ctype >= ECP_MAX_CTYPE) return NULL; + return ctx->handler[ctype] ? ctx->handler[ctype]->handle_msg : NULL; } - - if (ctype >= ECP_MAX_CTYPE) return NULL; - return ctx->handler[ctype] ? ctx->handler[ctype]->handle_msg : NULL; } ecp_open_handler_t ecp_get_open_handler(ECPConnection *conn) { ECPContext *ctx = conn->sock->ctx; unsigned char ctype; - ctype = conn->type; + ctype = conn->type & ECP_CTYPE_MASK; if (ecp_conn_is_sys(conn)) { - switch (ctype) { -#ifdef ECP_WITH_DIR - case ECP_CTYPE_DIR: - return ecp_dir_handle_open; -#endif - -#ifdef ECP_WITH_VCONN - case ECP_CTYPE_VCONN: - case ECP_CTYPE_VLINK: - return ecp_vconn_handle_open; -#endif - - default: - return NULL; - } + if (ctype >= ECP_MAX_CTYPE_SYS) return NULL; + return ctx->handler_sys[ctype] ? ctx->handler_sys[ctype]->handle_open : NULL; + } else { + if (ctype >= ECP_MAX_CTYPE) return NULL; + return ctx->handler[ctype] ? ctx->handler[ctype]->handle_open : NULL; } - - if (ctype >= ECP_MAX_CTYPE) return NULL; - return ctx->handler[ctype] ? ctx->handler[ctype]->handle_open : NULL; } ecp_close_handler_t ecp_get_close_handler(ECPConnection *conn) { ECPContext *ctx = conn->sock->ctx; unsigned char ctype; - ctype = conn->type; + ctype = conn->type & ECP_CTYPE_MASK; if (ecp_conn_is_sys(conn)) { - switch (ctype) { -#ifdef ECP_WITH_DIR - case ECP_CTYPE_DIR: - return NULL; -#endif - -#ifdef ECP_WITH_VCONN - case ECP_CTYPE_VCONN: - case ECP_CTYPE_VLINK: - return ecp_vconn_handle_close; -#endif - - default: - return NULL; - } + if (ctype >= ECP_MAX_CTYPE_SYS) return NULL; + return ctx->handler_sys[ctype] ? ctx->handler_sys[ctype]->handle_close : NULL; + } else { + if (ctype >= ECP_MAX_CTYPE) return NULL; + return ctx->handler[ctype] ? ctx->handler[ctype]->handle_close : NULL; } - - if (ctype >= ECP_MAX_CTYPE) return NULL; - return ctx->handler[ctype] ? ctx->handler[ctype]->handle_close : NULL; } -ecp_dir_handler_t ecp_get_dir_handler(ECPConnection *conn) { +ecp_send_open_t ecp_get_send_open_f(ECPConnection *conn) { ECPContext *ctx = conn->sock->ctx; + unsigned char ctype; - return ctx->handle_dir; + ctype = conn->type & ECP_CTYPE_MASK; + if (ecp_conn_is_sys(conn)) { + if (ctype >= ECP_MAX_CTYPE_SYS) return NULL; + return ctx->handler_sys[ctype] ? ctx->handler_sys[ctype]->send_open : NULL; + } else { + if (ctype >= ECP_MAX_CTYPE) return NULL; + return ctx->handler[ctype] ? ctx->handler[ctype]->send_open : NULL; + } } void ecp_err_handle(ECPConnection *conn, unsigned char mtype, int err) { @@ -1454,6 +1544,7 @@ static ssize_t _send_ireq(ECPConnection *conn, ECPTimerItem *ti) { ECPBuffer payload; unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_INIT_REQ, conn)]; unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_INIT_REQ, conn)]; + ssize_t rv; packet.buffer = pkt_buf; packet.size = sizeof(pkt_buf); @@ -1462,29 +1553,50 @@ static ssize_t _send_ireq(ECPConnection *conn, ECPTimerItem *ti) { ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_INIT_REQ); - return _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, NULL, NULL, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_INIT_REQ), 0, ti); + rv = _ecp_pld_send(conn, &packet, ECP_ECDH_IDX_PERMA, ECP_ECDH_IDX_INV, NULL, NULL, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_INIT_REQ), 0, ti); + return rv; } static ssize_t _retry_ireq(ECPConnection *conn, ECPTimerItem *ti) { + unsigned short refcount = 0; int rv; + /* timer holds one reference to this connection */ + ecp_conn_remove(conn, &refcount); + if (refcount > 1) return ECP_ERR_BUSY; + rv = ecp_conn_reset(conn); if (rv) return rv; + rv = ecp_conn_reset_outb(conn); + if (rv) return rv; + + rv = ecp_conn_insert(conn); + if (rv) return rv; + return _send_ireq(conn, ti); } -ssize_t ecp_send_init_req(ECPConnection *conn) { - ECPTimerItem ti; +ssize_t ecp_send_init_req(ECPConnection *conn, int retry) { + ssize_t rv; + + if (retry) { + ECPTimerItem ti; - ecp_timer_item_init(&ti, conn, ECP_MTYPE_OPEN_REP, _retry_ireq, ECP_SEND_TRIES-1, ECP_SEND_TIMEOUT); + ecp_timer_item_init(&ti, conn, ECP_MTYPE_OPEN_REP, _retry_ireq, ECP_SEND_TRIES-1, ECP_SEND_TIMEOUT); + + rv = _send_ireq(conn, &ti); + } else { + rv = _send_ireq(conn, NULL); + } - return _send_ireq(conn, &ti); + return rv; } -ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey) { +ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey, ECP2Buffer *bufs) { ssize_t rv; + ecp_tr_release(bufs->packet, 1); rv = ecp_send_init_rep(sock, parent, addr, c_idx, public_buf, shkey); if (rv < 0) return rv; @@ -1531,9 +1643,8 @@ ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t return rv; } -ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size) { - ecp_open_send_t send_open_f; - unsigned char ctype; +ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { + ecp_send_open_t send_open_f; unsigned char *cookie; ssize_t rv; int _rv; @@ -1543,29 +1654,11 @@ ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_ _rv = ecp_conn_dhkey_set_pub(conn, msg[0], (ecp_ecdh_public_t *)(msg+1)); if (_rv) return _rv; - ctype = conn->type; - send_open_f = NULL; cookie = msg+1+ECP_SIZE_ECDH_PUB; - if (ecp_conn_is_sys(conn)) { - switch (ctype) { -#ifdef ECP_WITH_VCONN - case ECP_CTYPE_VCONN: - case ECP_CTYPE_VLINK: - send_open_f = ecp_vconn_send_open_req; - break; -#endif - - default: - break; - } - } else { - ECPContext *ctx = conn->sock->ctx; - - if (ctype >= ECP_MAX_CTYPE) return ECP_ERR_CTYPE; - send_open_f = ctx->handler[ctype] ? ctx->handler[ctype]->send_open : NULL; - } + send_open_f = ecp_get_send_open_f(conn); if (send_open_f == NULL) send_open_f = ecp_send_open_req; + ecp_tr_release(bufs->packet, 1); rv = send_open_f(conn, cookie); if (rv < 0) return rv; @@ -1684,17 +1777,27 @@ ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned cha remote_key.valid = 1; } - _rv = ecp_conn_alloc(sock, ctype, &conn); + conn = ecp_conn_new_inb(sock, ctype); + if (conn == NULL) return ECP_ERR_ALLOC; + + _rv = ecp_conn_create_inb(conn, parent, s_idx, c_idx, (ecp_ecdh_public_t *)public_buf, remote_key.valid ? &remote_key : NULL, shkey); if (_rv) return _rv; - _rv = ecp_conn_init_inb(conn, parent, s_idx, c_idx, (ecp_ecdh_public_t *)public_buf, remote_key.valid ? &remote_key : NULL, shkey); - if (!_rv) _rv = ecp_conn_insert(conn); + _rv = ecp_conn_insert(conn); if (_rv) { ecp_conn_destroy(conn); - ecp_conn_free(conn); return _rv; } + if (ecp_conn_is_gc(conn)) { + _rv = ecp_conn_insert_gc(conn); + if (_rv) { + ecp_conn_refcount_dec(conn); + _ecp_conn_close(conn); + return _rv; + } + } + *_conn = conn; /* handle_open will be called later from msg handler */ @@ -1718,77 +1821,75 @@ ssize_t ecp_send_open_rep(ECPConnection *conn) { return rv; } -ssize_t ecp_handle_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { - size_t rsize; - ecp_open_handler_t handler; - int rv = ECP_OK; +ssize_t ecp_check_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size) { + int is_open; + ssize_t rv; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + is_open = _ecp_conn_is_open(conn); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif + + if (is_open) return ECP_ERR; if (mtype == ECP_MTYPE_OPEN_REQ) { if (ecp_conn_is_outb(conn)) return ECP_ERR; - rsize = 2; - if (msg_size < rsize) return ECP_ERR_SIZE; + rv = 2; + if (msg_size < rv) return ECP_ERR_SIZE; - if (msg[1]) rsize += ECP_SIZE_VBOX; - if (msg_size < rsize) return ECP_ERR_SIZE; + if (msg[1]) rv += ECP_SIZE_VBOX; + if (msg_size < rv) return ECP_ERR_SIZE; } else { if (ecp_conn_is_inb(conn)) return ECP_ERR; - rsize = 0; + rv = 0; } -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&conn->mutex); -#endif - - if (ecp_conn_is_open(conn)) rv = ECP_ERR; - if (!rv) rv = ecp_ext_conn_open(conn); - if (!rv) ecp_conn_set_open(conn); + return rv; +} -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&conn->mutex); -#endif +int ecp_handle_open(ECPConnection *conn, ECP2Buffer *bufs) { + ecp_open_handler_t handler; + int rv = ECP_OK; + rv = ecp_ext_conn_open(conn); if (rv) return rv; handler = ecp_get_open_handler(conn); - if (handler) rv = handler(conn, bufs); - if (rv) { + if (handler) { + rv = handler(conn, bufs); + if (rv) { + ecp_ext_conn_close(conn); + return rv; + } + } + #ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&conn->mutex); + pthread_mutex_lock(&conn->mutex); #endif - ecp_conn_clr_open(conn); + _ecp_conn_set_open(conn); #ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&conn->mutex); + pthread_mutex_unlock(&conn->mutex); #endif - if (ecp_conn_is_inb(conn)) _ecp_conn_close(conn); - return rv; - } - if (ecp_conn_is_inb(conn)) { - ssize_t _rv; - ecp_tr_release(bufs->packet, 1); - - _rv = ecp_send_open_rep(conn); - if (_rv < 0) { - _ecp_conn_close(conn); - return _rv; - } - rv = ecp_conn_insert_inb(conn); - if (rv) { - _ecp_conn_close(conn); - return rv; - } + ecp_send_open_rep(conn); } else if (ecp_conn_is_root(conn)) { ecp_conn_remove_addr(conn); } - return rsize; + + return ECP_OK; } -static ssize_t _send_keyx_req(ECPConnection *conn, ECPTimerItem *ti) { +static ssize_t _send_kxreq(ECPConnection *conn, ECPTimerItem *ti) { ECPBuffer packet; ECPBuffer payload; unsigned char pkt_buf[ECP_SIZE_PKT_BUF(1+ECP_SIZE_ECDH_PUB, ECP_MTYPE_KEYX_REQ, conn)]; @@ -1812,8 +1913,16 @@ static ssize_t _send_keyx_req(ECPConnection *conn, ECPTimerItem *ti) { return rv; } -ssize_t ecp_send_keyx_req(ECPConnection *conn) { - return ecp_timer_send(conn, _send_keyx_req, ECP_MTYPE_KEYX_REP, ECP_SEND_TRIES, ECP_SEND_TIMEOUT); +ssize_t ecp_send_keyx_req(ECPConnection *conn, int retry) { + ssize_t rv; + + if (retry) { + rv = ecp_timer_send(conn, _send_kxreq, ECP_MTYPE_KEYX_REP, ECP_SEND_TRIES, ECP_SEND_TIMEOUT); + } else { + rv = _send_kxreq(conn, NULL); + } + + return rv; } ssize_t ecp_send_keyx_rep(ECPConnection *conn) { @@ -1857,7 +1966,6 @@ ssize_t ecp_handle_keyx(ECPConnection *conn, unsigned char mtype, unsigned char if (ecp_conn_is_outb(conn)) return ECP_ERR; ecp_tr_release(bufs->packet, 1); - rv = ecp_send_keyx_rep(conn); if (rv < 0) return rv; } @@ -1870,7 +1978,7 @@ ssize_t ecp_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, switch (mtype) { case ECP_MTYPE_OPEN_REQ: case ECP_MTYPE_OPEN_REP: - return ecp_handle_open(conn, mtype, msg, msg_size, bufs); + return ecp_check_open(conn, mtype, msg, msg_size); case ECP_MTYPE_KEYX_REQ: case ECP_MTYPE_KEYX_REP: @@ -1901,17 +2009,20 @@ ssize_t ecp_pld_handle_one(ECPConnection *conn, ecp_seq_t seq, unsigned char *pa _rv = ecp_pld_get_type(payload, pld_size, &mtype); if (_rv) return _rv; - ecp_timer_pop(conn, mtype); - msg = ecp_pld_get_msg(payload, pld_size); if (msg == NULL) return ECP_ERR; hdr_size = msg - payload; msg_size = pld_size - hdr_size; rv = ecp_msg_handle(conn, seq, mtype, msg, msg_size, bufs); - if (rv < 0) return rv; + ecp_timer_pop(conn, mtype); + if (rv < 0) { + ecp_err_handle(conn, mtype, rv); + return rv; + } rv += hdr_size; + if (rv > pld_size) return ECP_ERR_SIZE; return rv; } @@ -1920,7 +2031,7 @@ ssize_t ecp_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payloa size_t pld_size = _pld_size; ssize_t rv; - rv = ecp_ext_pld_handle(conn, seq, payload, pld_size, bufs); + rv = ecp_ext_pld_handle_one(conn, seq, payload, pld_size, bufs); if (rv < 0) return rv; payload += rv; @@ -1938,7 +2049,7 @@ ssize_t ecp_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payloa return _pld_size; } -ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t _pkt_size, ECPConnection **_conn, unsigned char **_payload, ecp_seq_t *_seq) { +ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t _pkt_size, ECPConnection **_conn, unsigned char **_payload, ecp_seq_t *_seq, int *is_open_msg) { ECPConnection *conn = NULL; unsigned char idx; unsigned char s_idx; @@ -1962,6 +2073,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, *_conn = NULL; *_payload = NULL; *_seq = 0; + *is_open_msg = 0; packet = bufs->packet->buffer; idx = packet[ECP_SIZE_PROTO]; @@ -1984,7 +2096,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, if (conn) { is_inb = ecp_conn_is_inb(conn); - is_open = ecp_conn_is_open(conn); + is_open = _ecp_conn_is_open(conn); if (!is_open && !is_inb && (idx == ECP_ECDH_IDX_INV)) { nonce_buf = packet+ECP_SIZE_PROTO+1; @@ -2083,6 +2195,44 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, payload = bufs->payload->buffer; rv = ecp_aead_dec(payload, bufs->payload->size, packet, pkt_size, &shkey, &nonce_pkt, is_inb ? ECP_NTYPE_INB : ECP_NTYPE_OUTB); + + /* init reply collision */ + if ((rv == ECP_ERR_DECRYPT) && conn && !is_open && !is_inb && (idx == ECP_ECDH_IDX_INV)) { + ECPConnection *_conn = conn; + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&sock->conn_table.mutex); +#endif + + conn = conn_table_search_addr(sock, addr); + + while (conn && (rv == ECP_ERR_DECRYPT)) { + if (conn != _conn) { +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + _rv = conn_shkey_get(conn, s_idx, c_idx, &shkey); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif + + if (_rv) rv = _rv; + if (rv == ECP_ERR_DECRYPT) rv = ecp_aead_dec(payload, bufs->payload->size, packet, pkt_size, &shkey, &nonce_pkt, ECP_NTYPE_OUTB); + } + if (rv == ECP_ERR_DECRYPT) conn = conn_table_search_addr_next(sock, addr, conn); + } + + if (rv < 0) conn = NULL; + if (conn) ecp_conn_refcount_inc(conn); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&sock->conn_table.mutex); +#endif + + ecp_conn_refcount_dec(_conn); + } if (rv < 0) goto unpack_err; pld_size = rv; @@ -2108,11 +2258,8 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, case ECP_MTYPE_INIT_REQ: { unsigned char _public_buf[ECP_SIZE_ECDH_PUB]; - /* we should release incoming packet before sending reply packet */ memcpy(_public_buf, public_buf, sizeof(_public_buf)); - ecp_tr_release(bufs->packet, 1); - - rv = ecp_handle_init_req(sock, parent, addr, c_idx, _public_buf, &shkey); + rv = ecp_handle_init_req(sock, parent, addr, c_idx, _public_buf, &shkey, bufs); if (rv < 0) return rv; rv += hdr_size; @@ -2126,7 +2273,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, /* pass to payload handler */ nonce_in = nonce_pkt; nonce_map = ECP_ACK_FULL; - is_open = 1; + *is_open_msg = 1; rv = 0; break; } @@ -2158,10 +2305,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, switch (mtype) { case ECP_MTYPE_INIT_REP: { - /* we should release incoming packet before sending reply packet */ - ecp_tr_release(bufs->packet, 1); - - rv = ecp_handle_init_rep(conn, msg, msg_size); + rv = ecp_handle_init_rep(conn, msg, msg_size, bufs); if (rv < 0) goto unpack_err; rv += hdr_size; @@ -2172,7 +2316,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, /* pass to payload handler */ nonce_in = nonce_pkt; nonce_map = ECP_ACK_FULL; - is_open = 1; + *is_open_msg = 1; rv = 0; break; } @@ -2187,16 +2331,16 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, } if (conn) { - if (is_open) { + if (is_open || *is_open_msg) { #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&conn->mutex); #endif conn->nonce_in = nonce_in; conn->nonce_map = nonce_map; - if (is_inb) { - conn->access_ts = ecp_tm_get_tick(); - if (addr) conn->remote.addr = *addr; + conn->access_ts = ecp_tm_get_s(); + if (is_inb && addr) { + conn->remote.addr = *addr; } #ifdef ECP_WITH_PTHREAD @@ -2219,13 +2363,14 @@ unpack_err: } ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t pkt_size) { - ECPConnection *conn = NULL; + ECPConnection *conn; unsigned char *payload; + int is_open_msg; ecp_seq_t seq; size_t pld_size; ssize_t rv; - rv = ecp_unpack(sock, parent, addr, bufs, pkt_size, &conn, &payload, &seq); + rv = ecp_unpack(sock, parent, addr, bufs, pkt_size, &conn, &payload, &seq, &is_open_msg); if (rv < 0) return rv; pld_size = pkt_size - rv; @@ -2235,7 +2380,7 @@ ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *ad } if (pld_size) { - rv = ecp_ext_pld_store(conn, seq, payload, pld_size, bufs); + rv = ecp_ext_pld_handle(conn, seq, payload, pld_size, bufs); if (rv < 0) goto pkt_handle_fin; payload += rv; @@ -2250,6 +2395,16 @@ ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *ad pld_size -= rv; } + if (is_open_msg) { + int _rv; + + _rv = ecp_handle_open(conn, bufs); + if (_rv) { + rv = _rv; + goto pkt_handle_fin; + } + } + rv = pkt_size - pld_size; pkt_handle_fin: @@ -2483,8 +2638,8 @@ int ecp_pld_get_frag(unsigned char *pld, size_t pld_size, unsigned char *frag_cn *frag_cnt = pld[1]; *frag_tot = pld[2]; *frag_size = \ - (pld[3] << 8) | \ - (pld[4]); + ((uint16_t)pld[3] << 8) | \ + ((uint16_t)pld[4]); return ECP_OK; } diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h index 4b47bcb..9be0dc0 100644 --- a/ecp/src/ecp/core.h +++ b/ecp/src/ecp/core.h @@ -15,18 +15,18 @@ #define ECP_ERR_ALLOC -3 #define ECP_ERR_SIZE -4 #define ECP_ERR_BUSY -5 -#define ECP_ERR_EMPTY -6 -#define ECP_ERR_FULL -7 -#define ECP_ERR_MTYPE -8 -#define ECP_ERR_CTYPE -9 -#define ECP_ERR_HANDLER -10 -#define ECP_ERR_COOKIE -11 - -#define ECP_ERR_NET_ADDR -12 -#define ECP_ERR_MAX_PARENT -13 -#define ECP_ERR_NEXT -14 - -#define ECP_ERR_ECDH_KEY_DUP -21 +#define ECP_ERR_DUP -6 +#define ECP_ERR_EMPTY -7 +#define ECP_ERR_FULL -8 +#define ECP_ERR_MTYPE -9 +#define ECP_ERR_CTYPE -10 +#define ECP_ERR_HANDLER -11 +#define ECP_ERR_COOKIE -12 + +#define ECP_ERR_NET_ADDR -13 +#define ECP_ERR_MAX_PARENT -14 +#define ECP_ERR_NEXT -15 + #define ECP_ERR_ECDH_IDX -22 #define ECP_ERR_ENCRYPT -26 #define ECP_ERR_DECRYPT -27 @@ -43,6 +43,7 @@ #define ECP_MAX_CONN_KEY 2 #define ECP_MAX_NODE_KEY 2 #define ECP_MAX_CTYPE 8 +#define ECP_MAX_CTYPE_SYS 3 #define ECP_MAX_MTYPE 16 #define ECP_MAX_PARENT 3 #define ECP_MAX_SEQ_FWD 1024 @@ -121,31 +122,37 @@ #define ECP_CONN_FLAG_INB 0x80 #define ECP_CONN_FLAG_VBOX 0x01 #define ECP_CONN_FLAG_RBUF 0x02 +#define ECP_CONN_FLAG_GC 0x04 #define ECP_CONN_FLAG_MASK 0x7F /* mutable flags */ -#define ECP_CONN_FLAG_REG 0x04 -#define ECP_CONN_FLAG_OPEN 0x08 +#define ECP_CONN_FLAG_REG 0x01 +#define ECP_CONN_FLAG_OPEN 0x02 +#define ECP_CONN_FLAG_CLOSED 0x04 #define ECP_SEND_FLAG_REPLY 0x01 #define ECP_SEND_FLAG_MORE 0x02 #define ecp_conn_has_vbox(conn) ((conn)->flags_im & ECP_CONN_FLAG_VBOX) #define ecp_conn_has_rbuf(conn) ((conn)->flags_im & ECP_CONN_FLAG_RBUF) +#define ecp_conn_is_gc(conn) ((conn)->flags_im & ECP_CONN_FLAG_GC) #define ecp_conn_is_inb(conn) ((conn)->flags_im & ECP_CONN_FLAG_INB) #define ecp_conn_is_outb(conn) (!((conn)->flags_im & ECP_CONN_FLAG_INB)) -#define ecp_conn_is_reg(conn) ((conn)->flags & ECP_CONN_FLAG_REG) -#define ecp_conn_is_open(conn) ((conn)->flags & ECP_CONN_FLAG_OPEN) #define ecp_conn_is_sys(conn) ((conn)->type & ECP_CTYPE_FLAG_SYS) +#define _ecp_conn_is_reg(conn) ((conn)->flags & ECP_CONN_FLAG_REG) +#define _ecp_conn_is_open(conn) ((conn)->flags & ECP_CONN_FLAG_OPEN) +#define _ecp_conn_is_closed(conn) ((conn)->flags & ECP_CONN_FLAG_CLOSED) #define ecp_conn_set_inb(conn) ((conn)->flags_im |= ECP_CONN_FLAG_INB) #define ecp_conn_set_outb(conn) ((conn)->flags_im &= ~ECP_CONN_FLAG_INB) -#define ecp_conn_set_reg(conn) ((conn)->flags |= ECP_CONN_FLAG_REG) -#define ecp_conn_set_open(conn) ((conn)->flags |= ECP_CONN_FLAG_OPEN) +#define _ecp_conn_set_reg(conn) ((conn)->flags |= ECP_CONN_FLAG_REG) +#define _ecp_conn_set_open(conn) ((conn)->flags |= ECP_CONN_FLAG_OPEN) +#define _ecp_conn_set_closed(conn) ((conn)->flags |= ECP_CONN_FLAG_CLOSED) -#define ecp_conn_clr_reg(conn) ((conn)->flags &= ~ECP_CONN_FLAG_REG) -#define ecp_conn_clr_open(conn) ((conn)->flags &= ~ECP_CONN_FLAG_OPEN) +#define _ecp_conn_clr_reg(conn) ((conn)->flags &= ~ECP_CONN_FLAG_REG) +#define _ecp_conn_clr_open(conn) ((conn)->flags &= ~ECP_CONN_FLAG_OPEN) +#define _ecp_conn_clr_closed(conn) ((conn)->flags &= ~ECP_CONN_FLAG_CLOSED) typedef uint32_t ecp_ack_t; #define ECP_SIZE_ACKB (sizeof(ecp_ack_t)*8) @@ -174,9 +181,8 @@ typedef uint64_t ecp_nonce_t; struct ECP2Buffer; struct ECPSocket; struct ECPConnection; - -#ifdef ECP_WITH_DIRSRV -struct ECPDirList; +#ifdef ECP_WITH_FRAG +struct ECPFragIter; #endif #ifdef ECP_WITH_HTABLE @@ -186,15 +192,16 @@ struct ECPDirList; #include "transport.h" #include "timer.h" +typedef int (*ecp_conn_expired_t) (struct ECPConnection *conn, ecp_sts_t now, ecp_sts_t to); + typedef void (*ecp_err_handler_t) (struct ECPConnection *conn, unsigned char mtype, int err); -typedef ssize_t (*ecp_dir_handler_t) (struct ECPConnection *conn, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b); -typedef struct ECPConnection * (*ecp_conn_alloc_t) (struct ECPSocket *sock, unsigned char type); +typedef struct ECPConnection * (*ecp_conn_new_t) (struct ECPSocket *sock, unsigned char type); typedef void (*ecp_conn_free_t) (struct ECPConnection *conn); typedef ssize_t (*ecp_msg_handler_t) (struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b); typedef int (*ecp_open_handler_t) (struct ECPConnection *conn, struct ECP2Buffer *b); typedef void (*ecp_close_handler_t) (struct ECPConnection *conn); -typedef ssize_t (*ecp_open_send_t) (struct ECPConnection *conn, unsigned char *cookie); +typedef ssize_t (*ecp_send_open_t) (struct ECPConnection *conn, unsigned char *cookie); typedef struct ECPBuffer { unsigned char *buffer; @@ -241,24 +248,21 @@ typedef struct ECPConnHandler { ecp_msg_handler_t handle_msg; ecp_open_handler_t handle_open; ecp_close_handler_t handle_close; - ecp_open_send_t send_open; + ecp_send_open_t send_open; } ECPConnHandler; typedef struct ECPContext { ecp_err_handler_t handle_err; - ecp_dir_handler_t handle_dir; - ecp_conn_alloc_t conn_alloc; + ecp_conn_new_t conn_new; /* inbound connections only */ ecp_conn_free_t conn_free; ECPConnHandler *handler[ECP_MAX_CTYPE]; -#ifdef ECP_WITH_DIRSRV - struct ECPDirSrv *dir_srv; -#endif + ECPConnHandler *handler_sys[ECP_MAX_CTYPE_SYS]; } ECPContext; typedef struct ECPConnTable { #ifdef ECP_WITH_HTABLE ecp_ht_table_t *keys; - ecp_ht_table_t *keys_inb; + ecp_ht_table_t *keys_gc; ecp_ht_table_t *addrs; #else struct ECPConnection *arr[ECP_MAX_SOCK_CONN]; @@ -266,7 +270,7 @@ typedef struct ECPConnTable { #endif #ifdef ECP_WITH_PTHREAD pthread_mutex_t mutex; - pthread_mutex_t mutex_inb; + pthread_mutex_t mutex_gc; #endif } ECPConnTable; @@ -304,70 +308,79 @@ typedef struct ECPConnection { unsigned char rkey_curr; ECPDHShkey shkey[ECP_MAX_NODE_KEY][ECP_MAX_NODE_KEY]; ecp_sts_t access_ts; -#ifdef ECP_WITH_PTHREAD - pthread_mutex_t mutex; -#endif + void *param; #ifdef ECP_WITH_VCONN struct ECPConnection *parent; - struct ECPConnection *next; unsigned short pcount; #endif +#ifdef ECP_WITH_FRAG + struct ECPFragIter *iter; +#endif +#ifdef ECP_WITH_PTHREAD + pthread_mutex_t mutex; +#endif } ECPConnection; int ecp_dhkey_gen(ECPDHKey *key); -int ecp_init(ECPContext *ctx); -int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_dir_handler_t handle_dir, ecp_conn_alloc_t conn_alloc, ecp_conn_free_t conn_free); -int ecp_ctx_set_handler(ECPContext *ctx, ECPConnHandler *handler, unsigned char ctype); +int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free); +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); -int ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, void *addr); +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); int ecp_sock_init(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key); int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key); void ecp_sock_destroy(ECPSocket *sock); -int ecp_sock_open(ECPSocket *sock, void *myaddr); +int ecp_sock_open(ECPSocket *sock, ecp_tr_addr_t *myaddr); void ecp_sock_close(ECPSocket *sock); int ecp_sock_minkey_new(ECPSocket *sock); int ecp_sock_dhkey_new(ECPSocket *sock); int ecp_sock_dhkey_get(ECPSocket *sock, unsigned char idx, ECPDHKey *key); int ecp_sock_dhkey_get_pub(ECPSocket *sock, unsigned char *idx, ecp_ecdh_public_t *public); void ecp_sock_get_nonce(ECPSocket *sock, ecp_nonce_t *nonce); + +void ecp_sock_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t conn_expired); int ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to); int ecp_cookie_gen(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf); int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf); -int ecp_conn_alloc(ECPSocket *sock, unsigned char ctype, ECPConnection **_conn); -void ecp_conn_free(ECPConnection *conn); - +ECPConnection *ecp_conn_new_inb(ECPSocket *sock, unsigned char ctype); void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype); -void ecp_conn_reinit(ECPConnection *conn); -int ecp_conn_create(ECPConnection *conn, ECPSocket *sock, unsigned char ctype); -int ecp_conn_create_inb(ECPConnection *conn, ECPSocket *sock, unsigned char ctype); +int ecp_conn_reset(ECPConnection *conn); +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 *remote_key, ecp_aead_key_t *shkey); +int ecp_conn_create_outb(ECPConnection *conn, ECPConnection *parent, ECPNode *node); +int ecp_conn_reset_outb(ECPConnection *conn); void ecp_conn_destroy(ECPConnection *conn); - -void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags); -void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags); -void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key); -void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr); - -int ecp_conn_init_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *remote_key, ecp_aead_key_t *shkey); -int ecp_conn_init_outb(ECPConnection *conn, ECPNode *node); +void ecp_conn_free(ECPConnection *conn); int ecp_conn_insert(ECPConnection *conn); -int ecp_conn_insert_inb(ECPConnection *conn); +int ecp_conn_insert_gc(ECPConnection *conn); void ecp_conn_remove(ECPConnection *conn, unsigned short *refcount); void ecp_conn_remove_addr(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_reset(ECPConnection *conn); +int ecp_conn_try_open(ECPConnection *conn, ECPNode *node); int _ecp_conn_close(ECPConnection *conn); int ecp_conn_close(ECPConnection *conn); +void ecp_conn_mark_closed(ECPConnection *conn); +int _ecp_conn_expired(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to); +int ecp_conn_is_zombie(ECPConnection *conn, ecp_sts_t now, ecp_sts_t to); void ecp_conn_refcount_inc(ECPConnection *conn); void ecp_conn_refcount_dec(ECPConnection *conn); +void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags); +void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags); +void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key); +void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr); + int ecp_conn_dhkey_new(ECPConnection *conn); int ecp_conn_dhkey_get(ECPConnection *conn, unsigned char idx, ECPDHKey *key); int ecp_conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx, ECPDHPub *key); @@ -375,24 +388,26 @@ int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_pub int ecp_conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_public_t *public); void ecp_conn_dhkey_set_curr(ECPConnection *conn); -void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_open_send_t send_open); +void ecp_conn_handler_init(ECPConnHandler *handler, ecp_msg_handler_t handle_msg, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_send_open_t send_open); ecp_msg_handler_t ecp_get_msg_handler(ECPConnection *conn); ecp_open_handler_t ecp_get_open_handler(ECPConnection *conn); ecp_close_handler_t ecp_get_close_handler(ECPConnection *conn); -ecp_dir_handler_t ecp_get_dir_handler(ECPConnection *conn); +ecp_send_open_t ecp_get_send_open_f(ECPConnection *conn); void ecp_err_handle(ECPConnection *conn, unsigned char mtype, int err); -ssize_t ecp_send_init_req(ECPConnection *conn); -ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey); +ssize_t ecp_send_init_req(ECPConnection *conn, int retry); +ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey, ECP2Buffer *bufs); ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey); -ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size); +ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs); + ssize_t ecp_write_open_req(ECPConnection *conn, ECPBuffer *payload); ssize_t ecp_send_open_req(ECPConnection *conn, unsigned char *cookie); ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, unsigned char *public_buf, unsigned char *msg, size_t msg_size, ecp_aead_key_t *shkey, ECPConnection **_conn); ssize_t ecp_send_open_rep(ECPConnection *conn); -ssize_t ecp_handle_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs); +ssize_t ecp_check_open(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size); +int ecp_handle_open(ECPConnection *conn, ECP2Buffer *bufs); -ssize_t ecp_send_keyx_req(ECPConnection *conn); +ssize_t ecp_send_keyx_req(ECPConnection *conn, int retry); ssize_t ecp_send_keyx_rep(ECPConnection *conn); ssize_t ecp_handle_keyx(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs); @@ -400,7 +415,7 @@ ssize_t ecp_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, ssize_t ecp_pld_handle_one(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs); ssize_t ecp_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t _pld_size, ECP2Buffer *bufs); -ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t _pkt_size, ECPConnection **_conn, unsigned char **_payload, ecp_seq_t *_seq); +ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t _pkt_size, ECPConnection **_conn, unsigned char **_payload, ecp_seq_t *_seq, int *is_open_msg); ssize_t ecp_pkt_handle(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECP2Buffer *bufs, size_t pkt_size); ssize_t ecp_pkt_send(ECPSocket *sock, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ecp_tr_addr_t *addr); diff --git a/ecp/src/ecp/crypto/crypto.c b/ecp/src/ecp/crypto/crypto.c index 6841e9d..ba013fa 100644 --- a/ecp/src/ecp/crypto/crypto.c +++ b/ecp/src/ecp/crypto/crypto.c @@ -1,8 +1,8 @@ #include <stdlib.h> #include <string.h> -#include <core.h> -#include <cr.h> +#include <ecp/core.h> +#include <ecp/cr.h> #include <openssl/curve25519.h> diff --git a/ecp/src/ecp/dir/Makefile b/ecp/src/ecp/dir/Makefile index 9283144..a002b65 100644 --- a/ecp/src/ecp/dir/Makefile +++ b/ecp/src/ecp/dir/Makefile @@ -2,10 +2,6 @@ include ../common.mk obj = dir.o -ifeq ($(with_dirsrv),yes) -obj += dir_srv.o -endif - %.o: %.c $(CC) $(CFLAGS) -c $< diff --git a/ecp/src/ecp/dir/dir.c b/ecp/src/ecp/dir/dir.c index 72097c7..d826e24 100644 --- a/ecp/src/ecp/dir/dir.c +++ b/ecp/src/ecp/dir/dir.c @@ -1,131 +1,72 @@ #include <stdlib.h> #include <string.h> -#include <core.h> -#include <cr.h> +#include <ecp/core.h> +#include <ecp/cr.h> #include "dir.h" -#include "dir_srv.h" -static int dir_update(ECPDirList *list, ECPDirItem *item) { - int i; - - for (i=0; i<list->count; i++) { - if (memcmp(&list->item[i].node.key_perma.public, &item->node.key_perma.public, sizeof(item->node.key_perma.public)) == 0) { - return ECP_OK; - } - } - - if (list->count == ECP_MAX_DIR_ITEM) return ECP_ERR_SIZE; - - list->item[list->count] = *item; - list->count++; - - return ECP_OK; -} - -ssize_t ecp_dir_parse(ECPDirList *list, unsigned char *buf, size_t buf_size) { - ECPDirItem item; - size_t rsize; - uint16_t count; - int i; - int rv; - - if (buf_size < sizeof(uint16_t)) return ECP_ERR_SIZE; - - count = \ - (buf[0] << 8) | \ - (buf[1]); - - rsize = sizeof(uint16_t) + count * ECP_SIZE_DIR_ITEM; - if (buf_size < rsize) return ECP_ERR_SIZE; - - buf += sizeof(uint16_t); - for (i=0; i<count; i++) { - ecp_dir_item_parse(&item, buf); - - rv = dir_update(list, &item); - if (rv) return rv; - - buf += ECP_SIZE_DIR_ITEM; - } - - return rsize; -} - -ssize_t ecp_dir_serialize(ECPDirList *list, unsigned char *buf, size_t buf_size) { - size_t rsize; - int i; - - rsize = sizeof(uint16_t) + list->count * ECP_SIZE_DIR_ITEM; - if (buf_size < rsize) return ECP_ERR_SIZE; - - buf[0] = (list->count & 0xFF00) >> 8; - buf[1] = (list->count & 0x00FF); - buf += sizeof(uint16_t); - for (i=0; i<list->count; i++) { - ecp_dir_item_serialize(&list->item[i], buf); - buf += ECP_SIZE_DIR_ITEM; - } - - return rsize; -} - -void ecp_dir_item_parse(ECPDirItem *item, unsigned char *buf) { +size_t ecp_dir_item_parse(ECPDirItem *item, unsigned char *buf) { ECPDHPub *key; ecp_tr_addr_t *addr; + size_t rsize = 0; + + memset(item, 0, sizeof(ECPDirItem)); key = &item->node.key_perma; addr = &item->node.addr; + key->valid = 1; memcpy(&key->public, buf, sizeof(key->public)); buf += sizeof(key->public); + rsize += sizeof(key->public); memcpy(&addr->host, buf, sizeof(addr->host)); buf += sizeof(addr->host); + rsize += sizeof(addr->host); addr->port = \ - (buf[0] << 8) | \ - (buf[1]); + ((uint16_t)buf[0] << 8) | \ + ((uint16_t)buf[1]); buf += sizeof(uint16_t); + rsize += sizeof(uint16_t); item->capabilities = \ - (buf[0] << 8) | \ - (buf[1]); + ((uint16_t)buf[0] << 8) | \ + ((uint16_t)buf[1]); buf += sizeof(uint16_t); + rsize += sizeof(uint16_t); + + return rsize; } -void ecp_dir_item_serialize(ECPDirItem *item, unsigned char *buf) { +size_t ecp_dir_item_serialize(ECPDirItem *item, unsigned char *buf) { ECPDHPub *key; ecp_tr_addr_t *addr; + size_t rsize = 0; key = &item->node.key_perma; addr = &item->node.addr; memcpy(buf, &key->public, sizeof(key->public)); buf += sizeof(key->public); + rsize += sizeof(key->public); memcpy(buf, &addr->host, sizeof(addr->host)); buf += sizeof(addr->host); + rsize += sizeof(addr->host); - buf[0] = (addr->port & 0xFF00) >> 8; - buf[1] = (addr->port & 0x00FF); + buf[0] = addr->port >> 8; + buf[1] = addr->port; buf += sizeof(uint16_t); + rsize += sizeof(uint16_t); - buf[0] = (item->capabilities & 0xFF00) >> 8; - buf[1] = (item->capabilities & 0x00FF); + buf[0] = item->capabilities >> 8; + buf[1] = item->capabilities; buf += sizeof(uint16_t); -} - -ssize_t ecp_dir_handle(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *b) { - ecp_dir_handler_t handler; + rsize += sizeof(uint16_t); - handler = ecp_get_dir_handler(conn); - if (handler) { - return handler(conn, msg, msg_size, b); - } else { - return ECP_ERR_HANDLER; - } + return rsize; } int ecp_dir_handle_open(ECPConnection *conn, ECP2Buffer *b) { @@ -133,41 +74,12 @@ int ecp_dir_handle_open(ECPConnection *conn, ECP2Buffer *b) { if (ecp_conn_is_inb(conn)) return ECP_OK; -#ifdef ECP_WITH_DIRSRV - rv = ecp_dir_send_upd(conn); -#else rv = ecp_dir_send_req(conn); -#endif if (rv < 0) return rv; return ECP_OK; } -ssize_t ecp_dir_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) { - switch (mtype) { -#ifdef ECP_WITH_DIRSRV - case ECP_MTYPE_DIR_UPD: { - return ecp_dir_handle_upd(conn, msg, msg_size); - } - - case ECP_MTYPE_DIR_REQ: { - return ecp_dir_handle_req(conn, msg, msg_size); - } -#endif - - case ECP_MTYPE_DIR_REP: { -#ifdef ECP_WITH_DIRSRV - return ecp_dir_handle_rep(conn, msg, msg_size); -#else - return ecp_dir_handle(conn, msg, msg_size, b); -#endif - } - - default: - return ECP_ERR_MTYPE; - } -} - static ssize_t _dir_send_req(ECPConnection *conn, ECPTimerItem *ti) { ECPBuffer packet; ECPBuffer payload; @@ -187,15 +99,6 @@ ssize_t ecp_dir_send_req(ECPConnection *conn) { return ecp_timer_send(conn, _dir_send_req, ECP_MTYPE_DIR_REP, ECP_SEND_TRIES, ECP_SEND_TIMEOUT); } -int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ECPNode *node) { - int rv; - ssize_t _rv; - - rv = ecp_conn_create(conn, sock, ECP_CTYPE_DIR); - if (rv) return rv; - - rv = ecp_conn_open(conn, node); - if (rv) return rv; - - return ECP_OK; +void ecp_dir_conn_init(ECPConnection *conn, ECPSocket *sock) { + ecp_conn_init(conn, sock, ECP_CTYPE_DIR); } diff --git a/ecp/src/ecp/dir/dir.h b/ecp/src/ecp/dir/dir.h index e9f8e1e..b28f801 100644 --- a/ecp/src/ecp/dir/dir.h +++ b/ecp/src/ecp/dir/dir.h @@ -1,32 +1,24 @@ -#define ECP_MAX_DIR_ITEM 30 #define ECP_SIZE_DIR_ITEM 40 #define ECP_MTYPE_DIR_UPD 0x00 #define ECP_MTYPE_DIR_REQ 0x01 -#define ECP_MTYPE_DIR_REP 0x02 +#define ECP_MTYPE_DIR_ANN 0x02 +#define ECP_MTYPE_DIR_REP 0x03 +#define ECP_MTYPE_DIR_SHADOW 0x04 #define ECP_CTYPE_DIR (0x00 | ECP_CTYPE_FLAG_SYS) +#define ECP_DIR_CAP_DIR 0x01 +#define ECP_DIR_CAP_VCONN 0x02 + typedef struct ECPDirItem { ECPNode node; uint16_t capabilities; } ECPDirItem; -typedef struct ECPDirList { - ECPDirItem item[ECP_MAX_DIR_ITEM]; - uint16_t count; -} ECPDirList; - -ssize_t ecp_dir_parse(ECPDirList *list, unsigned char *buf, size_t buf_size); -ssize_t ecp_dir_serialize(ECPDirList *list, unsigned char *buf, size_t buf_size); - -void ecp_dir_item_parse(ECPDirItem *item, unsigned char *buf); -void ecp_dir_item_serialize(ECPDirItem *item, unsigned char *buf); - -ssize_t ecp_dir_handle(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *b); +size_t ecp_dir_item_parse(ECPDirItem *item, unsigned char *buf); +size_t ecp_dir_item_serialize(ECPDirItem *item, unsigned char *buf); int ecp_dir_handle_open(ECPConnection *conn, ECP2Buffer *b); -ssize_t ecp_dir_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b); - ssize_t ecp_dir_send_req(ECPConnection *conn); -int ecp_dir_get(ECPConnection *conn, ECPSocket *sock, ECPNode *node);
\ No newline at end of file +void ecp_dir_conn_init(ECPConnection *conn, ECPSocket *sock);
\ No newline at end of file diff --git a/ecp/src/ecp/dir/dir_srv.c b/ecp/src/ecp/dir/dir_srv.c deleted file mode 100644 index cbaafc5..0000000 --- a/ecp/src/ecp/dir/dir_srv.c +++ /dev/null @@ -1,143 +0,0 @@ -#include <stdlib.h> - -#include <core.h> -#include <cr.h> - -#include "dir.h" -#include "dir_srv.h" - -int ecp_dir_create(ECPContext *ctx, ECPDirSrv *dir_srv, ECPDirList *dir_online, ECPDirList *dir_shadow) { - int rv; - -#ifdef ECP_WITH_PTHREAD - rv = pthread_mutex_init(&dir_srv->online.mutex, NULL); - if (rv) return ECP_ERR; - - rv = pthread_mutex_init(&dir_srv->shadow.mutex, NULL); - if (rv) { - pthread_mutex_destroy(&dir_srv->online.mutex); - return ECP_ERR; - } -#endif - - dir_srv->online.list = dir_online; - dir_srv->shadow.list = dir_shadow; - ctx->dir_srv = dir_srv; - - return ECP_OK; -} - -void ecp_dir_destroy(ECPContext *ctx) { - ECPDirSrv *dir_srv = ctx->dir_srv; - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_destroy(&dir_srv->shadow.mutex); - pthread_mutex_destroy(&dir_srv->online.mutex); -#endif - -} - -ssize_t ecp_dir_send_list(ECPConnection *conn, unsigned char mtype, ECPDirTable *dir_table) { - ECPBuffer packet; - ECPBuffer payload; - unsigned char pkt_buf[ECP_MAX_PKT]; - unsigned char pld_buf[ECP_MAX_PLD]; - unsigned char *msg; - size_t hdr_size; - size_t msg_size; - ssize_t rv; - - packet.buffer = pkt_buf; - packet.size = ECP_MAX_PKT; - payload.buffer = pld_buf; - payload.size = ECP_MAX_PLD; - - ecp_pld_set_type(payload.buffer, payload.size, mtype); - msg = ecp_pld_get_msg(payload.buffer, payload.size); - hdr_size = msg - payload.buffer; - msg_size = payload.size - hdr_size; - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&dir_table->mutex); -#endif - - rv = ecp_dir_serialize(dir_table->list, msg, msg_size); - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&dir_table->mutex); -#endif - - if (rv < 0) return rv; - - rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(rv, mtype), 0); - return rv; -} - -ssize_t ecp_dir_send_upd(ECPConnection *conn) { - ECPDirSrv *dir_srv = conn->sock->ctx->dir_srv; - ECPDirTable *dir_table = &dir_srv->shadow; - ssize_t rv; - - rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_UPD, dir_table); - return rv; -} - -ssize_t ecp_dir_handle_upd(ECPConnection *conn, unsigned char *msg, size_t msg_size) { - ECPDirSrv *dir_srv = conn->sock->ctx->dir_srv; - ECPDirTable *dir_table = &dir_srv->shadow; - ssize_t rsize; - ssize_t rv; - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&dir_table->mutex); -#endif - - rsize = ecp_dir_parse(dir_table->list, msg, msg_size); - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&dir_table->mutex); -#endif - - if (rsize < 0) return rsize; - - rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_REP, dir_table); - if (rv < 0) return rv; - - return rsize; -} - -ssize_t ecp_dir_handle_req(ECPConnection *conn, unsigned char *msg, size_t msg_size) { - ssize_t rv; - - rv = ecp_dir_send_rep(conn); - if (rv < 0) return rv; - - return 0; -} - -ssize_t ecp_dir_send_rep(ECPConnection *conn) { - ECPDirSrv *dir_srv = conn->sock->ctx->dir_srv; - ECPDirTable *dir_table = &dir_srv->online; - ssize_t rv; - - rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_REP, dir_table); - return rv; -} - -ssize_t ecp_dir_handle_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size) { - ECPDirSrv *dir_srv = conn->sock->ctx->dir_srv; - ECPDirTable *dir_table = &dir_srv->shadow; - ssize_t rv; - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&dir_table->mutex); -#endif - - rv = ecp_dir_parse(dir_table->list, msg, msg_size); - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&dir_table->mutex); -#endif - - return rv; -} diff --git a/ecp/src/ecp/dir/dir_srv.h b/ecp/src/ecp/dir/dir_srv.h deleted file mode 100644 index 5e107df..0000000 --- a/ecp/src/ecp/dir/dir_srv.h +++ /dev/null @@ -1,23 +0,0 @@ -typedef struct ECPDirTable { - ECPDirList *list; -#ifdef ECP_WITH_PTHREAD - pthread_mutex_t mutex; -#endif -} ECPDirTable; - -typedef struct ECPDirSrv { - ECPDirTable online; - ECPDirTable shadow; -} ECPDirSrv; - -int ecp_dir_create(ECPContext *ctx, ECPDirSrv *dir_srv, ECPDirList *dir_online, ECPDirList *dir_shadow); -void ecp_dir_destroy(ECPContext *ctx); -ssize_t ecp_dir_send_list(ECPConnection *conn, unsigned char mtype, ECPDirTable *list); - -ssize_t ecp_dir_send_upd(ECPConnection *conn); -ssize_t ecp_dir_handle_upd(ECPConnection *conn, unsigned char *msg, size_t msg_size); - -ssize_t ecp_dir_handle_req(ECPConnection *conn, unsigned char *msg, size_t msg_size); - -ssize_t ecp_dir_send_rep(ECPConnection *conn); -ssize_t ecp_dir_handle_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size); diff --git a/ecp/src/ecp/ext.h b/ecp/src/ecp/ext.h index 4c91000..d661329 100644 --- a/ecp/src/ecp/ext.h +++ b/ecp/src/ecp/ext.h @@ -1,23 +1,36 @@ +#ifdef ECP_WITH_FRAG + +ssize_t ecp_ext_pld_handle_one(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs); +ssize_t ecp_ext_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload); + +#else + +#define ecp_ext_pld_handle_one(c,s,p,sz,b) (0) +#define ecp_ext_msg_send(c,t,m,sz,p1,p2) (0) + +#endif + #ifdef ECP_WITH_RBUF int ecp_ext_err_handle(ECPConnection *conn, unsigned char mtype, int err); -int ecp_ext_conn_open(ECPConnection *conn); +int ecp_ext_conn_create(ECPConnection *conn); void ecp_ext_conn_destroy(ECPConnection *conn); +int ecp_ext_conn_open(ECPConnection *conn); +void ecp_ext_conn_close(ECPConnection *conn); + ssize_t ecp_ext_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs); -ssize_t ecp_ext_pld_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs); ssize_t ecp_ext_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs); ssize_t ecp_ext_pld_send(ECPConnection *conn, ECPBuffer *payload, size_t pld_size, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ecp_tr_addr_t *addr); -ssize_t ecp_ext_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload); #else #define ecp_ext_err_handle(c,t,e) (ECP_PASS) -#define ecp_ext_conn_open(c) (ECP_OK) +#define ecp_ext_conn_create(c) (0) #define ecp_ext_conn_destroy(c) ; +#define ecp_ext_conn_open(c) (ECP_OK) +#define ecp_ext_conn_close(c) ; #define ecp_ext_msg_handle(c,s,t,m,sz,b) (0) -#define ecp_ext_pld_store(c,s,p,sz,b) (0) #define ecp_ext_pld_handle(c,s,p,sz,b) (0) #define ecp_ext_pld_send(c,p1,sz1,p2,sz2,f,t,a) (0) -#define ecp_ext_msg_send(c,t,m,sz,p1,p2) (0) #endif diff --git a/ecp/src/ecp/ext/Makefile b/ecp/src/ecp/ext/Makefile index 0e61e83..b20258f 100644 --- a/ecp/src/ecp/ext/Makefile +++ b/ecp/src/ecp/ext/Makefile @@ -1,6 +1,18 @@ include ../common.mk -obj = ext.o frag.o rbuf.o rbuf_send.o rbuf_recv.o msgq.o +obj = + +ifeq ($(with_frag),yes) +obj += frag.o +endif + +ifeq ($(with_rbuf),yes) +obj += rbuf.o rbuf_send.o rbuf_recv.o rbuf_ext.o +endif + +ifeq ($(with_msgq),yes) +obj += msgq.o +endif %.o: %.c diff --git a/ecp/src/ecp/ext/frag.c b/ecp/src/ecp/ext/frag.c index 58941ba..8795470 100644 --- a/ecp/src/ecp/ext/frag.c +++ b/ecp/src/ecp/ext/frag.c @@ -1,12 +1,11 @@ #include <stdlib.h> #include <string.h> -#include <core.h> +#include <ecp/core.h> -#include "rbuf.h" #include "frag.h" -int ecp_frag_iter_init(ECPRBConn *conn, ECPFragIter *iter, unsigned char *buffer, size_t buf_size) { +int ecp_frag_iter_init(ECPConnection *conn, ECPFragIter *iter, unsigned char *buffer, size_t buf_size) { memset(iter, 0, sizeof(ECPFragIter)); iter->buffer = buffer; iter->buf_size = buf_size; @@ -15,17 +14,64 @@ int ecp_frag_iter_init(ECPRBConn *conn, ECPFragIter *iter, unsigned char *buffer return ECP_OK; } -ECPFragIter *ecp_frag_iter_get(ECPRBConn *conn) { - return conn->iter; -} - void ecp_frag_iter_reset(ECPFragIter *iter) { iter->seq = 0; iter->frag_cnt = 0; iter->pld_size = 0; } -ssize_t ecp_msg_frag(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload) { +ssize_t ecp_pld_defrag(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *payload, size_t pld_size) { + ECPFragIter *iter = conn->iter; + unsigned char *msg; + unsigned char frag_cnt, frag_tot; + uint16_t frag_size; + size_t hdr_size, msg_size; + size_t buf_offset; + int rv; + + rv = ecp_pld_get_frag(payload, pld_size, &frag_cnt, &frag_tot, &frag_size); + if (rv) return ECP_ERR; + + msg = ecp_pld_get_msg(payload, pld_size); + if (msg == NULL) return ECP_ERR; + hdr_size = msg - payload; + + msg_size = pld_size - hdr_size; + if (msg_size == 0) return ECP_ERR; + + if (iter->pld_size && (iter->seq + frag_cnt != seq)) ecp_frag_iter_reset(iter); + + if (iter->pld_size == 0) { + iter->seq = seq - frag_cnt; + iter->frag_cnt = 0; + } + + mtype &= ~ECP_MTYPE_FLAG_FRAG; + buf_offset = ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype) + frag_size * frag_cnt; + if (buf_offset + msg_size > iter->buf_size) return ECP_ERR_SIZE; + memcpy(iter->buffer + buf_offset, msg, msg_size); + + if (frag_cnt == 0) { + if (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype) > iter->buf_size) return ECP_ERR_SIZE; + + iter->buffer[0] = mtype; + if (ECP_SIZE_MT_FLAG(mtype)) { + memcpy(iter->buffer + ECP_SIZE_MTYPE, payload + ECP_SIZE_MTYPE, ECP_SIZE_MT_FLAG(mtype)); + } + msg_size += ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype); + } + + iter->frag_cnt++; + iter->pld_size += msg_size; + if (iter->frag_cnt == frag_tot) { + ecp_pld_handle_one(conn, iter->seq, iter->buffer, iter->pld_size, NULL); + ecp_frag_iter_reset(iter); + } + + return pld_size; +} + +ssize_t ecp_msg_send_wfrag(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload) { unsigned char *msg_buf; unsigned char *pld_buf; size_t pld_size; @@ -72,58 +118,26 @@ ssize_t ecp_msg_frag(ECPConnection *conn, unsigned char mtype, unsigned char *ms return msg_size; } -ssize_t ecp_pld_defrag(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *payload, size_t pld_size) { - ECPRBConn *_conn = NULL; - ECPFragIter *iter = NULL; - unsigned char *msg; - unsigned char frag_cnt, frag_tot; - uint16_t frag_size; - size_t hdr_size, msg_size; - size_t buf_offset; - int rv; - - _conn = ecp_rbuf_get_rbconn(conn); - if (_conn) iter = ecp_frag_iter_get(_conn); - if (iter == NULL) ECP_ERR; - - rv = ecp_pld_get_frag(payload, pld_size, &frag_cnt, &frag_tot, &frag_size); - if (rv) return ECP_ERR; - - msg = ecp_pld_get_msg(payload, pld_size); - if (msg == NULL) return ECP_ERR; - hdr_size = msg - payload; - - msg_size = pld_size - hdr_size; - if (msg_size == 0) return ECP_ERR; - - if (iter->pld_size && (iter->seq + frag_cnt != seq)) ecp_frag_iter_reset(iter); - - if (iter->pld_size == 0) { - iter->seq = seq - frag_cnt; - iter->frag_cnt = 0; - } - - mtype &= ~ECP_MTYPE_FLAG_FRAG; - buf_offset = ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype) + frag_size * frag_cnt; - if (buf_offset + msg_size > iter->buf_size) return ECP_ERR_SIZE; - memcpy(iter->buffer + buf_offset, msg, msg_size); +ssize_t ecp_ext_pld_handle_one(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs) { + if (conn->iter) { + unsigned char mtype; + int rv; - if (frag_cnt == 0) { - if (ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype) > iter->buf_size) return ECP_ERR_SIZE; + rv = ecp_pld_get_type(payload, pld_size, &mtype); + if (rv) return rv; - iter->buffer[0] = mtype; - if (ECP_SIZE_MT_FLAG(mtype)) { - memcpy(iter->buffer + ECP_SIZE_MTYPE, payload + ECP_SIZE_MTYPE, ECP_SIZE_MT_FLAG(mtype)); + if (mtype & ECP_MTYPE_FLAG_FRAG) { + return ecp_pld_defrag(conn, seq, mtype, payload, pld_size); } - msg_size += ECP_SIZE_MTYPE + ECP_SIZE_MT_FLAG(mtype); } - iter->frag_cnt++; - iter->pld_size += msg_size; - if (iter->frag_cnt == frag_tot) { - ecp_pld_handle_one(conn, iter->seq, iter->buffer, iter->pld_size, NULL); - ecp_frag_iter_reset(iter); - } + return 0; +} - return pld_size; +ssize_t ecp_ext_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload) { + if (ECP_SIZE_PKT_BUF(msg_size, mtype, conn) > ECP_MAX_PKT) { + return ecp_msg_send_wfrag(conn, mtype, msg, msg_size, packet, payload); + } else { + return 0; + } } diff --git a/ecp/src/ecp/ext/frag.h b/ecp/src/ecp/ext/frag.h index 1400c1d..2bf35d1 100644 --- a/ecp/src/ecp/ext/frag.h +++ b/ecp/src/ecp/ext/frag.h @@ -6,8 +6,7 @@ typedef struct ECPFragIter { size_t pld_size; } ECPFragIter; -int ecp_frag_iter_init(ECPRBConn *conn, ECPFragIter *iter, unsigned char *buffer, size_t buf_size); -ECPFragIter *ecp_frag_iter_get(ECPRBConn *conn); +int ecp_frag_iter_init(ECPConnection *conn, ECPFragIter *iter, unsigned char *buffer, size_t buf_size); void ecp_frag_iter_reset(ECPFragIter *iter); -ssize_t ecp_msg_frag(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload); -ssize_t ecp_pld_defrag(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *payload, size_t pld_size);
\ No newline at end of file +ssize_t ecp_pld_defrag(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *payload, size_t pld_size); +ssize_t ecp_msg_send_wfrag(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload); diff --git a/ecp/src/ecp/ext/msgq.c b/ecp/src/ecp/ext/msgq.c index e383b03..7172e51 100644 --- a/ecp/src/ecp/ext/msgq.c +++ b/ecp/src/ecp/ext/msgq.c @@ -2,7 +2,7 @@ #include <stdlib.h> #include <string.h> -#include <core.h> +#include <ecp/core.h> #include "rbuf.h" #include "msgq.h" @@ -21,13 +21,15 @@ static struct timespec *abstime_ts(struct timespec *ts, ecp_sts_t msec) { return ts; } -int ecp_msgq_create(ECPRBConn *conn, ECPMsgQ *msgq) { - int i; - int rv; +void ecp_msgq_init(ECPRBConn *conn, ECPMsgQ *msgq) { + memset(msgq, 0, sizeof(ECPMsgQ)); - if (conn->recv == NULL) return ECP_ERR; + conn->recv->msgq = msgq; +} - memset(msgq, 0, sizeof(ECPMsgQ)); +int ecp_msgq_create(ECPRBConn *conn) { + ECPMsgQ *msgq = conn->recv->msgq; + int i, rv; for (i=0; i<ECP_MSGQ_MAX_MTYPE; i++) { rv = pthread_cond_init(&msgq->cond[i], NULL); @@ -40,7 +42,6 @@ int ecp_msgq_create(ECPRBConn *conn, ECPMsgQ *msgq) { return ECP_ERR; } } - conn->recv->msgq = msgq; return ECP_OK; } @@ -52,8 +53,6 @@ void ecp_msgq_destroy(ECPRBConn *conn) { for (i=0; i<ECP_MSGQ_MAX_MTYPE; i++) { pthread_cond_destroy(&msgq->cond[i]); } - - conn->recv->msgq = NULL; } void ecp_msgq_start(ECPRBConn *conn, ecp_seq_t seq) { @@ -117,6 +116,8 @@ ssize_t ecp_msgq_pop(ECPRBConn *conn, unsigned char mtype, unsigned char *msg, s msg_size = pld_size - hdr_size; rbuf->arr.pld[idx].flags &= ~ECP_RBUF_FLAG_IN_MSGQ; + // if (rbuf->arr.pld[idx].flags == 0); + msgq->idx_r[mtype]++; if (msgq->seq_start == seq) { int i; diff --git a/ecp/src/ecp/ext/msgq.h b/ecp/src/ecp/ext/msgq.h index dddb6e7..669a5af 100644 --- a/ecp/src/ecp/ext/msgq.h +++ b/ecp/src/ecp/ext/msgq.h @@ -11,7 +11,8 @@ typedef struct ECPMsgQ { pthread_cond_t cond[ECP_MSGQ_MAX_MTYPE]; } ECPMsgQ; -int ecp_msgq_create(ECPRBConn *conn, ECPMsgQ *msgq); +void ecp_msgq_init(ECPRBConn *conn, ECPMsgQ *msgq); +int ecp_msgq_create(ECPRBConn *conn); void ecp_msgq_destroy(ECPRBConn *conn); void ecp_msgq_start(ECPRBConn *conn, ecp_seq_t seq); int ecp_msgq_push(ECPRBConn *conn, ecp_seq_t seq, unsigned char mtype); diff --git a/ecp/src/ecp/ext/rbuf.c b/ecp/src/ecp/ext/rbuf.c index 70ee0d2..e1fab7b 100644 --- a/ecp/src/ecp/ext/rbuf.c +++ b/ecp/src/ecp/ext/rbuf.c @@ -1,6 +1,6 @@ #include <stdlib.h> -#include <core.h> +#include <ecp/core.h> #include "rbuf.h" @@ -28,41 +28,35 @@ int _ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq, unsigned short *idx) { return ECP_OK; } -void ecp_rbuf_conn_init(ECPRBConn *conn) { +void ecp_rbuf_init(ECPRBConn *conn) { ECPConnection *_conn = ecp_rbuf_get_conn(conn); ecp_conn_set_flags(_conn, ECP_CONN_FLAG_RBUF); conn->send = NULL; conn->recv = NULL; - conn->iter = NULL; } -int ecp_rbuf_conn_create(ECPRBConn *conn, ECPSocket *sock, unsigned char type) { - ECPConnection *_conn = ecp_rbuf_get_conn(conn); +int ecp_rbuf_create(ECPRBConn *conn) { int rv; - rv = ecp_conn_create(_conn, sock, type); - if (rv) return rv; - - ecp_rbuf_conn_init(conn); - return ECP_OK; -} - -int ecp_rbuf_conn_create_inb(ECPRBConn *conn, ECPSocket *sock, unsigned char type) { - ECPConnection *_conn = ecp_rbuf_get_conn(conn); - int rv; - - rv = ecp_conn_create_inb(_conn, sock, type); - if (rv) return rv; + if (conn->send) { + rv = ecp_rbsend_create(conn); + if (rv) return rv; + } + if (conn->recv) { + rv = ecp_rbrecv_create(conn); + if (rv) { + if (conn->send) ecp_rbsend_destroy(conn); + return rv; + } + } - ecp_rbuf_conn_init(conn); return ECP_OK; } void ecp_rbuf_destroy(ECPRBConn *conn) { if (conn->send) ecp_rbsend_destroy(conn); if (conn->recv) ecp_rbrecv_destroy(conn); - conn->iter = NULL; } void ecp_rbuf_start(ECPRBConn *conn) { @@ -71,14 +65,32 @@ void ecp_rbuf_start(ECPRBConn *conn) { if (conn->send) { ecp_seq_t seq_out; +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&_conn->mutex); +#endif + seq_out = (ecp_seq_t)(_conn->nonce_out); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&_conn->mutex); +#endif + ecp_rbsend_start(conn, seq_out); } if (conn->recv) { ecp_seq_t seq_in; +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&_conn->mutex); +#endif + seq_in = (ecp_seq_t)(_conn->nonce_in); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&_conn->mutex); +#endif + ecp_rbrecv_start(conn, seq_in); } } diff --git a/ecp/src/ecp/ext/rbuf.h b/ecp/src/ecp/ext/rbuf.h index 36ff963..bf6e6df 100644 --- a/ecp/src/ecp/ext/rbuf.h +++ b/ecp/src/ecp/ext/rbuf.h @@ -87,16 +87,14 @@ typedef struct ECPRBConn { ECPConnection b; ECPRBRecv *recv; ECPRBSend *send; - struct ECPFragIter *iter; } ECPRBConn; ECPRBConn *ecp_rbuf_get_rbconn(ECPConnection *conn); ECPConnection *ecp_rbuf_get_conn(ECPRBConn *conn); void _ecp_rbuf_start(ECPRBuffer *rbuf, ecp_seq_t seq); int _ecp_rbuf_msg_idx(ECPRBuffer *rbuf, ecp_seq_t seq, unsigned short *idx); -void ecp_rbuf_conn_init(ECPRBConn *conn); -int ecp_rbuf_conn_create(ECPRBConn *conn, ECPSocket *sock, unsigned char type); -int ecp_rbuf_conn_create_inb(ECPRBConn *conn, ECPSocket *sock, unsigned char type); +void ecp_rbuf_init(ECPRBConn *conn); +int ecp_rbuf_create(ECPRBConn *conn); void ecp_rbuf_destroy(ECPRBConn *conn); void ecp_rbuf_start(ECPRBConn *conn); ssize_t ecp_rbuf_msg_handle(ECPRBConn *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs); @@ -105,19 +103,23 @@ int ecp_rbuf_err_handle(ECPRBConn *conn, unsigned char mtype, int err); /* send */ ssize_t ecp_rbuf_send_flush(ECPRBConn *conn); ssize_t ecp_rbuf_handle_ack(ECPRBConn *conn, unsigned char *msg, size_t msg_size); -int ecp_rbsend_create(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigned short pkt_size); +void ecp_rbsend_init(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigned short pkt_size); +int ecp_rbsend_create(ECPRBConn *conn); void ecp_rbsend_destroy(ECPRBConn *conn); void ecp_rbsend_start(ECPRBConn *conn, ecp_seq_t seq); int ecp_rbuf_set_wsize(ECPRBConn *conn, ecp_win_t size); int ecp_rbuf_flush(ECPRBConn *conn); ssize_t ecp_rbuf_pld_send(ECPRBConn *conn, ECPBuffer *payload, size_t pld_size, ECPBuffer *packet, size_t pkt_size, ECPTimerItem *ti); +/* recv */ ssize_t ecp_rbuf_handle_nop(ECPRBConn *conn, unsigned char *msg, size_t msg_size); ssize_t ecp_rbuf_handle_flush(ECPRBConn *conn); -void ecp_rbuf_handle_timer(ECPRBConn *conn) ; -int ecp_rbrecv_create(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsigned short pld_size); +void ecp_rbuf_handle_timer(ECPRBConn *conn); +void ecp_rbrecv_init(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsigned short pld_size); +int ecp_rbrecv_create(ECPRBConn *conn); void ecp_rbrecv_destroy(ECPRBConn *conn); void ecp_rbrecv_start(ECPRBConn *conn, ecp_seq_t seq); + int ecp_rbuf_set_hole(ECPRBConn *conn, unsigned short hole_max); int ecp_rbuf_set_delay(ECPRBConn *conn, ecp_sts_t delay); ssize_t ecp_rbuf_store(ECPRBConn *conn, ecp_seq_t seq, unsigned char *pld, size_t pld_size); diff --git a/ecp/src/ecp/ext/ext.c b/ecp/src/ecp/ext/rbuf_ext.c index d407e80..67b6a8d 100644 --- a/ecp/src/ecp/ext/ext.c +++ b/ecp/src/ecp/ext/rbuf_ext.c @@ -1,10 +1,9 @@ #include <stdlib.h> -#include <core.h> -#include <ext.h> +#include <ecp/core.h> +#include <ecp/ext.h> #include "rbuf.h" -#include "frag.h" int ecp_ext_err_handle(ECPConnection *conn, unsigned char mtype, int err) { ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); @@ -13,44 +12,41 @@ int ecp_ext_err_handle(ECPConnection *conn, unsigned char mtype, int err) { return ECP_PASS; } -int ecp_ext_conn_open(ECPConnection *conn) { +int ecp_ext_conn_create(ECPConnection *conn) { ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); + int rv = ECP_OK; - if (_conn) ecp_rbuf_start(_conn); - return ECP_OK; + if (_conn) rv = ecp_rbuf_create(_conn); + return rv; } void ecp_ext_conn_destroy(ECPConnection *conn) { ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); + if (_conn) ecp_rbuf_destroy(_conn); } -ssize_t ecp_ext_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { +int ecp_ext_conn_open(ECPConnection *conn) { ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); - if (_conn) return ecp_rbuf_msg_handle(_conn, seq, mtype, msg, msg_size, bufs); - return 0; + if (_conn) ecp_rbuf_start(_conn); + return ECP_OK; } -ssize_t ecp_ext_pld_store(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs) { +void ecp_ext_conn_close(ECPConnection *conn) {} + +ssize_t ecp_ext_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); - if (_conn && _conn->recv) return ecp_rbuf_store(_conn, seq, payload, pld_size); + if (_conn) return ecp_rbuf_msg_handle(_conn, seq, mtype, msg, msg_size, bufs); return 0; } ssize_t ecp_ext_pld_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char *payload, size_t pld_size, ECP2Buffer *bufs) { - unsigned char mtype; - int rv; - - rv = ecp_pld_get_type(payload, pld_size, &mtype); - if (rv) return rv; + ECPRBConn *_conn = ecp_rbuf_get_rbconn(conn); - if (mtype & ECP_MTYPE_FLAG_FRAG) { - return ecp_pld_defrag(conn, seq, mtype, payload, pld_size); - } else { - return 0; - } + if (_conn && _conn->recv) return ecp_rbuf_store(_conn, seq, payload, pld_size); + return 0; } ssize_t ecp_ext_pld_send(ECPConnection *conn, ECPBuffer *payload, size_t pld_size, ECPBuffer *packet, size_t pkt_size, unsigned char flags, ECPTimerItem *ti, ecp_tr_addr_t *addr) { @@ -59,11 +55,3 @@ ssize_t ecp_ext_pld_send(ECPConnection *conn, ECPBuffer *payload, size_t pld_siz if (_conn && _conn->send) return ecp_rbuf_pld_send(_conn, payload, pld_size, packet, pkt_size, ti); return 0; } - -ssize_t ecp_ext_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECPBuffer *packet, ECPBuffer *payload) { - if (ECP_SIZE_PKT_BUF(msg_size, mtype, conn) > ECP_MAX_PKT) { - return ecp_msg_frag(conn, mtype, msg, msg_size, packet, payload); - } else { - return 0; - } -} diff --git a/ecp/src/ecp/ext/rbuf_recv.c b/ecp/src/ecp/ext/rbuf_recv.c index de25cb6..b981e3f 100644 --- a/ecp/src/ecp/ext/rbuf_recv.c +++ b/ecp/src/ecp/ext/rbuf_recv.c @@ -1,8 +1,8 @@ #include <stdlib.h> #include <string.h> -#include <core.h> -#include <tm.h> +#include <ecp/core.h> +#include <ecp/tm.h> #include "rbuf.h" @@ -89,7 +89,7 @@ static void msg_flush(ECPRBConn *conn) { rv = ecp_pld_get_pts(rbuf->arr.pld[idx].buf, rbuf->arr.pld[idx].size, &msg_pts); if (!rv && buf->deliver_delay) { - ecp_sts_t now = ecp_tm_get_tick(); + ecp_sts_t now = ecp_tm_get_ms(); msg_pts += buf->deliver_delay; if (ECP_PTS_LT(now, msg_pts)) { @@ -122,6 +122,7 @@ static void msg_flush(ECPRBConn *conn) { rbuf->arr.pld[idx].flags &= ~ECP_RBUF_FLAG_SKIP; } rbuf->arr.pld[idx].flags &= ~ECP_RBUF_FLAG_IN_RBUF; + // if (rbuf->arr.pld[idx].flags == 0); } else { if (buf->flags & ECP_RBUF_FLAG_RELIABLE) break; if (!ECP_SEQ_LT(seq, rbuf->seq_max - buf->hole_max)) break; @@ -274,9 +275,8 @@ void ecp_rbuf_handle_timer(ECPRBConn *conn) { #endif } -int ecp_rbrecv_create(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsigned short pld_size) { +void ecp_rbrecv_init(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsigned short pld_size) { ECPRBuffer *rbuf = &buf->rbuf; - int rv; memset(buf, 0, sizeof(ECPRBRecv)); memset(pld, 0, sizeof(ECPRBPayload) * pld_size); @@ -286,12 +286,31 @@ int ecp_rbrecv_create(ECPRBConn *conn, ECPRBRecv *buf, ECPRBPayload *pld, unsign rbuf->arr.pld = pld; rbuf->arr_size = pld_size; + conn->recv = buf; +} + +int ecp_rbrecv_create(ECPRBConn *conn) { + ECPRBRecv *buf = conn->recv; + int rv; + #ifdef ECP_WITH_PTHREAD rv = pthread_mutex_init(&buf->mutex, NULL); if (rv) return ECP_ERR; #endif - conn->recv = buf; +#ifdef ECP_WITH_MSGQ + if (buf->msgq) { + rv = ecp_msgq_create(conn); + if (rv) { +#ifdef ECP_WITH_PTHREAD + pthread_mutex_destroy(&buf->mutex); +#endif + + return ECP_ERR; + } + } +#endif + return ECP_OK; } @@ -305,8 +324,6 @@ void ecp_rbrecv_destroy(ECPRBConn *conn) { #ifdef ECP_WITH_MSGQ if (buf->msgq) ecp_msgq_destroy(conn); #endif - - conn->recv = NULL; } void ecp_rbrecv_start(ECPRBConn *conn, ecp_seq_t seq) { diff --git a/ecp/src/ecp/ext/rbuf_send.c b/ecp/src/ecp/ext/rbuf_send.c index d3d2f04..40d526c 100644 --- a/ecp/src/ecp/ext/rbuf_send.c +++ b/ecp/src/ecp/ext/rbuf_send.c @@ -1,7 +1,7 @@ #include <stdlib.h> #include <string.h> -#include <core.h> +#include <ecp/core.h> #include "rbuf.h" @@ -43,6 +43,7 @@ static void cc_flush(ECPRBConn *conn, unsigned char flags) { } if (!(buf->flags & ECP_RBUF_FLAG_RELIABLE)) { rbuf->arr.pkt[idx].flags = 0; + // if (rbuf->arr.pkt[idx].flags == 0); } buf->seq_cc++; idx = ECP_RBUF_IDX_MASK(idx + 1, rbuf->arr_size); @@ -209,6 +210,7 @@ ssize_t ecp_rbuf_handle_ack(ECPRBConn *conn, unsigned char *msg, size_t msg_size idx = rbuf->idx_start; for (i=0; i<msg_cnt; i++) { rbuf->arr.pkt[idx].flags = 0; + // if (rbuf->arr.pkt[idx].flags == 0); idx = ECP_RBUF_IDX_MASK(idx + 1, rbuf->arr_size); } rbuf->seq_start = seq_start; @@ -237,9 +239,8 @@ handle_ack_fin: return rsize; } -int ecp_rbsend_create(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigned short pkt_size) { +void ecp_rbsend_init(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigned short pkt_size) { ECPRBuffer *rbuf = &buf->rbuf; - int rv; memset(buf, 0, sizeof(ECPRBRecv)); memset(pkt, 0, sizeof(ECPRBPacket) * pkt_size); @@ -247,12 +248,18 @@ int ecp_rbsend_create(ECPRBConn *conn, ECPRBSend *buf, ECPRBPacket *pkt, unsigne rbuf->arr.pkt = pkt; rbuf->arr_size = pkt_size; + conn->send = buf; +} + +int ecp_rbsend_create(ECPRBConn *conn) { + ECPRBSend *buf = conn->send; + int rv; + #ifdef ECP_WITH_PTHREAD rv = pthread_mutex_init(&buf->mutex, NULL); if (rv) return ECP_ERR; #endif - conn->send = buf; return ECP_OK; } @@ -262,8 +269,6 @@ void ecp_rbsend_destroy(ECPRBConn *conn) { #ifdef ECP_WITH_PTHREAD pthread_mutex_destroy(&buf->mutex); #endif - - conn->send = NULL; } void ecp_rbsend_start(ECPRBConn *conn, ecp_seq_t seq) { diff --git a/ecp/src/ecp/ht.h b/ecp/src/ecp/ht.h index 31ca698..805fbda 100644 --- a/ecp/src/ecp/ht.h +++ b/ecp/src/ecp/ht.h @@ -2,13 +2,16 @@ ecp_ht_table_t *ecp_ht_create_keys(void); ecp_ht_table_t *ecp_ht_create_addrs(void); void ecp_ht_destroy(ecp_ht_table_t *h); -int ecp_ht_insert(ecp_ht_table_t *h, void *k, ECPConnection *v); -ECPConnection *ecp_ht_remove(ecp_ht_table_t *h, void *k); -ECPConnection *ecp_ht_search(ecp_ht_table_t *h, void *k); +int ecp_ht_insert(ecp_ht_table_t *h, void *k, void *v); +void *ecp_ht_remove(ecp_ht_table_t *h, void *k); +void *ecp_ht_remove_kv(ecp_ht_table_t *h, void *k, void *v); +void *ecp_ht_search(ecp_ht_table_t *h, void *k); +void *ecp_ht_search_next(ecp_ht_table_t *h, void *k, void *v); +unsigned int ecp_ht_count(ecp_ht_table_t *h); void ecp_ht_itr_create(ecp_ht_itr_t *i, ecp_ht_table_t *h); int ecp_ht_itr_advance(ecp_ht_itr_t *i); int ecp_ht_itr_remove(ecp_ht_itr_t *i); int ecp_ht_itr_search(ecp_ht_itr_t *i, void *k); void *ecp_ht_itr_key(ecp_ht_itr_t *i); -ECPConnection *ecp_ht_itr_value(ecp_ht_itr_t *i); +void *ecp_ht_itr_value(ecp_ht_itr_t *i); diff --git a/ecp/src/ecp/htable/hashtable.c b/ecp/src/ecp/htable/hashtable.c index 4a48edb..13ed68c 100755 --- a/ecp/src/ecp/htable/hashtable.c +++ b/ecp/src/ecp/htable/hashtable.c @@ -212,6 +212,32 @@ hashtable_search(struct hashtable *h, void *k) } /*****************************************************************************/ +void * /* returns value associated with key k after value v */ +hashtable_search_next(struct hashtable *h, void *k, void *v) +{ + struct entry *e; + unsigned int hashvalue, index, f; + hashvalue = hashtable_hash(h,k); + index = indexFor(h->tablelength,hashvalue); + f = 0; + e = h->table[index]; + while (NULL != e) + { + if (f) + { + /* Check hash value to short circuit heavier comparison */ + if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v; + } + else if (v == e->v) + { + f = 1; + } + e = e->next; + } + return NULL; +} + +/*****************************************************************************/ void * /* returns value associated with key */ hashtable_remove(struct hashtable *h, void *k) { @@ -228,6 +254,17 @@ hashtable_remove(struct hashtable *h, void *k) return v; } +void * /* returns value associated with key */ +hashtable_remove_kv(struct hashtable *h, void *k, void *v) +{ + struct entry *e; + e = hashtable_remove_kv_static(h,k,v); + if (NULL == e) return NULL; + freekey(e->k); + free(e); + return v; +} + struct entry * /* returns hash table entry associated with key */ hashtable_remove_static(struct hashtable *h, void *k) { @@ -253,6 +290,30 @@ hashtable_remove_static(struct hashtable *h, void *k) return NULL; } +struct entry * /* returns hash table entry associated with key k and value v */ +hashtable_remove_kv_static(struct hashtable *h, void *k, void *v) +{ + struct entry *e; + struct entry **pE; + unsigned int hashvalue, index; + hashvalue = hashtable_hash(h,k); + index = indexFor(h->tablelength,hashvalue); + pE = &(h->table[index]); + e = *pE; + while (NULL != e) + { + if (v == e->v) + { + *pE = e->next; + h->entrycount--; + return e; + } + pE = &(e->next); + e = e->next; + } + return NULL; +} + /*****************************************************************************/ /* destroy */ void diff --git a/ecp/src/ecp/htable/hashtable.h b/ecp/src/ecp/htable/hashtable.h index 8faeafc..a5b3ab8 100755 --- a/ecp/src/ecp/htable/hashtable.h +++ b/ecp/src/ecp/htable/hashtable.h @@ -150,6 +150,9 @@ int fnname (struct hashtable *h, keytype *k, valuetype *v) \ void * hashtable_search(struct hashtable *h, void *k); +void * +hashtable_search_next(struct hashtable *h, void *k, void *v); + #define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \ valuetype * fnname (struct hashtable *h, keytype *k) \ { \ @@ -168,9 +171,15 @@ valuetype * fnname (struct hashtable *h, keytype *k) \ void * /* returns value */ hashtable_remove(struct hashtable *h, void *k); +void * /* returns value v */ +hashtable_remove_kv(struct hashtable *h, void *k, void *v); + struct entry * /* returns hash table entry */ hashtable_remove_static(struct hashtable *h, void *k); +struct entry * /* returns hash table entry */ +hashtable_remove_kv_static(struct hashtable *h, void *k, void *v); + #define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \ valuetype * fnname (struct hashtable *h, keytype *k) \ { \ diff --git a/ecp/src/ecp/htable/htable.c b/ecp/src/ecp/htable/htable.c index c0efebb..c22d2ab 100644 --- a/ecp/src/ecp/htable/htable.c +++ b/ecp/src/ecp/htable/htable.c @@ -1,9 +1,9 @@ #include <stdlib.h> -#include <core.h> -#include <cr.h> -#include <tr.h> -#include <ht.h> +#include <ecp/core.h> +#include <ecp/cr.h> +#include <ecp/tr.h> +#include <ecp/ht.h> ecp_ht_table_t *ecp_ht_create_keys(void) { return hashtable_create(1000, (unsigned int (*)(void *))ecp_ecdh_pub_hash, (int (*)(void *, void *))ecp_ecdh_pub_eq); @@ -17,7 +17,7 @@ void ecp_ht_destroy(ecp_ht_table_t *h) { hashtable_destroy(h, 0); } -int ecp_ht_insert(ecp_ht_table_t *h, void *k, ECPConnection *v) { +int ecp_ht_insert(ecp_ht_table_t *h, void *k, void *v) { int rv; rv = hashtable_insert(h, k, v); @@ -25,14 +25,26 @@ int ecp_ht_insert(ecp_ht_table_t *h, void *k, ECPConnection *v) { return ECP_OK; } -ECPConnection *ecp_ht_remove(ecp_ht_table_t *h, void *k) { +void *ecp_ht_remove(ecp_ht_table_t *h, void *k) { return hashtable_remove(h, k); } -ECPConnection *ecp_ht_search(ecp_ht_table_t *h, void *k) { +void *ecp_ht_remove_kv(ecp_ht_table_t *h, void *k, void *v) { + return hashtable_remove_kv(h, k, v); +} + +void *ecp_ht_search(ecp_ht_table_t *h, void *k) { return hashtable_search(h, k); } +void *ecp_ht_search_next(ecp_ht_table_t *h, void *k, void *v) { + return hashtable_search_next(h, k, v); +} + +unsigned int ecp_ht_count(ecp_ht_table_t *h) { + return hashtable_count(h); +} + void ecp_ht_itr_create(ecp_ht_itr_t *i, ecp_ht_table_t *h) { hashtable_iterator(i, h); } @@ -42,7 +54,7 @@ int ecp_ht_itr_advance(ecp_ht_itr_t *i) { rv = hashtable_iterator_advance(i); if (rv == 0) return ECP_ITR_END; - return rv; + return ECP_OK; } int ecp_ht_itr_remove(ecp_ht_itr_t *i) { @@ -65,6 +77,6 @@ void *ecp_ht_itr_key(ecp_ht_itr_t *i) { return hashtable_iterator_key(i); } -ECPConnection *ecp_ht_itr_value(ecp_ht_itr_t *i) { +void *ecp_ht_itr_value(ecp_ht_itr_t *i) { return hashtable_iterator_value(i); } diff --git a/ecp/src/ecp/timer.c b/ecp/src/ecp/timer.c index fb0f62a..38df398 100644 --- a/ecp/src/ecp/timer.c +++ b/ecp/src/ecp/timer.c @@ -37,13 +37,13 @@ int ecp_timer_push(ECPTimerItem *ti) { ECPConnection *conn = ti->conn; ECPTimer *timer = &conn->sock->timer; - ti->abstime = ecp_tm_get_tick() + ti->timeout; + ti->abstime = ecp_tm_get_ms() + ti->timeout; #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&timer->mutex); pthread_mutex_lock(&conn->mutex); #endif - is_reg = ecp_conn_is_reg(conn); + is_reg = _ecp_conn_is_reg(conn); if (is_reg) conn->refcount++; #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&conn->mutex); @@ -137,7 +137,7 @@ ecp_sts_t ecp_timer_exe(ECPSocket *sock) { ECPTimer *timer = &sock->timer; ECPTimerItem to_exec[ECP_MAX_TIMER]; int to_exec_size = 0; - ecp_sts_t now = ecp_tm_get_tick(); + ecp_sts_t now = ecp_tm_get_ms(); #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&timer->mutex); diff --git a/ecp/src/ecp/tm.h b/ecp/src/ecp/tm.h index 033a031..45e5784 100644 --- a/ecp/src/ecp/tm.h +++ b/ecp/src/ecp/tm.h @@ -1,4 +1,5 @@ int ecp_tm_init(ECPContext *ctx); -ecp_sts_t ecp_tm_get_tick(void); +ecp_sts_t ecp_tm_get_s(void); +ecp_sts_t ecp_tm_get_ms(void); void ecp_tm_sleep(ecp_sts_t msec); void ecp_tm_timer_set(ecp_sts_t next); diff --git a/ecp/src/ecp/tr.h b/ecp/src/ecp/tr.h index 263577c..6c99f15 100644 --- a/ecp/src/ecp/tr.h +++ b/ecp/src/ecp/tr.h @@ -2,7 +2,7 @@ int ecp_tr_init(ECPContext *ctx); unsigned int ecp_tr_addr_hash(ecp_tr_addr_t *addr); int ecp_tr_addr_eq(ecp_tr_addr_t *addr1, ecp_tr_addr_t *addr2); int ecp_tr_addr_set(ecp_tr_addr_t *addr, void *addr_s); -int ecp_tr_open(ECPSocket *sock, void *addr_s); +int ecp_tr_open(ECPSocket *sock, ecp_tr_addr_t *addr); void ecp_tr_close(ECPSocket *sock); ssize_t ecp_tr_send(ECPSocket *sock, ECPBuffer *packet, size_t pkt_size, ecp_tr_addr_t *addr, unsigned char flags); ssize_t ecp_tr_recv(ECPSocket *sock, ECPBuffer *packet, ecp_tr_addr_t *addr, int timeout); diff --git a/ecp/src/ecp/vconn/vconn.c b/ecp/src/ecp/vconn/vconn.c index 3d4dd29..f52b2f5 100644 --- a/ecp/src/ecp/vconn/vconn.c +++ b/ecp/src/ecp/vconn/vconn.c @@ -1,11 +1,11 @@ #include <stdlib.h> #include <string.h> -#include <core.h> -#include <tr.h> +#include <ecp/core.h> +#include <ecp/tr.h> #ifdef ECP_WITH_HTABLE -#include <ht.h> +#include <ecp/ht.h> #endif #include "vconn.h" @@ -13,9 +13,9 @@ #ifdef ECP_WITH_HTABLE -static int insert_key_next(ECPConnection *conn, unsigned char c_idx, ecp_ecdh_public_t *public) { +static int insert_key_next(ECPVConnInb *vconn, unsigned char c_idx, ecp_ecdh_public_t *public) { + ECPConnection *conn = &vconn->b; ECPSocket *sock = conn->sock; - ECPVConn *_conn = (ECPVConn *)conn; ECPDHPub *key = NULL; int rv = ECP_OK; @@ -25,11 +25,11 @@ static int insert_key_next(ECPConnection *conn, unsigned char c_idx, ecp_ecdh_pu pthread_mutex_lock(&conn->mutex); #endif - if (c_idx != _conn->key_next_curr) { + if (c_idx != vconn->key_next_curr) { unsigned char _c_idx; _c_idx = c_idx % ECP_MAX_NODE_KEY; - key = &_conn->key_next[_c_idx]; + key = &vconn->key_next[_c_idx]; if (key->valid && (memcmp(public, &key->public, sizeof(key->public)) == 0)) { key = NULL; @@ -54,7 +54,7 @@ static int insert_key_next(ECPConnection *conn, unsigned char c_idx, ecp_ecdh_pu rv = ecp_ht_insert(sock->conn_table.keys, &key->public, conn); if (!rv) { key->valid = 1; - _conn->key_next_curr = c_idx; + vconn->key_next_curr = c_idx; } #ifdef ECP_WITH_PTHREAD @@ -67,23 +67,37 @@ static int insert_key_next(ECPConnection *conn, unsigned char c_idx, ecp_ecdh_pu } static ssize_t handle_next(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { + ECPVConnInb *vconn = (ECPVConnInb *)conn; ECPSocket *sock = conn->sock; + int is_open; if (msg_size < ECP_SIZE_ECDH_PUB) return ECP_ERR_SIZE; if (ecp_conn_is_outb(conn)) return ECP_ERR; #ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&conn->mutex); +#endif + + is_open = _ecp_conn_is_open(conn); + +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&conn->mutex); +#endif + + if (is_open) return ECP_ERR_NEXT; + +#ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&sock->conn_table.mutex); #endif - conn->next = ecp_ht_search(sock->conn_table.keys, (ecp_ecdh_public_t *)msg); - if (conn->next) ecp_conn_refcount_inc(conn->next); + vconn->next = ecp_ht_search(sock->conn_table.keys, (ecp_ecdh_public_t *)msg); + if (vconn->next) ecp_conn_refcount_inc(vconn->next); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&sock->conn_table.mutex); #endif - if (conn->next == NULL) return ECP_ERR_NEXT; + if (vconn->next == NULL) return ECP_ERR_NEXT; return ECP_SIZE_ECDH_PUB; } @@ -105,13 +119,15 @@ static ssize_t handle_relay(ECPConnection *conn, unsigned char *msg, size_t msg_ switch (conn->type) { /* forward message */ case ECP_CTYPE_VCONN: { + ECPVConnInb *vconn = (ECPVConnInb *)conn; + if (ecp_conn_is_outb(conn)) return ECP_ERR; - conn_next = conn->next; + conn_next = vconn->next; if (conn_next) { _idx = (idx & 0x0F); - _rv = insert_key_next(conn, _idx, (ecp_ecdh_public_t *)(msg+ECP_SIZE_PROTO+1)); + _rv = insert_key_next(vconn, _idx, (ecp_ecdh_public_t *)(msg+ECP_SIZE_PROTO+1)); if (_rv) return _rv; } @@ -167,6 +183,7 @@ static ssize_t handle_relay(ECPConnection *conn, unsigned char *msg, size_t msg_ static ssize_t handle_exec(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { ECPBuffer *packet; + ssize_t rv; if (bufs == NULL) return ECP_ERR; @@ -174,7 +191,8 @@ static ssize_t handle_exec(ECPConnection *conn, unsigned char *msg, size_t msg_s if (packet->size < msg_size) return ECP_ERR_SIZE; memcpy(packet->buffer, msg, msg_size); - return ecp_pkt_handle(conn->sock, conn, NULL, bufs, msg_size); + rv = ecp_pkt_handle(conn->sock, conn, NULL, bufs, msg_size); + return rv; } ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *payload, ECPBuffer *packet, size_t pkt_size, ecp_tr_addr_t *addr) { @@ -197,70 +215,77 @@ ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *payload, ECPBuffer return rv; } -static int vconn_create(ECPConnection vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPSocket *sock) { +void ecp_vconn_init(ECPVConnOutb vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPSocket *sock) { ECPDHPub key; - int i, j; - int rv; + int i; key.valid = 1; for (i=0; i<vconn_size; i++) { - 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); + ecp_conn_init(&vconn[i].b, sock, ECP_CTYPE_VCONN); + ecp_conn_set_remote_key(&vconn[i].b, &key); + if (i < vconn_size - 1) { + vconn[i].next = &vconn[i + 1].b; + } else { + vconn[i].next = NULL; + } } - - return ECP_OK; } -int ecp_vconn_create(ECPConnection vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPConnection *conn) { - ECPConnection *_conn; - unsigned short pcount; - int rv; +#ifdef ECP_WITH_HTABLE - _conn = conn; - pcount = vconn_size; +void ecp_vconn_init_inb(ECPVConnInb *vconn, ECPSocket *sock) { + ECPConnection *conn = &vconn->b; - if (pcount > ECP_MAX_PARENT) return ECP_ERR_MAX_PARENT; + ecp_conn_init(conn, sock, ECP_CTYPE_VCONN); + vconn->next = NULL; + memset(vconn->key_next, 0, sizeof(vconn->key_next)); + vconn->key_next_curr = ECP_ECDH_IDX_INV; +} - rv = vconn_create(vconn, keys, vconn_size, conn->sock); - if (rv) return rv; +#endif /* ECP_WITH_HTABLE */ - while (pcount) { - _conn->parent = &vconn[pcount-1]; - _conn->parent->next = _conn; - _conn->pcount = pcount; +int ecp_vconn_open(ECPVConnOutb *vconn, ECPConnection *conn, ECPNode *node) { + ECPVConnOutb *_vconn; + int rv; - _conn = _conn->parent; - pcount--; + _vconn = vconn; + while (_vconn->next) { + _vconn = (ECPVConnOutb *)_vconn->next; } - return ECP_OK; + _vconn->next = conn; + if (node) { + ecp_conn_set_remote_key(conn, &node->key_perma); + ecp_conn_set_remote_addr(&vconn->b, &node->addr); + } + + rv = _ecp_conn_open(&vconn->b, NULL, NULL, 1); + return rv; } -#ifdef ECP_WITH_HTABLE +int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs) { + int rv = ECP_OK; -int ecp_vconn_create_inb(ECPVConn *conn, ECPSocket *sock) { - ECPConnection *_conn = &conn->b; - int rv; + if (ecp_conn_is_outb(conn)) { + ECPVConnOutb *vconn = (ECPVConnOutb *)conn; - rv = ecp_conn_create_inb(_conn, sock, ECP_CTYPE_VCONN); - if (rv) return rv; + if (vconn->next == NULL) return ECP_ERR; - memset(conn->key_next, 0, sizeof(conn->key_next)); - conn->key_next_curr = ECP_ECDH_IDX_INV; + /* 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); + if (rv) rv = ECP_ERR_NEXT; + } - return ECP_OK; + return rv; } -void ecp_vconn_destroy(ECPConnection *conn) { +#ifdef ECP_WITH_HTABLE + +void ecp_vconn_handle_close(ECPConnection *conn) { + ECPVConnInb *vconn = (ECPVConnInb *)conn; ECPSocket *sock = conn->sock; - ECPVConn *_conn = (ECPVConn *)conn; int i; if (ecp_conn_is_outb(conn)) return; @@ -272,7 +297,7 @@ void ecp_vconn_destroy(ECPConnection *conn) { for (i=0; i<ECP_MAX_NODE_KEY; i++) { ECPDHPub *key; - key = &_conn->key_next[i]; + key = &vconn->key_next[i]; if (key->valid) { ecp_ht_remove(sock->conn_table.keys, &key->public); } @@ -282,77 +307,82 @@ void ecp_vconn_destroy(ECPConnection *conn) { pthread_mutex_unlock(&sock->conn_table.mutex); #endif - if (conn->next) ecp_conn_refcount_dec(conn->next); + if (vconn->next) ecp_conn_refcount_dec(vconn->next); } #endif /* ECP_WITH_HTABLE */ -int ecp_vconn_open(ECPConnection *conn, ECPNode *node) { - ECPConnection *vconn0; - int rv; +ssize_t ecp_vconn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { + ssize_t rv; - vconn0 = conn; - while (vconn0->parent) { - vconn0 = vconn0->parent; - } + switch (mtype) { +#ifdef ECP_WITH_HTABLE + case ECP_MTYPE_NEXT: + rv = handle_next(conn, msg, msg_size, bufs); + break; - if (node) { - ecp_conn_set_remote_key(conn, &node->key_perma); - ecp_conn_set_remote_addr(vconn0, &node->addr); + case ECP_MTYPE_RELAY: + rv = handle_relay(conn, msg, msg_size, bufs); + break; +#endif + + case ECP_MTYPE_EXEC: + rv = handle_exec(conn, msg, msg_size, bufs); + break; + + default: + rv = ECP_ERR_MTYPE; + break; } - rv = ecp_conn_open(vconn0, NULL); return rv; } -static int vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs) { - int rv = ECP_OK; +ssize_t ecp_vconn_send_open_req(ECPConnection *conn, unsigned char *cookie) { + ECPVConnOutb *vconn = (ECPVConnOutb *)conn; + ECPDHPub key_next; + ECPBuffer packet; + ECPBuffer payload; + unsigned char pkt_buf[ECP_SIZE_PKT_BUF(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ, conn)+ECP_SIZE_COOKIE+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_COOKIE+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT)]; + unsigned char *msg; + unsigned char *_pld_buf; + size_t _pld_size; + ssize_t rv; + int _rv; - if (ecp_conn_is_outb(conn) && conn->next) { - ecp_tr_release(bufs->packet, 1); - rv = ecp_conn_open(conn->next, NULL); - if (rv) ecp_err_handle(conn->next, ECP_MTYPE_INIT_REQ, rv); - } + if (vconn->next == NULL) return ECP_ERR_NEXT; - return rv;; -} + _rv = ecp_conn_dhkey_get_remote(vconn->next, ECP_ECDH_IDX_PERMA, &key_next); + if (_rv) return _rv; -int ecp_vlink_create(ECPConnection *conn, ECPSocket *sock) { - int rv; + packet.buffer = pkt_buf; + packet.size = sizeof(pkt_buf); + payload.buffer = pld_buf; + payload.size = sizeof(pld_buf); - rv = ecp_conn_create(conn, sock, ECP_CTYPE_VLINK); - if (!rv) ecp_conn_set_flags(conn, ECP_CONN_FLAG_VBOX); - return rv; -} + 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; -int ecp_vlink_create_inb(ECPConnection *conn, ECPSocket *sock) { - int rv; + ecp_pld_set_type(_pld_buf, _pld_size, ECP_MTYPE_NEXT); + msg = ecp_pld_get_msg(_pld_buf, _pld_size); + memcpy(msg, &key_next.public, ECP_SIZE_ECDH_PUB); - rv = ecp_conn_create_inb(conn, sock, ECP_CTYPE_VLINK); - if (!rv) ecp_conn_set_flags(conn, ECP_CONN_FLAG_VBOX); + rv = ecp_pld_send_wcookie(conn, &packet, &payload, rv+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT), 0, cookie); return rv; } -void ecp_vlink_destroy(ECPConnection *conn) { - ECPSocket *sock = conn->sock; - ECPDHPub *key = &conn->remote.key_perma; - - if (key->valid) { -#ifdef ECP_WITH_PTHREAD - pthread_mutex_lock(&sock->conn_table.mutex); -#endif - - ecp_ht_remove(sock->conn_table.keys, &key->public); - -#ifdef ECP_WITH_PTHREAD - pthread_mutex_unlock(&sock->conn_table.mutex); -#endif - } +void ecp_vlink_init(ECPConnection *conn, ECPSocket *sock) { + ecp_conn_init(conn, sock, ECP_CTYPE_VLINK); + ecp_conn_set_flags(conn, ECP_CONN_FLAG_VBOX); } -static int vlink_handle_open(ECPConnection *conn) { +#ifdef ECP_WITH_HTABLE + +int ecp_vlink_handle_open(ECPConnection *conn, ECP2Buffer *bufs) { ECPSocket *sock = conn->sock; ECPDHPub *key; int rv = ECP_OK; @@ -393,55 +423,30 @@ static int vlink_handle_open(ECPConnection *conn) { return rv; } -#endif /* ECP_WITH_HTABLE */ - -int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs) { - int rv; - - switch (conn->type) { - case ECP_CTYPE_VCONN: - rv = vconn_handle_open(conn, bufs); - break; +void ecp_vlink_handle_close(ECPConnection *conn) { + ECPSocket *sock = conn->sock; + ECPDHPub *key = &conn->remote.key_perma; - case ECP_CTYPE_VLINK: -#ifdef ECP_WITH_HTABLE - rv = vlink_handle_open(conn); -#else - rv = ECP_OK; + if (key->valid) { +#ifdef ECP_WITH_PTHREAD + pthread_mutex_lock(&sock->conn_table.mutex); #endif - break; - - default: - rv = ECP_ERR_CTYPE; - break; - } - - return rv; -} -void ecp_vconn_handle_close(ECPConnection *conn) { - switch (conn->type) { -#ifdef ECP_WITH_HTABLE - case ECP_CTYPE_VCONN: - ecp_vconn_destroy(conn); - break; + ecp_ht_remove(sock->conn_table.keys, &key->public); - case ECP_CTYPE_VLINK: - ecp_vlink_destroy(conn); - break; +#ifdef ECP_WITH_PTHREAD + pthread_mutex_unlock(&sock->conn_table.mutex); #endif } } -ssize_t ecp_vconn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { +#endif /* ECP_WITH_HTABLE */ + +ssize_t ecp_vlink_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { ssize_t rv; switch (mtype) { #ifdef ECP_WITH_HTABLE - case ECP_MTYPE_NEXT: - rv = handle_next(conn, msg, msg_size, bufs); - break; - case ECP_MTYPE_RELAY: rv = handle_relay(conn, msg, msg_size, bufs); break; @@ -459,42 +464,18 @@ ssize_t ecp_vconn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char m return rv; } -ssize_t ecp_vconn_send_open_req(ECPConnection *conn, unsigned char *cookie) { - if (conn->type == ECP_CTYPE_VCONN) { - ECPDHPub key_next; - ECPBuffer packet; - ECPBuffer payload; - unsigned char pkt_buf[ECP_SIZE_PKT_BUF(2+ECP_SIZE_VBOX, ECP_MTYPE_OPEN_REQ, conn)+ECP_SIZE_COOKIE+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_COOKIE+ECP_SIZE_PLD(ECP_SIZE_ECDH_PUB, ECP_MTYPE_NEXT)]; - unsigned char *msg; - unsigned char *_pld_buf; - size_t _pld_size; - ssize_t rv; - int _rv; - - if (conn->next == NULL) return ECP_ERR_NEXT; - - _rv = ecp_conn_dhkey_get_remote(conn->next, ECP_ECDH_IDX_PERMA, &key_next); - if (_rv) return _rv; - - packet.buffer = pkt_buf; - packet.size = sizeof(pkt_buf); - payload.buffer = pld_buf; - payload.size = sizeof(pld_buf); - - rv = ecp_write_open_req(conn, &payload); - if (rv < 0) return rv; - - _pld_buf = payload.buffer + rv; - _pld_size = payload.size - rv; - - ecp_pld_set_type(_pld_buf, _pld_size, ECP_MTYPE_NEXT); - msg = ecp_pld_get_msg(_pld_buf, _pld_size); - memcpy(msg, &key_next.public, ECP_SIZE_ECDH_PUB); - - 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); - } +int ecp_vconn_handler_init(ECPContext *ctx, ECPConnHandler *vconn_handler) { + int rv; + + ecp_conn_handler_init(vconn_handler, ecp_vconn_handle_msg, ecp_vconn_handle_open, ecp_vconn_handle_close, ecp_vconn_send_open_req); + rv = ecp_ctx_set_handler(ctx, ECP_CTYPE_VCONN, vconn_handler); + return rv; +} + +int ecp_vlink_handler_init(ECPContext *ctx, ECPConnHandler *vlink_handler) { + int rv; + + ecp_conn_handler_init(vlink_handler, ecp_vlink_handle_msg, ecp_vlink_handle_open, ecp_vlink_handle_close, NULL); + rv = ecp_ctx_set_handler(ctx, ECP_CTYPE_VLINK, vlink_handler); + return rv; } diff --git a/ecp/src/ecp/vconn/vconn.h b/ecp/src/ecp/vconn/vconn.h index 8871ded..62275bf 100644 --- a/ecp/src/ecp/vconn/vconn.h +++ b/ecp/src/ecp/vconn/vconn.h @@ -5,29 +5,39 @@ #define ECP_MTYPE_EXEC 0x02 #define ECP_MTYPE_RELAY 0x01 -/* inbound only */ -typedef struct ECPVConn { +typedef struct ECPVConnInb { ECPConnection b; + ECPConnection *next; ECPDHPub key_next[ECP_MAX_NODE_KEY]; unsigned char key_next_curr; -} ECPVConn; +} ECPVConnInb; + +typedef struct ECPVConnOutb { + ECPConnection b; + ECPConnection *next; +} ECPVConnOutb; ssize_t ecp_vconn_pack_parent(ECPConnection *conn, ECPBuffer *payload, ECPBuffer *packet, size_t pkt_size, ecp_tr_addr_t *addr); -int ecp_vconn_create(ECPConnection vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPConnection *conn); +void ecp_vconn_init(ECPVConnOutb vconn[], ecp_ecdh_public_t keys[], size_t vconn_size, ECPSocket *sock); #ifdef ECP_WITH_HTABLE -int ecp_vconn_create_inb(ECPVConn *conn, ECPSocket *sock); -void ecp_vconn_destroy(ECPConnection *conn); +void ecp_vconn_init_inb(ECPVConnInb *vconn, ECPSocket *sock); #endif -int ecp_vconn_open(ECPConnection *conn, ECPNode *node); - -int ecp_vlink_create(ECPConnection *conn, ECPSocket *sock); +int ecp_vconn_open(ECPVConnOutb *vconn, ECPConnection *conn, ECPNode *node); #ifdef ECP_WITH_HTABLE -int ecp_vlink_create_inb(ECPConnection *conn, ECPSocket *sock); -void ecp_vlink_destroy(ECPConnection *conn); -#endif - int ecp_vconn_handle_open(ECPConnection *conn, ECP2Buffer *bufs); void ecp_vconn_handle_close(ECPConnection *conn); +#endif ssize_t ecp_vconn_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs); ssize_t ecp_vconn_send_open_req(ECPConnection *conn, unsigned char *cookie); + + +void ecp_vlink_init(ECPConnection *conn, ECPSocket *sock); +#ifdef ECP_WITH_HTABLE +int ecp_vlink_handle_open(ECPConnection *conn, ECP2Buffer *bufs); +void ecp_vlink_handle_close(ECPConnection *conn); +#endif +ssize_t ecp_vlink_handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs); + +int ecp_vconn_handler_init(ECPContext *ctx, ECPConnHandler *vconn_handler); +int ecp_vlink_handler_init(ECPContext *ctx, ECPConnHandler *vlink_handler); diff --git a/ecp/src/platform/fe310/time.c b/ecp/src/platform/fe310/time.c index 5e4bc26..4bf530c 100644 --- a/ecp/src/platform/fe310/time.c +++ b/ecp/src/platform/fe310/time.c @@ -1,7 +1,7 @@ #include <stdlib.h> -#include <core.h> -#include <tr.h> +#include <ecp/core.h> +#include <ecp/tm.h> #include <eos/eos.h> #include <eos/event.h> @@ -23,7 +23,11 @@ int ecp_tm_init(ECPContext *ctx) { return ECP_OK; } -ecp_sts_t ecp_tm_get_tick(void) { +ecp_sts_t ecp_tm_get_s(void) { + return eos_time_get_tick() / EOS_TIMER_RTC_FREQ; +} + +ecp_sts_t ecp_tm_get_ms(void) { return eos_time_get_tick() * 1000 / EOS_TIMER_RTC_FREQ; } diff --git a/ecp/src/platform/fe310/transport.c b/ecp/src/platform/fe310/transport.c index c359bd1..bc758c9 100644 --- a/ecp/src/platform/fe310/transport.c +++ b/ecp/src/platform/fe310/transport.c @@ -2,8 +2,8 @@ #include <string.h> #include <stdio.h> -#include <core.h> -#include <tr.h> +#include <ecp/core.h> +#include <ecp/tr.h> #include <eos/eos.h> #include <eos/dev/net.h> @@ -65,7 +65,7 @@ int ecp_tr_addr_set(ecp_tr_addr_t *addr, void *addr_s) { return ECP_ERR; } -int ecp_tr_open(ECPSocket *sock, void *addr_s) { +int ecp_tr_open(ECPSocket *sock, ecp_tr_addr_t *addr) { sock->sock = eos_sock_open_udp(packet_handler, NULL); if (sock->sock < 0) { sock->sock = 0; diff --git a/ecp/src/platform/posix/features.mk b/ecp/src/platform/posix/features.mk index 2ce8220..ea5e44c 100644 --- a/ecp/src/platform/posix/features.mk +++ b/ecp/src/platform/posix/features.mk @@ -1,7 +1,8 @@ with_pthread = yes with_htable = yes with_vconn = yes -with_dirsrv = yes +with_frag = yes with_rbuf = yes with_msgq = yes +with_dir = yes with_debug = yes diff --git a/ecp/src/platform/posix/time.c b/ecp/src/platform/posix/time.c index 7030bf3..49a85e7 100644 --- a/ecp/src/platform/posix/time.c +++ b/ecp/src/platform/posix/time.c @@ -1,15 +1,20 @@ #include <stdlib.h> #include <unistd.h> +#include <time.h> #include <sys/time.h> -#include <core.h> -#include <tm.h> +#include <ecp/core.h> +#include <ecp/tm.h> int ecp_tm_init(ECPContext *ctx) { return ECP_OK; } -ecp_sts_t ecp_tm_get_tick(void) { +ecp_sts_t ecp_tm_get_s(void) { + return time(NULL); +} + +ecp_sts_t ecp_tm_get_ms(void) { struct timeval tv; ecp_sts_t ms_now; diff --git a/ecp/src/platform/posix/transport.c b/ecp/src/platform/posix/transport.c index ebfbc7b..51f311a 100644 --- a/ecp/src/platform/posix/transport.c +++ b/ecp/src/platform/posix/transport.c @@ -6,8 +6,8 @@ #include <arpa/inet.h> #include <poll.h> -#include <core.h> -#include <tr.h> +#include <ecp/core.h> +#include <ecp/tr.h> #define MAX_ADDR_STR 32 @@ -49,20 +49,15 @@ int ecp_tr_addr_set(ecp_tr_addr_t *addr, void *addr_s) { return 0; } -int ecp_tr_open(ECPSocket *sock, void *addr_s) { +int ecp_tr_open(ECPSocket *sock, ecp_tr_addr_t *addr) { struct sockaddr_in _myaddr; int rv; memset((char *)&_myaddr, 0, sizeof(_myaddr)); _myaddr.sin_family = AF_INET; - if (addr_s) { - ecp_tr_addr_t addr; - - rv = ecp_tr_addr_set(&addr, addr_s); - if (rv) return rv; - - memcpy((void *)&_myaddr.sin_addr, addr.host, sizeof(addr.host)); - _myaddr.sin_port = addr.port; + if (addr) { + memcpy((void *)&_myaddr.sin_addr, addr->host, sizeof(addr->host)); + _myaddr.sin_port = addr->port; } else { _myaddr.sin_addr.s_addr = htonl(INADDR_ANY); _myaddr.sin_port = htons(0); diff --git a/ecp/test/Makefile b/ecp/test/Makefile index 50a4202..b2fd6f8 100644 --- a/ecp/test/Makefile +++ b/ecp/test/Makefile @@ -1,13 +1,15 @@ src_dir = ../src include $(src_dir)/ecp/common.mk CFLAGS += -I../util -Wno-int-to-void-pointer-cast +dep = ../build-posix/*.a ../util/libecputil.a + +target = basic client server vc_inb vc_outb vcs vc_server vc_client -dep=../build-posix/*.a ../util/libecputil.a %.o: %.c $(CC) $(CFLAGS) -c $< -all: basic client server vcs vc_server vc_client +all: $(target) basic: basic.o init.o $(dep) $(CC) -o $@ $< init.o $(dep) $(LDFLAGS) @@ -18,6 +20,12 @@ client: client.o init.o $(dep) server: server.o init.o $(dep) $(CC) -o $@ $< init.o $(dep) $(LDFLAGS) +vc_inb: vc_inb.o vc_common.o init_vconn.o $(dep) + $(CC) -o $@ $< vc_common.o init_vconn.o $(dep) $(LDFLAGS) + +vc_outb: vc_outb.o vc_common.o init_vconn.o $(dep) + $(CC) -o $@ $< vc_common.o init_vconn.o $(dep) $(LDFLAGS) + vcs: vcs.o init_vconn.o $(dep) $(CC) -o $@ $< init_vconn.o $(dep) $(LDFLAGS) @@ -29,4 +37,4 @@ vc_client: vc_client.o init_vconn.o $(dep) clean: rm -f *.o - rm -f basic dir client server echo frag stress vcs vc_server vc_client vc_client_t voip + rm -f $(target) diff --git a/ecp/test/basic.c b/ecp/test/basic.c index b266a07..637a829 100644 --- a/ecp/test/basic.c +++ b/ecp/test/basic.c @@ -2,7 +2,9 @@ #include <unistd.h> #include <stdio.h> -#include <core.h> +#include <ecp/core.h> + +#include "init.h" ECPContext ctx_s; ECPSocket sock_s; @@ -43,6 +45,7 @@ static ssize_t handle_msg_s(ECPConnection *conn, ecp_seq_t seq, unsigned char mt } int main(int argc, char *argv[]) { + ecp_tr_addr_t addr; ECPDHKey key_perma_c; ECPDHKey key_perma_s; ECPNode node; @@ -53,7 +56,7 @@ int main(int argc, char *argv[]) { printf("ecp_init RV:%d\n", rv); ecp_conn_handler_init(&handler_s, handle_msg_s, NULL, NULL, NULL); - ecp_ctx_set_handler(&ctx_s, &handler_s, CTYPE_TEST); + ecp_ctx_set_handler(&ctx_s, CTYPE_TEST, &handler_s); rv = ecp_dhkey_gen(&key_perma_s); printf("ecp_dhkey_gen RV:%d\n", rv); @@ -61,7 +64,10 @@ int main(int argc, char *argv[]) { rv = ecp_sock_create(&sock_s, &ctx_s, &key_perma_s); printf("ecp_sock_create RV:%d\n", rv); - rv = ecp_sock_open(&sock_s, "0.0.0.0:3000"); + rv = ecp_addr_init(&addr, "0.0.0.0:3000"); + printf("ecp_addr_init RV:%d\n", rv); + + rv = ecp_sock_open(&sock_s, &addr); printf("ecp_sock_open RV:%d\n", rv); rv = ecp_start_receiver(&sock_s); @@ -72,7 +78,7 @@ int main(int argc, char *argv[]) { printf("ecp_init RV:%d\n", rv); ecp_conn_handler_init(&handler_c, handle_msg_c, handle_open_c, NULL, NULL); - ecp_ctx_set_handler(&ctx_c, &handler_c, CTYPE_TEST); + ecp_ctx_set_handler(&ctx_c, CTYPE_TEST, &handler_c); rv = ecp_dhkey_gen(&key_perma_c); printf("ecp_dhkey_gen RV:%d\n", rv); @@ -86,12 +92,11 @@ int main(int argc, char *argv[]) { rv = ecp_start_receiver(&sock_c); printf("ecp_start_receiver RV:%d\n", rv); - rv = ecp_node_init(&node, &key_perma_s.public, "127.0.0.1:3000"); - printf("ecp_node_init RV:%d\n", rv); - - rv = ecp_conn_create(&conn, &sock_c, CTYPE_TEST); - printf("ecp_conn_create RV:%d\n", rv); + ecp_node_init(&node, &key_perma_s.public, NULL); + rv = ecp_node_set_addr(&node, "127.0.0.1:3000"); + printf("ecp_node_set_addr RV:%d\n", rv); + ecp_conn_init(&conn, &sock_c, CTYPE_TEST); rv = ecp_conn_open(&conn, &node); printf("ecp_conn_open RV:%d\n", rv); diff --git a/ecp/test/client.c b/ecp/test/client.c index d526f76..52a8587 100644 --- a/ecp/test/client.c +++ b/ecp/test/client.c @@ -3,10 +3,12 @@ #include <unistd.h> #include <stdio.h> -#include <core.h> +#include <ecp/core.h> #include <util.h> +#include "init.h" + ECPContext ctx; ECPSocket sock; ECPConnHandler handler; @@ -48,7 +50,7 @@ int main(int argc, char *argv[]) { printf("ecp_init RV:%d\n", rv); ecp_conn_handler_init(&handler, handle_msg, handle_open, NULL, NULL); - ecp_ctx_set_handler(&ctx, &handler, CTYPE_TEST); + ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler); rv = ecp_dhkey_gen(&key_perma); printf("ecp_dhkey_gen RV:%d\n", rv); @@ -62,15 +64,14 @@ int main(int argc, char *argv[]) { rv = ecp_start_receiver(&sock); printf("ecp_start_receiver RV:%d\n", rv); - rv = ecp_conn_create(&conn, &sock, CTYPE_TEST); - printf("ecp_conn_create RV:%d\n", rv); - rv = ecp_util_load_pub(&node_pub, argv[2]); printf("ecp_util_load_pub RV:%d\n", rv); - rv = ecp_node_init(&node, &node_pub, argv[1]); - printf("ecp_node_init RV:%d\n", rv); + ecp_node_init(&node, &node_pub, NULL); + rv = ecp_node_set_addr(&node, argv[1]); + printf("ecp_node_set_addr RV:%d\n", rv); + ecp_conn_init(&conn, &sock, CTYPE_TEST); rv = ecp_conn_open(&conn, &node); printf("ecp_conn_open RV:%d\n", rv); diff --git a/ecp/test/init.c b/ecp/test/init.c index f4b033a..b75b2ee 100644 --- a/ecp/test/init.c +++ b/ecp/test/init.c @@ -1,34 +1,27 @@ #include <stdlib.h> #include <stdio.h> -#include <core.h> +#include <ecp/core.h> -void handle_err(ECPConnection *conn, unsigned char mtype, int err) { +static void handle_err(ECPConnection *conn, unsigned char mtype, int err) { printf("ERR: CTYPE:%d MTYPE:%x ERR:%d\n", conn->type, mtype, err); } -static ECPConnection *conn_alloc(ECPSocket *sock, unsigned char type) { +static ECPConnection *conn_new(ECPSocket *sock, unsigned char type) { ECPConnection *conn; - int rv; conn = malloc(sizeof(ECPConnection)); - if (conn == NULL) return NULL; - - rv = ecp_conn_create_inb(conn, sock, type); - if (rv) { - free(conn); - return NULL; - } + if (conn) ecp_conn_init(conn, sock, type); return conn; } static void conn_free(ECPConnection *conn) { - free(conn); + if (ecp_conn_is_gc(conn)) free(conn); } int ecp_init(ECPContext *ctx) { int rv; - rv = ecp_ctx_init(ctx, handle_err, NULL, conn_alloc, conn_free); + rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free); return rv; } diff --git a/ecp/test/init.h b/ecp/test/init.h new file mode 100644 index 0000000..a1a21d1 --- /dev/null +++ b/ecp/test/init.h @@ -0,0 +1 @@ +int ecp_init(ECPContext *ctx);
\ No newline at end of file diff --git a/ecp/test/init_vconn.c b/ecp/test/init_vconn.c index 88b6fa0..b690bec 100644 --- a/ecp/test/init_vconn.c +++ b/ecp/test/init_vconn.c @@ -2,50 +2,59 @@ #include <unistd.h> #include <stdio.h> -#include <core.h> -#include <vconn/vconn.h> +#include <ecp/core.h> +#include <ecp/vconn/vconn.h> -void handle_err(ECPConnection *conn, unsigned char mtype, int err) { +static void handle_err(ECPConnection *conn, unsigned char mtype, int err) { printf("ERR: CTYPE:0x%x MTYPE:0x%x ERR:%d\n", conn->type, mtype, err); } -static ECPConnection *conn_alloc(ECPSocket *sock, unsigned char type) { - ECPConnection *conn; - int rv; +static ECPConnection *conn_new(ECPSocket *sock, unsigned char type) { + ECPConnection *conn = NULL; switch (type) { - case ECP_CTYPE_VCONN: - conn = malloc(sizeof(ECPVConn)); - if (conn) rv = ecp_vconn_create_inb((ECPVConn *)conn, sock); + case ECP_CTYPE_VCONN: { + ECPVConnInb *_conn; + + _conn = malloc(sizeof(ECPVConnInb)); + if (_conn) { + ecp_vconn_init_inb(_conn, sock); + conn = &_conn->b; + } break; + } - case ECP_CTYPE_VLINK: + case ECP_CTYPE_VLINK: { conn = malloc(sizeof(ECPConnection)); - if (conn) rv = ecp_vlink_create_inb(conn, sock); + if (conn) ecp_vlink_init(conn, sock); break; + } - default: + default: { conn = malloc(sizeof(ECPConnection)); - if (conn) rv = ecp_conn_create_inb(conn, sock, type); + if (conn) ecp_conn_init(conn, sock, type); break; - } - - if (conn == NULL) return NULL; - if (rv) { - free(conn); - return NULL; + } } return conn; } static void conn_free(ECPConnection *conn) { - free(conn); + if (ecp_conn_is_gc(conn)) free(conn); } -int ecp_init(ECPContext *ctx) { +int ecp_init(ECPContext *ctx, ECPConnHandler *vconn_handler, ECPConnHandler *vlink_handler) { int rv; - rv = ecp_ctx_init(ctx, handle_err, NULL, conn_alloc, conn_free); - return rv; + rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free); + if (rv) return rv; + + rv = ecp_vconn_handler_init(ctx, vconn_handler); + if (rv) return rv; + + rv = ecp_vlink_handler_init(ctx, vlink_handler); + if (rv) return rv; + + return ECP_OK; }
\ No newline at end of file diff --git a/ecp/test/init_vconn.h b/ecp/test/init_vconn.h new file mode 100644 index 0000000..64e3269 --- /dev/null +++ b/ecp/test/init_vconn.h @@ -0,0 +1 @@ +int ecp_init(ECPContext *ctx, ECPConnHandler *vconn_handler, ECPConnHandler *vlink_handler);
\ No newline at end of file diff --git a/ecp/test/server.c b/ecp/test/server.c index 228dbea..19b2f4f 100644 --- a/ecp/test/server.c +++ b/ecp/test/server.c @@ -3,10 +3,12 @@ #include <unistd.h> #include <stdio.h> -#include <core.h> +#include <ecp/core.h> #include <util.h> +#include "init.h" + ECPContext ctx; ECPSocket sock; ECPDHKey key_perma; @@ -31,6 +33,7 @@ static void usage(char *arg) { } int main(int argc, char *argv[]) { + ecp_tr_addr_t addr; ECPDHKey key_perma; int rv; @@ -41,7 +44,7 @@ int main(int argc, char *argv[]) { printf("ecp_init RV:%d\n", rv); ecp_conn_handler_init(&handler, handle_msg, NULL, NULL, NULL); - ecp_ctx_set_handler(&ctx, &handler, CTYPE_TEST); + ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler); rv = ecp_util_load_key(&key_perma.public, &key_perma.private, argv[2]); printf("ecp_util_load_key RV:%d\n", rv); @@ -50,7 +53,10 @@ int main(int argc, char *argv[]) { rv = ecp_sock_create(&sock, &ctx, &key_perma); printf("ecp_sock_create RV:%d\n", rv); - rv = ecp_sock_open(&sock, argv[1]); + rv = ecp_addr_init(&addr, argv[1]); + printf("ecp_addr_init RV:%d\n", rv); + + rv = ecp_sock_open(&sock, &addr); printf("ecp_sock_open RV:%d\n", rv); rv = ecp_start_receiver(&sock); diff --git a/ecp/test/stress.c b/ecp/test/stress.c deleted file mode 100644 index 6eed851..0000000 --- a/ecp/test/stress.c +++ /dev/null @@ -1,256 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <unistd.h> -#include <signal.h> -#include <sys/time.h> -#include <pthread.h> - -#include "core.h" - -#ifdef __linux__ -#define SIGINFO SIGTSTP -#endif - -#define NUM_S 32 -#define NUM_C 256 -#define MSG_RATE 65 - -#define CTYPE_TEST 0 -#define MTYPE_MSG 8 - -ECPContext ctx_s; -ECPDHKey key_perma_s; -ECPConnHandler handler_s; -ECPSocket *sock_s; - -ECPConnHandler handler_c; -ECPContext *ctx_c; -ECPSocket *sock_c; -ECPDHKey *key_perma_c; - -ECPNode *node; -ECPConnection *conn; - -pthread_t *s_thd; -pthread_t *r_thd; -pthread_mutex_t *t_mtx; -int *t_sent, *t_rcvd; - -uint64_t t_start = 0, t_end = 0; -int c_start = 0; - -int num_s = NUM_S, num_c = NUM_C; -int msg_rate = MSG_RATE; - -static void display(void) { - int i, s = 0, r = 0; - - for (i=0; i<num_c; i++) { - pthread_mutex_lock(&t_mtx[i]); - s += t_sent[i]; - r += t_rcvd[i]; - pthread_mutex_unlock(&t_mtx[i]); - } - - uint64_t t_time = t_end - t_start; - - printf("TOTAL SENT:%d RCVD:%d\n", s, r); - printf("L:%f%%\n", (s-r)/(float)s*100); - printf("T/S S:%f R:%f\n", s/((float)t_time/1000000), r/((float)t_time/1000000)); -} - -static void catchINFO(int sig) { - struct timeval tv; - - if (!c_start) { - gettimeofday(&tv, NULL); - t_start = tv.tv_sec*(uint64_t)1000000+tv.tv_usec; - c_start = 1; - printf("COUNTER START\n"); - } else { - gettimeofday(&tv, NULL); - t_end = tv.tv_sec*(uint64_t)1000000+tv.tv_usec; - display(); - } -} - -void *sender(ECPConnection *c) { - int idx = (int)(c->conn_data); - ECPBuffer packet; - ECPBuffer payload; - unsigned char pkt_buf[ECP_MAX_PKT]; - unsigned char pld_buf[ECP_MAX_PLD]; - - packet.buffer = pkt_buf; - packet.size = ECP_MAX_PKT; - payload.buffer = pld_buf; - payload.size = ECP_MAX_PLD; - - printf("OPEN:%d\n", idx); - while(1) { - uint32_t rnd; - c->sock->ctx->rng(&rnd, sizeof(uint32_t)); - usleep(rnd % (2000000/msg_rate)); - - ecp_pld_set_type(payload.buffer, payload.size, MTYPE_MSG); - ssize_t _rv = 0; - // XXX refactor - // _rv = ecp_pld_send(c, &packet, &payload, ECP_SIZE_PLD(1000, 0)); - if (c_start && (_rv > 0)) { - pthread_mutex_lock(&t_mtx[idx]); - t_sent[idx]++; - pthread_mutex_unlock(&t_mtx[idx]); - } - } -} - -ssize_t handle_open_c(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *p, ssize_t s, ECP2Buffer *b) { - int idx = (int)(conn->conn_data); - int rv = 0; - - ecp_conn_handle_open(conn, sq, t, p, s, b); - rv = pthread_create(&s_thd[idx], NULL, (void *(*)(void *))sender, (void *)conn); - if (rv) { - char msg[256]; - sprintf(msg, "THD %d CREATE\n", idx); - perror(msg); - exit(1); - } - return s; -} - -ssize_t handle_msg_c(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *p, ssize_t s, ECP2Buffer *b) { - int idx = (int)(conn->conn_data); - ECPBuffer packet; - ECPBuffer payload; - unsigned char pkt_buf[ECP_MAX_PKT]; - unsigned char pld_buf[ECP_MAX_PLD]; - - packet.buffer = pkt_buf; - packet.size = ECP_MAX_PKT; - payload.buffer = pld_buf; - payload.size = ECP_MAX_PLD; - - if (c_start) { - pthread_mutex_lock(&t_mtx[idx]); - t_rcvd[idx]++; - pthread_mutex_unlock(&t_mtx[idx]); - } - - // ecp_pld_set_type(payload.buffer, payload.size, MTYPE_MSG); - // ssize_t _rv = ecp_pld_send(c, &packet, &payload, ECP_SIZE_PLD(1000, 0)); - return s; -} - -ssize_t handle_msg_s(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *p, ssize_t s, ECP2Buffer *b) { - ECPBuffer packet; - ECPBuffer payload; - unsigned char pkt_buf[ECP_MAX_PKT]; - unsigned char pld_buf[ECP_MAX_PLD]; - - packet.buffer = pkt_buf; - packet.size = ECP_MAX_PKT; - payload.buffer = pld_buf; - payload.size = ECP_MAX_PLD; - - ecp_pld_set_type(payload.buffer, payload.size, MTYPE_MSG); - // XXX refactor - // ssize_t _rv = ecp_pld_send(conn, &packet, &payload, ECP_SIZE_PLD(1000, 0)); - return s; -} - -int main(int argc, char *argv[]) { - char addr[256]; - int rv; - int i; - - ECPConnHandler handler_c; - - ECPContext *ctx_c; - ECPSocket *sock_c; - ECPDHKey *key_perma_c; - - ECPNode *node; - ECPConnection *conn; - - sock_s = malloc(num_s * sizeof(ECPSocket)); - ctx_c = malloc(num_c * sizeof(ECPContext)); - sock_c = malloc(num_c * sizeof(ECPSocket)); - key_perma_c = malloc(num_c * sizeof(ECPDHKey)); - node = malloc(num_c * sizeof(ECPNode)); - conn = malloc(num_c * sizeof(ECPConnection)); - - s_thd = malloc(num_c * sizeof(pthread_t)); - r_thd = malloc(num_c * sizeof(pthread_t)); - t_mtx = malloc(num_c * sizeof(pthread_mutex_t)); - t_sent = malloc(num_c * sizeof(int)); - t_rcvd = malloc(num_c * sizeof(int)); - memset(t_rcvd, 0, num_c * sizeof(int)); - memset(t_sent, 0, num_c * sizeof(int)); - - struct sigaction actINFO; - memset(&actINFO, 0, sizeof(actINFO)); - actINFO.sa_handler = &catchINFO; - sigaction(SIGINFO, &actINFO, NULL); - - rv = ecp_init(&ctx_s); - if (!rv) rv = ecp_conn_handler_init(&handler_s); - handler_s.msg[MTYPE_MSG] = handle_msg_s; - ctx_s.handler[CTYPE_TEST] = &handler_s; - - if (!rv) rv = ecp_dhkey_gen(&ctx_s, &key_perma_s); - - for (i=0; i<num_s; i++) { - if (!rv) rv = ecp_sock_init(&sock_s[i], &ctx_s, &key_perma_s); - - strcpy(addr, "0.0.0.0:"); - sprintf(addr+strlen(addr), "%d", 3000+i); - if (!rv) rv = ecp_sock_open(&sock_s[i], addr); - - if (!rv) rv = pthread_create(&r_thd[i], NULL, (void *(*)(void *))ecp_receiver, (void *)&sock_s[i]); - - if (rv) { - char msg[256]; - sprintf(msg, "SERVER %d CREATE:%d\n", i, rv); - perror(msg); - exit(1); - } - } - - rv = ecp_conn_handler_init(&handler_c); - - handler_c.msg[ECP_MTYPE_OPEN] = handle_open_c; - handler_c.msg[MTYPE_MSG] = handle_msg_c; - - for (i=0; i<num_c; i++) { - pthread_mutex_init(&t_mtx[i], NULL); - - if (!rv) rv = ecp_init(&ctx_c[i]); - ctx_c[i].handler[CTYPE_TEST] = &handler_c; - - if (!rv) rv = ecp_dhkey_gen(&ctx_c[i], &key_perma_c[i]); - if (!rv) rv = ecp_sock_init(&sock_c[i], &ctx_c[i], &key_perma_c[i]); - if (!rv) rv = ecp_sock_open(&sock_c[i], NULL); - - if (!rv) rv = pthread_create(&r_thd[i], NULL, (void *(*)(void *))ecp_receiver, (void *)&sock_c[i]); - - strcpy(addr, "127.0.0.1:"); - sprintf(addr+strlen(addr), "%d", 3000 + (i % num_s)); - if (!rv) rv = ecp_node_init(&node[i], &key_perma_s.public, addr); - - if (!rv) rv = ecp_conn_init(&conn[i], &sock_c[i], CTYPE_TEST); - conn[i].conn_data = (void *)i; - - if (!rv) rv = ecp_conn_open(&conn[i], &node[i]); - - if (rv) { - char msg[256]; - sprintf(msg, "CLIENT %d CREATE:%d\n", i, rv); - perror(msg); - exit(1); - } - - } - while (1) sleep(1); -}
\ No newline at end of file diff --git a/ecp/test/vc_client.c b/ecp/test/vc_client.c index 89602ca..41c364d 100644 --- a/ecp/test/vc_client.c +++ b/ecp/test/vc_client.c @@ -3,16 +3,20 @@ #include <unistd.h> #include <stdio.h> -#include <core.h> -#include <vconn/vconn.h> +#include <ecp/core.h> +#include <ecp/vconn/vconn.h> #include <util.h> +#include "init_vconn.h" + ECPContext ctx; ECPSocket sock; ECPConnHandler handler; +ECPConnHandler vconn_handler; +ECPConnHandler vlink_handler; ECPConnection conn; -ECPConnection vconn[3]; +ECPVConnOutb vconn[3]; #define CTYPE_TEST 0 #define MTYPE_MSG 0 @@ -47,11 +51,11 @@ int main(int argc, char *argv[]) { if ((argc < 4) || (argc > 6)) usage(argv[0]); - rv = ecp_init(&ctx); + rv = ecp_init(&ctx, &vconn_handler, &vlink_handler); printf("ecp_init RV:%d\n", rv); ecp_conn_handler_init(&handler, handle_msg, handle_open, NULL, NULL); - ecp_ctx_set_handler(&ctx, &handler, CTYPE_TEST); + ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler); rv = ecp_dhkey_gen(&key_perma); printf("ecp_dhkey_gen RV:%d\n", rv); @@ -65,24 +69,21 @@ int main(int argc, char *argv[]) { rv = ecp_start_receiver(&sock); printf("ecp_start_receiver RV:%d\n", rv); + rv = ecp_util_load_pub(&node_pub, argv[1]); + printf("ecp_util_load_pub RV:%d\n", rv); + + ecp_node_init(&node, &node_pub, NULL); + rv = ecp_node_set_addr(&node, argv[2]); + printf("ecp_node_set_addr RV:%d\n", rv); + for (i=3; i<argc; i++) { rv = ecp_util_load_pub(&vconn_pub[i-3], argv[i]); printf("ecp_util_load_pub RV:%d\n", rv); } - rv = ecp_conn_create(&conn, &sock, CTYPE_TEST); - printf("ecp_conn_create RV:%d\n", rv); - - rv = ecp_vconn_create(vconn, vconn_pub, argc-3, &conn); - printf("ecp_vconn_create RV:%d\n", rv); - - rv = ecp_util_load_pub(&node_pub, argv[1]); - printf("ecp_util_load_pub RV:%d\n", rv); - - rv = ecp_node_init(&node, &node_pub, argv[2]); - printf("ecp_node_init RV:%d\n", rv); - - rv = ecp_vconn_open(&conn, &node); + ecp_conn_init(&conn, &sock, CTYPE_TEST); + ecp_vconn_init(vconn, vconn_pub, argc-3, &sock); + rv = ecp_vconn_open(vconn, &conn, &node); printf("ecp_vconn_open RV:%d\n", rv); while (1) sleep(1); diff --git a/ecp/test/vc_client_t.c b/ecp/test/vc_client_t.c deleted file mode 100644 index 968d643..0000000 --- a/ecp/test/vc_client_t.c +++ /dev/null @@ -1,118 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/time.h> - -#include "core.h" -#include "vconn/vconn.h" -#include "util.h" - -ECPContext ctx; -ECPSocket sock; -ECPConnHandler handler; - -ECPNode node; -ECPConnection conn; - -ECPVConnOut vconn[20]; -ECPNode vconn_node[20]; - -#define CTYPE_TEST 0 -#define MTYPE_MSG 8 - - -int counter = 0; -uint64_t t_start = 0; -uint64_t t_end = 0; -ssize_t handle_open(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *p, ssize_t s, ECP2Buffer *b) { - ssize_t rv = ecp_conn_handle_open(conn, sq, t, p, s, b); - if (rv < 0) { - printf("OPEN ERR:%ld\n", s); - return rv; - } - - printf("OPEN\n"); - char *msg = "PERA JE CAR!"; - unsigned char buf[1000]; - - strcpy((char *)buf, msg); - // ssize_t _rv = ecp_send(conn, MTYPE_MSG, buf, 1000); - - struct timeval tv; - gettimeofday(&tv, NULL); - t_start = tv.tv_sec*(uint64_t)1000000+tv.tv_usec; - - return rv; -} - -ssize_t handle_msg(ECPConnection *conn, ecp_seq_t sq, unsigned char t, unsigned char *p, ssize_t s, ECP2Buffer *b) { - ecp_send(conn, t, p, s); - write(2, p+1, s-1); - fflush(stderr); - // printf("MSG C:%s size:%ld\n", p, s); - return s; - - counter++; - char *msg = "PERA JE CAR!"; - unsigned char buf[1000]; - - strcpy((char *)buf, msg); - ssize_t _rv = ecp_send(conn, MTYPE_MSG, buf, 1000); - - if (counter % 100 == 0) { - struct timeval tv; - uint64_t t_time; - - gettimeofday(&tv, NULL); - t_end = tv.tv_sec*(uint64_t)1000000+tv.tv_usec; - t_time = t_end - t_start; - printf("T:%f\n", (float)t_time/1000000); - t_start = t_end; - } - return s; -} - -static void usage(char *arg) { - fprintf(stderr, "Usage: %s <server.pub> <vcs1.pub> ... <vcsn.pub>\n", arg); - exit(1); -} - -int main(int argc, char *argv[]) { - int rv, i; - - if ((argc < 3) || (argc > 22)) usage(argv[0]); - - rv = ecp_init(&ctx); - printf("ecp_init RV:%d\n", rv); - - rv = ecp_conn_handler_init(&handler); - handler.msg[ECP_MTYPE_OPEN] = handle_open; - handler.msg[MTYPE_MSG] = handle_msg; - ctx.handler[CTYPE_TEST] = &handler; - - rv = ecp_sock_init(&sock, &ctx, NULL); - printf("ecp_sock_init RV:%d\n", rv); - - rv = ecp_sock_open(&sock, NULL); - printf("ecp_sock_open RV:%d\n", rv); - - rv = ecp_start_receiver(&sock); - printf("ecp_start_receiver RV:%d\n", rv); - - rv = ecp_util_node_load(&ctx, &node, argv[1]); - printf("ecp_util_node_load RV:%d\n", rv); - - for (i=0; i<argc-2; i++) { - rv = ecp_util_node_load(&ctx, &vconn_node[i], argv[i+2]); - printf("ecp_util_node_load RV:%d\n", rv); - } - - rv = ecp_conn_init(&conn, &sock, CTYPE_TEST); - printf("ecp_conn_init RV:%d\n", rv); - - rv = ecp_vconn_open(&conn, &node, vconn, vconn_node, argc-2); - printf("ecp_vconn_open RV:%d\n", rv); - - while (1) sleep(1); -} diff --git a/ecp/test/vc_common.c b/ecp/test/vc_common.c new file mode 100644 index 0000000..0508ac1 --- /dev/null +++ b/ecp/test/vc_common.c @@ -0,0 +1,127 @@ +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> + +#include <ecp/core.h> +#include <ecp/dir/dir.h> +#include <ecp/vconn/vconn.h> + +#include <openssl/crypto.h> +#include <openssl/sha.h> + +#include "vc_common.h" + +#define VCONN_NODES 3 + +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) +#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) + +static void msg_remove_item(unsigned char *msg, uint16_t i, uint16_t c) { + if (c - i - 1) memmove(msg + i * ECP_SIZE_DIR_ITEM, msg + (i + 1) * ECP_SIZE_DIR_ITEM, (c - i - 1) * ECP_SIZE_DIR_ITEM); +} + +static void hrw_select(unsigned char *msg, uint16_t count, ecp_ecdh_public_t *pub, ecp_ecdh_public_t *hrw_pub, ecp_ecdh_public_t vconn_pub[], size_t *_vconn_size, ecp_tr_addr_t *addr) { + unsigned char *_msg = msg; + unsigned char hash[SHA_DIGEST_LENGTH]; + unsigned char hrw_hash[SHA_DIGEST_LENGTH]; + ecp_ecdh_public_t hash_pub[2]; + size_t vconn_size = *_vconn_size; + ECPDirItem dir_item; + SHA_CTX ctx; + int i, hrw_i; + + if (count == 0) return; + + memset(hrw_hash, 0, sizeof(hrw_hash)); + memcpy(&hash_pub[0], pub, sizeof(ecp_ecdh_public_t)); + + for (i=0; i<count; i++) { + unsigned char *host; + uint16_t port; + size_t rv; + + rv = ecp_dir_item_parse(&dir_item, _msg); + _msg += rv; + + host = dir_item.node.addr.host; + port = dir_item.node.addr.port; + printf("ITEM: %d.%d.%d.%d:%d\n", host[0], host[1], host[2], host[3], ntohs(port)); + + memcpy(&hash_pub[1], &dir_item.node.key_perma.public, sizeof(ecp_ecdh_public_t)); + SHA1_Init(&ctx); + SHA1_Update(&ctx, hash_pub, sizeof(hash_pub)); + SHA1_Final(hash, &ctx); + if (memcmp(hrw_hash, hash, sizeof(hash)) < 0) { + hrw_i = i; + memcpy(hrw_hash, hash, sizeof(hash)); + memcpy(hrw_pub, &dir_item.node.key_perma, sizeof(ecp_ecdh_public_t)); + } + } + + printf("SELECTED: %d\n", hrw_i); + msg_remove_item(msg, hrw_i, count); + count--; + + vconn_size = MIN(count, vconn_size); + for (i=0; i<vconn_size; i++) { + uint16_t s; + + s = arc4random() % count; + _msg = msg + s * ECP_SIZE_DIR_ITEM; + ecp_dir_item_parse(&dir_item, _msg); + memcpy(&vconn_pub[i], &dir_item.node.key_perma, sizeof(ecp_ecdh_public_t)); + if (i==0) *addr = dir_item.node.addr; + msg_remove_item(msg, s, count); + count--; + } + *_vconn_size = vconn_size; +} + +int vc_open_inb(ECPConnection *vlink, unsigned char *msg, uint16_t count, ecp_ecdh_public_t *local_pub) { + ecp_ecdh_public_t vconn_pub[VCONN_NODES - 1]; + ecp_ecdh_public_t hrw_pub; + ecp_tr_addr_t addr; + ECPNode node; + ECPVConnOutb *vconn; + size_t vconn_size; + int rv; + + vconn_size = VCONN_NODES - 1; + hrw_select(msg, count, local_pub, &hrw_pub, vconn_pub, &vconn_size, &addr); + + vconn = malloc(sizeof(ECPVConnOutb) * vconn_size); + if (vconn == NULL) return ECP_ERR_ALLOC; + + ecp_vconn_init(vconn, vconn_pub, vconn_size, vlink->sock); + ecp_node_init(&node, &hrw_pub, &addr); + rv = ecp_vconn_open(vconn, vlink, &node); + printf("ecp_vconn_open RV:%d\n", rv); + + return ECP_OK; +} + +int vc_open_outb(ECPConnection *conn, unsigned char *msg, uint16_t count, ecp_ecdh_public_t *remote_pub) { + ecp_ecdh_public_t vconn_pub[VCONN_NODES]; + ecp_ecdh_public_t hrw_pub; + ecp_tr_addr_t addr; + ECPNode node; + ECPVConnOutb *vconn; + size_t vconn_size; + int rv; + + vconn_size = VCONN_NODES - 1; + hrw_select(msg, count, remote_pub, &hrw_pub, vconn_pub, &vconn_size, &addr); + memcpy(&vconn_pub[vconn_size], &hrw_pub, sizeof(ecp_ecdh_public_t)); + vconn_size++; + + vconn = malloc(sizeof(ECPVConnOutb) * vconn_size); + if (vconn == NULL) return ECP_ERR_ALLOC; + + ecp_vconn_init(vconn, vconn_pub, vconn_size, conn->sock); + ecp_node_init(&node, remote_pub, &addr); + rv = ecp_vconn_open(vconn, conn, &node); + printf("ecp_vconn_open RV:%d\n", rv); + + return ECP_OK; +} diff --git a/ecp/test/vc_common.h b/ecp/test/vc_common.h new file mode 100644 index 0000000..a684566 --- /dev/null +++ b/ecp/test/vc_common.h @@ -0,0 +1,2 @@ +int vc_open_inb(ECPConnection *vlink, unsigned char *msg, uint16_t count, ecp_ecdh_public_t *local_pub); +int vc_open_outb(ECPConnection *conn, unsigned char *msg, uint16_t count, ecp_ecdh_public_t *remote_pub); diff --git a/ecp/test/vc_inb.c b/ecp/test/vc_inb.c new file mode 100644 index 0000000..13b493c --- /dev/null +++ b/ecp/test/vc_inb.c @@ -0,0 +1,124 @@ +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> + +#include <ecp/core.h> +#include <ecp/dir/dir.h> +#include <ecp/vconn/vconn.h> + +#include <util.h> + +#include "init_vconn.h" +#include "vc_common.h" + +ECPContext ctx; +ECPSocket sock; +ECPConnHandler handler; +ECPConnHandler dir_handler; +ECPConnHandler vconn_handler; +ECPConnHandler vlink_handler; + +#define CTYPE_TEST 0 +#define MTYPE_MSG 0 + +static int handle_open(ECPConnection *conn, ECP2Buffer *b) { + printf("OPEN\n"); + + return ECP_OK; +} + +static ssize_t handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) { + char *_msg = "VAISTINU JE CAR!"; + ssize_t rv; + + printf("MSG:%s size:%ld\n", msg, msg_size); + rv = ecp_msg_send(conn, MTYPE_MSG, (unsigned char *)_msg, strlen(_msg)+1); + + return msg_size; +} + +static ssize_t handle_dir_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) { + size_t rsize; + uint16_t count; + ECPConnection *vlink; + int rv; + + if (msg_size < sizeof(uint16_t)) return ECP_ERR_SIZE; + + count = \ + ((uint16_t)msg[0] << 8) | \ + ((uint16_t)msg[1]); + + printf("DIR MSG:%d\n", count); + + rsize = sizeof(uint16_t) + count * ECP_SIZE_DIR_ITEM; + if (msg_size < rsize) return ECP_ERR_SIZE; + + msg += sizeof(uint16_t); + + vlink = malloc(sizeof(ECPConnection)); + if (vlink == NULL) return ECP_ERR_ALLOC; + + ecp_vlink_init(vlink, conn->sock); + rv = vc_open_inb(vlink, msg, count, &conn->sock->key_perma.public); + if (rv) { + free(vlink); + return rv; + } + + return rsize; +} + +static void usage(char *arg) { + fprintf(stderr, "Usage: %s <my.priv> <dir pub> <dir addr>\n", arg); + exit(1); +} + +int main(int argc, char *argv[]) { + ECPConnection *conn_dir; + ECPNode node_dir; + ecp_ecdh_public_t dir_pub; + ECPDHKey key_perma; + int rv; + + if (argc != 4) usage(argv[0]); + + rv = ecp_init(&ctx, &vconn_handler, &vlink_handler); + printf("ecp_init RV:%d\n", rv); + + ecp_conn_handler_init(&dir_handler, handle_dir_msg, ecp_dir_handle_open, NULL, NULL); + ecp_ctx_set_handler(&ctx, ECP_CTYPE_DIR, &dir_handler); + + ecp_conn_handler_init(&handler, handle_msg, handle_open, NULL, NULL); + ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler); + + rv = ecp_util_load_key(&key_perma.public, &key_perma.private, argv[1]); + printf("ecp_util_load_key RV:%d\n", rv); + key_perma.valid = 1; + + rv = ecp_sock_create(&sock, &ctx, &key_perma); + printf("ecp_sock_create RV:%d\n", rv); + + rv = ecp_sock_open(&sock, NULL); + printf("ecp_sock_open RV:%d\n", rv); + + rv = ecp_start_receiver(&sock); + printf("ecp_start_receiver RV:%d\n", rv); + + rv = ecp_util_load_pub(&dir_pub, argv[2]); + printf("ecp_util_load_pub RV:%d\n", rv); + + ecp_node_init(&node_dir, &dir_pub, NULL); + rv = ecp_node_set_addr(&node_dir, argv[3]); + printf("ecp_node_set_addr RV:%d\n", rv); + + conn_dir = malloc(sizeof(ECPConnection)); + if (conn_dir == NULL) printf("out of memory\n"); + + ecp_dir_conn_init(conn_dir, &sock); + rv = ecp_conn_open(conn_dir, &node_dir); + printf("ecp_conn_open RV:%d\n", rv); + + while (1) sleep(1); +} diff --git a/ecp/test/vc_outb.c b/ecp/test/vc_outb.c new file mode 100644 index 0000000..6018602 --- /dev/null +++ b/ecp/test/vc_outb.c @@ -0,0 +1,128 @@ +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> + +#include <ecp/core.h> +#include <ecp/dir/dir.h> +#include <ecp/vconn/vconn.h> + +#include <util.h> + +#include "init_vconn.h" +#include "vc_common.h" + +ECPContext ctx; +ECPSocket sock; +ECPConnHandler handler; +ECPConnHandler dir_handler; +ECPConnHandler vconn_handler; +ECPConnHandler vlink_handler; +ecp_ecdh_public_t remote_pub; + +#define CTYPE_TEST 0 +#define MTYPE_MSG 0 + +static int handle_open(ECPConnection *conn, ECP2Buffer *b) { + char *_msg = "PERA JE CAR!"; + ssize_t rv; + + printf("OPEN\n"); + rv = ecp_msg_send(conn, MTYPE_MSG, (unsigned char *)_msg, strlen(_msg)+1); + + return ECP_OK; +} + +static ssize_t handle_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) { + printf("MSG:%s size:%ld\n", msg, msg_size); + + return msg_size; +} + +static ssize_t handle_dir_msg(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *b) { + size_t rsize; + uint16_t count; + ECPConnection *_conn; + int rv; + + if (msg_size < sizeof(uint16_t)) return ECP_ERR_SIZE; + + count = \ + ((uint16_t)msg[0] << 8) | \ + ((uint16_t)msg[1]); + + printf("DIR MSG:%d\n", count); + + rsize = sizeof(uint16_t) + count * ECP_SIZE_DIR_ITEM; + if (msg_size < rsize) return ECP_ERR_SIZE; + + msg += sizeof(uint16_t); + + _conn = malloc(sizeof(ECPConnection)); + if (_conn == NULL) return ECP_ERR_ALLOC; + + ecp_conn_init(_conn, conn->sock, CTYPE_TEST); + rv = vc_open_outb(_conn, msg, count, &remote_pub); + if (rv) { + printf("vc_open_outb RV:%d\n", rv); + free(_conn); + return rv; + } + + return rsize; +} + +static void usage(char *arg) { + fprintf(stderr, "Usage: %s <remote.pub> <dir pub> <dir addr>\n", arg); + exit(1); +} + +int main(int argc, char *argv[]) { + ECPConnection *conn_dir; + ECPNode node_dir; + ecp_ecdh_public_t dir_pub; + ECPDHKey key_perma; + int rv; + + if (argc != 4) usage(argv[0]); + + rv = ecp_init(&ctx, &vconn_handler, &vlink_handler); + printf("ecp_init RV:%d\n", rv); + + ecp_conn_handler_init(&dir_handler, handle_dir_msg, ecp_dir_handle_open, NULL, NULL); + ecp_ctx_set_handler(&ctx, ECP_CTYPE_DIR, &dir_handler); + + ecp_conn_handler_init(&handler, handle_msg, handle_open, NULL, NULL); + ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler); + + rv = ecp_dhkey_gen(&key_perma); + printf("ecp_dhkey_gen RV:%d\n", rv); + + rv = ecp_sock_create(&sock, &ctx, &key_perma); + printf("ecp_sock_create RV:%d\n", rv); + + rv = ecp_sock_open(&sock, NULL); + printf("ecp_sock_open RV:%d\n", rv); + + rv = ecp_start_receiver(&sock); + printf("ecp_start_receiver RV:%d\n", rv); + + rv = ecp_util_load_pub(&remote_pub, argv[1]); + printf("ecp_util_load_pub RV:%d\n", rv); + + rv = ecp_util_load_pub(&dir_pub, argv[2]); + printf("ecp_util_load_pub RV:%d\n", rv); + + ecp_node_init(&node_dir, &dir_pub, NULL); + rv = ecp_node_set_addr(&node_dir, argv[3]); + printf("ecp_node_set_addr RV:%d\n", rv); + + conn_dir = malloc(sizeof(ECPConnection)); + if (conn_dir == NULL) printf("out of memory\n"); + + ecp_dir_conn_init(conn_dir, &sock); + rv = ecp_conn_open(conn_dir, &node_dir); + printf("ecp_conn_open RV:%d\n", rv); + + while (1) sleep(1); +} diff --git a/ecp/test/vc_server.c b/ecp/test/vc_server.c index de7f275..548b52d 100644 --- a/ecp/test/vc_server.c +++ b/ecp/test/vc_server.c @@ -3,16 +3,20 @@ #include <unistd.h> #include <stdio.h> -#include <core.h> -#include <vconn/vconn.h> +#include <ecp/core.h> +#include <ecp/vconn/vconn.h> #include <util.h> +#include "init_vconn.h" + ECPContext ctx; ECPSocket sock; ECPConnHandler handler; +ECPConnHandler vconn_handler; +ECPConnHandler vlink_handler; ECPConnection conn; -ECPConnection vconn[3]; +ECPVConnOutb vconn[3]; #define CTYPE_TEST 0 #define MTYPE_MSG 0 @@ -46,11 +50,11 @@ int main(int argc, char *argv[]) { if ((argc < 4) || (argc > 7)) usage(argv[0]); - rv = ecp_init(&ctx); + rv = ecp_init(&ctx, &vconn_handler, &vlink_handler); printf("ecp_init RV:%d\n", rv); ecp_conn_handler_init(&handler, handle_msg, handle_open, NULL, NULL); - ecp_ctx_set_handler(&ctx, &handler, CTYPE_TEST); + ecp_ctx_set_handler(&ctx, CTYPE_TEST, &handler); rv = ecp_util_load_key(&key_perma.public, &key_perma.private, argv[1]); printf("ecp_util_load_key RV:%d\n", rv); @@ -65,29 +69,29 @@ int main(int argc, char *argv[]) { rv = ecp_start_receiver(&sock); printf("ecp_start_receiver RV:%d\n", rv); - rv = ecp_vlink_create(&conn, &sock); - printf("ecp_vlink_create RV:%d\n", rv); + rv = ecp_util_load_pub(&node_pub, argv[argc-1]); + printf("ecp_util_load_pub RV:%d\n", rv); + ecp_node_init(&node, &node_pub, NULL); + rv = ecp_node_set_addr(&node, argv[2]); + printf("ecp_node_set_addr RV:%d\n", rv); + + ecp_vlink_init(&conn, &sock); if (argc > 4) { - ecp_ecdh_public_t vconn_key[3]; + ecp_ecdh_public_t vconn_pub[3]; for (i=3; i<argc-1; i++) { - rv = ecp_util_load_pub(&vconn_key[i-3], argv[i]); + rv = ecp_util_load_pub(&vconn_pub[i-3], argv[i]); printf("ecp_util_load_pub RV:%d\n", rv); } + ecp_vconn_init(vconn, vconn_pub, argc-4, &sock); - rv = ecp_vconn_create(vconn, vconn_key, argc-4, &conn); - printf("ecp_vconn_create RV:%d\n", rv); + rv = ecp_vconn_open(vconn, &conn, &node); + printf("ecp_vconn_open RV:%d\n", rv); + } else { + rv = ecp_conn_open(&conn, &node); + printf("ecp_conn_open RV:%d\n", rv); } - rv = ecp_util_load_pub(&node_pub, argv[argc-1]); - printf("ecp_util_load_pub RV:%d\n", rv); - - rv = ecp_node_init(&node, &node_pub, argv[2]); - printf("ecp_node_init RV:%d\n", rv); - - rv = ecp_vconn_open(&conn, &node); - printf("ecp_vconn_open RV:%d\n", rv); - while (1) sleep(1); } diff --git a/ecp/test/vcs.c b/ecp/test/vcs.c index c4beed7..92d1eb2 100644 --- a/ecp/test/vcs.c +++ b/ecp/test/vcs.c @@ -3,14 +3,18 @@ #include <unistd.h> #include <stdio.h> -#include <core.h> -#include <vconn/vconn.h> +#include <ecp/core.h> +#include <ecp/vconn/vconn.h> #include <util.h> +#include "init_vconn.h" + ECPContext ctx; ECPSocket sock; ECPConnection conn; +ECPConnHandler vconn_handler; +ECPConnHandler vlink_handler; static void usage(char *arg) { fprintf(stderr, "Usage: %s <my addr> <my.priv> [ <node addr> <node.pub> ]\n", arg); @@ -18,12 +22,13 @@ static void usage(char *arg) { } int main(int argc, char *argv[]) { + ecp_tr_addr_t addr; ECPDHKey key_perma; int rv; if ((argc < 3) || (argc > 5)) usage(argv[0]); - rv = ecp_init(&ctx); + rv = ecp_init(&ctx, &vconn_handler, &vlink_handler); printf("ecp_init RV:%d\n", rv); rv = ecp_util_load_key(&key_perma.public, &key_perma.private, argv[2]); @@ -33,7 +38,10 @@ int main(int argc, char *argv[]) { rv = ecp_sock_create(&sock, &ctx, &key_perma); printf("ecp_sock_create RV:%d\n", rv); - rv = ecp_sock_open(&sock, argv[1]); + rv = ecp_addr_init(&addr, argv[1]); + printf("ecp_addr_init RV:%d\n", rv); + + rv = ecp_sock_open(&sock, &addr); printf("ecp_sock_open RV:%d\n", rv); rv = ecp_start_receiver(&sock); @@ -43,15 +51,14 @@ int main(int argc, char *argv[]) { ECPNode node; ecp_ecdh_public_t node_pub; - rv = ecp_vlink_create(&conn, &sock); - printf("ecp_vlink_create RV:%d\n", rv); - rv = ecp_util_load_pub(&node_pub, argv[4]); printf("ecp_util_load_pub RV:%d\n", rv); - rv = ecp_node_init(&node, &node_pub, argv[3]); - printf("ecp_node_init RV:%d\n", rv); + ecp_node_init(&node, &node_pub, NULL); + rv = ecp_node_set_addr(&node, argv[3]); + printf("ecp_node_set_addr RV:%d\n", rv); + ecp_vlink_init(&conn, &sock); rv = ecp_conn_open(&conn, &node); printf("ecp_conn_open RV:%d\n", rv); } diff --git a/ecp/util/mknode.c b/ecp/util/mknode.c index 764ac18..bc66da0 100644 --- a/ecp/util/mknode.c +++ b/ecp/util/mknode.c @@ -4,7 +4,7 @@ #include <stdio.h> #include <string.h> -#include <core.h> +#include <ecp/core.h> #include "util.h" @@ -38,8 +38,11 @@ int main(int argc, char *argv[]) { rv = ecp_dhkey_gen(&key); if (rv) goto err; - rv = ecp_node_init(&node, &key.public, addr); - if (rv) goto err; + ecp_node_init(&node, &key.public, NULL); + if (addr) { + rv = ecp_node_set_addr(&node, addr); + if (rv) goto err; + } rv = ecp_util_save_key(&key.public, &key.private, fn_key); if (rv) goto err; diff --git a/ecp/util/util.c b/ecp/util/util.c index 2b67127..efcf152 100644 --- a/ecp/util/util.c +++ b/ecp/util/util.c @@ -3,7 +3,7 @@ #include <unistd.h> #include <sys/stat.h> -#include <core.h> +#include <ecp/core.h> #include "util.h" |