diff options
author | Uros Majstorovic <majstor@majstor.org> | 2022-03-12 13:41:28 +0100 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2022-03-12 13:41:28 +0100 |
commit | fb521b5d33ccb57c2f56d0548f172edbe31e9e91 (patch) | |
tree | fdc1f7112fe19c78a5c66183bb94e5b1128923f0 /ecp/src/ecp/dir | |
parent | 3436ce5d3ffbc2777e785310bac971c830cbb4ff (diff) |
dir/ext source files moved
Diffstat (limited to 'ecp/src/ecp/dir')
-rw-r--r-- | ecp/src/ecp/dir/dir.c | 203 | ||||
-rw-r--r-- | ecp/src/ecp/dir/dir.h | 32 | ||||
-rw-r--r-- | ecp/src/ecp/dir/dir_srv.c | 88 | ||||
-rw-r--r-- | ecp/src/ecp/dir/dir_srv.h | 10 |
4 files changed, 333 insertions, 0 deletions
diff --git a/ecp/src/ecp/dir/dir.c b/ecp/src/ecp/dir/dir.c new file mode 100644 index 0000000..7c4b0d6 --- /dev/null +++ b/ecp/src/ecp/dir/dir.c @@ -0,0 +1,203 @@ +#include <stdlib.h> +#include <string.h> + +#include <core.h> +#include <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) { + ECPDHPub *key; + ecp_tr_addr_t *addr; + + key = &item->node.key_perma; + addr = &item->node.addr; + + memcpy(&key->public, buf, sizeof(key->public)); + buf += sizeof(key->public); + + memcpy(&addr->host, buf, sizeof(addr->host)); + buf += sizeof(addr->host); + + addr->port = \ + (buf[0] << 8) | \ + (buf[1]); + buf += sizeof(uint16_t); + + item->capabilities = \ + (buf[0] << 8) | \ + (buf[1]); + buf += sizeof(uint16_t); +} + +void ecp_dir_item_serialize(ECPDirItem *item, unsigned char *buf) { + ECPDHPub *key; + ecp_tr_addr_t *addr; + + key = &item->node.key_perma; + addr = &item->node.addr; + + memcpy(buf, &key->public, sizeof(key->public)); + buf += sizeof(key->public); + + memcpy(buf, &addr->host, sizeof(addr->host)); + buf += sizeof(addr->host); + + buf[0] = (addr->port & 0xFF00) >> 8; + buf[1] = (addr->port & 0x00FF); + buf += sizeof(uint16_t); + + buf[0] = (item->capabilities & 0xFF00) >> 8; + buf[1] = (item->capabilities & 0x00FF); + 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; + + handler = ecp_get_dir_handler(conn); + if (handler) { + return handler(conn, msg, msg_size, b); + } else { + return ECP_ERR_HANDLER; + } +} + +int ecp_dir_handle_open(ECPConnection *conn, ECP2Buffer *b) { + ssize_t rv; + + 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; + } +} + +// iterator for client + +static ssize_t _dir_send_req(ECPConnection *conn, ECPTimerItem *ti) { + ECPBuffer packet; + ECPBuffer payload; + unsigned char pkt_buf[ECP_SIZE_PKT_BUF(0, ECP_MTYPE_DIR_REQ, conn)]; + unsigned char pld_buf[ECP_SIZE_PLD_BUF(0, ECP_MTYPE_DIR_REQ, conn)]; + + 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_REQ); + return ecp_pld_send_wtimer(conn, &packet, &payload, ECP_SIZE_PLD(0, ECP_MTYPE_DIR_REQ), 0, ti); +} + +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; +} diff --git a/ecp/src/ecp/dir/dir.h b/ecp/src/ecp/dir/dir.h new file mode 100644 index 0000000..e9f8e1e --- /dev/null +++ b/ecp/src/ecp/dir/dir.h @@ -0,0 +1,32 @@ +#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_CTYPE_DIR (0x00 | ECP_CTYPE_FLAG_SYS) + +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); + +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 diff --git a/ecp/src/ecp/dir/dir_srv.c b/ecp/src/ecp/dir/dir_srv.c new file mode 100644 index 0000000..b4d030d --- /dev/null +++ b/ecp/src/ecp/dir/dir_srv.c @@ -0,0 +1,88 @@ +#include <stdlib.h> + +#include <core.h> +#include <cr.h> + +#include "dir.h" +#include "dir_srv.h" + +int ecp_dir_init(ECPContext *ctx, ECPDirList *dir_online, ECPDirList *dir_shadow) { + ctx->dir_online = dir_online; + ctx->dir_shadow = dir_shadow; + + return ECP_OK; +} + +ssize_t ecp_dir_send_list(ECPConnection *conn, unsigned char mtype, ECPDirList *list) { + 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; + + rv = ecp_dir_serialize(list, msg, msg_size); + 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) { + ECPContext *ctx = conn->sock->ctx; + ssize_t rv; + + rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_UPD, ctx->dir_shadow); + return rv; +} + +ssize_t ecp_dir_handle_upd(ECPConnection *conn, unsigned char *msg, size_t msg_size) { + ECPContext *ctx = conn->sock->ctx; + ssize_t rsize; + ssize_t rv; + + rsize = ecp_dir_parse(ctx->dir_shadow, msg, msg_size); + if (rsize < 0) return rsize; + + rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_REP, ctx->dir_shadow); + 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) { + ECPContext *ctx = conn->sock->ctx; + ssize_t rv; + + rv = ecp_dir_send_list(conn, ECP_MTYPE_DIR_REP, ctx->dir_online); + return rv; +} + +ssize_t ecp_dir_handle_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size) { + ECPContext *ctx = conn->sock->ctx; + ssize_t rv; + + rv = ecp_dir_parse(ctx->dir_shadow, msg, msg_size); + return rv; +}
\ No newline at end of file diff --git a/ecp/src/ecp/dir/dir_srv.h b/ecp/src/ecp/dir/dir_srv.h new file mode 100644 index 0000000..85606c8 --- /dev/null +++ b/ecp/src/ecp/dir/dir_srv.h @@ -0,0 +1,10 @@ +int ecp_dir_init(ECPContext *ctx, ECPDirList *dir_online, ECPDirList *dir_shadow); +ssize_t ecp_dir_send_list(ECPConnection *conn, unsigned char mtype, ECPDirList *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); |