271 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			271 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * 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 <http://askele.com>
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifndef __SNTL_SNTLLV2_H__
 | |
| #define	__SNTL_SNTLLV2_H__
 | |
| 
 | |
| #include <stdint.h>
 | |
| #include <time.h>
 | |
| #include <sys/types.h>
 | |
| #include <pthread.h>
 | |
| 
 | |
| #include <openssl/ssl.h>
 | |
| 
 | |
| #include <tdata/usrtc.h>
 | |
| #include <tdata/idx_allocator.h>
 | |
| #include <tdata/list.h>
 | |
| #include <sexpr/sexp.h>
 | |
| #include <sexpr/faststack.h>
 | |
| 
 | |
| #include <sntl/errno.h>
 | |
| 
 | |
| #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 unused_messages; /** < unused 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)
 | |
| 
 | |
| 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 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__ */
 | |
| 
 | |
| 
 |