summaryrefslogtreecommitdiff
path: root/src/sbearssl/sbearssl_run.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2017-03-22 21:37:30 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2017-03-22 21:37:30 +0000
commitdddbfab568d42e443f102d35c84432824cc59fee (patch)
tree4983b1f5b44f861a3abc60ba7d47476820fcbb2f /src/sbearssl/sbearssl_run.c
parent6278e21405c40df65f8de6a9799576d1eb346164 (diff)
downloads6-networking-dddbfab568d42e443f102d35c84432824cc59fee.tar.xz
Fix case where s6-tls[cd] would sometimes not detect an application and remain there forever with its zombie, both condemned to err in limbo for all eternity, the living and the dead, hand in hand
Diffstat (limited to 'src/sbearssl/sbearssl_run.c')
-rw-r--r--src/sbearssl/sbearssl_run.c60
1 files changed, 46 insertions, 14 deletions
diff --git a/src/sbearssl/sbearssl_run.c b/src/sbearssl/sbearssl_run.c
index ca4a79e..26a8bd3 100644
--- a/src/sbearssl/sbearssl_run.c
+++ b/src/sbearssl/sbearssl_run.c
@@ -1,7 +1,6 @@
/* ISC license. */
#include <skalibs/nonposix.h>
-#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <signal.h>
@@ -12,13 +11,33 @@
#include <skalibs/tai.h>
#include <skalibs/iopause.h>
#include <skalibs/djbunix.h>
+#include <skalibs/selfpipe.h>
#include <s6-networking/sbearssl.h>
-int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity, uint32_t options, tain_t const *tto)
+static inline void handle_signals (pid_t pid, int *e)
{
- iopause_fd x[4] ;
+ for (;;) switch (selfpipe_read())
+ {
+ case -1 : strerr_diefu1sys(111, "read selfpipe") ;
+ case 0 : return ;
+ case SIGCHLD :
+ {
+ int wstat ;
+ if (wait_pid_nohang(pid, &wstat) == pid)
+ {
+ *e = wstat ;
+ return ;
+ }
+ }
+ }
+}
+
+int sbearssl_run (br_ssl_engine_context *ctx, int *fds, pid_t pid, unsigned int verbosity, uint32_t options, tain_t const *tto)
+{
+ iopause_fd x[5] = { { .fd = fds[4], .events = IOPAUSE_READ } } ;
unsigned int xindex[4] ;
int markedforflush = 0 ;
+ int e = -1 ;
if (ndelay_on(fds[2]) < 0 || ndelay_on(fds[3]) < 0)
strerr_diefu1sys(111, "set fds non-blocking") ;
@@ -28,11 +47,16 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity,
for (;;)
{
tain_t deadline ;
- unsigned int j = 0 ;
+ unsigned int j = 1 ;
unsigned int state = br_ssl_engine_current_state(ctx) ;
int r ;
- if (state & BR_SSL_CLOSED) break ;
+ if (state & BR_SSL_CLOSED)
+ {
+ r = br_ssl_engine_last_error(ctx) ;
+ if (r) strerr_diefu2x(98, "establish or maintain SSL connection to peer: ", sbearssl_error_str(r)) ;
+ break ;
+ }
tain_add_g(&deadline, fds[0] >= 0 && fds[2] >= 0 && state & (BR_SSL_SENDAPP | BR_SSL_RECVREC) ? tto : &tain_infinite_relative) ;
@@ -42,30 +66,30 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity,
x[j].events = IOPAUSE_READ ;
xindex[0] = j++ ;
}
- else xindex[0] = 4 ;
+ else xindex[0] = 5 ;
if (fds[1] >= 0 && state & BR_SSL_RECVAPP)
{
x[j].fd = fds[1] ;
x[j].events = IOPAUSE_WRITE ;
xindex[1] = j++ ;
}
- else xindex[1] = 4 ;
+ else xindex[1] = 5 ;
if (fds[2] >= 0 && state & BR_SSL_RECVREC)
{
x[j].fd = fds[2] ;
x[j].events = IOPAUSE_READ ;
xindex[2] = j++ ;
}
- else xindex[2] = 4 ;
+ else xindex[2] = 5 ;
if (fds[3] >= 0 && state & BR_SSL_SENDREC)
{
x[j].fd = fds[3] ;
x[j].events = IOPAUSE_WRITE ;
xindex[3] = j++ ;
}
- else xindex[3] = 4 ;
+ else xindex[3] = 5 ;
- if (!j) break ;
+ if (j == 1) break ;
r = iopause_g(x, j, &deadline) ;
if (r < 0) strerr_diefu1sys(111, "iopause") ;
else if (!r)
@@ -77,6 +101,7 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity,
fd_close(fds[3]) ; fds[3] = -1 ;
}
else br_ssl_engine_close(ctx) ;
+ if (e >= 0) break ;
continue ;
}
@@ -85,6 +110,11 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity,
x[j].revents |= IOPAUSE_READ | IOPAUSE_WRITE ;
+ /* Signal */
+
+ if (x[0].revents & IOPAUSE_READ) handle_signals(pid, &e) ;
+
+
/* Flush to local */
if (state & BR_SSL_RECVAPP && x[xindex[1]].events & x[xindex[1]].revents & IOPAUSE_WRITE)
@@ -111,7 +141,7 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity,
/* Flush to remote */
- if (state & BR_SSL_SENDREC && x[xindex[3]].events & x[xindex[3]].revents & IOPAUSE_WRITE)
+ if (state & BR_SSL_SENDREC && xindex[3] < 5 && x[xindex[3]].events & x[xindex[3]].revents & IOPAUSE_WRITE)
{
size_t len ;
unsigned char const *s = br_ssl_engine_sendrec_buf(ctx, &len) ;
@@ -132,6 +162,7 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity,
fd_close(fds[3]) ; fds[3] = -1 ;
}
else br_ssl_engine_close(ctx) ;
+ if (e >= 0) break ;
}
state = br_ssl_engine_current_state(ctx) ;
}
@@ -140,7 +171,7 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity,
/* Fill from local */
- if (state & BR_SSL_SENDAPP && x[xindex[0]].events & IOPAUSE_READ && (markedforflush || x[xindex[0]].revents & IOPAUSE_READ))
+ if (state & BR_SSL_SENDAPP && xindex[0] < 5 && x[xindex[0]].events & IOPAUSE_READ && (markedforflush || x[xindex[0]].revents & IOPAUSE_READ))
{
size_t len ;
unsigned char *s = br_ssl_engine_sendapp_buf(ctx, &len) ;
@@ -160,6 +191,7 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity,
fd_close(fds[3]) ; fds[3] = -1 ;
}
else br_ssl_engine_close(ctx) ;
+ if (e >= 0) break ;
}
}
}
@@ -179,7 +211,7 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity,
/* Fill from remote */
- if (state & BR_SSL_RECVREC && x[xindex[2]].events & x[xindex[2]].revents & IOPAUSE_READ)
+ if (state & BR_SSL_RECVREC && xindex[2] < 5 && x[xindex[2]].events & x[xindex[2]].revents & IOPAUSE_READ)
{
size_t len ;
unsigned char *s = br_ssl_engine_recvrec_buf(ctx, &len) ;
@@ -204,5 +236,5 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity,
if (fds[0] >= 0) fd_close(fds[0]) ;
if (fds[3] >= 0) fd_close(fds[3]) ;
if (fds[2] >= 0) fd_close(fds[2]) ;
- return br_ssl_engine_last_error(ctx) ;
+ return e ;
}