Re: FIN_WAIT2 not working
- From: "Gary R. Garrison" <g.r.garrison@xxxxxxxxxxxxxxx>
- Date: Thu, 27 Nov 2008 09:01:37 +0100
I seem to have a working solution.
Does the behaviour change if in the app on the Linux side you call
shutdown(SHUT_WR) on the socket and then hang in a timed select/poll
waiting for the socket to become readable, meanwhile on the Windows
side, you make certain that the Windows side calls close() after the
read return of zero?
I implemented a shutdown(SHUT_WR) solution yesterday that waits for a response before closing. This appears to have fixed the problem.
Did the application do anything to put the Windows system into an
immediate ACK mode or is this very close to the beginning of the
connection?
The captured packets shown were not at the beginning of a capture - Windows seems to have entered immediate ACK mode at some point. The first packet in the block I sent was the 304th packet in this particular socket exchange.
If all else fails and you have the ability to change both sides of the
equation, you could have the Windows side to an application-level ack
of the data on which the Linux side waits before calling close() on
the socket. It goes one step further than the shutdown() idea above
by making sure that the Windows side has no more window updates to
send - they best be piggy-backed on that app-level ack.
The problem actually involves multiple existing systems using multiple OSes. A certain amount of existing code exists in a windows utility program that's been distributed for years. I really don't want to have to modify and redistribute that just because a new Linux platform doesn't handle "close()" correctly.
In any case, as mentioned at the beginning of this - I have a working solution. Your suggestion would have led me to it if I hadn't found it about the same time you did Rick. The reference I had found on internet implemented a shutdown as you suggest, followed by a loop using select for a certain timeout period to watch input. I had trouble with that loop and instead found a way using the tcp_info structure. Heres a look at the code :
int Close_Socket(int socketd)
{
int vl_Status;
int InfoLen;
volatile struct tcp_info MyInfo;
if (0 != shutdown(socketd, SHUT_WR))
{ // can't shutdown write so shutdown all
if (0 != close(socketd))
{
return (INVALID_SOCKET);
}
return (SUCCESS);
}
// write has been shutdown so FIN has been sent
InfoLen = sizeof(MyInfo);
do
{
vl_Status = getsockopt( socketd, SOL_TCP, TCP_INFO, (void *)&MyInfo, &InfoLen );
}while ((0 == vl_Status) &&
((TCP_FIN_WAIT1 == MyInfo.tcpi_state) || (TCP_FIN_WAIT2 == MyInfo.tcpi_state)) );
if (0 != close(socketd))
{
return (INVALID_SOCKET);
}
return (SUCCESS);
}
.
- References:
- FIN_WAIT2 not working
- From: Gary R. Garrison
- Re: FIN_WAIT2 not working
- From: Rick Jones
- Re: FIN_WAIT2 not working
- From: Gary R. Garrison
- Re: FIN_WAIT2 not working
- From: Rick Jones
- FIN_WAIT2 not working
- Prev by Date: Re: VPN requirements
- Next by Date: FC9 and default GW
- Previous by thread: Re: FIN_WAIT2 not working
- Next by thread: Throughput Formula
- Index(es):
Relevant Pages
|