From 89a4ef3849f8481b1e0e81c8cabd5c2ddb01e93f Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 3 Jun 2025 16:02:15 -0400 Subject: [PATCH] Test randomly selected client port for availabilty in sslrecords test MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Encountered this error in a pr today: https://github.com/openssl/openssl/actions/runs/15418713146/job/43387767612 === Proxy started on port [::1]:56662 Engine "ossltest" set. Using default temp DH parameters ACCEPT [::1]:59189 Server responds on [::1]:59189 Engine "ossltest" set. C0774F02907F0000:error:80000062:system library:BIO_bind:Address already in use:crypto/bio/bio_sock2.c:240:calling bind() C0774F02907F0000:error:10000075:BIO routines:BIO_bind:unable to bind socket:crypto/bio/bio_sock2.c:242: connect:errno=98 === Its occuring because we randomly select a port to use for our client connection in the sslrecords test. Thats usually fine, but sometimes, we get unlucky and pick a port thats already in use. This presents as random failures in our CI on this test. So lets try harden ourselves against it. When creating the client connection, test the randomly selected port by trying to bind to it via a call to IO::Socket::IP->new(). If that fails, try a different port number, until we get one that works. If it works, use that port in the assignment for the clients local port value. Reviewed-by: Saša Nedvědický Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/27752) (cherry picked from commit f78f824c8e4064148af1186490e9b445871765fd) --- util/perl/TLSProxy/Proxy.pm | 39 ++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/util/perl/TLSProxy/Proxy.pm b/util/perl/TLSProxy/Proxy.pm index 7ad7c939ad5..64da22bfb99 100644 --- a/util/perl/TLSProxy/Proxy.pm +++ b/util/perl/TLSProxy/Proxy.pm @@ -74,15 +74,51 @@ my $ciphersuite = undef; sub new { + require IO::Socket::IP; my $class = shift; my ($filter, $execute, $cert, $debug) = @_; + my $test_client_port; + + # Sometimes, our random selection of client ports gets unlucky + # And we randomly select a port thats already in use. This causes + # this test to fail, so lets harden ourselves against that by doing + # a test bind to the randomly selected port, and only continue once we + # find a port thats available. + my $test_client_addr = $have_IPv6 ? "[::1]" : "127.0.0.1"; + my $found_port = 0; + for (my $i = 0; $i <= 10; $i++) { + $test_client_port = 49152 + int(rand(65535 - 49152)); + my $test_sock; + if ($have_IPv6) { + $test_sock = IO::Socket::IP->new(Family => AF_INET6, + LocalPort => $test_client_port, + LocalAddr => $test_client_addr); + } else { + $test_sock = IO::Socket::IP->new(Family => AF_INET, + LocalPort => $test_client_port, + LocalAddr => $test_client_addr); + } + if ($test_sock) { + $found_port = 1; + $test_sock->close(); + print "Found available client port ${test_client_port}\n"; + last; + } + print "Port ${test_client_port} in use. Trying again\n"; + } + + if ($found_port == 0) { + die "Unable to find usable port for TLSProxy"; + } + my $self = { #Public read/write - proxy_addr => $have_IPv6 ? "[::1]" : "127.0.0.1", + proxy_addr => $test_client_addr, + client_addr => $test_client_addr, filter => $filter, serverflags => "", clientflags => "", @@ -92,6 +128,7 @@ sub new #Public read proxy_port => 0, + client_port => $test_client_port, server_port => 0, serverpid => 0, clientpid => 0, -- 2.47.2