Keepalive versus the carrier NAT
A phone on a carrier NAT will drop an idle TCP mapping in about a minute. The default Linux keepalive of 7200 seconds never gets a chance to speak. The connection is already gone, and the next write fails with a timeout that looks like packet loss.
I use tcp_keepalive_time = 60, interval 10, six probes. That is frequent enough for the NAT I actually sit behind, and not so frequent that a sleeping radio is woken every few seconds. If a flow is idle for half a minute on purpose, tearing it down is cheaper than pretending it is still there.