summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2014-12-02 19:44:50 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2014-12-02 19:44:50 +0000
commiteed9dcb825905471e4cc4a3f1e2570d610554c79 (patch)
tree9ddbd7ee27cfdb0305b16ee18dd88eff028162b0
parent1f7da40c302ab4440dc517e5cd98755d8a334664 (diff)
convert select() to poll(). This is one of the most complicated
conversions in the tree, because the original code is very rotten and fragile. Please test and report any failures. Assistance from millert, bcook, and jsing.
-rw-r--r--usr.bin/openssl/s_client.c67
-rw-r--r--usr.bin/openssl/s_server.c36
2 files changed, 63 insertions, 40 deletions
diff --git a/usr.bin/openssl/s_client.c b/usr.bin/openssl/s_client.c
index 988d799b97c..94e24dacaae 100644
--- a/usr.bin/openssl/s_client.c
+++ b/usr.bin/openssl/s_client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s_client.c,v 1.8 2014/11/18 20:54:28 krw Exp $ */
+/* $OpenBSD: s_client.c,v 1.9 2014/12/02 19:44:49 deraadt Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -137,7 +137,6 @@
#include <sys/types.h>
#include <sys/ioctl.h>
-#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -150,6 +149,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <poll.h>
#include "apps.h"
@@ -334,11 +334,10 @@ s_client_main(int argc, char **argv)
{
unsigned int off = 0, clr = 0;
SSL *con = NULL;
- int s, k, width, state = 0, af = AF_UNSPEC;
+ int s, k, state = 0, af = AF_UNSPEC;
char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL;
int cbuf_len, cbuf_off;
int sbuf_len, sbuf_off;
- fd_set readfds, writefds;
char *port = PORT_STR;
int full_log = 1;
char *host = SSL_HOST_NAME;
@@ -361,7 +360,7 @@ s_client_main(int argc, char **argv)
int socket_type = SOCK_STREAM;
BIO *sbio;
int mbuf_len = 0;
- struct timeval timeout, *timeoutp;
+ struct timeval timeout;
const char *errstr = NULL;
#ifndef OPENSSL_NO_ENGINE
char *engine_id = NULL;
@@ -874,8 +873,6 @@ re_start:
SSL_set_connect_state(con);
/* ok, lets connect */
- width = SSL_get_fd(con) + 1;
-
read_tty = 1;
write_tty = 0;
tty_on = 0;
@@ -991,14 +988,12 @@ re_start:
mbuf[0] = 0;
}
for (;;) {
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
+ struct pollfd pfd[3]; /* stdin, stdout, socket */
+ int ptimeout = -1;
if ((SSL_version(con) == DTLS1_VERSION) &&
DTLSv1_get_timeout(con, &timeout))
- timeoutp = &timeout;
- else
- timeoutp = NULL;
+ ptimeout = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;
if (SSL_in_init(con) && !SSL_total_renegotiations(con)) {
in_init = 1;
@@ -1038,24 +1033,31 @@ re_start:
ssl_pending = read_ssl && SSL_pending(con);
- /* XXX should add tests for fd_set overflow */
-
+ pfd[0].fd = -1;
+ pfd[1].fd = -1;
if (!ssl_pending) {
if (tty_on) {
- if (read_tty)
- FD_SET(fileno(stdin), &readfds);
- if (write_tty)
- FD_SET(fileno(stdout), &writefds);
+ if (read_tty) {
+ pfd[0].fd = fileno(stdin);
+ pfd[0].events = POLLIN;
+ }
+ if (write_tty) {
+ pfd[1].fd = fileno(stdout);
+ pfd[1].events = POLLOUT;
+ }
}
+
+ pfd[2].fd = SSL_get_fd(con);
+ pfd[2].events = 0;
if (read_ssl)
- FD_SET(SSL_get_fd(con), &readfds);
+ pfd[2].events |= POLLIN;
if (write_ssl)
- FD_SET(SSL_get_fd(con), &writefds);
+ pfd[2].events |= POLLOUT;
+
/* printf("mode tty(%d %d%d) ssl(%d%d)\n",
tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
- i = select(width, &readfds, &writefds,
- NULL, timeoutp);
+ i = poll(pfd, 3, ptimeout);
if (i < 0) {
BIO_printf(bio_err, "bad select %d\n",
errno);
@@ -1066,7 +1068,11 @@ re_start:
if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0) {
BIO_printf(bio_err, "TIMEOUT occured\n");
}
- if (!ssl_pending && FD_ISSET(SSL_get_fd(con), &writefds)) {
+ if (!ssl_pending && (pfd[2].revents & (POLLOUT|POLLERR|POLLNVAL))) {
+ if (pfd[2].revents & (POLLERR|POLLNVAL)) {
+ BIO_printf(bio_err, "poll error");
+ goto shut;
+ }
k = SSL_write(con, &(cbuf[cbuf_off]),
(unsigned int) cbuf_len);
switch (SSL_get_error(con, k)) {
@@ -1123,7 +1129,12 @@ re_start:
ERR_print_errors(bio_err);
goto shut;
}
- } else if (!ssl_pending && FD_ISSET(fileno(stdout), &writefds)) {
+ } else if (!ssl_pending &&
+ (pfd[1].revents & (POLLOUT|POLLERR|POLLNVAL))) {
+ if (pfd[1].revents & (POLLERR|POLLNVAL)) {
+ BIO_printf(bio_err, "poll error");
+ goto shut;
+ }
i = write(fileno(stdout), &(sbuf[sbuf_off]), sbuf_len);
if (i <= 0) {
@@ -1138,7 +1149,7 @@ re_start:
read_ssl = 1;
write_tty = 0;
}
- } else if (ssl_pending || FD_ISSET(SSL_get_fd(con), &readfds)) {
+ } else if (ssl_pending || (pfd[2].revents & (POLLIN|POLLHUP))) {
#ifdef RENEG
{
static int iiii;
@@ -1188,7 +1199,11 @@ re_start:
goto shut;
/* break; */
}
- } else if (FD_ISSET(fileno(stdin), &readfds)) {
+ } else if (pfd[0].revents) {
+ if (pfd[0].revents & (POLLERR|POLLNVAL)) {
+ BIO_printf(bio_err, "poll error");
+ goto shut;
+ }
if (crlf) {
int j, lf_num;
diff --git a/usr.bin/openssl/s_server.c b/usr.bin/openssl/s_server.c
index 1e6f85f9fbb..b3cdb30a61f 100644
--- a/usr.bin/openssl/s_server.c
+++ b/usr.bin/openssl/s_server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s_server.c,v 1.6 2014/11/06 14:50:12 jsing Exp $ */
+/* $OpenBSD: s_server.c,v 1.7 2014/12/02 19:44:49 deraadt Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -148,7 +148,6 @@
#include <sys/types.h>
#include <sys/ioctl.h>
-#include <sys/select.h>
#include <sys/socket.h>
#include <assert.h>
@@ -158,6 +157,7 @@
#include <limits.h>
#include <string.h>
#include <unistd.h>
+#include <poll.h>
#include "apps.h"
@@ -1279,14 +1279,12 @@ static int
sv_body(char *hostname, int s, unsigned char *context)
{
char *buf = NULL;
- fd_set readfds;
- int ret = 1, width;
+ int ret = 1;
int k, i;
unsigned long l;
SSL *con = NULL;
BIO *sbio;
struct timeval timeout;
- struct timeval *timeoutp;
if ((buf = malloc(bufsize)) == NULL) {
BIO_printf(bio_err, "out of memory\n");
@@ -1366,35 +1364,45 @@ sv_body(char *hostname, int s, unsigned char *context)
SSL_set_tlsext_debug_arg(con, bio_s_out);
}
- width = s + 1;
for (;;) {
int read_from_terminal;
int read_from_sslcon;
+ struct pollfd pfd[2];
+ int ptimeout;
read_from_terminal = 0;
read_from_sslcon = SSL_pending(con);
if (!read_from_sslcon) {
- FD_ZERO(&readfds);
- FD_SET(fileno(stdin), &readfds);
- FD_SET(s, &readfds);
+ pfd[0].fd = fileno(stdin);
+ pfd[0].events = POLLIN;
+ pfd[1].fd = s;
+ pfd[1].events = POLLIN;
+
if ((SSL_version(con) == DTLS1_VERSION) &&
DTLSv1_get_timeout(con, &timeout))
- timeoutp = &timeout;
+ ptimeout = timeout.tv_sec * 1000 +
+ timeout.tv_usec / 1000;
else
- timeoutp = NULL;
+ ptimeout = -1;
- i = select(width, &readfds, NULL, NULL, timeoutp);
+ i = poll(pfd, 2, ptimeout);
if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0) {
BIO_printf(bio_err, "TIMEOUT occured\n");
}
if (i <= 0)
continue;
- if (FD_ISSET(fileno(stdin), &readfds))
+ if (pfd[0].revents) {
+ if ((pfd[0].revents & (POLLERR|POLLNVAL)))
+ continue;
read_from_terminal = 1;
- if (FD_ISSET(s, &readfds))
+ }
+ if (pfd[1].revents) {
+ if ((pfd[1].revents & (POLLERR|POLLNVAL)))
+ continue;
read_from_sslcon = 1;
+ }
}
if (read_from_terminal) {
if (s_crlf) {