CSc/Node.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
NodeP thisP;
hh
parents:
diff changeset
     4
DebugP deP;
hh
parents:
diff changeset
     5
DataP dataP;
hh
parents:
diff changeset
     6
hh
parents:
diff changeset
     7
void sighandle(int sig) { return; }
hh
parents:
diff changeset
     8
hh
parents:
diff changeset
     9
void bindN() {
hh
parents:
diff changeset
    10
	LOG(4, "binding...");
hh
parents:
diff changeset
    11
	struct addrinfo *sa = (struct addrinfo*)malloc(sizeof(struct addrinfo));
hh
parents:
diff changeset
    12
	memset(sa, 0, sizeof(struct addrinfo));
hh
parents:
diff changeset
    13
	sa->ai_family = AF_INET;
hh
parents:
diff changeset
    14
	sa->ai_socktype = SOCK_STREAM;
hh
parents:
diff changeset
    15
	sa->ai_protocol = 0;
hh
parents:
diff changeset
    16
	sa->ai_flags = AI_PASSIVE;
hh
parents:
diff changeset
    17
	char s[64];
hh
parents:
diff changeset
    18
	sprintf(s, "%d", thisP->locPort);
hh
parents:
diff changeset
    19
	int e;
hh
parents:
diff changeset
    20
	if((e = getaddrinfo(NULL, s, sa, &sa)) != 0) HARDERR(gai_strerror(e));
hh
parents:
diff changeset
    21
	GAI(4, sa);
hh
parents:
diff changeset
    22
	if((thisP->ssc = socket(sa->ai_family, sa->ai_socktype, sa->ai_protocol)) < 0) SYSERR("socket alloc");
hh
parents:
diff changeset
    23
   	int opt = 1;
hh
parents:
diff changeset
    24
   	if(setsockopt(thisP->ssc, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) SYSERR("set socket options");
hh
parents:
diff changeset
    25
	if(bind(thisP->ssc, sa->ai_addr, sa->ai_addrlen) < 0) SYSERR("bind");
hh
parents:
diff changeset
    26
	if(listen(thisP->ssc, 1) < 0) SYSERR("listen");
hh
parents:
diff changeset
    27
	LOG(2, "bound to %d", thisP->locPort);
hh
parents:
diff changeset
    28
}
hh
parents:
diff changeset
    29
void conn(int i, int remPort) {
hh
parents:
diff changeset
    30
	DebugT debug, *deP = &debug;
hh
parents:
diff changeset
    31
	DEBID("%s to %u", thisP->debug.id, remPort);
hh
parents:
diff changeset
    32
	thisP->cliSides[i].remPort = remPort;
hh
parents:
diff changeset
    33
	int e;
hh
parents:
diff changeset
    34
	LOG(4, "connecting to %u...", remPort);
hh
parents:
diff changeset
    35
	int retry = csP->connThreshold;
hh
parents:
diff changeset
    36
	struct addrinfo *ai = (struct addrinfo*)malloc(sizeof(struct addrinfo));
hh
parents:
diff changeset
    37
	memset(ai, 0, sizeof(struct addrinfo));
hh
parents:
diff changeset
    38
	ai->ai_family = AF_INET;
hh
parents:
diff changeset
    39
	ai->ai_socktype = SOCK_STREAM;
hh
parents:
diff changeset
    40
	ai->ai_protocol = 0;
hh
parents:
diff changeset
    41
	ai->ai_flags = 0;
hh
parents:
diff changeset
    42
	char port[6];
hh
parents:
diff changeset
    43
	sprintf(port, "%d", remPort);
hh
parents:
diff changeset
    44
	if((e = getaddrinfo("localhost", port, ai, &ai)) != 0) HARDERR(gai_strerror(e));
hh
parents:
diff changeset
    45
	GAI(3, ai);
hh
parents:
diff changeset
    46
	if((thisP->cliSides[i].sc = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) SYSERR("socket alloc");
hh
parents:
diff changeset
    47
	while(retry--) {
hh
parents:
diff changeset
    48
		if(connect(thisP->cliSides[i].sc, ai->ai_addr, ai->ai_addrlen) < 0) {
hh
parents:
diff changeset
    49
			if(errno != ECONNREFUSED) SYSERR("connect");
hh
parents:
diff changeset
    50
			usleep(csP->connTO);
hh
parents:
diff changeset
    51
		}
hh
parents:
diff changeset
    52
		else break;
hh
parents:
diff changeset
    53
	}
hh
parents:
diff changeset
    54
	if(retry < 1) {
hh
parents:
diff changeset
    55
		LOG(0, "connection refused threshold %d reached", csP->connThreshold);
hh
parents:
diff changeset
    56
		exit(EXIT_FAILURE);
hh
parents:
diff changeset
    57
	}
hh
parents:
diff changeset
    58
	if(sem_wait(&(csP->shP->counterSem)) < 0) SYSERR("sem_wait");
hh
parents:
diff changeset
    59
	csP->shP->conns++;
hh
parents:
diff changeset
    60
	if(sem_post(&(csP->shP->counterSem)) < 0) SYSERR("sem_post");
hh
parents:
diff changeset
    61
	socklen_t l = sizeof(struct sockaddr);
hh
parents:
diff changeset
    62
	struct sockaddr *sa = malloc(l);
hh
parents:
diff changeset
    63
	if(getpeername(thisP->cliSides[i].sc, sa, &l) < 0) SYSERR("getpeername");
hh
parents:
diff changeset
    64
	LOG(4, "peer: %s on sc=%d", gpa(sa), thisP->cliSides[i].sc); free(sa);
hh
parents:
diff changeset
    65
hh
parents:
diff changeset
    66
	if(thisP->ssl) {
hh
parents:
diff changeset
    67
		ERR_clear_error();
hh
parents:
diff changeset
    68
		if(!(thisP->cliSides[i].sslP = SSL_new(thisP->ctx))) SSLERR("new SSL");
hh
parents:
diff changeset
    69
		if(!SSL_set_fd(thisP->cliSides[i].sslP, thisP->cliSides[i].sc)) SSLERR("client SSL set fd");
hh
parents:
diff changeset
    70
		if((e = SSL_connect(thisP->cliSides[i].sslP)) < 1) {
hh
parents:
diff changeset
    71
			switch(SSL_get_error(thisP->cliSides[i].sslP, e)) {
hh
parents:
diff changeset
    72
				case SSL_ERROR_SYSCALL: SYSERR("SSL connect"); break;
hh
parents:
diff changeset
    73
				default:	SSLERR("SSL connect"); break;
hh
parents:
diff changeset
    74
			}
hh
parents:
diff changeset
    75
		}
hh
parents:
diff changeset
    76
	}
hh
parents:
diff changeset
    77
	LOG(2, "connected via sc=%d after %d retries", thisP->cliSides[i].sc, csP->connThreshold - (retry + 1));
hh
parents:
diff changeset
    78
}
hh
parents:
diff changeset
    79
void acc(int i) {
hh
parents:
diff changeset
    80
	LOG(4, "accepting...");
hh
parents:
diff changeset
    81
	if((thisP->srvSides[i].sc = accept(thisP->ssc, NULL, NULL)) < 0) SYSERR("accept");
hh
parents:
diff changeset
    82
	socklen_t l = sizeof(struct sockaddr);
hh
parents:
diff changeset
    83
	struct sockaddr *sa = malloc(l);
hh
parents:
diff changeset
    84
	if(getpeername(thisP->srvSides[i].sc, sa, &l) < 0) SYSERR("getpeername");
hh
parents:
diff changeset
    85
	LOG(4, "peer: %s on sc=%d", gpa(sa), thisP->srvSides[i].sc); free(sa);
hh
parents:
diff changeset
    86
	if(thisP->ssl) {
hh
parents:
diff changeset
    87
		int e;
hh
parents:
diff changeset
    88
		ERR_clear_error();
hh
parents:
diff changeset
    89
		if(!(thisP->srvSides[i].sslP = SSL_new(thisP->ctx))) SSLERR("new SSL");
hh
parents:
diff changeset
    90
		if(!SSL_set_fd(thisP->srvSides[i].sslP, thisP->srvSides[i].sc)) SSLERR("server SSL set fd");
hh
parents:
diff changeset
    91
		if((e = SSL_accept(thisP->srvSides[i].sslP)) < 1) {
hh
parents:
diff changeset
    92
			switch(SSL_get_error(thisP->srvSides[i].sslP, e)) {
hh
parents:
diff changeset
    93
				case SSL_ERROR_SYSCALL: SYSERR("SSL accept"); break;
hh
parents:
diff changeset
    94
				default:	SSLERR("SSL accept"); break;
hh
parents:
diff changeset
    95
			}
hh
parents:
diff changeset
    96
		}
hh
parents:
diff changeset
    97
	}
hh
parents:
diff changeset
    98
	LOG(2, "accepted");
hh
parents:
diff changeset
    99
}
hh
parents:
diff changeset
   100
void closeN(int i, nodeside side) {
hh
parents:
diff changeset
   101
	SocketP sc;
hh
parents:
diff changeset
   102
	if(side) sc = thisP->srvSides; else sc = thisP->cliSides;
hh
parents:
diff changeset
   103
	LOG(5, "closing sc=%d...", sc[i].sc);
hh
parents:
diff changeset
   104
	if(thisP->ssl) {
hh
parents:
diff changeset
   105
		int e;
hh
parents:
diff changeset
   106
		if((e = SSL_shutdown(sc[i].sslP)) < 0) SYSERR("SSL shutdown (1)");
hh
parents:
diff changeset
   107
		if(!e) {
hh
parents:
diff changeset
   108
			LOG(5, "SSL shutdown rc=0");
hh
parents:
diff changeset
   109
			if((e = SSL_shutdown(sc[i].sslP)) < 0) {
hh
parents:
diff changeset
   110
				switch(SSL_get_error(sc[i].sslP, e)) {
hh
parents:
diff changeset
   111
					case SSL_ERROR_SYSCALL:
hh
parents:
diff changeset
   112
						if(!(e = ERR_get_error())) {
hh
parents:
diff changeset
   113
							if(errno) SYSERR("SSL shutdown (2)");
hh
parents:
diff changeset
   114
							break;
hh
parents:
diff changeset
   115
						}
hh
parents:
diff changeset
   116
						break;
hh
parents:
diff changeset
   117
					default:	SSLERR("SSL shutdown (2)"); break;
hh
parents:
diff changeset
   118
				}
hh
parents:
diff changeset
   119
			}
hh
parents:
diff changeset
   120
		}
hh
parents:
diff changeset
   121
	}
hh
parents:
diff changeset
   122
	close(sc[i].sc);
hh
parents:
diff changeset
   123
	LOG(4, "closed sc=%d", sc[i].sc);
hh
parents:
diff changeset
   124
	sc[i].sc = -1;
hh
parents:
diff changeset
   125
}
hh
parents:
diff changeset
   126
void *close_clients() {
hh
parents:
diff changeset
   127
	DebugT debug, *deP = &debug;
hh
parents:
diff changeset
   128
	DEBID("%s CLOSE clients", thisP->debug.id);
hh
parents:
diff changeset
   129
	LOG(5, "start...");
hh
parents:
diff changeset
   130
	for (int i = 0; i < thisP->nodes; i++) if(thisP->cliSides[i].sc > -1) closeN(i, client);
hh
parents:
diff changeset
   131
	LOG(4, "all clients closed");
hh
parents:
diff changeset
   132
	pthread_exit(NULL);
hh
parents:
diff changeset
   133
}
hh
parents:
diff changeset
   134
void close_node() {
hh
parents:
diff changeset
   135
	if(!thisP->closing) {
hh
parents:
diff changeset
   136
		thisP->closingThread = 0;
hh
parents:
diff changeset
   137
		if(pthread_create(&thisP->closingThread, NULL, &close_clients, NULL) != 0) SYSERR("create thread");
hh
parents:
diff changeset
   138
	thisP->closing = 1;
hh
parents:
diff changeset
   139
	}
hh
parents:
diff changeset
   140
}
hh
parents:
diff changeset
   141
int readN(int i) {
hh
parents:
diff changeset
   142
	LOG(5, "ready to read len=%d from sc=%d...", dataP->dataLen, thisP->srvSides[i].sc);
hh
parents:
diff changeset
   143
	int n, rest = dataP->dataLen;
hh
parents:
diff changeset
   144
	void *buf = dataP->contP;
hh
parents:
diff changeset
   145
	while(rest > 0) {
hh
parents:
diff changeset
   146
		if(thisP->ssl) { if((n = SSL_read(thisP->srvSides[i].sslP, buf, rest)) < 0) SSLERR("read socket"); }
hh
parents:
diff changeset
   147
		else { if((n = read(thisP->srvSides[i].sc, buf, rest)) < 0) SYSERR("read socket"); }
hh
parents:
diff changeset
   148
		if(n == 0) {
hh
parents:
diff changeset
   149
			LOG(4, "read EOF");
hh
parents:
diff changeset
   150
			return 0;
hh
parents:
diff changeset
   151
		}
hh
parents:
diff changeset
   152
		else {
hh
parents:
diff changeset
   153
			buf += n; rest -= n;
hh
parents:
diff changeset
   154
			if(rest > 0) LOG(5, "partly read %d bytes", n);
hh
parents:
diff changeset
   155
		}
hh
parents:
diff changeset
   156
	}
hh
parents:
diff changeset
   157
	if(sem_wait(&(csP->shP->counterSem)) < 0) SYSERR("sem_wait");
hh
parents:
diff changeset
   158
	csP->shP->msgs++;
hh
parents:
diff changeset
   159
	if(sem_post(&(csP->shP->counterSem)) < 0) SYSERR("sem_post");
hh
parents:
diff changeset
   160
	LOG(5, "read %d from %u", dataP->dataLen, dataP->contP->hdr.listPort);
hh
parents:
diff changeset
   161
	return dataP->dataLen;
hh
parents:
diff changeset
   162
}
hh
parents:
diff changeset
   163
int writeN(int i) {
hh
parents:
diff changeset
   164
	DebugT debug, *deP = &debug;
hh
parents:
diff changeset
   165
	DEBID("%s to %u", thisP->debug.id, thisP->cliSides[i].remPort);
hh
parents:
diff changeset
   166
	LOG(5, "ready to write len=%d to sc=%d...", dataP->dataLen, thisP->cliSides[i].sc);
hh
parents:
diff changeset
   167
	int n, rest = dataP->dataLen;
hh
parents:
diff changeset
   168
	void *buf = dataP->contP;
hh
parents:
diff changeset
   169
	while(rest > 0) {
hh
parents:
diff changeset
   170
		if(thisP->ssl) { if((n = SSL_write(thisP->cliSides[i].sslP, buf, rest)) < 0) SSLERR("socket write"); }
hh
parents:
diff changeset
   171
		else { if((n = write(thisP->cliSides[i].sc, buf, rest)) < 0) SYSERR("socket write"); }
hh
parents:
diff changeset
   172
		buf += n; rest -= n;
hh
parents:
diff changeset
   173
		if(rest > 0) LOG(5, "partly written %d bytes", n);
hh
parents:
diff changeset
   174
	}
hh
parents:
diff changeset
   175
	LOG(5, "written %d", dataP->dataLen);
hh
parents:
diff changeset
   176
	return dataP->dataLen;
hh
parents:
diff changeset
   177
}
hh
parents:
diff changeset
   178
int getN(int i) {
hh
parents:
diff changeset
   179
	return readN(i) > 0;
hh
parents:
diff changeset
   180
}
hh
parents:
diff changeset
   181
int putN(int i) {
hh
parents:
diff changeset
   182
	dataP->contP->hdr.listPort = thisP->locPort;
hh
parents:
diff changeset
   183
	return writeN(i) > 0;
hh
parents:
diff changeset
   184
}
hh
parents:
diff changeset
   185
int next_node() {
hh
parents:
diff changeset
   186
	int next;
hh
parents:
diff changeset
   187
	if(thisP->topo == ring) {
hh
parents:
diff changeset
   188
		next = thisP->locPort + 1;
hh
parents:
diff changeset
   189
		if(next > thisP->last) next = thisP->first;
hh
parents:
diff changeset
   190
	}
hh
parents:
diff changeset
   191
	else while((next = thisP->first + thisP->nodes * ((float)random() / RAND_MAX)) == thisP->locPort);
hh
parents:
diff changeset
   192
	return next;
hh
parents:
diff changeset
   193
}
hh
parents:
diff changeset
   194
void forward(int sci) {
hh
parents:
diff changeset
   195
	int next, scn;
hh
parents:
diff changeset
   196
	char digest[24];
hh
parents:
diff changeset
   197
	if(getN(sci)) {
hh
parents:
diff changeset
   198
   	LOG(5, "received data from %u", remPortData(dataP));
hh
parents:
diff changeset
   199
		if(thisP->kicker) {
hh
parents:
diff changeset
   200
			LOG(4, "received from node %u: %s, ttl=%d",
hh
parents:
diff changeset
   201
						remPortData(dataP), digest24Data(dataP, digest), ttlData(dataP));
hh
parents:
diff changeset
   202
//			if(ttlData(dataP) == 2) sabotageData(dataP);
hh
parents:
diff changeset
   203
//			if(ttlData(dataP) == 2) errno=0, SYSERR("signal test");
hh
parents:
diff changeset
   204
			if(dttlData(dataP) <= 0) {
hh
parents:
diff changeset
   205
      		LOG(1, "received after passing all %s: %s", thisP->topo==mash ? "mashes" : "rings",digest24Data(dataP, digest));
hh
parents:
diff changeset
   206
				close_node();
hh
parents:
diff changeset
   207
				*(thisP->forw) = 0;
hh
parents:
diff changeset
   208
				LOG(4, "leaving forward closing");
hh
parents:
diff changeset
   209
				return;
hh
parents:
diff changeset
   210
			}
hh
parents:
diff changeset
   211
		}
hh
parents:
diff changeset
   212
		next = next_node(); scn = next - thisP->first;
hh
parents:
diff changeset
   213
		LOG(5, "forwarding to %d, len=%d, ttl=%d --->", next, dataP->dataLen, ttlData(dataP));
hh
parents:
diff changeset
   214
		if(thisP->cliSides[scn].sc < 0) conn(scn, next);
hh
parents:
diff changeset
   215
		if(*(thisP->forw) && csP->pacing) { LOG(5, "pacing..."); nanosleep(&(csP->pace), NULL); }
hh
parents:
diff changeset
   216
		putN(scn);
hh
parents:
diff changeset
   217
      LOG(5, "forwarded to %u", next);
hh
parents:
diff changeset
   218
	}
hh
parents:
diff changeset
   219
	else {
hh
parents:
diff changeset
   220
		close_node();
hh
parents:
diff changeset
   221
		closeN(sci, server);
hh
parents:
diff changeset
   222
	}
hh
parents:
diff changeset
   223
	return;
hh
parents:
diff changeset
   224
}
hh
parents:
diff changeset
   225
void main_loop() {
hh
parents:
diff changeset
   226
	sigset_t pacing;
hh
parents:
diff changeset
   227
	sigemptyset(&pacing);
hh
parents:
diff changeset
   228
   sigaddset(&pacing, PACING);
hh
parents:
diff changeset
   229
	union {		// simple select mask debug
hh
parents:
diff changeset
   230
	   fd_set rs;
hh
parents:
diff changeset
   231
	   uint mask;
hh
parents:
diff changeset
   232
	} u;
hh
parents:
diff changeset
   233
	int nfds;
hh
parents:
diff changeset
   234
	FD_ZERO(&(u.rs)); nfds = 0;
hh
parents:
diff changeset
   235
	if(*(thisP->forw)) {
hh
parents:
diff changeset
   236
		FD_SET(thisP->ssc, &(u.rs)); if(thisP->ssc >= nfds) nfds = thisP->ssc + 1; }
hh
parents:
diff changeset
   237
	while(nfds) {
hh
parents:
diff changeset
   238
		struct timeval t = {csP->selTO, 0};
hh
parents:
diff changeset
   239
		LOG(5, "selecting, mask=%08x", u.mask);
hh
parents:
diff changeset
   240
		int rc;
hh
parents:
diff changeset
   241
		rc = select(nfds, &(u.rs), NULL, NULL, &t);
hh
parents:
diff changeset
   242
		if(rc < 0 && errno != EINTR) SYSERR("select");
hh
parents:
diff changeset
   243
		if(rc > 0) {
hh
parents:
diff changeset
   244
			LOG(5, "return from select, mask=%08x", u.mask);
hh
parents:
diff changeset
   245
			if(FD_ISSET(thisP->ssc, &(u.rs))) {												// ssc posted: accept & forward
hh
parents:
diff changeset
   246
				int i;
hh
parents:
diff changeset
   247
				for(i=0; thisP->srvSides[i].sc > -1 && i < thisP->nodes; i++);		// find unused slot for accept
hh
parents:
diff changeset
   248
				if(i == thisP->nodes) HARDERR("can't accept, all slots in use");
hh
parents:
diff changeset
   249
				LOG(5, "slot for accept=%d", i);
hh
parents:
diff changeset
   250
				acc(i);
hh
parents:
diff changeset
   251
				forward(i);
hh
parents:
diff changeset
   252
			}
hh
parents:
diff changeset
   253
			else																						// check which connected socket is posted
hh
parents:
diff changeset
   254
				for(int i = 0; i < thisP->nodes; i++)
hh
parents:
diff changeset
   255
					if(thisP->srvSides[i].sc > -1 && FD_ISSET(thisP->srvSides[i].sc, &(u.rs))) forward(i);
hh
parents:
diff changeset
   256
		}
hh
parents:
diff changeset
   257
		FD_ZERO(&(u.rs)); nfds = 0;
hh
parents:
diff changeset
   258
		if(*(thisP->forw)) { FD_SET(thisP->ssc, &(u.rs)); if(thisP->ssc >= nfds) nfds = thisP->ssc + 1; }
hh
parents:
diff changeset
   259
		for(int i = 0; i < thisP->nodes; i++) {											// mask all connected client side sockets for select
hh
parents:
diff changeset
   260
			int sc = thisP->srvSides[i].sc;
hh
parents:
diff changeset
   261
			if(sc > -1) { FD_SET(sc, &(u.rs)); if(sc >= nfds) nfds = sc + 1; }
hh
parents:
diff changeset
   262
		}
hh
parents:
diff changeset
   263
	}
hh
parents:
diff changeset
   264
}
hh
parents:
diff changeset
   265
void Node(topology topo, int *forw, int port, int first, int n, int ssl) {
hh
parents:
diff changeset
   266
	NodeT this;
hh
parents:
diff changeset
   267
	thisP = &this;
hh
parents:
diff changeset
   268
	deP = &(thisP->debug);
hh
parents:
diff changeset
   269
	DEBID("%sSSL %s node %d", ssl ? "" : "non", topo==mash ? "MASH" : "RING", port);
hh
parents:
diff changeset
   270
	LOG(4, "initializing...");
hh
parents:
diff changeset
   271
	dataP = &thisP->data;
hh
parents:
diff changeset
   272
	Data(dataP, deP);
hh
parents:
diff changeset
   273
	thisP->topo = topo;
hh
parents:
diff changeset
   274
	thisP->locPort = port;
hh
parents:
diff changeset
   275
	thisP->first = first;
hh
parents:
diff changeset
   276
	thisP->last = first + n - 1;
hh
parents:
diff changeset
   277
	thisP->nodes = n;
hh
parents:
diff changeset
   278
	thisP->cliSides = malloc(n*sizeof(SocketT));
hh
parents:
diff changeset
   279
	thisP->srvSides = malloc(n*sizeof(SocketT));
hh
parents:
diff changeset
   280
	for(int k=0; k<n; k++) 	thisP->cliSides[k].sc = thisP->srvSides[k].sc = -1;
hh
parents:
diff changeset
   281
	thisP->kicker = (port == first);
hh
parents:
diff changeset
   282
	thisP->forw = forw;
hh
parents:
diff changeset
   283
	thisP->nodeIdx = port - first;
hh
parents:
diff changeset
   284
	thisP->closing = 0;
hh
parents:
diff changeset
   285
	thisP->ssl = ssl;
hh
parents:
diff changeset
   286
	if(thisP->ssl) {
hh
parents:
diff changeset
   287
		char s[64];
hh
parents:
diff changeset
   288
		SSL_load_error_strings();
hh
parents:
diff changeset
   289
		SSL_library_init();
hh
parents:
diff changeset
   290
		LOG(4, "setting SSL contex...");
hh
parents:
diff changeset
   291
		if(!(thisP->ctx = SSL_CTX_new(TLS_method()))) SSLERR("new SSL CTX");
hh
parents:
diff changeset
   292
		SSL_CTX_set_mode(thisP->ctx, SSL_MODE_AUTO_RETRY);
hh
parents:
diff changeset
   293
		SSL_CTX_set_verify(thisP->ctx, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
hh
parents:
diff changeset
   294
		sprintf(s, "%s/keys/%d.key", csP->ceP, thisP->locPort);
hh
parents:
diff changeset
   295
		if(SSL_CTX_use_PrivateKey_file(thisP->ctx, s, SSL_FILETYPE_PEM) != 1) SSLERR("hh's key file");
hh
parents:
diff changeset
   296
		sprintf(s, "%s/certs/%d.pem", csP->ceP, thisP->locPort);
hh
parents:
diff changeset
   297
		LOG(5, "SSL private key used: %s", s);
hh
parents:
diff changeset
   298
		if(SSL_CTX_use_certificate_file(thisP->ctx, s, SSL_FILETYPE_PEM) != 1) SSLERR("hh's cert file");
hh
parents:
diff changeset
   299
		LOG(5, "SSL certificate used: %s", s);
hh
parents:
diff changeset
   300
		if(SSL_CTX_load_verify_locations(thisP->ctx, NULL, csP->caP) != 1)	SSLERR("hh's thrusted certs path");
hh
parents:
diff changeset
   301
	}
hh
parents:
diff changeset
   302
	LOG(5, "initalized");
hh
parents:
diff changeset
   303
hh
parents:
diff changeset
   304
	bindN(thisP);
hh
parents:
diff changeset
   305
	if(thisP->kicker) {
hh
parents:
diff changeset
   306
		loadData(dataP, csP->ttl, csP->text);
hh
parents:
diff changeset
   307
		int sci, next;
hh
parents:
diff changeset
   308
		next = next_node(); sci = next - thisP->first;
hh
parents:
diff changeset
   309
		char digest[24];
hh
parents:
diff changeset
   310
		LOG(1, "KICKER: ready to initial send %s, len=%d to node %d", digest24Data(dataP, digest), dataP->dataLen, next);
hh
parents:
diff changeset
   311
		conn(sci, next);
hh
parents:
diff changeset
   312
		putN(sci);
hh
parents:
diff changeset
   313
	}
hh
parents:
diff changeset
   314
hh
parents:
diff changeset
   315
	main_loop();
hh
parents:
diff changeset
   316
hh
parents:
diff changeset
   317
	LOG(5, "closing ssc");
hh
parents:
diff changeset
   318
	close(thisP->ssc);
hh
parents:
diff changeset
   319
	if(thisP->closing) {		// wait for closing thread
hh
parents:
diff changeset
   320
		if(pthread_join(thisP->closingThread, NULL) != 0) SYSERR("join closing thread"); }
hh
parents:
diff changeset
   321
	struct sigaction sigact;
hh
parents:
diff changeset
   322
	sigfillset(&sigact.sa_mask);
hh
parents:
diff changeset
   323
	sigact.sa_handler=sighandle;
hh
parents:
diff changeset
   324
	if(sigaction(SIGUSR2,&sigact,NULL) < 0) SYSERR("sigaction");
hh
parents:
diff changeset
   325
	if(sem_wait(&csP->shP->counterSem) < 0) SYSERR("sem_wait");
hh
parents:
diff changeset
   326
	int active = --csP->shP->act;
hh
parents:
diff changeset
   327
	if(sem_post(&csP->shP->counterSem) < 0) SYSERR("sem_post");
hh
parents:
diff changeset
   328
	if(active > 0)	pause();
hh
parents:
diff changeset
   329
	else kill(0, SIGUSR2);
hh
parents:
diff changeset
   330
	int exitRc = EXIT_SUCCESS;
hh
parents:
diff changeset
   331
	if(thisP->kicker && !chkData(dataP)) {
hh
parents:
diff changeset
   332
		SOFTERR("INPUT AND OUTPUT DIFFER");
hh
parents:
diff changeset
   333
		exitRc = EXIT_FAILURE; }
hh
parents:
diff changeset
   334
	LOG(2, "ended");
hh
parents:
diff changeset
   335
	exit(exitRc);
hh
parents:
diff changeset
   336
}