[ipxe-devel] [PATCH] [tcp] Send keepalive packets to prevent TCP stalls

Michael Brown mcb30 at ipxe.org
Thu Jun 9 13:11:11 UTC 2016

On 09/06/16 13:44, Ladi Prosek wrote:
>> Do you know what prevents the usual TCP retransmission mechanism from
>> recovering?  ARP discovery should still work even for retransmitted packets.
> Just like you wrote in the ipxe-devel thread linked from the commit
> description, from the client point of view the connection is "stable".
> Everything the client has sent has been acked so the retransmission
> timer is not running. The server is retransmitting for sure but its
> packets just can't reach the client - they're routed somewhere else or
> are blackholed altogether.

Understood that the client (iPXE) will not be retransmitting, but that 
still doesn't explain what happens to the server's retransmitted packets.

> I can get to this state easily by configuring my virtual NIC with the
> hardcoded default MAC. There are more such hosts on the network
> claiming the same MAC so sooner or later I find myself cut off.

OK, but in that situation we don't expect traffic to get through anyway; 
it's a broken setup.

I'm trying to think of a situation in which this situation could arise 
in a non-broken setup, to convince myself that this is something we 
should be adding.  The best I can think of off-hand is where iPXE is 
behind some kind of NAT, and the NATting device has lost track of the 
relevant state.

> That sounds good. Under certain circumstances this may generate
> otherwise unnecessary traffic so I just want to be careful. For
> example if it's an HTTP connection and it is kept alive (as in HTTP
> keepalive), it will look idle and will be pinging the server with
> keepalives periodically even though it's not waiting for anything. Big
> deal? Probably not. Worth adding a way for upper layers to signal this
> down to the TCP implementation? Probably not either.

I think we should keep it as simple as possible.  Always send keepalives 
on any established connection, use start_timer_fixed() with some period 
long enough to not be disruptive to real traffic (e.g. 15 seconds), 
reset the timer whenever any packet is received on that connection.

It might also be desirable to use the common transmit path to send the 
keepalive packet, if that can cleanly be made to result in smaller and 
simpler code.  I don't think we need to use the (seq-1) trick since 
we're not aiming to elicit a response unless the remote end genuinely 
has something it's already trying to send.  We should be able to just 
send an unsolicited pure ACK, which the existing transmit path can 
already create via the TCP_ACK_PENDING flag.


More information about the ipxe-devel mailing list