#ifndef _CSH_
#define _CSH_ 1
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <math.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/time.h>
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <signal.h>
#include <execinfo.h>
#include <libgen.h>
typedef struct DebugS {
char id[128];
char msg[256];
} DebugT, *DebugP;
#define DebugA() (DebugP)malloc(sizeof(DebugT))
typedef struct ShareS {
int conns;
int msgs;
int act;
int mashOpenClientCount;
int mashOpenSSLClientCount;
sem_t counterSem;
sem_t debugSem;
} ShareT, *ShareP;
#define ShareA(v) if((v = mmap(NULL, sizeof(ShareT), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0)) < 0) SYSERR("mmap")
typedef struct CSS {
DebugT debug;
int debMaxLev;
int port0;
int portZ;
char *text;
int ttl;
int mp0;
int mn;
int rp0;
int rn;
struct timespec pace;
int pacing;
int issl;
int connThreshold; // connection retry threshhold
int connTO; // connection timeout in usecs
int selTO; // selection timeout in secs
char *ceP; // -->SSL certs path
char *caP; // -->CA certs path
ShareP shP;
char home[128];
} CST, *CSP;
#define CSA(v) if((v = (CSP)malloc(sizeof(CST))) < 0) SYSERR("malloc")
typedef struct HeaderS {
int ttl;
int ts;
int listPort;
} HeaderT, *HeaderP;
typedef struct PayloadS {
time_t ts;
char text;
} PayloadT, *PayloadP;
typedef struct ContainerS {
HeaderT hdr;
PayloadT payl;
} ContainerT, *ContainerP;
typedef struct DataS {
DebugT debug;
ContainerP contP;
int dataLen;
} DataT, *DataP;
#define DataA(v) if((v = (DataP)malloc(sizeof(DataT))) < 0) SYSERR("malloc")
typedef struct SocketS {
int remPort;
int sc;
SSL *sslP;
} SocketT, *SocketP;
#define SocketA(v) if((v = (SocketP)malloc(sizeof(SocketT))) < 0) SYSERR("malloc")
typedef enum{ring, mash} topology;
typedef struct NodeS {
DebugT debug;
topology topo;
int ssc;
int locPort;
int first;
int last;
int nodes;
int nodeIdx;
int kicker;
int *forw;
int closing;
pthread_t closingThread;
SocketP cliSides;
SocketP srvSides;
DataT data;
int len;
int ssl;
SSL_CTX *ctx;
struct sigaction *sigactP;
} NodeT, *NodeP;
#define NodeA(v) if((v = (NodeP)malloc(sizeof(NodeT))) < 0) SYSERR("malloc")
typedef enum{client, server} nodeside;
extern void debug_init();
extern char *gpa(struct sockaddr *);
extern void gai(int, struct addrinfo *ai, DebugP);
#define GAI(level, ai) gai(level, ai, deP)
extern void ssl_err(DebugP, char*);
extern void abend(DebugP);
extern void Node(topology, int*, int, int, int, int);
extern void Data(DataP, DebugP);
extern int dttlData(DataP);
extern int ttlData(DataP);
extern int remPortData(DataP);
extern DataP loadData(DataP, int, char*);
extern char *unldData(DataP);
extern char *digest24Data(DataP, char *);
extern int chkData(DataP);
extern void sabotageData(DataP);
extern int tsData(DataP);
extern void back_trace();
extern void pre(char *);
extern void deb(int, DebugP);
extern void err(int, char *, DebugP);
#define DEBID(...) sprintf(deP->id, __VA_ARGS__)
#define LOG(level, ...) sprintf(deP->msg, __VA_ARGS__), deb(level, deP)
#define SYSERR(e) LOG(0, "%s: %s (%d)", e, strerror(errno), errno), abend(deP)
#define SSLERR(e) ssl_err(deP, e)
#define SOFTERR(e) LOG(0, e), fflush(stderr)
#define HARDERR(e) SOFTERR(e), abend(deP);
#define ERR(e) perror(e), exit(EXIT_FAILURE)
#define PACING SIGUSR1
extern CSP csP;
#endif