Re: [Filterproxy-devel] Re: FilterProxy BUG
Brought to you by:
mcelrath
|
From: Bob M. <mce...@dr...> - 2002-05-07 18:32:03
|
Guillaume Morin [gui...@mo...] wrote:
> Dans un message du 07 May =E0 11:09, Bob McElrath =E9crivait :
> > > It is Linux 2.2.14 (tried too with .19) and glibc 2.1.3. Getpeername =
can
> > > return undef, if the syscall fails (here with ENOTCONN). If the peer =
has
> > > shutdown the connection, it looks logical to me.
> >=20
> > The peer cannot shut down the connection. This is a "listen" socket,
> > and should stay open when there are no connections.
>=20
> I do not see how the listen socket is concerned. You call getpeername on
> connected socket which are not listen anymore. Shutting down the
> connection would trigger ENOTCONN, I do not see what is surprising.
Well, if accept() is returning undef (which is what causes the main loop
to exit), then it's the listen socket that has failed. I believe the
getpeername() that is failing is not the one in FilterProxy.pl, but a
getpeername called inside the accept() method somewhere (which is buried
in perl XS). This then causes accept() to return undef, which causes
the main loop to exit. The getpeername() in FilterProxy.pl cannot cause
the main loop to exit.
BTW I didn't see any getpeername syscalls in the strace you sent me. It
just looked like accept returned ECONNRESET.
> > > I do not know if you should ignore that one ... But there is surely a
> > > list of accept(2) errors that you want to ignore.
> >=20
> > Hmmm good point. I don't see how to get the linux error in perl. All
> > the perl man pages just say it returns undef.
> >=20
> > Do you know where to get this error code? Maybe try printing out '$!'?
>=20
> yes if you use $! and compare it to the constants define in POSIX qw/:err=
no_h/
> I think you should restart after at least ECONNRESET, EAGAIN, EINTR.
Ok, I'll add this. But I wish it fixed your problem.
> > The accept(2) man pages says to retry when it gives odd errors. Maybe
> > rearrange that main loop:
> > while(1) {
> > my $client =3D $daemon->accept;
> > next unless(defined $client);
> > ...
> > }
> >=20
> > Maybe throw a sleep() in there so it doesn't consume 100% of the cpu if
> > the network goes down (or something).
>=20
> I've basically done this. But after the first EPIPE error, all sucessive
> calls were EPIPE (I tried this during one minute or so).
Then it seems the logical solution would be to close the Listen socket
and start over (which you tried unsuccessfully). Perhaps close() does
not relinquish the listening socket. Try $daemon->shutdown()? From the
perlfunc man page:
=20
This is useful with sockets when you want to tell the other side
you're done writing but not done reading, or vice versa. It's also a
more insistent form of close because it also disables the file
descriptor in any forked copies in other processes.
Note that for this to work consistently, FilterProxy should kill any
forked children. The shutdown() will probably forcibly close all
sockets to all clients.
Cheers,
-- Bob
Bob McElrath (rsm...@st...)=20
Univ. of Wisconsin at Madison, Department of Physics
|