version 1.210, 2019/11/04 17:33:28 |
version 1.211, 2019/11/13 04:10:38 |
|
|
readwrite(int net_fd, struct tls *tls_ctx) |
readwrite(int net_fd, struct tls *tls_ctx) |
{ |
{ |
struct pollfd pfd[4]; |
struct pollfd pfd[4]; |
|
int gone[4] = { 0 }; |
int stdin_fd = STDIN_FILENO; |
int stdin_fd = STDIN_FILENO; |
int stdout_fd = STDOUT_FILENO; |
int stdout_fd = STDOUT_FILENO; |
unsigned char netinbuf[BUFSIZE]; |
unsigned char netinbuf[BUFSIZE]; |
size_t netinbufpos = 0; |
size_t netinbufpos = 0; |
unsigned char stdinbuf[BUFSIZE]; |
unsigned char stdinbuf[BUFSIZE]; |
size_t stdinbufpos = 0; |
size_t stdinbufpos = 0; |
int n, num_fds; |
int n, num_fds, shutdown_netin, shutdown_netout; |
ssize_t ret; |
ssize_t ret; |
|
|
/* don't read from stdin if requested */ |
/* don't read from stdin if requested */ |
|
|
pfd[POLL_STDOUT].fd = stdout_fd; |
pfd[POLL_STDOUT].fd = stdout_fd; |
pfd[POLL_STDOUT].events = 0; |
pfd[POLL_STDOUT].events = 0; |
|
|
|
/* used to indicate we wish to shut down the network socket */ |
|
shutdown_netin = shutdown_netout = 0; |
|
|
while (1) { |
while (1) { |
/* both inputs are gone, buffers are empty, we are done */ |
/* both inputs are gone, buffers are empty, we are done */ |
if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1 && |
if (gone[POLL_STDIN] && gone[POLL_NETIN] && |
stdinbufpos == 0 && netinbufpos == 0) |
stdinbufpos == 0 && netinbufpos == 0) |
return; |
return; |
/* both outputs are gone, we can't continue */ |
/* both outputs are gone, we can't continue */ |
if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) |
if (gone[POLL_NETOUT] && gone[POLL_STDOUT]) |
return; |
return; |
/* listen and net in gone, queues empty, done */ |
/* listen and net in gone, queues empty, done */ |
if (lflag && pfd[POLL_NETIN].fd == -1 && |
if (lflag && gone[POLL_NETIN] && stdinbufpos == 0 |
stdinbufpos == 0 && netinbufpos == 0) |
&& netinbufpos == 0) |
return; |
return; |
|
|
/* help says -i is for "wait between lines sent". We read and |
/* help says -i is for "wait between lines sent". We read and |
|
|
if (iflag) |
if (iflag) |
sleep(iflag); |
sleep(iflag); |
|
|
|
/* If it's gone, take it away from poll */ |
|
for (n = 0; n < 4; n++) { |
|
if (gone[n]) |
|
pfd[n].events = pfd[n].revents = 0; |
|
} |
|
|
/* poll */ |
/* poll */ |
num_fds = poll(pfd, 4, timeout); |
num_fds = poll(pfd, 4, timeout); |
|
|
|
|
/* treat socket error conditions */ |
/* treat socket error conditions */ |
for (n = 0; n < 4; n++) { |
for (n = 0; n < 4; n++) { |
if (pfd[n].revents & (POLLERR|POLLNVAL)) { |
if (pfd[n].revents & (POLLERR|POLLNVAL)) { |
pfd[n].fd = -1; |
gone[n] = 1; |
} |
} |
} |
} |
/* reading is possible after HUP */ |
/* reading is possible after HUP */ |
if (pfd[POLL_STDIN].events & POLLIN && |
if (pfd[POLL_STDIN].events & POLLIN && |
pfd[POLL_STDIN].revents & POLLHUP && |
pfd[POLL_STDIN].revents & POLLHUP && |
!(pfd[POLL_STDIN].revents & POLLIN)) |
!(pfd[POLL_STDIN].revents & POLLIN)) |
pfd[POLL_STDIN].fd = -1; |
gone[POLL_STDIN] = 1; |
|
|
if (pfd[POLL_NETIN].events & POLLIN && |
if (pfd[POLL_NETIN].events & POLLIN && |
pfd[POLL_NETIN].revents & POLLHUP && |
pfd[POLL_NETIN].revents & POLLHUP && |
!(pfd[POLL_NETIN].revents & POLLIN)) |
!(pfd[POLL_NETIN].revents & POLLIN)) |
pfd[POLL_NETIN].fd = -1; |
gone[POLL_NETIN] = 1; |
|
|
if (pfd[POLL_NETOUT].revents & POLLHUP) { |
if (pfd[POLL_NETOUT].revents & POLLHUP) { |
if (Nflag) |
if (Nflag) |
shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); |
shutdown_netout = 1; |
pfd[POLL_NETOUT].fd = -1; |
gone[POLL_NETOUT] = 1; |
} |
} |
/* if HUP, stop watching stdout */ |
|
if (pfd[POLL_STDOUT].revents & POLLHUP) |
|
pfd[POLL_STDOUT].fd = -1; |
|
/* if no net out, stop watching stdin */ |
/* if no net out, stop watching stdin */ |
if (pfd[POLL_NETOUT].fd == -1) |
if (gone[POLL_NETOUT]) |
pfd[POLL_STDIN].fd = -1; |
gone[POLL_STDIN] = 1; |
|
|
|
/* if stdout HUP's, stop watching stdout */ |
|
if (pfd[POLL_STDOUT].revents & POLLHUP) |
|
gone[POLL_STDOUT] = 1; |
/* if no stdout, stop watching net in */ |
/* if no stdout, stop watching net in */ |
if (pfd[POLL_STDOUT].fd == -1) { |
if (gone[POLL_STDOUT]) { |
if (pfd[POLL_NETIN].fd != -1) |
shutdown_netin = 1; |
shutdown(pfd[POLL_NETIN].fd, SHUT_RD); |
gone[POLL_NETIN] = 1; |
pfd[POLL_NETIN].fd = -1; |
|
} |
} |
|
|
/* try to read from stdin */ |
/* try to read from stdin */ |
|
|
else if (ret == TLS_WANT_POLLOUT) |
else if (ret == TLS_WANT_POLLOUT) |
pfd[POLL_STDIN].events = POLLOUT; |
pfd[POLL_STDIN].events = POLLOUT; |
else if (ret == 0 || ret == -1) |
else if (ret == 0 || ret == -1) |
pfd[POLL_STDIN].fd = -1; |
gone[POLL_STDIN] = 1; |
/* read something - poll net out */ |
/* read something - poll net out */ |
if (stdinbufpos > 0) |
if (stdinbufpos > 0) |
pfd[POLL_NETOUT].events = POLLOUT; |
pfd[POLL_NETOUT].events = POLLOUT; |
|
|
else if (ret == TLS_WANT_POLLOUT) |
else if (ret == TLS_WANT_POLLOUT) |
pfd[POLL_NETOUT].events = POLLOUT; |
pfd[POLL_NETOUT].events = POLLOUT; |
else if (ret == -1) |
else if (ret == -1) |
pfd[POLL_NETOUT].fd = -1; |
gone[POLL_NETOUT] = 1; |
/* buffer empty - remove self from polling */ |
/* buffer empty - remove self from polling */ |
if (stdinbufpos == 0) |
if (stdinbufpos == 0) |
pfd[POLL_NETOUT].events = 0; |
pfd[POLL_NETOUT].events = 0; |
|
|
else if (ret == TLS_WANT_POLLOUT) |
else if (ret == TLS_WANT_POLLOUT) |
pfd[POLL_NETIN].events = POLLOUT; |
pfd[POLL_NETIN].events = POLLOUT; |
else if (ret == -1) |
else if (ret == -1) |
pfd[POLL_NETIN].fd = -1; |
gone[POLL_NETIN] = 1; |
/* eof on net in - remove from pfd */ |
/* eof on net in - remove from pfd */ |
if (ret == 0) { |
if (ret == 0) { |
shutdown(pfd[POLL_NETIN].fd, SHUT_RD); |
gone[POLL_NETIN] = 1; |
pfd[POLL_NETIN].fd = -1; |
|
} |
} |
if (recvlimit > 0 && ++recvcount >= recvlimit) { |
if (recvlimit > 0 && ++recvcount >= recvlimit) { |
if (pfd[POLL_NETIN].fd != -1) |
shutdown_netin = 1; |
shutdown(pfd[POLL_NETIN].fd, SHUT_RD); |
gone[POLL_NETIN] = 1; |
pfd[POLL_NETIN].fd = -1; |
gone[POLL_STDIN] = 1; |
pfd[POLL_STDIN].fd = -1; |
|
} |
} |
/* read something - poll stdout */ |
/* read something - poll stdout */ |
if (netinbufpos > 0) |
if (netinbufpos > 0) |
|
|
else if (ret == TLS_WANT_POLLOUT) |
else if (ret == TLS_WANT_POLLOUT) |
pfd[POLL_STDOUT].events = POLLOUT; |
pfd[POLL_STDOUT].events = POLLOUT; |
else if (ret == -1) |
else if (ret == -1) |
pfd[POLL_STDOUT].fd = -1; |
gone[POLL_STDOUT] = 1; |
/* buffer empty - remove self from polling */ |
/* buffer empty - remove self from polling */ |
if (netinbufpos == 0) |
if (netinbufpos == 0) |
pfd[POLL_STDOUT].events = 0; |
pfd[POLL_STDOUT].events = 0; |
|
|
} |
} |
|
|
/* stdin gone and queue empty? */ |
/* stdin gone and queue empty? */ |
if (pfd[POLL_STDIN].fd == -1 && stdinbufpos == 0) { |
if (gone[POLL_STDIN] && stdinbufpos == 0) { |
if (pfd[POLL_NETOUT].fd != -1 && Nflag) |
if (Nflag) { |
shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); |
shutdown_netin = 1; |
pfd[POLL_NETOUT].fd = -1; |
shutdown_netout = 1; |
|
} |
|
gone[POLL_NETOUT] = 1; |
} |
} |
/* net in gone and queue empty? */ |
/* net in gone and queue empty? */ |
if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) { |
if (gone[POLL_NETIN] && netinbufpos == 0) { |
pfd[POLL_STDOUT].fd = -1; |
if (Nflag) { |
|
shutdown_netin = 1; |
|
shutdown_netout = 1; |
|
} |
|
gone[POLL_STDOUT] = 1; |
|
} |
|
|
|
/* call tls_close if any part of the network socket is closing */ |
|
if ((shutdown_netin || shutdown_netout) && usetls) { |
|
timeout_tls(pfd[POLL_NETIN].fd, tls_ctx, tls_close); |
|
shutdown_netout = shutdown_netin = 1; |
|
} |
|
if (shutdown_netin) { |
|
shutdown(pfd[POLL_NETIN].fd, SHUT_RD); |
|
gone[POLL_NETIN] = 1; |
|
} |
|
if (shutdown_netout) { |
|
shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); |
|
gone[POLL_NETOUT] = 1; |
} |
} |
} |
} |
} |
} |