From 2a2b8bcd59deb3e2c4875dcf856071bd3936aa1e Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Thu, 11 Jun 2015 21:22:40 +0900 Subject: [PATCH 1/2] common: fix #248 TLS on FreeBSD According to document[1][2][3], retry when SSL_get_error returns SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE. [1] https://www.openssl.org/docs/ssl/SSL_read.html [2] https://www.openssl.org/docs/ssl/SSL_write.html [3] https://www.openssl.org/docs/ssl/SSL_accept.html --- common/ssl_calls.c | 106 ++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 31 deletions(-) diff --git a/common/ssl_calls.c b/common/ssl_calls.c index ae30fe71..8aa575df 100644 --- a/common/ssl_calls.c +++ b/common/ssl_calls.c @@ -669,13 +669,24 @@ ssl_tls_accept(struct ssl_tls *self) return 1; } - connection_status = SSL_accept(self->ssl); + while(1) { + connection_status = SSL_accept(self->ssl); - if (connection_status <= 0) - { - if (ssl_tls_print_error("SSL_accept", self->ssl, connection_status)) + if (connection_status <= 0) { - return 1; + if (ssl_tls_print_error("SSL_accept", self->ssl, connection_status)) + { + return 1; + } + /** + * retry when SSL_get_error returns: + * SSL_ERROR_WANT_READ + * SSL_ERROR_WANT_WRITE + */ + } + else + { + break; } } @@ -709,6 +720,11 @@ ssl_tls_disconnect(struct ssl_tls *self) { return 1; } + /** + * retry when SSL_get_error returns: + * SSL_ERROR_WANT_READ + * SSL_ERROR_WANT_WRITE + */ } } return 0; @@ -737,23 +753,37 @@ int APP_CC ssl_tls_read(struct ssl_tls *tls, char *data, int length) { int status; + int break_flag; - status = SSL_read(tls->ssl, data, length); + while(1) { + status = SSL_read(tls->ssl, data, length); - switch (SSL_get_error(tls->ssl, status)) - { - case SSL_ERROR_NONE: - break; - - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - status = 0; - break; + switch (SSL_get_error(tls->ssl, status)) + { + case SSL_ERROR_NONE: + break_flag = 1; + break; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /** + * retry when SSL_get_error returns: + * SSL_ERROR_WANT_READ + * SSL_ERROR_WANT_WRITE + */ + continue; + + default: + ssl_tls_print_error("SSL_read", tls->ssl, status); + status = -1; + break_flag = 1; + break; + } - default: - ssl_tls_print_error("SSL_read", tls->ssl, status); - status = -1; + if (break_flag) + { break; + } } if (SSL_pending(tls->ssl) > 0) @@ -769,23 +799,37 @@ int APP_CC ssl_tls_write(struct ssl_tls *tls, const char *data, int length) { int status; + int break_flag; - status = SSL_write(tls->ssl, data, length); + while(1) { + status = SSL_write(tls->ssl, data, length); - switch (SSL_get_error(tls->ssl, status)) - { - case SSL_ERROR_NONE: - break; - - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - status = 0; - break; + switch (SSL_get_error(tls->ssl, status)) + { + case SSL_ERROR_NONE: + break_flag = 1; + break; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /** + * retry when SSL_get_error returns: + * SSL_ERROR_WANT_READ + * SSL_ERROR_WANT_WRITE + */ + continue; + + default: + ssl_tls_print_error("SSL_write", tls->ssl, status); + status = -1; + break_flag = 1; + break; + } - default: - ssl_tls_print_error("SSL_write", tls->ssl, status); - status = -1; + if (break_flag) + { break; + } } return status; From cd6ab20e947a0bad468c9a57f09555f64ce81eef Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Fri, 12 Jun 2015 13:03:07 +0900 Subject: [PATCH 2/2] common: shut up some messages in ssl_tls_print_error SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE are not fatal error but just indicate SSL_read, SSL_write, SSL_accept functions to repeat. --- common/ssl_calls.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/common/ssl_calls.c b/common/ssl_calls.c index 8aa575df..7bc33fcb 100644 --- a/common/ssl_calls.c +++ b/common/ssl_calls.c @@ -562,11 +562,7 @@ ssl_tls_print_error(char *func, SSL *connection, int value) return 1; case SSL_ERROR_WANT_READ: - g_writeln("ssl_tls_print_error: SSL_ERROR_WANT_READ"); - return 0; - case SSL_ERROR_WANT_WRITE: - g_writeln("ssl_tls_print_error: SSL_ERROR_WANT_WRITE"); return 0; case SSL_ERROR_SYSCALL: