I noticed an ssh connection which I had left open for 7 hours. Even though it had been open for that long and even though my laptop had been suspended for some part of those 7 hours, the connection still worked without a flaw. #HowIPv6HelpedMeThisWeek
Westergaard Social

@kasperd wait, how did you manage this sorcery? every time my laptop sleeps, any open ssh connections are broken (what's really weird/obnoxious is, it's exclusively client-side: if I type anything into the terminal, I won't see it echoed back or anything, the connection's done; but if it was typed into a terminal-multiplexer on the server-side, and I reconnect, I'll see the characters there, at least up until I'd hit Enter). My connections are exclusively ipv6. Did you reconfigure suspend to preserve network connections somehow? (I'm on ubuntu: maybe they handle suspend differently)

I know of two reasons for the connection to break when the client machine is suspended:

  • Server tries to send data while client is suspended.
  • The client IP address has changed.

The scenario where the server tried to send data is probably not what you encountered based on your description. In that scenario the server would time out the connection, and the data you entered on the client afterwards would not be accepted by the server.

In my case the connection was idle. A shell prompt had been sent by the server, and there had been no further communication on the ssh connection from either side for the next 7 hours. The scenario you describe sounds like the ssh connection was in the same idle connection while sleeping.

If the machine gets a different IP address once woken up, then the symptoms you describe can happen. I have encountered that myself on another one of my machines.

What happens is that the client IP is no longer assigned to the client host after being woken up. However the client IP is still used by the TCP socket (unless you use MPTCP, the IP addresses remain unchanged for the lifetime of a TCP connection).

Thus when the ssh client sends more data the TCP layer will in fact send packets with a source IP address no longer assigned to the client machine. This works, but responses are not coming back. When the router sends neighbor solicitations for the client IP, it will get no responses. And so TCP packets from server to this client are no longer delivered.

The very moment you send such a packet from the ssh client to the server various timers are triggered, and that will actually cause a timeout and the TCP connection will die shortly afterwards. You can revive the TCP connection if you notice quickly enough and assign the previous client IP address to the interface again before any timeout condition occurs.

The reason it worked in my case was that the connection was on an interface with a static IPv6 address.

Conceptually it would only require a small change to make it work with privacy addresses as well. It would just require the host to keep all old privacy addresses until the last socket using it has been closed. I am not sure if such a change would be in the kernel or the user mode daemon responsible for configuring the network interface.

@kasperd ah, that makes perfect sense: I do use the (standard/unmodified) privacy-address scheme on my laptops/ssh-clients. I had assumed it had something to do with the connection going away entirely/behaving like new as the wifi hardware slept and then awoke; but your explanation about the dynamic IP address having gone away seems much more likely, now. I'll have to see if I can prove to myself that that's what's going on.

@kasperd This actually helped me as well.

With my ISP IPv4 SSH connections get dropped every 30 minutes.

On IPv6 it works fine.