[前][次][番号順一覧][スレッド一覧]

ruby-changes:65546

From: Kazuki <ko1@a...>
Date: Tue, 16 Mar 2021 20:39:11 +0900 (JST)
Subject: [ruby-changes:65546] 945ed40862 (master): [ruby/openssl] ssl: retry write on EPROTOTYPE on macOS

https://git.ruby-lang.org/ruby.git/commit/?id=945ed40862

From 945ed40862393778b1c991b00714dcaf73319c77 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@r...>
Date: Mon, 22 Oct 2018 10:26:33 +0900
Subject: [ruby/openssl] ssl: retry write on EPROTOTYPE on macOS

Errno::EPROTOTYPE is not supposed to be raised by SSLSocket#write.
However, on macOS, send(2) which is called via SSL_write() can
occasionally return EPROTOTYPE. Retry SSL_write() so that we get a
proper error, just as ext/socket does.

Reference: https://bugs.ruby-lang.org/issues/14713
Reference: https://github.com/ruby/openssl/issues/227

https://github.com/ruby/openssl/commit/2e700c80bf
---
 ext/openssl/ossl_ssl.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 4b7efa3..da5439f 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -1691,6 +1691,11 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L1691
             rb_io_wait_readable(fptr->fd);
             continue;
 	case SSL_ERROR_SYSCALL:
+#ifdef __APPLE__
+            /* See ossl_ssl_write_internal() */
+            if (errno == EPROTOTYPE)
+                continue;
+#endif
 	    if (errno) rb_sys_fail(funcname);
 	    ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
 #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
@@ -1982,6 +1987,16 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L1987
                 rb_io_wait_readable(fptr->fd);
                 continue;
 	    case SSL_ERROR_SYSCALL:
+#ifdef __APPLE__
+                /*
+                 * It appears that send syscall can return EPROTOTYPE if the
+                 * socket is being torn down. Retry to get a proper errno to
+                 * make the error handling in line with the socket library.
+                 * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
+                 */
+                if (errno == EPROTOTYPE)
+                    continue;
+#endif
 		if (errno) rb_sys_fail(0);
 	    default:
 		ossl_raise(eSSLError, "SSL_write");
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]