diff options
author | Matt Caswell <matt@openssl.org> | 2016-05-20 11:20:22 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2016-05-27 15:18:35 +0100 |
commit | 384f08dc76e4df2c004042bd9b1bad60f98c281f (patch) | |
tree | 27d3d8e1a582f099dd4f796b1e3706e417d01dca /apps/s_server.c | |
parent | ec91f92ddf74bea473148674aff25410311edaab (diff) | |
download | openssl-384f08dc76e4df2c004042bd9b1bad60f98c281f.tar.gz |
Fix some s_server issues on Windows
In s_server we call BIO_sock_should_retry() to determine the state of the
socket and work out whether we should retry an operation on it or not.
However if you leave it too long to call this then other operations may
have occurred in the meantime which affect the result. Therefore we should
call it early and remember the result for when we need to use it. This fixes
a test problem on Windows.
Another issue with s_server on Windows is that some of output to stdout does
not get displayed immediately. Apparently more liberal use of BIO_flush is
required.
RT#4255
Reviewed-by: Richard Levitte <levitte@openssl.org>
Diffstat (limited to 'apps/s_server.c')
-rw-r--r-- | apps/s_server.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/apps/s_server.c b/apps/s_server.c index 35baac91d9..7271b611ef 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -2309,12 +2309,14 @@ static int sv_body(int s, int stype, unsigned char *context) break; case SSL_ERROR_WANT_ASYNC: BIO_printf(bio_s_out, "Write BLOCK (Async)\n"); + (void)BIO_flush(bio_s_out); wait_for_async(con); break; case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_X509_LOOKUP: BIO_printf(bio_s_out, "Write BLOCK\n"); + (void)BIO_flush(bio_s_out); break; case SSL_ERROR_WANT_ASYNC_JOB: /* @@ -2383,16 +2385,19 @@ static int sv_body(int s, int stype, unsigned char *context) ascii2ebcdic(buf, buf, i); #endif raw_write_stdout(buf, (unsigned int)i); + (void)BIO_flush(bio_s_out); if (SSL_has_pending(con)) goto again; break; case SSL_ERROR_WANT_ASYNC: BIO_printf(bio_s_out, "Read BLOCK (Async)\n"); + (void)BIO_flush(bio_s_out); wait_for_async(con); break; case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: BIO_printf(bio_s_out, "Read BLOCK\n"); + (void)BIO_flush(bio_s_out); break; case SSL_ERROR_WANT_ASYNC_JOB: /* @@ -2448,6 +2453,7 @@ static int init_ssl_connection(SSL *con) unsigned next_proto_neg_len; #endif unsigned char *exportedkeymat; + int retry = 0; #ifndef OPENSSL_NO_DTLS if(dtlslisten) { @@ -2482,6 +2488,8 @@ static int init_ssl_connection(SSL *con) do { i = SSL_accept(con); + if (i <= 0) + retry = BIO_sock_should_retry(i); #ifdef CERT_CB_TEST_RETRY { while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP @@ -2489,6 +2497,8 @@ static int init_ssl_connection(SSL *con) BIO_printf(bio_err, "LOOKUP from certificate callback during accept\n"); i = SSL_accept(con); + if (i <= 0) + retry = BIO_sock_should_retry(i); } } #endif @@ -2507,13 +2517,15 @@ static int init_ssl_connection(SSL *con) else BIO_printf(bio_s_out, "LOOKUP not successful\n"); i = SSL_accept(con); + if (i <= 0) + retry = BIO_sock_should_retry(i); } #endif } while (i < 0 && SSL_waiting_for_async(con)); if (i <= 0) { if ((dtlslisten && i == 0) - || (!dtlslisten && BIO_sock_should_retry(i))) { + || (!dtlslisten && retry)) { BIO_printf(bio_s_out, "DELAY\n"); return (1); } @@ -2599,6 +2611,7 @@ static int init_ssl_connection(SSL *con) OPENSSL_free(exportedkeymat); } + (void)BIO_flush(bio_s_out); return (1); } |