On Tue, 09 Apr 2019 07:48:45 +0200, Steffen Ullrich wrote:

> > You're welcome :-) Does clearing the SSL_MODE_AUTO_RETRY context flag
> > (i.e., reverting the default from OpenSSL <1.1.1) solves this for you
> > too? If so, what do you think about my proposed paths forwards from

Not yet, I first wanted to check Net::SSLeay and IO::Socket::SSL
upstream releases/commits, and ...
 
> Simply clearing SSL_MODE_AUTO_RETRY will cause problems with blocking
> connections in TLS 1.3.
> I've tried to work around the behavior change by clearing SSL_MODE_AUTO_RETRY
> for non-blocking and setting it again when doing blocking connections.
> Please check if
> https://github.com/noxxi/p5-io-socket-ssl/commit/09bc6a3203bc7bc89078317da42a3e96cdbf94fc
> fixes the problems you see.

... this comes in very handy, thanks Steffen :)


Unoftunately the patch doesn't apply:

patching file lib/IO/Socket/SSL.pm
Hunk #1 FAILED at 73.
Hunk #2 succeeded at 260 with fuzz 2 (offset 128 lines).
Hunk #3 succeeded at 1052 (offset 174 lines).
Hunk #4 FAILED at 1091.
Hunk #5 succeeded at 1126 (offset -38 lines).
2 out of 5 hunks FAILED -- rejects in file lib/IO/Socket/SSL.pm


The problem is that we have IO::Socket::SL 2.060 and Net::SSLeay 1.85
(with some patches), and due to Debian being in freeze for the
upcoming release, we can't just update to the newest (dev) releases …
[0]


Anyway, next step: I've updated the patch so that it applies against
2.060, and the package builds and passes the test suite. (Patch
attached.)


When I install the package with the patch and run our test case
again, I don't get any hangs anymore:

% time perl -MLWP::UserAgent -e 
'LWP::UserAgent->new->post("https://facebook.com";, { data => "foo" }) or die'
perl -MLWP::UserAgent -e   0.18s user 0.02s system 22% cpu 0.867 total 


So this looks promising but definitively needs more eyeballs.


Thanks again,
gregor


[0] Status of the packages, with patches in the debia/patches
directory, at:
https://salsa.debian.org/perl-team/modules/packages/libio-socket-ssl-perl
https://salsa.debian.org/perl-team/modules/packages/libnet-ssleay-perl

-- 
 .''`.  https://info.comodo.priv.at -- Debian Developer https://www.debian.org
 : :' : OpenPGP fingerprint D1E1 316E 93A7 60A8 104D  85FA BB3A 6801 8649 AA06
 `. `'  Member VIBE!AT & SPI Inc. -- Supporter Free Software Foundation Europe
   `-   NP: Tom Waits: Sins Of My Father
From 09bc6a3203bc7bc89078317da42a3e96cdbf94fc Mon Sep 17 00:00:00 2001
From: Steffen Ullrich <steffen_ullr...@genua.de>
Date: Tue, 9 Apr 2019 00:08:06 +0200
Subject: [PATCH] deal with OpenSSL 1.1.1 switching on SSL_AUTO_RETRY by
 default by disabling it when non-blocking

---
 lib/IO/Socket/SSL.pm | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

--- a/lib/IO/Socket/SSL.pm
+++ b/lib/IO/Socket/SSL.pm
@@ -67,6 +67,7 @@ my $can_ecdh;        # do we support ECD
 my $can_ocsp;        # do we support OCSP
 my $can_ocsp_staple; # do we support OCSP stapling
 my $can_tckt_keycb;  # TLS ticket key callback
+my $auto_retry;      # (clear|set)_mode SSL_MODE_AUTO_RETRY with OpenSSL 1.1.1+ with non-blocking
 BEGIN {
     $can_client_sni = Net::SSLeay::OPENSSL_VERSION_NUMBER() >= 0x01000000;
     $can_server_sni = defined &Net::SSLeay::get_servername;
@@ -260,6 +261,30 @@ DH
 	INIT { init() }
 	init();
     }
+
+    if (!defined &Net::SSLeay::clear_mode) {
+	# assume SSL_CTRL_CLEAR_MODE being 78 since it was always this way
+	*Net::SSLeay::clear_mode = sub {
+	    my ($ctx,$opt) = @_;
+	    Net::SSLeay::ctrl($ctx,78,$opt,0);
+	};
+    }
+
+    if (Net::SSLeay::OPENSSL_VERSION_NUMBER() >= 0x10101000) {
+	# openssl 1.1.1 enabled SSL_MODE_AUTO_RETRY by default, which is bad for
+	# non-blocking sockets
+	my $mode_auto_retry =
+	    # was always 0x00000004
+	    eval { Net::SSLeay::MODE_AUTO_RETRY() } || 0x00000004;
+	$auto_retry = sub {
+	    my ($ssl,$on) = @_;
+	    if ($on) {
+		Net::SSLeay::set_mode($ssl, $mode_auto_retry);
+	    } else {
+		Net::SSLeay::clear_mode($ssl, $mode_auto_retry);
+	    }
+	}
+    }
 }
 
 # global defaults which can be changed using set_defaults
@@ -1028,6 +1053,7 @@ sub accept_SSL {
     } else {
 	# timeout does not apply because invalid or socket non-blocking
 	$timeout = undef;
+	$auto_retry && $auto_retry->($ssl,$socket->blocking);
     }
 
     my $start = defined($timeout) && time();
@@ -1101,6 +1127,14 @@ sub accept_SSL {
 
 ####### I/O subroutines ########################
 
+if ($auto_retry) {
+    *blocking = sub {
+	my $self = shift;
+	{ @_ && $auto_retry->($self->_get_ssl_object || last, @_); }
+	return $self->SUPER::blocking(@_);
+    };
+}
+
 sub _generic_read {
     my ($self, $read_func, undef, $length, $offset) = @_;
     my $ssl =  ${*$self}{_SSL_object} || return;

Attachment: signature.asc
Description: Digital Signature

Reply via email to