#include #include #include #ifdef ECP_WITH_PTHREAD #include #endif #define ECP_OK 0 #define ECP_ERR -1 #define ECP_ERR_ITER -2 #define ECP_ERR_TIMEOUT -3 #define ECP_ERR_ALLOC -4 #define ECP_ERR_SIZE -5 #define ECP_ERR_BUSY -6 #define ECP_ERR_DUP -7 #define ECP_ERR_EMPTY -8 #define ECP_ERR_FULL -9 #define ECP_ERR_MTYPE -10 #define ECP_ERR_CTYPE -11 #define ECP_ERR_HANDLER -12 #define ECP_ERR_READY -13 #define ECP_ERR_CLOSED -14 #define ECP_ERR_PKT -20 #define ECP_ERR_ZPAD -21 #define ECP_ERR_COOKIE -22 #define ECP_ERR_AUTH -23 #define ECP_ERR_KEYID -24 #define ECP_ERR_SEQ -25 #define ECP_ERR_FRAG -26 #define ECP_ERR_ENCRYPT -30 #define ECP_ERR_DECRYPT -31 #define ECP_ERR_SIGN -32 #define ECP_ERR_VERIFY -33 #define ECP_ERR_ADDR -40 #define ECP_ERR_OPEN -41 #define ECP_ERR_BIND -42 #define ECP_ERR_SEND -43 #define ECP_ERR_RECV -44 #define ECP_ERR_EOF -45 #define ECP_ERR_MAX_PARENT -50 #define ECP_ERR_NEXT -51 #define ECP_MAX_SOCK_CONN 4 #define ECP_MAX_SOCK_KEY 2 #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_SEQ_FWD 1024 #define ECP_MAX_ATAG_FWD 100 /* max diff between current irep nonce and auth tag nonce */ #define ECP_MAX_EXPIRED 100 #define ECP_MIN_KEYX_DT 3600 #define ECP_SIZE_PROTO 2 #define ECP_SIZE_NONCE 8 #define ECP_SIZE_MTYPE 1 #define ECP_SIZE_ATAG (ECP_SIZE_HMAC_DIGEST) #define ECP_SIZE_COOKIE (ECP_SIZE_NONCE+ECP_SIZE_ATAG) #define ECP_SIZE_ZPAD_HDR 64 #define ECP_SIZE_ZPAD_PLD 64 #define ECP_SIZE_PKT_HDR (ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE) #define ECP_SIZE_PKT_HDR_IREQ (ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB+ECP_SIZE_ZPAD_HDR+ECP_SIZE_NONCE) #define ECP_SIZE_PKT_HDR_IREP (ECP_SIZE_PROTO+1+ECP_SIZE_NONCE) #define ECP_SIZE_PKT_HDR_OREQ (ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE+ECP_SIZE_NONCE) #define ECP_SIZE_PKT_FRM (ECP_SIZE_PKT_HDR+ECP_SIZE_AEAD_TAG) #define ECP_SIZE_PKT_FRM_IREQ (ECP_SIZE_PKT_HDR_IREQ+ECP_SIZE_AEAD_TAG) #define ECP_SIZE_PKT_FRM_IREP (ECP_SIZE_PKT_HDR_IREP+ECP_SIZE_AEAD_TAG) #define ECP_SIZE_PKT_FRM_OREQ (ECP_SIZE_PKT_HDR_OREQ+ECP_SIZE_AEAD_TAG) #define ECP_MAX_PKT 1432 // 1500 MTU - 60 bytes max IPv4 hdr - 8 bytes UDP hdr #define ECP_MAX_PLD (ECP_MAX_PKT-ECP_SIZE_PKT_FRM) #define ECP_MIN_PKT (ECP_SIZE_PKT_FRM+ECP_SIZE_MTYPE) #define ECP_SIZE_VBOX (ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE+2*ECP_SIZE_ECDH_PUB+ECP_SIZE_AEAD_TAG) #define ECP_SIZE_MT_FRAG(T) ((T) & ECP_MTYPE_FLAG_FRAG ? 2 + sizeof(uint16_t) : 0) #define ECP_SIZE_MT_PTS(T) ((T) & ECP_MTYPE_FLAG_PTS ? sizeof(ecp_pts_t) : 0) #define ECP_SIZE_MT_FLAG(T) (ECP_SIZE_MT_FRAG(T)+ECP_SIZE_MT_PTS(T)) #define ECP_SIZE_PLD(X,T) ((X)+ECP_SIZE_MTYPE+ECP_SIZE_MT_FLAG(T)) #ifdef ECP_WITH_VCONN #define ECP_SIZE_VCONN_PKT 512 #ifndef ECP_SIZE_VCONN_PKT #define ECP_SIZE_VCONN_PKT 0 #endif #define ECP_MAX_PARENT 3 /* #define ECP_CONN_PCOUNT(C) ((C)->pcount) */ #define ECP_CONN_PCOUNT(C) ECP_MAX_PARENT #define ECP_SIZE_VCONN_MSG_HDR (ECP_SIZE_MTYPE+sizeof(uint16_t)) #define ECP_SIZE_VCONN_PKT_FRM (ECP_SIZE_PKT_FRM+ECP_SIZE_VCONN_MSG_HDR) #if ECP_SIZE_VCONN_PKT #define ECP_SIZE_VCONN_PLD (ECP_SIZE_VCONN_PKT-ECP_SIZE_PKT_FRM) #define ECP_SIZE_VCONN_PKT_INNER (ECP_SIZE_VCONN_PKT-(ECP_MAX_PARENT*ECP_SIZE_VCONN_PKT_FRM)) #else #define ECP_SIZE_VCONN_PKT_INNER 0 #endif #endif // ECP_WITH_VCONN #ifdef ECP_WITH_VCONN #define _ECP_SIZE_PLD_BUF(X,C) ((X)+ECP_CONN_PCOUNT(C)*ECP_SIZE_VCONN_PKT_FRM) #define _ECP_SIZE_PKT_BUF(X,C) (ECP_SIZE_PKT_FRM+ECP_SIZE_PLD_BUF(X,C)) #if ECP_SIZE_VCONN_PKT #define ECP_SIZE_PLD_BUF(X,C) ((C)->parent ? ECP_SIZE_VCONN_PLD : _ECP_SIZE_PLD_BUF(X,C)) #define ECP_SIZE_PKT_BUF(X,C) ((C)->parent ? ECP_SIZE_VCONN_PKT : _ECP_SIZE_PKT_BUF(X,C)) #else #define ECP_SIZE_PLD_BUF(X,C) _ECP_SIZE_PLD_BUF(X,C) #define ECP_SIZE_PKT_BUF(X,C) _ECP_SIZE_PKT_BUF(X,C) #endif #else // ECP_WITH_VCONN #define ECP_SIZE_PLD_BUF(X,C) (X) #define ECP_SIZE_PKT_BUF(X,C) (ECP_SIZE_PKT_FRM+ECP_SIZE_PLD_BUF(X,C)) #endif // ECP_WITH_VCONN #ifdef ECP_WITH_VCONN #define _ECP_SIZE_PLD_BUF_IREP(X,P) ((X)+((P) ? (ECP_CONN_PCOUNT(P)+1)*ECP_SIZE_VCONN_PKT_FRM : 0)) #define _ECP_SIZE_PKT_BUF_IREP(X,P) (ECP_SIZE_PKT_FRM+ECP_SIZE_PLD_BUF_IREP(X,P)) #if ECP_SIZE_VCONN_PKT #define ECP_SIZE_PLD_BUF_IREP(X,P) ((P) ? ECP_SIZE_VCONN_PLD : _ECP_SIZE_PLD_BUF_IREP(X,P)) #define ECP_SIZE_PKT_BUF_IREP(X,P) ((P) ? ECP_SIZE_VCONN_PKT : _ECP_SIZE_PKT_BUF_IREP(X,P)) #else #define ECP_SIZE_PLD_BUF_IREP(X,P) _ECP_SIZE_PLD_BUF_IREP(X,P) #define ECP_SIZE_PKT_BUF_IREP(X,P) _ECP_SIZE_PKT_BUF_IREP(X,P) #endif #else // ECP_WITH_VCONN #define ECP_SIZE_PLD_BUF_IREP(X,P) (X) #define ECP_SIZE_PKT_BUF_IREP(X,P) (ECP_SIZE_PKT_FRM+ECP_SIZE_PLD_BUF_IREP(X,P)) #endif // ECP_WITH_VCONN #ifdef ECP_WITH_VCONN #define _ECP_SIZE_PLD_BUF_IREQ(X,C) ((X)+(ECP_CONN_PCOUNT(C) ? (ECP_CONN_PCOUNT(C)-1)*ECP_SIZE_VCONN_PKT_FRM+ECP_SIZE_PKT_FRM_IREQ+ECP_SIZE_VCONN_MSG_HDR : 0)) #define _ECP_SIZE_PKT_BUF_IREQ(X,C) (ECP_SIZE_PKT_FRM_IREQ+(X)+ECP_CONN_PCOUNT(C)*ECP_SIZE_VCONN_PKT_FRM) #if ECP_SIZE_VCONN_PKT #define ECP_SIZE_PLD_BUF_IREQ(X,C) ((C)->parent ? ECP_SIZE_VCONN_PLD : _ECP_SIZE_PLD_BUF_IREQ(X,C)) #define ECP_SIZE_PKT_BUF_IREQ(X,C) ((C)->parent ? ECP_SIZE_VCONN_PKT : _ECP_SIZE_PKT_BUF_IREQ(X,C)) #else #define ECP_SIZE_PLD_BUF_IREQ(X,C) _ECP_SIZE_PLD_BUF_IREQ(X,C) #define ECP_SIZE_PKT_BUF_IREQ(X,C) _ECP_SIZE_PKT_BUF_IREQ(X,C) #endif #else // ECP_WITH_VCONN #define ECP_SIZE_PLD_BUF_IREQ(X,C) (X) #define ECP_SIZE_PKT_BUF_IREQ(X,C) (ECP_SIZE_PKT_FRM_IREQ+(X)) #endif // ECP_WITH_VCONN #ifdef ECP_WITH_VCONN #define _ECP_SIZE_PLD_BUF_OREQ(X,C) ((X)+(ECP_CONN_PCOUNT(C) ? (ECP_CONN_PCOUNT(C)-1)*ECP_SIZE_VCONN_PKT_FRM+ECP_SIZE_PKT_FRM_OREQ+ECP_SIZE_VCONN_MSG_HDR : 0)) #define _ECP_SIZE_PKT_BUF_OREQ(X,C) (ECP_SIZE_PKT_FRM_OREQ+(X)+ECP_CONN_PCOUNT(C)*ECP_SIZE_VCONN_PKT_FRM) #if ECP_SIZE_VCONN_PKT #define ECP_SIZE_PLD_BUF_OREQ(X,C) ((C)->parent ? ECP_SIZE_VCONN_PLD : _ECP_SIZE_PLD_BUF_OREQ(X,C)) #define ECP_SIZE_PKT_BUF_OREQ(X,C) ((C)->parent ? ECP_SIZE_VCONN_PKT : _ECP_SIZE_PKT_BUF_OREQ(X,C)) #else #define ECP_SIZE_PLD_BUF_OREQ(X,C) _ECP_SIZE_PLD_BUF_OREQ(X,C) #define ECP_SIZE_PKT_BUF_OREQ(X,C) _ECP_SIZE_PKT_BUF_OREQ(X,C) #endif #else // ECP_WITH_VCONN #define ECP_SIZE_PLD_BUF_OREQ(X,C) (X) #define ECP_SIZE_PKT_BUF_OREQ(X,C) (ECP_SIZE_PKT_FRM_OREQ+(X)) #endif // ECP_WITH_VCONN #ifdef ECP_WITH_VCONN #define ecp_conn_is_root(C) ((C)->parent == NULL) #else #define ecp_conn_is_root(C) 1 #endif #define ECP_SEND_TRIES 3 #define ECP_SEND_TIMEOUT 500 #define ECP_POLL_TIMEOUT 500 #define ECP_KEYID_INV 0xFF #define ECP_KEYID_PERMA 0x0F #define ECP_KEYID_NOKEY 0x08 #define ECP_KEYID_MASK 0x07 #define ECP_NTYPE_INB 1 #define ECP_NTYPE_OUTB 2 #define ECP_NTYPE_VBOX 3 #define ECP_MTYPE_FLAG_SYS 0x80 #define ECP_MTYPE_FLAG_FRAG 0x40 #define ECP_MTYPE_FLAG_PTS 0x20 #define ECP_MTYPE_MASK 0x1F #define ECP_MTYPE_ZPAD (0x1F | ECP_MTYPE_FLAG_SYS) #define ECP_MTYPE_INIT_REQ (0x00 | ECP_MTYPE_FLAG_SYS) #define ECP_MTYPE_INIT_REP (0x01 | ECP_MTYPE_FLAG_SYS) #define ECP_MTYPE_OPEN_REQ (0x02 | ECP_MTYPE_FLAG_SYS) #define ECP_MTYPE_OPEN_REP (0x03 | ECP_MTYPE_FLAG_SYS) #define ECP_MTYPE_KEYX_REQ (0x04 | ECP_MTYPE_FLAG_SYS) #define ECP_MTYPE_KEYX_REP (0x05 | ECP_MTYPE_FLAG_SYS) #define ECP_CTYPE_FLAG_SYS 0x80 #define ECP_CTYPE_MASK 0x7F /* immutable flags */ #define ECP_CONN_FLAG_INB 0x01 #define ECP_CONN_FLAG_NOFREE 0x02 #define ECP_CONN_FLAG_VBOX 0x04 #define ECP_CONN_FLAG_GC 0x08 /* mutable flags */ #define ECP_CONN_FLAG_REG 0x01 #define ECP_CONN_FLAG_RDY 0x02 #define ECP_CONN_FLAG_OPEN 0x04 #define ECP_CONN_FLAG_OPEN_P 0x08 #define ECP_CONN_FLAG_CLOSED 0x10 #define ECP_CONN_FLAG_GCT 0x20 #define ECP_CONN_FLAG_UMASK 0xC0 #define ECP_SEND_FLAG_REPLY 0x01 #define ECP_SEND_FLAG_MORE 0x02 #define ecp_conn_nofree(conn) ((conn)->flags_im & ECP_CONN_FLAG_NOFREE) #define ecp_conn_has_vbox(conn) ((conn)->flags_im & ECP_CONN_FLAG_VBOX) #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_sys(conn) ((conn)->type & ECP_CTYPE_FLAG_SYS) #define _ecp_conn_is_reg(conn) ((conn)->flags & ECP_CONN_FLAG_REG) #define _ecp_conn_is_rdy(conn) ((conn)->flags & ECP_CONN_FLAG_RDY) #define _ecp_conn_is_open(conn) ((conn)->flags & ECP_CONN_FLAG_OPEN) #define _ecp_conn_is_open_p(conn) ((conn)->flags & ECP_CONN_FLAG_OPEN_P) #define _ecp_conn_is_closed(conn) ((conn)->flags & ECP_CONN_FLAG_CLOSED) #define _ecp_conn_in_gct(conn) ((conn)->flags & ECP_CONN_FLAG_GCT) #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_rdy(conn) ((conn)->flags |= ECP_CONN_FLAG_RDY) #define _ecp_conn_set_open(conn) ((conn)->flags |= ECP_CONN_FLAG_OPEN) #define _ecp_conn_set_open_p(conn) ((conn)->flags |= ECP_CONN_FLAG_OPEN_P) #define _ecp_conn_set_closed(conn) ((conn)->flags |= ECP_CONN_FLAG_CLOSED) #define _ecp_conn_push_gct(conn) ((conn)->flags |= ECP_CONN_FLAG_GCT) #define _ecp_conn_clr_reg(conn) ((conn)->flags &= ~ECP_CONN_FLAG_REG) #define _ecp_conn_clr_rdy(conn) ((conn)->flags &= ~ECP_CONN_FLAG_RDY) #define _ecp_conn_clr_open(conn) ((conn)->flags &= ~ECP_CONN_FLAG_OPEN) #define _ecp_conn_clr_open_p(conn) ((conn)->flags &= ~ECP_CONN_FLAG_OPEN_P) #define _ecp_conn_clr_closed(conn) ((conn)->flags &= ~ECP_CONN_FLAG_CLOSED) #define _ecp_conn_pull_gct(conn) ((conn)->flags &= ~ECP_CONN_FLAG_GCT) typedef uint32_t ecp_ack_t; #define ECP_SIZE_ACKB (sizeof(ecp_ack_t)*8) #define ECP_ACK_FULL (~((ecp_ack_t)0)) typedef uint32_t ecp_sts_t; #define ECP_STS_HALF ((ecp_sts_t)1 << (sizeof(ecp_sts_t) * 8 - 1)) #define ECP_STS_LT(a,b) ((ecp_sts_t)((ecp_sts_t)(a) - (ecp_sts_t)(b)) > ECP_STS_HALF) #define ECP_STS_LTE(a,b) ((ecp_sts_t)((ecp_sts_t)(b) - (ecp_sts_t)(a)) < ECP_STS_HALF) typedef uint32_t ecp_pts_t; #define ECP_PTS_HALF ((ecp_pts_t)1 << (sizeof(ecp_pts_t) * 8 - 1)) #define ECP_PTS_LT(a,b) ((ecp_pts_t)((ecp_pts_t)(a) - (ecp_pts_t)(b)) > ECP_PTS_HALF) #define ECP_PTS_LTE(a,b) ((ecp_pts_t)((ecp_pts_t)(b) - (ecp_pts_t)(a)) < ECP_PTS_HALF) typedef uint32_t ecp_seq_t; #define ECP_SEQ_HALF ((ecp_seq_t)1 << (sizeof(ecp_seq_t) * 8 - 1)) #define ECP_SEQ_LT(a,b) ((ecp_seq_t)((ecp_seq_t)(a) - (ecp_seq_t)(b)) > ECP_SEQ_HALF) #define ECP_SEQ_LTE(a,b) ((ecp_seq_t)((ecp_seq_t)(b) - (ecp_seq_t)(a)) < ECP_SEQ_HALF) typedef uint64_t ecp_nonce_t; #define ECP_NONCE_HALF ((ecp_nonce_t)1 << (sizeof(ecp_nonce_t) * 8 - 1)) #define ECP_NONCE_LT(a,b) ((ecp_nonce_t)((ecp_nonce_t)(a) - (ecp_nonce_t)(b)) > ECP_NONCE_HALF) #define ECP_NONCE_LTE(a,b) ((ecp_nonce_t)((ecp_nonce_t)(b) - (ecp_nonce_t)(a)) < ECP_NONCE_HALF) struct ECP2Buffer; struct ECPSocket; struct ECPConnection; #ifdef ECP_WITH_HTABLE #include "htable/htable.h" #endif #include "crypto/crypto.h" #include "transport.h" #include "timer.h" typedef int (*ecp_conn_expired_t) (struct ECPConnection *conn, ecp_sts_t now); typedef ssize_t (*ecp_conn_auth_t) (struct ECPSocket *sock, struct ECPConnection *parent, unsigned char ctype, ecp_ecdh_public_t *pub, unsigned char *msg, size_t msg_size); typedef struct ECPConnection * (*ecp_conn_new_t) (struct ECPSocket *sock, struct ECPConnection *parent, unsigned char type); typedef void (*ecp_conn_free_t) (struct ECPConnection *conn); typedef void (*ecp_err_handler_t) (struct ECPConnection *conn, unsigned char mtype, int err); typedef int (*ecp_logger_t) (const char *fmt, ...); 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_msg_handler_t) (struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b); typedef ssize_t (*ecp_oreq_send_t) (struct ECPConnection *conn, unsigned char *cookie); #define ECP_LOG_ERR(sock, ...) { if (sock->ctx->logger) sock->ctx->logger(__VA_ARGS__); } typedef struct ECPBuffer { unsigned char *buffer; size_t size; } ECPBuffer; typedef struct ECP2Buffer { ECPBuffer *packet; ECPBuffer *payload; } ECP2Buffer; typedef struct ECPDHKey { ecp_ecdh_public_t public; ecp_ecdh_private_t private; unsigned char valid; } ECPDHKey; typedef struct ECPDHPub { ecp_ecdh_public_t public; unsigned char valid; } ECPDHPub; typedef struct ECPNode { ecp_tr_addr_t addr; ECPDHPub key_perma; } ECPNode; typedef struct ECPDHShkey { ecp_aead_key_t key; unsigned char valid; } ECPDHShkey; typedef struct ECPPktMeta { uint16_t zpad; unsigned char *cookie; ecp_ecdh_public_t *public; ecp_aead_key_t *shkey; ecp_nonce_t *nonce; unsigned char ntype; unsigned char s_idx; unsigned char c_idx; size_t pkt_size; } ECPPktMeta; typedef struct ECPConnHandler { ecp_open_handler_t handle_open; ecp_close_handler_t handle_close; ecp_msg_handler_t handle_msg; ecp_err_handler_t handle_err; ecp_oreq_send_t send_oreq; } ECPConnHandler; typedef struct ECPContext { ecp_conn_auth_t conn_auth; /* inbound connections only */ ecp_conn_new_t conn_new; /* inbound connections only */ ecp_conn_free_t conn_free; ecp_err_handler_t handle_err; ecp_logger_t logger; ECPConnHandler *handler[ECP_MAX_CTYPE]; 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_gc; ecp_ht_table_t *addrs; #else struct ECPConnection *arr[ECP_MAX_SOCK_CONN]; unsigned short size; #endif #ifdef ECP_WITH_PTHREAD pthread_mutex_t mutex; pthread_mutex_t mutex_gc; #endif } ECPConnTable; #ifdef ECP_WITH_VCONN #ifdef ECP_WITH_HTABLE typedef struct ECPVConnTable { ecp_ht_table_t *vconn_keys; ecp_ht_table_t *vlink_keys; #ifdef ECP_WITH_PTHREAD pthread_mutex_t vconn_keys_mutex; pthread_mutex_t vlink_keys_mutex; #endif } ECPVConnTable; #endif #endif typedef struct ECPSocket { ECPContext *ctx; unsigned char running; ecp_tr_sock_t sock; ecp_nonce_t nonce_out; ECPDHKey key_perma; ECPDHKey key[ECP_MAX_SOCK_KEY]; unsigned char key_curr; ecp_hmac_key_t ckey; ECPConnTable conn_table; ECPTimer timer; #ifdef ECP_WITH_PTHREAD pthread_t rcvr_thd; pthread_mutex_t mutex; #endif #ifdef ECP_WITH_VCONN #ifdef ECP_WITH_HTABLE ECPVConnTable vconn_table; #endif #endif } ECPSocket; typedef struct ECPConnection { unsigned char type; unsigned char flags; unsigned char flags_im; unsigned short refcount; ecp_nonce_t nonce_out; ecp_nonce_t nonce_in; ecp_ack_t nonce_map; ECPSocket *sock; ECPNode remote; ECPDHKey key[ECP_MAX_CONN_KEY]; ECPDHPub rkey[ECP_MAX_NODE_KEY]; unsigned char key_curr; unsigned char key_next; unsigned char rkey_curr; ECPDHShkey shkey[ECP_MAX_NODE_KEY][ECP_MAX_NODE_KEY]; ecp_sts_t access_ts; ecp_sts_t keyx_ts; ecp_seq_t frag_seq; unsigned char frag_cnt; unsigned char frag_err; void *param; #ifdef ECP_WITH_VCONN struct ECPConnection *parent; unsigned short pcount; #endif #ifdef ECP_WITH_PTHREAD pthread_mutex_t mutex; #endif } ECPConnection; int ecp_dhkey_gen(ECPDHKey *key); int ecp_ctx_init(ECPContext *ctx, ecp_conn_auth_t conn_auth, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free, ecp_err_handler_t handle_err, ecp_logger_t logger); int ecp_ctx_set_handler(ECPContext *ctx, unsigned char ctype, ECPConnHandler *handler); ECPConnHandler *ecp_ctx_get_handler(ECPContext *ctx, unsigned char ctype); int ecp_addr_init(ecp_tr_addr_t *addr, void *addr_s); void ecp_node_init(ECPNode *node, ecp_ecdh_public_t *public, ecp_tr_addr_t *addr); void ecp_node_set_pub(ECPNode *node, ecp_ecdh_public_t *public); int ecp_node_set_addr(ECPNode *node, void *addr); 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, ecp_tr_addr_t *myaddr); void ecp_sock_close(ECPSocket *sock); void ecp_sock_ckey_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_expire(ECPSocket *sock, ecp_conn_expired_t conn_expired); ECPConnection *ecp_sock_gct_search(ECPSocket *sock, ecp_ecdh_public_t *public); unsigned int ecp_sock_gct_count(ECPSocket *sock); void ecp_atag_gen(ECPSocket *sock, unsigned char *public_buf, unsigned char *atag, ecp_nonce_t *nonce); int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf); ECPConnection *ecp_conn_new_inb(ECPSocket *sock, ECPConnection *parent, unsigned char ctype); void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype); void ecp_conn_set_flags(ECPConnection *conn, unsigned char flags); void ecp_conn_clr_flags(ECPConnection *conn, unsigned char flags); int ecp_conn_test_flags(ECPConnection *conn, unsigned char flags); int _ecp_conn_set_uflags(ECPConnection *conn, unsigned char flags); int _ecp_conn_clr_uflags(ECPConnection *conn, unsigned char flags); int _ecp_conn_test_uflags(ECPConnection *conn, unsigned char flags); int ecp_conn_set_uflags(ECPConnection *conn, unsigned char flags); int ecp_conn_clr_uflags(ECPConnection *conn, unsigned char flags); int ecp_conn_test_uflags(ECPConnection *conn, unsigned char flags); int ecp_conn_is_reg(ECPConnection *conn); int ecp_conn_is_open(ECPConnection *conn); int ecp_conn_set_closed(ECPConnection *conn); void ecp_conn_set_rdy(ECPConnection *conn); void *ecp_conn_set_param(ECPConnection *conn, void *param); void *ecp_conn_get_param(ECPConnection *conn); void ecp_conn_set_remote_key(ECPConnection *conn, ECPDHPub *key); void ecp_conn_set_remote_addr(ECPConnection *conn, ecp_tr_addr_t *addr); int ecp_conn_create(ECPConnection *conn, ECPConnection *parent); int ecp_conn_create_inb(ECPConnection *conn, ECPConnection *parent, unsigned char s_idx, unsigned char c_idx, ecp_ecdh_public_t *public, ECPDHPub *rkey_perma, ecp_aead_key_t *shkey); int ecp_conn_create_outb(ECPConnection *conn, ECPConnection *parent, ECPNode *node); void ecp_conn_destroy(ECPConnection *conn); void ecp_conn_free(ECPConnection *conn); int ecp_conn_insert(ECPConnection *conn, int rdy); int ecp_conn_insert_gc(ECPConnection *conn); int _ecp_conn_remove(ECPConnection *conn); void ecp_conn_remove(ECPConnection *conn); void ecp_conn_remove_addr(ECPConnection *conn); void ecp_conn_remove_gc(ECPConnection *conn); int _ecp_conn_open(ECPConnection *conn, ECPConnection *parent, ECPNode *node, int retry); int ecp_conn_open(ECPConnection *conn, ECPNode *node); int ecp_conn_try_open(ECPConnection *conn, ECPNode *node); void _ecp_conn_close(ECPConnection *conn); void ecp_conn_close(ECPConnection *conn); int _ecp_conn_is_zombie(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_lock(ECPConnection *conn); void ecp_conn_unlock(ECPConnection *conn); int ecp_conn_refcount_inc(ECPConnection *conn); void ecp_conn_refcount_dec(ECPConnection *conn); int ecp_conn_dhkey_new(ECPConnection *conn); int ecp_conn_dhkey_get(ECPConnection *conn, unsigned char idx, ECPDHKey *key); void ecp_conn_dhkey_set_curr(ECPConnection *conn); int ecp_conn_dhkey_get_pub(ECPConnection *conn, unsigned char *idx, ecp_ecdh_public_t *public); int ecp_conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_public_t *public); int ecp_conn_dhkey_get_remote(ECPConnection *conn, unsigned char idx, ECPDHPub *key); void ecp_conn_handler_init(ECPConnHandler *handler, ecp_open_handler_t handle_open, ecp_close_handler_t handle_close, ecp_msg_handler_t handle_msg, ecp_err_handler_t handle_err); void ecp_conn_handler_set_oreq_f(ECPConnHandler *handler, ecp_oreq_send_t send_oreq); ecp_open_handler_t ecp_get_open_handler(ECPConnection *conn); ecp_close_handler_t ecp_get_close_handler(ECPConnection *conn); ecp_msg_handler_t ecp_get_msg_handler(ECPConnection *conn); ecp_err_handler_t ecp_get_err_handler(ECPConnection *conn); ecp_oreq_send_t ecp_get_oreq_send_f(ECPConnection *conn); void ecp_err_handle(ECPConnection *conn, unsigned char mtype, int err); ssize_t ecp_send_init_req(ECPConnection *conn, ECPTimerItem *ti); ssize_t ecp_retry_init_req(ECPConnection *conn, ECPTimerItem *ti); ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, unsigned char *msg, size_t msg_size, 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, unsigned char *nonce_buf, 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_rep(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs); int ecp_handle_open(ECPConnection *conn, ECP2Buffer *bufs); 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); ssize_t ecp_msg_handle(ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_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, 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); void ecp_nonce2buf(unsigned char *b, ecp_nonce_t *n); void ecp_buf2nonce(ecp_nonce_t *n, unsigned char *b); int ecp_pkt_get_seq(unsigned char *pkt, size_t pkt_size, ecp_seq_t *s); ssize_t ecp_pack_irep(ECPConnection *parent, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr); ssize_t ecp_pack_conn(ECPConnection *conn, ECPBuffer *packet, size_t pkt_size, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *nonce, ECPBuffer *payload, size_t pld_size, ecp_tr_addr_t *addr); int ecp_pld_get_type(unsigned char *pld, size_t pld_size, unsigned char *mtype); int ecp_pld_set_type(unsigned char *pld, size_t pld_size, unsigned char mtype); int ecp_pld_get_frag(unsigned char *pld, size_t pld_size, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_sz); int ecp_pld_set_frag(unsigned char *pld, size_t pld_size, unsigned char frag_cnt, unsigned char frag_tot, uint16_t frag_sz); int ecp_pld_get_pts(unsigned char *pld, size_t pld_size, ecp_pts_t *pts); int ecp_pld_set_pts(unsigned char *pld, size_t pld_size, ecp_pts_t pts); unsigned char *ecp_pld_get_msg(unsigned char *pld, size_t pld_size); unsigned char *ecp_msg_get_pld(unsigned char mtype, unsigned char *msg); int ecp_msg_get_frag(unsigned char mtype, unsigned char *msg, unsigned char *frag_cnt, unsigned char *frag_tot, uint16_t *frag_size); int ecp_msg_get_pts(unsigned char mtype, unsigned char *msg, ecp_pts_t *pts); int ecp_frag_start(ECPConnection *conn, ecp_seq_t seq, unsigned char frag_cnt, unsigned char frag_tot, int *is_first, int *is_last); void ecp_frag_end(ECPConnection *conn, ecp_seq_t seq, unsigned char frag_cnt, int err); ssize_t _ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ssize_t pkt_size, unsigned char s_idx, unsigned char c_idx, uint16_t zpad, unsigned char *cookie, ecp_nonce_t *n, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti); ssize_t ecp_pld_send(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags); ssize_t ecp_pld_send_wtimer(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ECPTimerItem *ti); ssize_t ecp_pld_send_wcookie(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, unsigned char *cookie); ssize_t ecp_pld_send_wnonce(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, ecp_nonce_t *nonce); ssize_t ecp_pld_send_wsize(ECPConnection *conn, ECPBuffer *packet, ECPBuffer *payload, size_t pld_size, unsigned char flags, size_t pkt_size); ssize_t ecp_pld_send_irep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, ECPBuffer *packet, ECPPktMeta *pkt_meta, ECPBuffer *payload, size_t pld_size, unsigned char flags); ssize_t ecp_msg_send(ECPConnection *conn, unsigned char mtype, unsigned char *msg, size_t msg_size); void ecp_receiver(ECPSocket *sock); int ecp_start_receiver(ECPSocket *sock); int ecp_stop_receiver(ECPSocket *sock);