Skip to content

Commit d2e1e9a

Browse files
authored
Merge pull request #980 from rhenium/ky/ssl-errors-peeraddr-errno
ssl: refactor errno access
2 parents 42a7846 + 46c9223 commit d2e1e9a

File tree

1 file changed

+36
-29
lines changed

1 file changed

+36
-29
lines changed

ext/openssl/ossl_ssl.c

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,26 +1590,24 @@ ossl_ssl_s_alloc(VALUE klass)
15901590
}
15911591

15921592
static VALUE
1593-
peer_ip_address(VALUE self)
1593+
peer_ip_address(VALUE io)
15941594
{
1595-
VALUE remote_address = rb_funcall(rb_attr_get(self, id_i_io), rb_intern("remote_address"), 0);
1595+
VALUE remote_address = rb_funcall(io, rb_intern("remote_address"), 0);
15961596

15971597
return rb_funcall(remote_address, rb_intern("inspect_sockaddr"), 0);
15981598
}
15991599

16001600
static VALUE
1601-
fallback_peer_ip_address(VALUE self, VALUE args)
1601+
fallback_peer_ip_address(VALUE self, VALUE exc)
16021602
{
16031603
return rb_str_new_cstr("(null)");
16041604
}
16051605

16061606
static VALUE
1607-
peeraddr_ip_str(VALUE self)
1607+
peeraddr_ip_str(VALUE io)
16081608
{
1609-
VALUE rb_mErrno = rb_const_get(rb_cObject, rb_intern("Errno"));
1610-
VALUE rb_eSystemCallError = rb_const_get(rb_mErrno, rb_intern("SystemCallError"));
1611-
1612-
return rb_rescue2(peer_ip_address, self, fallback_peer_ip_address, (VALUE)0, rb_eSystemCallError, NULL);
1609+
return rb_rescue2(peer_ip_address, io, fallback_peer_ip_address, Qnil,
1610+
rb_eSystemCallError, (VALUE)0);
16131611
}
16141612

16151613
/*
@@ -1714,11 +1712,15 @@ ossl_ssl_setup(VALUE self)
17141712
return Qtrue;
17151713
}
17161714

1715+
static int
1716+
errno_mapped(void)
1717+
{
17171718
#ifdef _WIN32
1718-
#define ssl_get_error(ssl, ret) (errno = rb_w32_map_errno(WSAGetLastError()), SSL_get_error((ssl), (ret)))
1719+
return rb_w32_map_errno(WSAGetLastError());
17191720
#else
1720-
#define ssl_get_error(ssl, ret) SSL_get_error((ssl), (ret))
1721+
return errno;
17211722
#endif
1723+
}
17221724

17231725
static void
17241726
write_would_block(int nonblock)
@@ -1759,35 +1761,34 @@ static void
17591761
io_wait_writable(VALUE io)
17601762
{
17611763
#ifdef HAVE_RB_IO_MAYBE_WAIT
1762-
if (!rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) {
1764+
if (!rb_io_wait(io, INT2NUM(RUBY_IO_WRITABLE), RUBY_IO_TIMEOUT_DEFAULT)) {
17631765
rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become writable!");
17641766
}
17651767
#else
17661768
rb_io_t *fptr;
17671769
GetOpenFile(io, fptr);
1768-
rb_io_wait_writable(fptr->fd);
1770+
rb_thread_fd_writable(fptr->fd);
17691771
#endif
17701772
}
17711773

17721774
static void
17731775
io_wait_readable(VALUE io)
17741776
{
17751777
#ifdef HAVE_RB_IO_MAYBE_WAIT
1776-
if (!rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) {
1778+
if (!rb_io_wait(io, INT2NUM(RUBY_IO_READABLE), RUBY_IO_TIMEOUT_DEFAULT)) {
17771779
rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become readable!");
17781780
}
17791781
#else
17801782
rb_io_t *fptr;
17811783
GetOpenFile(io, fptr);
1782-
rb_io_wait_readable(fptr->fd);
1784+
rb_thread_wait_fd(fptr->fd);
17831785
#endif
17841786
}
17851787

17861788
static VALUE
17871789
ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
17881790
{
17891791
SSL *ssl;
1790-
int ret, ret2;
17911792
VALUE cb_state;
17921793
int nonblock = opts != Qfalse;
17931794

@@ -1797,7 +1798,8 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
17971798

17981799
VALUE io = rb_attr_get(self, id_i_io);
17991800
for (;;) {
1800-
ret = func(ssl);
1801+
int ret = func(ssl);
1802+
int saved_errno = errno_mapped();
18011803

18021804
cb_state = rb_attr_get(self, ID_callback_state);
18031805
if (!NIL_P(cb_state)) {
@@ -1809,7 +1811,8 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
18091811
if (ret > 0)
18101812
break;
18111813

1812-
switch ((ret2 = ssl_get_error(ssl, ret))) {
1814+
int code = SSL_get_error(ssl, ret);
1815+
switch (code) {
18131816
case SSL_ERROR_WANT_WRITE:
18141817
if (no_exception_p(opts)) { return sym_wait_writable; }
18151818
write_would_block(nonblock);
@@ -1823,10 +1826,11 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
18231826
case SSL_ERROR_SYSCALL:
18241827
#ifdef __APPLE__
18251828
/* See ossl_ssl_write_internal() */
1826-
if (errno == EPROTOTYPE)
1829+
if (saved_errno == EPROTOTYPE)
18271830
continue;
18281831
#endif
1829-
if (errno) rb_sys_fail(funcname);
1832+
if (saved_errno)
1833+
rb_exc_raise(rb_syserr_new(saved_errno, funcname));
18301834
/* fallthrough */
18311835
default: {
18321836
VALUE error_append = Qnil;
@@ -1847,10 +1851,10 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
18471851
ossl_raise(eSSLError,
18481852
"%s%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s%"PRIsVALUE,
18491853
funcname,
1850-
ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "",
1851-
ret2,
1852-
errno,
1853-
peeraddr_ip_str(self),
1854+
code == SSL_ERROR_SYSCALL ? " SYSCALL" : "",
1855+
code,
1856+
saved_errno,
1857+
peeraddr_ip_str(io),
18541858
SSL_state_string_long(ssl),
18551859
error_append);
18561860
}
@@ -1992,6 +1996,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
19921996
for (;;) {
19931997
rb_str_locktmp(str);
19941998
int nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1999+
int saved_errno = errno_mapped();
19952000
rb_str_unlocktmp(str);
19962001

19972002
cb_state = rb_attr_get(self, ID_callback_state);
@@ -2001,7 +2006,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
20012006
rb_jump_tag(NUM2INT(cb_state));
20022007
}
20032008

2004-
switch (ssl_get_error(ssl, nread)) {
2009+
switch (SSL_get_error(ssl, nread)) {
20052010
case SSL_ERROR_NONE:
20062011
rb_str_set_len(str, nread);
20072012
return str;
@@ -2024,8 +2029,8 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
20242029
break;
20252030
case SSL_ERROR_SYSCALL:
20262031
if (!ERR_peek_error()) {
2027-
if (errno)
2028-
rb_sys_fail(0);
2032+
if (saved_errno)
2033+
rb_exc_raise(rb_syserr_new(saved_errno, "SSL_read"));
20292034
else {
20302035
/*
20312036
* The underlying BIO returned 0. This is actually a
@@ -2110,6 +2115,7 @@ ossl_ssl_write_internal_safe(VALUE _args)
21102115

21112116
for (;;) {
21122117
int nwritten = SSL_write(ssl, RSTRING_PTR(str), num);
2118+
int saved_errno = errno_mapped();
21132119

21142120
cb_state = rb_attr_get(self, ID_callback_state);
21152121
if (!NIL_P(cb_state)) {
@@ -2118,7 +2124,7 @@ ossl_ssl_write_internal_safe(VALUE _args)
21182124
rb_jump_tag(NUM2INT(cb_state));
21192125
}
21202126

2121-
switch (ssl_get_error(ssl, nwritten)) {
2127+
switch (SSL_get_error(ssl, nwritten)) {
21222128
case SSL_ERROR_NONE:
21232129
return INT2NUM(nwritten);
21242130
case SSL_ERROR_WANT_WRITE:
@@ -2139,10 +2145,11 @@ ossl_ssl_write_internal_safe(VALUE _args)
21392145
* make the error handling in line with the socket library.
21402146
* [Bug #14713] https://bugs.ruby-lang.org/issues/14713
21412147
*/
2142-
if (errno == EPROTOTYPE)
2148+
if (saved_errno == EPROTOTYPE)
21432149
continue;
21442150
#endif
2145-
if (errno) rb_sys_fail(0);
2151+
if (saved_errno)
2152+
rb_exc_raise(rb_syserr_new(saved_errno, "SSL_write"));
21462153
/* fallthrough */
21472154
default:
21482155
ossl_raise(eSSLError, "SSL_write");

0 commit comments

Comments
 (0)