From c7454e1af74b1b99f3f47f782a6ac484c4c55b7f Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 17 Jan 2018 11:22:47 +0100 Subject: [PATCH] Create one permanent proxy socket per TLSProxy::Proxy instance On Windows, we sometimes see a behavior with SO_REUSEADDR where there remains lingering listening sockets on the same address and port as a newly created one. To avoid this scenario, we don't create a new proxy port for each new client run. Instead, we create one proxy socket when the proxy object is created, and close it when destroying that object. Reviewed-by: Bernd Edlinger (Merged from https://github.com/openssl/openssl/pull/5095) --- util/perl/TLSProxy/Proxy.pm | 65 +++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/util/perl/TLSProxy/Proxy.pm b/util/perl/TLSProxy/Proxy.pm index 8c7b6d6a82..ca49b33a36 100644 --- a/util/perl/TLSProxy/Proxy.pm +++ b/util/perl/TLSProxy/Proxy.pm @@ -101,9 +101,35 @@ sub new } } + # Create the Proxy socket + my $proxaddr = $self->{proxy_addr}; + $proxaddr =~ s/[\[\]]//g; # Remove [ and ] + my @proxyargs = ( + LocalHost => $proxaddr, + LocalPort => $self->{proxy_port}, + Proto => "tcp", + Listen => SOMAXCONN, + ); + push @proxyargs, ReuseAddr => 1 + unless $^O eq "MSWin32"; + $self->{proxy_sock} = $IP_factory->(@proxyargs); + + if ($self->{proxy_sock}) { + print "Proxy started on port ".$self->{proxy_port}."\n"; + } else { + warn "Failed creating proxy socket (".$proxaddr.",".$self->{proxy_port}."): $!\n"; + } + return bless $self, $class; } +sub DESTROY +{ + my $self = shift; + + $self->{proxy_sock}->close() if $self->{proxy_sock}; +} + sub clearClient { my $self = shift; @@ -155,6 +181,10 @@ sub start my ($self) = shift; my $pid; + if ($self->{proxy_sock} == 0) { + return 0; + } + $pid = fork(); if ($pid == 0) { my $execcmd = $self->execute @@ -186,26 +216,6 @@ sub clientstart my ($self) = shift; my $oldstdout; - # Create the Proxy socket - my $proxaddr = $self->proxy_addr; - $proxaddr =~ s/[\[\]]//g; # Remove [ and ] - my @proxyargs = ( - LocalHost => $proxaddr, - LocalPort => $self->proxy_port, - Proto => "tcp", - Listen => SOMAXCONN, - ); - push @proxyargs, ReuseAddr => 1 - unless $^O eq "MSWin32"; - my $proxy_sock = $IP_factory->(@proxyargs); - - if ($proxy_sock) { - print "Proxy started on port ".$self->proxy_port."\n"; - } else { - warn "Failed creating proxy socket (".$proxaddr.",".$self->proxy_port."): $!\n"; - return 0; - } - if ($self->execute) { my $pid = fork(); if ($pid == 0) { @@ -240,7 +250,7 @@ sub clientstart # Wait for incoming connection from client my $client_sock; - if(!($client_sock = $proxy_sock->accept())) { + if(!($client_sock = $self->{proxy_sock}->accept())) { warn "Failed accepting incoming connection: $!\n"; return 0; } @@ -324,9 +334,6 @@ sub clientstart #Closing this also kills the child process $client_sock->close(); } - if($proxy_sock) { - $proxy_sock->close(); - } if(!$self->debug) { select($oldstdout); } @@ -436,24 +443,18 @@ sub supports_IPv6 my $self = shift; return $have_IPv6; } - -#Read/write accessors sub proxy_addr { my $self = shift; - if (@_) { - $self->{proxy_addr} = shift; - } return $self->{proxy_addr}; } sub proxy_port { my $self = shift; - if (@_) { - $self->{proxy_port} = shift; - } return $self->{proxy_port}; } + +#Read/write accessors sub server_addr { my $self = shift; -- 2.34.1