Closed twata1 closed 1 year ago
This is an issue I get only on Windows systems and I'm not sure what causes the problem. I have theories about differences between the fork-emulation in Perl on Windows vs. real fork on other platforms, but also about antivirus (which is also specific to Windows) inferring with the tests. Can you therefore please verify that
If both of these is the case (i.e. problem reproducible and not a side effect of antivirus) please run this specific tests with perl -Mblib t/sni_verify.t
to find out a) if it still hangs when called this way and b) where exactly it hangs.
Thank you for your reply.
Today, I confirmed version 2.070 on Strawberry Perl 5.30.2 64bit under Windows 8.1.
It seems to me that perl -Mblib t/sni_verify.t
does not hang.
C:\home\sunlight2\IO-Socket-SSL-2.070>perl -Mblib t/sni_verify.t
1..17
ok # Server Initialization
ok # client ssl connect server.local
ok # client verify hostname in cert server.local
ok # server accept
ok # server got SNI name server.local
ok # client ssl connect server2.local
ok # client verify hostname in cert server2.local
ok # server accept
ok # server got SNI name server2.local
ok # client ssl connect smtp.mydomain.local
ok # client verify hostname in cert smtp.mydomain.local
ok # server accept
ok # server got SNI name smtp.mydomain.local
ok # client ssl connect www13.other.local
ok # client verify hostname in cert www13.other.local
ok # server accept
ok # server got SNI name www13.other.local
C:\home\sunlight2\IO-Socket-SSL-2.070>
But prove -lv t/sni_verify.t
seems to hang.
C:\home\sunlight2\IO-Socket-SSL-2.070>prove -lv t/sni_verify.t
t/sni_verify.t ..
1..17
ok # Server Initialization
(hangs)
So I just thought there was something wrong with the gmake test
and prove
commands.
Thank you,
I have the similar issue with v2.071 on Strawberry Perl 5.32.1 64bit. The t/sni_verify.t test hangs and does not complete.
Is there any solution to this ?
I have just made a pull request to resolve this issue (#105).
This looks a bit similar to failures with older Perls with Net::SSLeay tests that use forks and then do socket calls.
https://github.com/radiator-software/p5-net-ssleay/issues/356#issuecomment-1025741806
In short: https://perldoc.perl.org/5.20.0/perldelta
On Windows, perl no longer calls CloseHandle() on a socket handle. This makes debugging easier on Windows by removing certain irrelevant bad handle exceptions. It also fixes a race condition that made socket functions randomly fail in a Perl process with multiple OS threads, and possible test failures in dist/IO/t/cachepropagate-tcp.t. [perl #120091/118059]
For issue 118059, see https://github.com/Perl/perl5/issues/12979
In Net::SSLeay case sleep(1)
seems to help.
Using Net::SSLeay 1.93_01 and openssl 3.0.5 I do not have any hang but almost systematic failure with t/sni_verify.t.
After:
for my $host (@tests) {
my $client = IO::Socket::SSL->new(...);
# etc
print "Doing \$client = undef\n";
$client = undef;
}
It seems the server is trying to send packets, like "new session" protocol to the client, after it has successfuly connected (I guess this can happen reading https://www.openssl.org/docs/manmaster/man3/SSL_get_session.htm).
But if the client runs out of scope too fast in t/sni_verify.t, which is anticipated explicitly with $client = undef
, the server's accept will fail, c.f. this debug log where I have added # Client
and # Server
annotations at the very end:
1..17
DEBUG: lib/IO/Socket/SSL.pm:2969: new ctx 20027384
ok # Server Initialization
DEBUG: lib/IO/Socket/SSL.pm:973: no socket yet
DEBUG: lib/IO/Socket/SSL.pm:2969: new ctx 65480352
DEBUG: lib/IO/Socket/SSL.pm:704: socket not yet connected
DEBUG: lib/IO/Socket/SSL.pm:706: socket connected
DEBUG: lib/IO/Socket/SSL.pm:729: ssl handshake not started
DEBUG: lib/IO/Socket/SSL.pm:975: accept created normal socket IO::Socket::SSL=GLOB(0x3408d6c)
DEBUG: lib/IO/Socket/SSL.pm:771: using SNI with hostname server.local
DEBUG: lib/IO/Socket/SSL.pm:1003: starting sslifying
DEBUG: lib/IO/Socket/SSL.pm:806: request OCSP stapling
DEBUG: lib/IO/Socket/SSL.pm:836: call Net::SSLeay::connect
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.1 (OUT), TLS header, Certificate Status (22)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, Client hello (1)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.1 (IN), TLS header, Certificate Status (22)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (IN), TLS handshake, Client hello (1)
DEBUG: lib/IO/Socket/SSL.pm:2953: set context from servername server.local
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Certificate Status (22)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, Server hello (2)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Finished (20)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, Encrypted Extensions (8)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, Request CERT (13)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, Certificate (11)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, CERT verify (15)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, Finished (20)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (IN), TLS header, Certificate Status (22)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (IN), TLS handshake, Server hello (2)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (IN), TLS header, Finished (20)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (IN), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (IN), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (IN), TLS handshake, Request CERT (13)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (IN), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (IN), TLS handshake, Certificate (11)
DEBUG: lib/IO/Socket/SSL.pm:2813: ok=1 [1] /CN=IO::Socket::SSL Demo CA/CN=IO::Socket::SSL Demo CA
DEBUG: lib/IO/Socket/SSL.pm:2813: ok=1 [0] /CN=IO::Socket::SSL Demo CA/CN=server.local
DEBUG: lib/IO/Socket/SSL.pm:1786: scheme=default cert=63258200
DEBUG: lib/IO/Socket/SSL.pm:1796: identity=server.local cn=server.local alt=
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (IN), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (IN), TLS handshake, CERT verify (15)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (IN), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (IN), TLS handshake, Finished (20)
DEBUG: lib/IO/Socket/SSL.pm:2860: did not get stapled OCSP response
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Finished (20)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, Certificate (11)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, CERT verify (15)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Supplemental data (23)
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, Finished (20)
DEBUG: lib/IO/Socket/SSL.pm:839: done Net::SSLeay::connect -> 1
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (IN), TLS header, Finished (20)
DEBUG: lib/IO/Socket/SSL.pm:894: ssl handshake done
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (IN), TLS header, Supplemental data (23)
ok # client ssl connect server.local
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (IN), TLS handshake, Certificate (11)
DEBUG: lib/IO/Socket/SSL.pm:1786: scheme=http cert=63258200
DEBUG: lib/IO/Socket/SSL.pm:1796: identity=server.local cn=server.local alt=
ok # client verify hostname in cert server.local
Doing $client = undef
DEBUG: lib/IO/Socket/SSL.pm:3018: free ctx 65480352 open=65480352 # Client
DEBUG: lib/IO/Socket/SSL.pm:3022: free ctx 65480352 callback # Client
DEBUG: lib/IO/Socket/SSL.pm:3029: OK free ctx 65480352 # Client
DEBUG: lib/IO/Socket/SSL.pm:3018: free ctx 20027384 open= # Client
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (IN), TLS header, Supplemental data (23) # Server
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (IN), TLS handshake, CERT verify (15) # Server
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (IN), TLS header, Supplemental data (23) # Server
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (IN), TLS handshake, Finished (20) # Server
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Supplemental data (23) # Server
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, Newsession Ticket (4) # Server
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.2 (OUT), TLS header, Supplemental data (23) # Server
DEBUG: lib/IO/Socket/SSL.pm:3584: * TLSv1.3 (OUT), TLS handshake, Newsession Ticket (4) # Server
DEBUG: lib/IO/Socket/SSL.pm:1051: Net::SSLeay::accept -> -1 # Server
DEBUG: lib/IO/Socket/SSL.pm:1054: local error: SSL accept attempt failed # Server
not ok # server accept - SSL accept attempt failed # Server
ok # skip accept failed
DEBUG: lib/IO/Socket/SSL.pm:3018: free ctx 20027384 open=55351576 19735448 20027384 55380128 # Server
DEBUG: lib/IO/Socket/SSL.pm:3022: free ctx 20027384 callback # Server
DEBUG: lib/IO/Socket/SSL.pm:3029: OK free ctx 20027384 # Server
Trying with the 'sleep' to prevent $client running out of scope works, this is is a way to make the client life longer enough so that server can send the other packets, but this is not very nice ;) I guess there is a nicer way to prevent this race condition (?)
Hoping my analysis is correct (I am not ssl expert).
Hoping my analysis is correct (I am not ssl expert).
Nice analysis. You tracing feature is really useful here. Could you please try the following patch to t/sni_verify.t which tries to deal with the race by making the client wait for server application data?
diff --git a/t/sni_verify.t b/t/sni_verify.t
index 81841e2..b6923cf 100644
--- a/t/sni_verify.t
+++ b/t/sni_verify.t
@@ -75,6 +75,8 @@ if ( $pid == 0 ) {
print "not ok # client ssl connect $host - $SSL_ERROR\n";
print "ok # skip connect failed\n";
}
+ # wait for server to send something to make sure finished accept
+ <$client>;
}
exit;
}
@@ -86,6 +88,7 @@ for my $host (@tests) {
my $name = $csock->get_servername;
print "not " if ! $name or $name ne $host;
print "ok # server got SNI name $host\n";
+ print $csock "hi\n";
} else {
print "not ok # server accept - $SSL_ERROR\n";
print "ok # skip accept failed\n";
You got it, many thanks - t/sni_verify.t always succeed with this patch ;)
If you don't mind I suggest to do the same in other tests that are subject to scope issue (just hitted once an error in sni.t for instance that I fail to reproduce).
Hello,
$client
at the wrong placePlease find a patch against version 2.076 for these three cases. IO-Socket-SSL-2.076.txt
Hello,
It seems to me that t/sni_verify.t hangs as follows.
Windows 8.1, Strawberry Perl 5.30.2 (64bit)
Thank you,