[jdev] XMPP Ping/Keepalive: Recommended method ?

Bruce Campbell list-jdev at vicious.dropbear.id.au
Tue Jun 27 05:09:23 CDT 2006


On Mon, 26 Jun 2006, Joe Hildebrand wrote:

> On Jun 19, 2006, at 1:15 AM, Sergei Golovan wrote:
>
>> The problem is that this "ping" is not a ping at all because it only
>> sends data and does not expect reply.
>
> Well, not really.  You'll get a TCP ack back, which should be enough to keep 
> the lights on.

Not if you are dealing with inspection-type firewalls which don't really 
treat a TCP ACK as a data packet.

> Some servers can also be configured to send space 
> keep-alives.  If both sides use this algorithm things seem to work pretty 
> well:
>
> 1) set a timer to some amount of time, say 30 seconds
> 2) when the timer fires, send a space
> 3) whenever you send something, reset to the timer to zero
> 4) whenever you receive something, reset the timer to zero

It works to a point (being probably 95% of cases).  If you have a client 
sending pings every 40 seconds unless first reset, and the server sending 
pings every 30 seconds unless first reset, the client's first ping will be 
the one that discovers that the packet-inspecting firewall wants to see 
non-TCP-ack packets.

If you want to go down that path, you need two timeouts; a short one (30 
seconds) to be reset each time a packet is sent or received as above, and 
a longer one (60 seconds) to trigger a send locally.  In practice, this 
eventually settles down to each side sending a packet at 60 second 
intervals, with a roughly 30 second gap between them.

Even so, this requires server-side configuration; the server may not do 
whitespace pings for policy reasons.

> this allows you to detect dead links about as quickly as possible, without 
> increasing network traffic any more than absolutely necessary.

There isn't a lot of difference between a TCP packet containing a single 
whitespace character, and a TCP packet containing a dummy <iq/> or 
<message/> stanza.  Neither will be fragmented.

A whitespace ping is less expensive on the server side, as it gets thrown 
out by the c2s-equivilant component, and just returns a TCP ack. Conversely,
a dummy stanza will always be more expensive, as depending on the server 
design, it may be routed through several components to get to the 
sm-equivilant, then routed back and sent to the client in a second 
TCP-data + TCP-ack pair.

However, the gain is that the client 'knows' that the server is fully 
functioning, and any firewalls in between which expect to see data flowing 
in both directions have nicely had their idle timers reset, vs the client 
just knowing that the TCP stream to the c2s component is still 
functioning.

On the reverse issue, I don't think that servers should generate anything 
more than whitespace pings to verify an ongoing TCP stream with a client. 
This would require changes to most client (which are user-driven, not 
server driven), and generally servers want to clean up after any departed 
TCP streams as soon as possible.

I guess the point I'm trying to make is, do you want the clients to know 
that their next <message/> will not generate a TCP error, or do you want 
clients to know that their next <message/>, if not delivered, will come 
back with an undeliverable stanza ?

-- 
   Bruce Campbell



More information about the JDev mailing list