I got a SR where customer wanted to configure DCD option and they had some questions regarding how exactly ASA would do this cool thing, so I decided to write the facts that I found just in case it is useful to someone
Following is clear definition of the feature from the configuration guide:
DCD detects a dead connection and allows it to expire, without expiring connections that can still handle traffic. You configure DCD when you want idle, but valid connections to persist. After a TCP connection times out, the ASA sends DCD probes to the end hosts to determine the validity of the connection. If one of the end hosts fails to respond after the maximum retries are exhausted, the ASA frees the connection. If both end hosts respond that the connection is valid, the ASA updates the activity timeout to the current time and reschedules the idle timeout accordingly. The retry-intervalsets the time duration in hh:mm:ss format to wait after each unresponsive DCD probe before sending another probe, between 0:0:1 and 24:0:0. The default is 0:0:15. The max-retries sets the number of consecutive failed retries for DCD before declaring the connection as dead. The minimum value is 1 and the maximum value is 255. The default is 5.
Now the idea and implementation is defined in the TCP keep-Alives mentioned in RFC 1122. We will see the little trick being used.
In the Keep-Alives that I managed to find, ASA is sending the Keep-Alive segment with no data (Following the Should in the RFC:)).
ASA would send a segment with SEG.SEQ = SND.NXT-1 i.e if the host that ASA is sending segment to is expecting the sequence number 10, it will send sequence number 9, so that this sequence number is outside the receive window ( host has already received and acknowledged byte number 9) of the host receiving the keep-alive message. This would cause the receiving host to send an acknowledgment with the number 10 to the other end (ASA) stating that it is expecting the segment starting with the byte number 10. If ASA gets the messages from both the ends it would refresh the idle timer for the connection.
I did a recreate; ASA would start by sending the TCP-Keepalive message to the client and wait for the reply. I guess the reason is if the reply does not come from the Client it is the end of the story. If the Client sends a TCP-Keepalive ACK it would pass on this message to the server. I suppose the reason to pass on the message to the server would be if the server socket is closed it would send a RST, otherwise it does not cause any harm. Then ASA would send the Keepalive to the Server, and if the reply comes it would forward the reply to the Client and refresh the idle timer for the connection.
Packet captures in the Server and Client are attached.