Commit 09f1a093 authored by Richard Levitte's avatar Richard Levitte
Browse files

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: default avatarBernd Edlinger <bernd.edlinger@hotmail.de>
(Merged from https://github.com/openssl/openssl/pull/5095)

(cherry picked from commit c7454e1a)
parent 2087582d
Loading
Loading
Loading
Loading
+33 −32
Original line number Diff line number Diff line
@@ -94,9 +94,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;
@@ -145,6 +171,10 @@ sub start
    my ($self) = shift;
    my $pid;

    if ($self->{proxy_sock} == 0) {
        return 0;
    }

    $pid = fork();
    if ($pid == 0) {
        my $execcmd = $self->execute
@@ -175,26 +205,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) {
@@ -226,7 +236,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;
    }
@@ -299,9 +309,6 @@ sub clientstart
        #Closing this also kills the child process
        $client_sock->close();
    }
    if($proxy_sock) {
        $proxy_sock->close();
    }
    if(!$self->debug) {
        select($oldstdout);
    }
@@ -411,24 +418,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;