diff -r 000000000000 -r 5c129dd80d4f CSc/CS.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CSc/CS.c Thu Nov 21 14:55:10 2019 +0100 @@ -0,0 +1,158 @@ +#include "CS.h" + +CSP csP; +DebugP deP; + +void abend(DebugP deP) { +// LOG(0, "ABORT, netstat:"); +// int pid; +// if(!(pid = fork())) { +// execl("/bin/bash", "/bin/bash", "-c", "netstat -n --inet -a | grep 1[123][0-9][0-9][0-9] >net_stat", (char *) NULL); +// exit(EXIT_SUCCESS); +// } +// waitpid(pid, NULL, 0); + LOG(0, "ABORT, backtrace:"); + back_trace(); + kill(0, SIGTERM); + exit(EXIT_FAILURE); +} +char *gpa(struct sockaddr *ai_addr) { // returns string with IP4 address & port assigned to the socket + char *s = malloc(64); + unsigned short port = *(unsigned short*) ai_addr->sa_data; + char *a = ai_addr->sa_data + 2; + sprintf(s, "%hhu.%hhu.%hhu.%hhu %hu", a[0], a[1], a[2], a[3], ntohs(port)); + return s; +} +void gai(int level, struct addrinfo *ai, DebugP pr) { // logs assigned IP4 addresses from addrinfo chain + struct addrinfo *sa = ai; + if (csP->debMaxLev >= level) do { + char *s = gpa(sa->ai_addr); + strcpy(pr->msg, s); free(s); + deb(level, pr); + } while ((sa = sa->ai_next)); + fflush(stderr); +} +void ssl_err(DebugP pr, char *s) { + long e; + e = ERR_get_error(); + LOG(4, "ssl err, e=%lu", e); + while(e) { + LOG(0, "%s: %s", s, ERR_error_string(e, NULL)); + e = ERR_get_error(); + LOG(4, "ssl err, e=%lu", e); + } + abend(pr); +} +static int getArg(char *a) { + return (getenv(a) != NULL) ? atoi(getenv(a)) : 0; +} +static void constellation(topology topo, int ssl) { + DEBID("%sSSL %s", ssl ? "" : "non", topo==mash ? "MASH" : "RING"); + int first, nodes, *forw, pid, stat, exitRc = EXIT_SUCCESS; + pid_t *pids; + if(topo==ring) { first=csP->rp0; nodes=csP->rn; } + if(topo==mash) { first=csP->mp0; nodes=csP->mn; } + if(nodes == 0) exit(0); + if(nodes == 1) { LOG(0, "1 node configuration not implemented"); exit(0); } + LOG(1, "%d node(s) starting...", nodes); + pids = malloc(nodes*sizeof(int)); + first += ssl*500; + if((forw = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0)) < 0) SYSERR("mmap"); + *forw = 1; + for(int i = 0; i < nodes; i++) { + if(!(pid = fork())) Node(topo, forw, first+i, first, nodes, ssl); + else { LOG(3, "node %u established in process %u", first+i, pid); pids[i] = (pid_t)pid; } + } + LOG(2, "all nodes established"); + while((pid = wait(&stat)) > 0) { + if(WIFEXITED(stat)) { + LOG(4, "node process %u ended with exit(%d)", pid, WEXITSTATUS(stat)); + if(WEXITSTATUS(stat) != EXIT_SUCCESS) exitRc = EXIT_FAILURE; + } + else { LOG(4, "node process %u crashed", pid); exitRc = EXIT_FAILURE; } + } + LOG(1, "ENDED %s", exitRc == EXIT_SUCCESS ? "OK" : "BADLY"); + exit(exitRc); +} +int main(int argc, char *argv[]) { + CST cs; + csP = &cs; + deP = &(csP->debug); + ShareA(csP->shP); + struct sigaction ign; + + if(sem_init(&(csP->shP->debugSem), 1, 1) < 0) ERR("LOG sem_init"); + debug_init(argv[0]); + DEBID("client/server demo"); + if(getArg("DEB") >= 0) csP->debMaxLev = getArg("DEB"); + + if(sem_init(&csP->shP->counterSem, 1, 1) < 0) SYSERR("sem_init"); + ign.sa_flags = 0; + ign.sa_handler = SIG_IGN; + if(sigaction(SIGUSR2, &ign, NULL)<0) SYSERR("sigaction"); + + csP->shP->msgs = 0; + csP->shP->conns = 0; + csP->text="bla bla"; + csP->ttl = 3; + csP->rp0 = 11000; + csP->mp0 = 12000; + csP->rn = 0; + csP->mn = 0; + csP->pace.tv_sec = csP->pace.tv_nsec = 0; + csP->connThreshold = 77; // connection retries threshold + csP->connTO = 0.01 * 1000*1000; // connection timeout in usecs + csP->selTO = 1; // selection timeout in secs + csP->issl = 0; + csP->caP = (char*)"/home/local/etc/ssl/certs/"; + char *sslPathSuffP = "/../CS/"; + + if(getenv("T") != NULL) csP->text = getenv("T"); + if(getenv("CEP") != NULL) { + csP->ceP = (char*)malloc(strlen(getenv("CEP"))); + strcpy(csP->ceP, getenv("CEP")); } + else {csP->ceP = (char*)malloc(strlen(dirname(argv[0])) + strlen(sslPathSuffP) + 1); + strcpy(csP->ceP, dirname(argv[0])); + strcpy(csP->ceP + strlen(dirname(argv[0])), sslPathSuffP); } + if(getenv("CAP") != NULL) { + csP->caP = (char*)malloc(strlen(getenv("CAP")) + 1); + strcpy(csP->caP, getenv("CAP")); } + if(getArg("TTL") > 0) csP->ttl = getArg("TTL"); + if(getArg("RP0") > 0) csP->rp0 = getArg("RP0"); + if(getArg("MP0") > 0) csP->mp0 = getArg("MP0"); + if(getArg("N") >= 0) { + csP->mn = getArg("N"); + csP->rn = csP->mn; } + if(getArg("SSL") >= 0) csP->issl = getArg("SSL"); + if(getArg("RN") >= 0) csP->rn = getArg("RN"); + if(getArg("MN") >= 0) csP->mn = getArg("MN"); + csP->shP->act = csP->rn + csP->mn; // initialize active node processes counter + if(csP->issl > 1) csP->shP->act += csP->shP->act; + csP->pacing = 0; + if(getenv("P") != NULL) { + double d = atof(getenv("P")); + csP->pace.tv_sec=(time_t)trunc(d); + csP->pace.tv_nsec=(d-csP->pace.tv_sec)*1000*1000*1000; + if(csP->pace.tv_sec > 0 || csP->pace.tv_nsec > 0) csP->pacing = 1; + } + if(getArg("RS") >= 0) srandom(getArg("RS")); +// LOG(5, "initialized: ssl=%u, ssl path: %s, CA path: %s, pace=%f", +// csP->issl, csP->ceP, csP->caP, (double)csP->pace.tv_sec+(double)csP->pace.tv_nsec/(1000*1000*1000)); + LOG(1, "pgm=%s, ttl=%u, pace=%lu.%03lu, seed=%u, SSL=%u, debug=%d",\ + argv[0], csP->ttl, csP->pace.tv_sec, csP->pace.tv_nsec/(1000*1000), getArg("RS"), csP->issl, csP->debMaxLev); + if(csP->issl > 0) LOG(3, "certs path=%s, CA certs path=%s", csP->ceP, csP->caP); + + if(csP->issl < 2) { // 0 = no ssl, 1 = with SSL, 2 = both + if(!fork()) constellation(ring, csP->issl); + if(!fork()) constellation(mash, csP->issl); + } else for(int i = 0; i < 2; i++) { + if(!fork()) constellation(ring, i); + if(!fork()) constellation(mash, i); + } + + int stat, pid; + while((pid = wait(&stat)) > 0) if(WIFEXITED(stat)) LOG(4, "constellation process %u ended with exit(%d)", pid, WEXITSTATUS(stat)); + + LOG(1, "final balance: forwards=%d, connections=%d", csP->shP->msgs, csP->shP->conns); + return 0; +}