CSc/CS.c
author hh
Thu, 21 Nov 2019 14:55:10 +0100
changeset 0 5c129dd80d4f
permissions -rw-r--r--
--
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
hh
parents:
diff changeset
     1
#include "CS.h"
hh
parents:
diff changeset
     2
hh
parents:
diff changeset
     3
CSP csP;
hh
parents:
diff changeset
     4
DebugP deP;
hh
parents:
diff changeset
     5
hh
parents:
diff changeset
     6
void abend(DebugP deP) {
hh
parents:
diff changeset
     7
//	LOG(0, "ABORT, netstat:");
hh
parents:
diff changeset
     8
//	int pid;
hh
parents:
diff changeset
     9
//	if(!(pid = fork())) {
hh
parents:
diff changeset
    10
//		execl("/bin/bash", "/bin/bash", "-c", "netstat -n --inet -a | grep 1[123][0-9][0-9][0-9] >net_stat", (char *) NULL);
hh
parents:
diff changeset
    11
//		exit(EXIT_SUCCESS);
hh
parents:
diff changeset
    12
//	}
hh
parents:
diff changeset
    13
//	waitpid(pid, NULL, 0);
hh
parents:
diff changeset
    14
	LOG(0, "ABORT, backtrace:");
hh
parents:
diff changeset
    15
	back_trace();
hh
parents:
diff changeset
    16
	kill(0, SIGTERM);
hh
parents:
diff changeset
    17
	exit(EXIT_FAILURE);
hh
parents:
diff changeset
    18
}
hh
parents:
diff changeset
    19
char *gpa(struct sockaddr *ai_addr) {				// returns string with IP4 address & port assigned to the socket
hh
parents:
diff changeset
    20
	char *s = malloc(64);
hh
parents:
diff changeset
    21
	unsigned short port = *(unsigned short*) ai_addr->sa_data;
hh
parents:
diff changeset
    22
	char *a = ai_addr->sa_data + 2;
hh
parents:
diff changeset
    23
	sprintf(s, "%hhu.%hhu.%hhu.%hhu %hu", a[0], a[1], a[2], a[3], ntohs(port));
hh
parents:
diff changeset
    24
	return s;
hh
parents:
diff changeset
    25
}
hh
parents:
diff changeset
    26
void gai(int level, struct addrinfo *ai, DebugP pr) {	// logs assigned IP4 addresses from addrinfo chain
hh
parents:
diff changeset
    27
	struct addrinfo *sa = ai;
hh
parents:
diff changeset
    28
	if (csP->debMaxLev >= level) do {
hh
parents:
diff changeset
    29
		char *s = gpa(sa->ai_addr);
hh
parents:
diff changeset
    30
		strcpy(pr->msg, s); free(s);
hh
parents:
diff changeset
    31
		deb(level, pr);
hh
parents:
diff changeset
    32
	} while ((sa = sa->ai_next));
hh
parents:
diff changeset
    33
	fflush(stderr);
hh
parents:
diff changeset
    34
}
hh
parents:
diff changeset
    35
void ssl_err(DebugP pr, char *s) {
hh
parents:
diff changeset
    36
	long e;
hh
parents:
diff changeset
    37
	e = ERR_get_error();
hh
parents:
diff changeset
    38
	LOG(4, "ssl err, e=%lu", e);
hh
parents:
diff changeset
    39
	while(e) {
hh
parents:
diff changeset
    40
		LOG(0, "%s: %s", s, ERR_error_string(e, NULL));
hh
parents:
diff changeset
    41
		e = ERR_get_error();
hh
parents:
diff changeset
    42
		LOG(4, "ssl err, e=%lu", e);
hh
parents:
diff changeset
    43
	}
hh
parents:
diff changeset
    44
	abend(pr);
hh
parents:
diff changeset
    45
}
hh
parents:
diff changeset
    46
static int getArg(char *a) {
hh
parents:
diff changeset
    47
	return (getenv(a) != NULL) ? atoi(getenv(a)) : 0;
hh
parents:
diff changeset
    48
}
hh
parents:
diff changeset
    49
static void constellation(topology topo, int ssl) {
hh
parents:
diff changeset
    50
	DEBID("%sSSL %s", ssl ? "" : "non", topo==mash ? "MASH" : "RING");
hh
parents:
diff changeset
    51
	int first, nodes, *forw, pid, stat, exitRc = EXIT_SUCCESS;
hh
parents:
diff changeset
    52
	pid_t *pids;
hh
parents:
diff changeset
    53
	if(topo==ring) { first=csP->rp0; nodes=csP->rn; }
hh
parents:
diff changeset
    54
	if(topo==mash) { first=csP->mp0; nodes=csP->mn; }
hh
parents:
diff changeset
    55
	if(nodes == 0) exit(0);
hh
parents:
diff changeset
    56
	if(nodes == 1) { LOG(0, "1 node configuration not implemented"); exit(0); }
hh
parents:
diff changeset
    57
	LOG(1, "%d node(s) starting...", nodes);
hh
parents:
diff changeset
    58
	pids = malloc(nodes*sizeof(int));
hh
parents:
diff changeset
    59
	first += ssl*500;
hh
parents:
diff changeset
    60
	if((forw = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0)) < 0) SYSERR("mmap");
hh
parents:
diff changeset
    61
	*forw = 1;
hh
parents:
diff changeset
    62
	for(int i = 0; i < nodes; i++) {
hh
parents:
diff changeset
    63
		if(!(pid = fork())) Node(topo, forw, first+i, first, nodes, ssl);
hh
parents:
diff changeset
    64
		else { LOG(3, "node %u established in process %u", first+i, pid); pids[i] = (pid_t)pid; }	   
hh
parents:
diff changeset
    65
	}
hh
parents:
diff changeset
    66
	LOG(2, "all nodes established");
hh
parents:
diff changeset
    67
	while((pid = wait(&stat)) > 0) {
hh
parents:
diff changeset
    68
		if(WIFEXITED(stat)) {
hh
parents:
diff changeset
    69
			LOG(4, "node process %u ended with exit(%d)", pid, WEXITSTATUS(stat));
hh
parents:
diff changeset
    70
			if(WEXITSTATUS(stat) != EXIT_SUCCESS) exitRc = EXIT_FAILURE;
hh
parents:
diff changeset
    71
		}
hh
parents:
diff changeset
    72
		else { LOG(4, "node process %u crashed", pid); exitRc = EXIT_FAILURE; }
hh
parents:
diff changeset
    73
	}
hh
parents:
diff changeset
    74
	LOG(1, "ENDED %s", exitRc == EXIT_SUCCESS ? "OK" : "BADLY");
hh
parents:
diff changeset
    75
	exit(exitRc);
hh
parents:
diff changeset
    76
}
hh
parents:
diff changeset
    77
int main(int argc, char *argv[]) {
hh
parents:
diff changeset
    78
	CST cs;
hh
parents:
diff changeset
    79
	csP = &cs;
hh
parents:
diff changeset
    80
	deP = &(csP->debug);
hh
parents:
diff changeset
    81
	ShareA(csP->shP);
hh
parents:
diff changeset
    82
	struct sigaction ign;
hh
parents:
diff changeset
    83
hh
parents:
diff changeset
    84
	if(sem_init(&(csP->shP->debugSem), 1, 1) < 0) ERR("LOG sem_init");
hh
parents:
diff changeset
    85
	debug_init(argv[0]);
hh
parents:
diff changeset
    86
	DEBID("client/server demo");
hh
parents:
diff changeset
    87
	if(getArg("DEB") >= 0) csP->debMaxLev = getArg("DEB");
hh
parents:
diff changeset
    88
hh
parents:
diff changeset
    89
	if(sem_init(&csP->shP->counterSem, 1, 1) < 0) SYSERR("sem_init");
hh
parents:
diff changeset
    90
	ign.sa_flags = 0;
hh
parents:
diff changeset
    91
	ign.sa_handler = SIG_IGN;
hh
parents:
diff changeset
    92
	if(sigaction(SIGUSR2, &ign, NULL)<0) SYSERR("sigaction");
hh
parents:
diff changeset
    93
hh
parents:
diff changeset
    94
	csP->shP->msgs = 0;
hh
parents:
diff changeset
    95
	csP->shP->conns = 0;
hh
parents:
diff changeset
    96
	csP->text="bla bla";
hh
parents:
diff changeset
    97
	csP->ttl = 3;
hh
parents:
diff changeset
    98
	csP->rp0 = 11000;
hh
parents:
diff changeset
    99
	csP->mp0 = 12000;
hh
parents:
diff changeset
   100
	csP->rn = 0;
hh
parents:
diff changeset
   101
	csP->mn = 0;
hh
parents:
diff changeset
   102
	csP->pace.tv_sec = csP->pace.tv_nsec = 0;
hh
parents:
diff changeset
   103
	csP->connThreshold = 77;			// connection retries threshold
hh
parents:
diff changeset
   104
	csP->connTO = 0.01 * 1000*1000;	// connection timeout in usecs
hh
parents:
diff changeset
   105
	csP->selTO = 1;						// selection timeout in secs
hh
parents:
diff changeset
   106
	csP->issl = 0;
hh
parents:
diff changeset
   107
	csP->caP = (char*)"/home/local/etc/ssl/certs/";
hh
parents:
diff changeset
   108
	char *sslPathSuffP = "/../CS/";
hh
parents:
diff changeset
   109
hh
parents:
diff changeset
   110
	if(getenv("T") != NULL) csP->text = getenv("T");
hh
parents:
diff changeset
   111
	if(getenv("CEP") != NULL) {
hh
parents:
diff changeset
   112
		csP->ceP = (char*)malloc(strlen(getenv("CEP")));
hh
parents:
diff changeset
   113
		strcpy(csP->ceP, getenv("CEP")); }
hh
parents:
diff changeset
   114
	else {csP->ceP = (char*)malloc(strlen(dirname(argv[0])) + strlen(sslPathSuffP) + 1);
hh
parents:
diff changeset
   115
		strcpy(csP->ceP, dirname(argv[0]));
hh
parents:
diff changeset
   116
		strcpy(csP->ceP + strlen(dirname(argv[0])), sslPathSuffP); }
hh
parents:
diff changeset
   117
	if(getenv("CAP") != NULL)  {
hh
parents:
diff changeset
   118
		csP->caP = (char*)malloc(strlen(getenv("CAP")) + 1);
hh
parents:
diff changeset
   119
		strcpy(csP->caP, getenv("CAP"));	}
hh
parents:
diff changeset
   120
	if(getArg("TTL") > 0) csP->ttl = getArg("TTL");
hh
parents:
diff changeset
   121
	if(getArg("RP0") > 0) csP->rp0 = getArg("RP0");
hh
parents:
diff changeset
   122
	if(getArg("MP0") > 0) csP->mp0 = getArg("MP0");
hh
parents:
diff changeset
   123
	if(getArg("N") >= 0) {
hh
parents:
diff changeset
   124
		csP->mn = getArg("N");
hh
parents:
diff changeset
   125
		csP->rn = csP->mn; }
hh
parents:
diff changeset
   126
	if(getArg("SSL") >= 0) csP->issl = getArg("SSL");
hh
parents:
diff changeset
   127
	if(getArg("RN") >= 0) csP->rn = getArg("RN");
hh
parents:
diff changeset
   128
	if(getArg("MN") >= 0) csP->mn = getArg("MN");
hh
parents:
diff changeset
   129
	csP->shP->act = csP->rn + csP->mn;		// initialize active node processes counter
hh
parents:
diff changeset
   130
	if(csP->issl > 1) csP->shP->act += csP->shP->act;
hh
parents:
diff changeset
   131
	csP->pacing = 0;
hh
parents:
diff changeset
   132
   if(getenv("P") != NULL) {
hh
parents:
diff changeset
   133
	  	double d = atof(getenv("P"));
hh
parents:
diff changeset
   134
	  	csP->pace.tv_sec=(time_t)trunc(d);
hh
parents:
diff changeset
   135
	  	csP->pace.tv_nsec=(d-csP->pace.tv_sec)*1000*1000*1000;
hh
parents:
diff changeset
   136
	  	if(csP->pace.tv_sec > 0 || csP->pace.tv_nsec > 0) csP->pacing = 1;
hh
parents:
diff changeset
   137
   }
hh
parents:
diff changeset
   138
	if(getArg("RS") >= 0) srandom(getArg("RS"));
hh
parents:
diff changeset
   139
//	LOG(5, "initialized: ssl=%u, ssl path: %s, CA path: %s, pace=%f",
hh
parents:
diff changeset
   140
//				csP->issl, csP->ceP, csP->caP, (double)csP->pace.tv_sec+(double)csP->pace.tv_nsec/(1000*1000*1000));
hh
parents:
diff changeset
   141
   LOG(1, "pgm=%s, ttl=%u, pace=%lu.%03lu, seed=%u, SSL=%u, debug=%d",\
hh
parents:
diff changeset
   142
   			argv[0], csP->ttl, csP->pace.tv_sec, csP->pace.tv_nsec/(1000*1000), getArg("RS"), csP->issl, csP->debMaxLev);
hh
parents:
diff changeset
   143
   if(csP->issl > 0) LOG(3, "certs path=%s, CA certs path=%s", csP->ceP, csP->caP);
hh
parents:
diff changeset
   144
hh
parents:
diff changeset
   145
	if(csP->issl < 2) {		// 0 = no ssl, 1 = with SSL, 2 = both
hh
parents:
diff changeset
   146
		if(!fork()) constellation(ring, csP->issl);
hh
parents:
diff changeset
   147
		if(!fork()) constellation(mash, csP->issl);
hh
parents:
diff changeset
   148
	} else for(int i = 0; i < 2; i++) {
hh
parents:
diff changeset
   149
		if(!fork()) constellation(ring, i);
hh
parents:
diff changeset
   150
		if(!fork()) constellation(mash, i);
hh
parents:
diff changeset
   151
	}
hh
parents:
diff changeset
   152
hh
parents:
diff changeset
   153
	int stat, pid;
hh
parents:
diff changeset
   154
	while((pid = wait(&stat)) > 0) if(WIFEXITED(stat)) LOG(4, "constellation process %u ended with exit(%d)", pid, WEXITSTATUS(stat));
hh
parents:
diff changeset
   155
hh
parents:
diff changeset
   156
	LOG(1, "final balance: forwards=%d, connections=%d", csP->shP->msgs, csP->shP->conns);
hh
parents:
diff changeset
   157
	return 0;
hh
parents:
diff changeset
   158
}