You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libsxmp/include/sntl/sntllv2.h

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__ */