Since it is a reccuring question, I took the time to investigate into 
winsock keepalive packets.

Here is what Microsoft says about keepalive (full story at 
http://www.microsoft.com/technet/itsolutions/network/deploy/depovg/tcpip2k.mspx):
A TCP keep-alive packet is simply an ACK with the sequence number set to one 
less than the current sequence number for the connection. A host receiving 
one of these ACKs responds with an ACK for the current sequence number. 
Keep-alives can be used to verify that the computer at the remote end of a 
connection is still available. TCP keep-alives can be sent once every 
KeepAliveTime (defaults to 7,200,000 milliseconds or two hours) if no other 
data or higher-level keep-alives have been carried over the TCP connection. 
If there is no response to a keep-alive, it is repeated once every 
KeepAliveInterval seconds. KeepAliveInterval defaults to 1 second. TCP 
keep-alives are disabled by default, but Windows Sockets applications can 
use the setsockopt function to enable them.

TWSocket conatins code which enable keepalive packets. It always had.

Using a sniffer, I confirmed that winsock never send keep alive packet on my 
win xp pro sp2 computer (I tested with a public FTP server on the internet).

I added registry keys as explained in the above document:
KeepAliveInterval: This parameter determines the interval between keep-alive 
retransmissions until a response is received. Once a response is received, 
the delay until the next keep-alive transmission is again controlled by the 
value of KeepAliveTime. The connection is aborted after the number of 
retransmissions specified by TcpMaxDataRetransmissions have gone unanswered.
KeepAliveTime: The parameter controls how often TCP attempts to verify that 
an idle connection is still intact by sending a keep-alive packet. If the 
remote system is still reachable and functioning, it acknowledges the 
keep-alive transmission. Keep-alive packets are not sent by default. This 
feature may be enabled on a connection by an application.

I used a few seconds interval and alive time. Still not a single keep alive 
packet on the network !

I modified TWSocket code to add this method:

procedure TCustomWSocket.SetKeepAliveOption;
var
    OptVal        : Integer;
    Status        : Integer;
    KeepAliveIn   : TTcpKeepAlive;
    KeepAliveOut  : TTcpKeepAlive;
    BytesReturned : Cardinal;
begin
    OptVal  := 1;
    Status := WSocket_Synchronized_setsockopt(FHSocket, SOL_SOCKET,
                                              SO_KEEPALIVE, @OptVal,
                                              SizeOf(OptVal));

    if Status <> 0 then begin
        SocketError('setsockopt(SO_KEEPALIVE)');
        Exit;
    end;

    FillChar(KeepAliveIn, SizeOf(KeepAliveIn), 0);
    FillChar(KeepAliveOut, SizeOf(KeepAliveOut), 0);
    BytesReturned := 0;

    KeepAliveIn.OnOff             := 1;
    KeepAliveIn.KeepAliveInterval := 10000;  { 10 seconds retry }
    KeepAliveIn.KeepAliveTime     := 3000;
    Status := WSocket_WSAIoctl(FHSocket,      SIO_KEEPALIVE_VALS,
                               @KeepAliveIn,  SizeOf(KeepAliveIn),
                               @KeepAliveOut, SizeOf(KeepAliveOut),
                               BytesReturned, nil, nil);
    if Status <> 0 then begin
        SocketError('WSocket_WSAIoctl(SIO_KEEPALIVE_VALS)');
        Exit;
    end;
end;

By the way I had to add those constants:
    IOC_UNIX             = $00000000;       { Do not use this in 
ows     }
    IOCPARM_MASK         = $000007F7;       { Parameters must be < 128 
bytes }
    IOC_WS2              = $08000000;
    IOC_PROTOCOL         = $10000000;
    IOC_VOID             = $20000000;       { No 
           }
    IOC_OUT              = $40000000;       { Copy out 
           }
    IOC_IN               = $80000000;       { Copy in 
           }
    IOC_INOUT            = (IOC_IN or IOC_OUT);
    IOC_VENDOR           = $18000000;
    SIO_RCVALL           = IOC_IN or IOC_VENDOR or 1;
    SIO_RCVALL_MCAST     = IOC_IN or IOC_VENDOR or 2;
    SIO_RCVALL_IGMPMCAST = IOC_IN or IOC_VENDOR or 3;
    SIO_KEEPALIVE_VALS   = IOC_IN or IOC_VENDOR or 4;
    SIO_ABSORB_RTRALERT  = IOC_IN or IOC_VENDOR or 5;
    SIO_UCAST_IF         = IOC_IN or IOC_VENDOR or 6;
    SIO_LIMIT_BROADCASTS = IOC_IN or IOC_VENDOR or 7;
    SIO_INDEX_BIND       = IOC_IN or IOC_VENDOR or 8;
    SIO_INDEX_MCASTIF    = IOC_IN or IOC_VENDOR or 9;
    SIO_INDEX_ADD_MCAST  = IOC_IN or IOC_VENDOR or 10;
    SIO_INDEX_DEL_MCAST  = IOC_IN or IOC_VENDOR or 11;

I checked with MSVC that all constant have correct values.
I tryed calling SetKeepAliveOption when the socket is opened, just after 
linger options and when it is connected in Do_FD_CONNECT. Neither worked. No 
error but no keep alive packet on the network.

I don't know what to try next. I ggogled a lot without finding more 
interesting informations.

Any idea ?

--
Contribute to the SSL Effort. Visit http://www.overbyte.be/eng/ssl.html
--
[EMAIL PROTECTED]
http://www.overbyte.be


-- 
To unsubscribe or change your settings for TWSocket mailing list
please goto http://www.elists.org/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to