/* * Secure Network Transport Layer Library v2 implementation. * (sntllv2) it superseed all versions before due to the: * - memory consumption * - new features such as pulse emitting * - performance optimization * * This is a proprietary software. See COPYING for further details. * * (c) Askele Group 2013-2015 * */ #ifndef __SNTL_SNTLLV2_H__ #define __SNTL_SNTLLV2_H__ #include #include #include #include #include #include #include #include #include #include #include #define VERIFY_DEPTH 1 /* FIXME: */ typedef struct __perm_context_type { char *login; char *passwd; uint64_t certid; struct in_addr *addr; void *priv; } perm_ctx_t; /* 8 byte header */ typedef struct __sntllv2_head_type { uint16_t msgid; uint16_t payload_length; uint8_t attr; uint8_t opcode; uint16_t reserve; }__attribute__((packed)) sntllv2_head_t; struct __connections_subsys_type; struct __channel_t; struct __message_t; /* flags for the connection link */ #define SNSX_BATCHMODE (1 << 1) #define SNSX_MESSAGINGMODE (1 << 2) #define SNSX_ALIVE (1 << 3) #define SNSX_CLOSED (1 << 4) /* * älä jätä kommentteja omalla kielellä! yksinkertaisia englanti sijaan! * i found somebody who write comments and messages in non-english, * it's a fucking practice - forget it. */ typedef struct __connection_t { /* General section */ struct __connections_subsys_type *ssys; /* < connections subsystem */ char *uuid; /** < uuid of the connection */ /* Channels section */ idx_allocator_t idx_ch; /** < index allocation for channels */ pthread_mutex_t idx_ch_lock; /** < mutex for allocating and deallocating channels */ struct __channel_t **channels; /** < channels O(1) storage */ /* RPC section */ usrtc_t *rpc_list; /** < search tree of possible RPC typed lists */ /* SSL related section */ SSL_CTX *ctx; /** < SSL context */ SSL *ssl; /** < SSL connection */ int ssl_data_index; /** < SSL index for the custom data */ pthread_mutex_t sslinout[2]; /** < SSL related locks for in and out */ /* Security section */ perm_ctx_t *pctx; /** < higher layer authentification context */ /* Messages section */ struct __message_t **messages; /** < messages O(1) storage */ idx_allocator_t idx_msg; pthread_mutex_t idx_msg_lock; list_head_t write_pending; /** < list of messages waiting for write */ pthread_mutex_t write_pending_lock; volatile uint8_t pending_messages; /** < pending message count */ /* Other stuff */ pthread_t thrd_poll[8]; volatile uint8_t flags; /** < flags of the connection */ volatile uint8_t usecount; usrtc_node_t csnode; /** < node to store the connection within list */ } conn_t; struct __connection_rpc_list_type; struct __message_t; typedef struct __pp_msg_type { struct __message_t *msg; list_node_t node; } ppmsg_t; typedef struct __channel_t { uint16_t cid; /** < ID of the channel */ conn_t *connection; /** < pointer to the parent connection */ struct __connection_rpc_list_type *rpc_list; /** < rpc functions list */ int flags; /** < flags of the channel */ } chnl_t; /* message flags */ #define SXMSG_OPEN (1 << 1) #define SXMSG_CLOSED (1 << 2) #define SXMSG_PROTO (1 << 3) #define SXMSG_LINK (1 << 4) #define SXMSG_REPLYREQ (1 << 5) #define SXMSG_PULSE (1 << 6) #define SXMSG_TIMEDOUT (1 << 7) /** * \brief Message used in sntl message passing * * This structure used to manage a message within a channel * of the sntl structure stack. */ typedef struct __message_t { chnl_t *pch; /** < channel of the message(if applicable) */ pthread_mutex_t wait; /** < special wait mutex, used for pending list and sync */ sntllv2_head_t mhead; void *payload; /** < payload */ } sxmsg_t; #define sxmsg_payload(m) (m)->payload #define sxmsg_datalen(m) (m)->mhead.payload_length #define sxmsg_rapidbuf(m) (m)->payload #define sxmsg_retcode(m) (m)->mhead.opcode #define sxmsg_waitlock(m) pthread_mutex_lock(&((m)->wait)) #define sxmsg_waitunlock(m) pthread_mutex_unlock(&((m)->wait)) typedef struct __connection_rpc_entry_type { char *name; int (*rpcf)(void *, sexp_t *); usrtc_node_t node; } cx_rpc_t; typedef struct __connection_rpc_list_type { usrtc_t *rpc_tree; /** < search tree for the rpc lookup */ char *opt_version; /** < reserved for future implementations */ } cx_rpc_list_t; #define MAX_CONNECTIONS 32768 /** * \brief Connection subsystem structure. * * This structure used for management and control a set of a * determined connections with the same RPC lists and the same * mode (server, client). * */ typedef struct __connections_subsys_type { usrtc_t *connections; pthread_rwlock_t rwlock; char *rootca, *certpem, *certkey; /* path name to the certificates */ cx_rpc_list_t *system_rpc; /* special functions pointers */ int (*validate_sslpem)(conn_t *); /** < this function used to validate SSL certificate while SSL handshake */ int (*secure_check)(conn_t *); /** < this function authorize user to login, * and also should check SSL cert and user, and already made sessions */ usrtc_t* (*get_rpc_typed_list_tree)(conn_t *); /** < this function is used to set RPC list of the functions */ int (*set_typed_list_callback)(conn_t *, int, char *); /** < this function is a callback * during setting up a typed channel */ void (*on_destroy)(conn_t *); /** < callback on connection destroy */ void (*on_pulse)(conn_t *, sexp_t *); /** < callback on pulse emit */ void *priv; } conn_sys_t; #define connections_set_sslvalidate(c, f) (c)->validate_sslpem = (f) #define connections_set_authcheck(c, f) (c)->secure_check = (f) #define connections_set_rpcvalidator(c, f) (c)->get_rpc_typed_list_tree = (f) #define connections_set_channelcall(c, f) (c)->set_typed_list_callback = (f) #define connections_set_ondestroy(c, f) (c)->on_destroy = (f) #define connections_set_onpulse(c, f) (c)->on_pulse = (f) #define connections_set_priv(c, p) (c)->priv = (p) #define connections_get_priv(c) (c)->priv typedef struct __rpc_typed_list_type { int type_id; char *description; cx_rpc_list_t *rpc_list; usrtc_node_t lnode; } rpc_typed_list_t; #ifdef __cplusplus extern "C" { #endif /* API */ int sntl_init(void); int connections_init(conn_sys_t *ssys); conn_sys_t *connections_create(void); int connections_destroy(conn_sys_t *ssys); int connections_free(conn_sys_t *ssys); int connections_setsslserts(conn_sys_t *ssys, const char *rootca, const char *certpem, const char *certkey); /* create links */ conn_t *connection_master_link(conn_sys_t *ssys, int sck, struct in_addr *addr); conn_t *connection_link(conn_sys_t *ssys, const char *host, int port, const char *SSL_cert, const char *login, const char *passwd); int connection_close(conn_t *co); /* channels */ chnl_t *sxchannel_open(conn_t *co, int type); int sxchannel_close(chnl_t *channel); /* messages */ /* * creates a message with a payload. * Will return a error code, and, if applicable, pointer to message */ int sxmsg_send(chnl_t *channel, const char *data, size_t datalen, sxmsg_t **msg); /* the same - postponed message i.e. will be written to the queue - not to write immendatly */ int sxmsg_send_pp(chnl_t *channel, const char *data, size_t datalen, sxmsg_t **msg); /* send a pulse message */ int sxmsg_pulse(conn_t *co, const char *data, size_t datalen); int sxmsg_reply(sxmsg_t *msg, const char *data, size_t datalen); int sxmsg_reply_pp(sxmsg_t *msg, const char *data, size_t datalen); int sxmsg_rreply(sxmsg_t *msg, size_t datalen); int sxmsg_return(sxmsg_t *msg, int opcode); int sxmsg_return_pp(sxmsg_t *msg, int opcode); void sxmsg_clean(sxmsg_t *msg); #ifdef __cplusplus } #endif /* RPC List API */ #define SNTL_FILTER_INC 0xa #define SNTL_FILTER_EXC 0xb #define SNTL_FILTER_END -1 #ifdef __cplusplus extern "C" { #endif int sntl_rpclist_init(usrtc_t *tree); int sntl_rpclist_add(usrtc_t *tree, int type, const char *description, const char *version); int sntl_rpclist_add_function(usrtc_t *tree, int type, const char *fu_name, int (*rpcf)(void *, sexp_t *)); int sntl_rpclist_filter(usrtc_t *source, usrtc_t **dest, int flag, int *filter); #ifdef __cplusplus } #endif #define blub(txt) fprintf(stderr, "%s:%d in %s > %s\n", __FILE__, __LINE__, __FUNCTION__, txt) #define dumphead(head) fprintf(stderr, "id: %d, opcode: %d, attr: %d, len = %d\n", head->msgid, head->opcode, head->attr, head->payload_length) #endif /* __SNTL_SNTLLV2_H__ */