diff options
author | Koichiro IWAO <meta@vmeta.jp> | 2015-06-11 21:22:40 +0900 |
---|---|---|
committer | Koichiro IWAO <meta@vmeta.jp> | 2015-06-11 21:45:57 +0900 |
commit | 2a2b8bcd59deb3e2c4875dcf856071bd3936aa1e (patch) | |
tree | 1071807ca3363bc1038a9af1f77f35ed3f03206f /common | |
parent | 9fb02e381de377414526003b5d998573d10e55f7 (diff) | |
download | xrdp-proprietary-2a2b8bcd59deb3e2c4875dcf856071bd3936aa1e.tar.gz xrdp-proprietary-2a2b8bcd59deb3e2c4875dcf856071bd3936aa1e.zip |
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
Diffstat (limited to 'common')
-rw-r--r-- | common/ssl_calls.c | 106 |
1 files 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; |