On Tue, Sep 30, 2025 at 12:23:35AM +0200, Stefano Brivio wrote: > On Mon, 29 Sep 2025 16:25:39 +1000 > David Gibson wrote: > > > On Sun, Sep 28, 2025 at 03:29:46PM +0800, Yumei Huang wrote: > > > If a client connects while guest is not connected or ready yet, > > > resend SYN instead of just resetting connection after SYN_TIMEOUT. > > > > > > Signed-off-by: Yumei Huang > > > > Simpler than I thought. Nice. > > > > However, I think now that we're retrying we probably want to adjust > > SYN_TIMEOUT. I suspect the 10s was a generous amount to mitigate the > > fact we didn't retry. > > That was the idea, yes. > > > However, AFAICT most OSes resend SYNs faster than that (after 1-3s > > initially). > > Right. Remember all the examples from Linux with one-second retries > I wanted to show? :) > > > They also typically slow down the > > resents on subsequent retries. I'm not sure if that last is important > > in our case - since we're talking directly to a guest, we're unlikely > > to flood the link this way. > > Exponential back-off (or whatever is used by other implementations) > doesn't only serve the purpose of avoiding to flood the link. It's also > about functionality itself. > > That is, if you waited one second, and you didn't get any reply, that's > a good indication that you might not get a reply in one second from > now, because the peer might need a little bit longer. > > > In fact, I haven't read closely enough to be sure, but there was some > > language in RFC 6298 and RFC 1122 that suggested to me maybe we should > > be using the same backoff calculation for SYN retries as for regular > > retransmits. Which as a bonus might simplify our logic a little bit. > > Somewhat surprisingly, RFC 9293 doesn't say anything about this. :( Right, it discusses RTO, and never explicitly talks about SYN resends, kind of implying that SYN resends should use the same RTO calculations as data retransmits. > And while I'm fairly sure that RFC 2988 was intended to only cover > *data* retransmissions, RFC 6298 (which updates it) seems to simply > assume, in section 5., that it's also about SYN segments: > > (5.7) If the timer expires awaiting the ACK of a SYN segment and the > TCP implementation is using an RTO less than 3 seconds, the RTO > MUST be re-initialized to 3 seconds when data transmission > begins (i.e., after the three-way handshake completes). > > so, yes, I tend to agree with this. Let's just use the same logic. > > Just note that it's an approximation of RFC 6298, in any case, because > we don't implement RTT measurements. > > It's a rather complicated implementation that I originally decided to > skip because there's no actual data transmission between us and > guest/container, so there isn't much that can go wrong. Maybe we could > even assume that the RTT is zero. > > As a result of that, we can't implement RFC 2988 / RFC 6298 exactly as > it is. But we can get quite close to it. > > > Documentation/networking/ip-sysctl.rst > > ...in the unlikely case it's not clear: David means a Linux kernel tree > here. Yumei, it might be a good idea to have a kernel tree (maybe > git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git) at > hand to check this kind of stuff. > > > has some information on how > > Linux handles this (tcp_syn_retries and tcp_syn_linear_timeouts in > > particular). I guess we could configure ourselves to match the host's > > settings - we do something similar to determine what we consider > > ephemeral ports. > > > > Stefano, thoughts? > > Yes, I think reading those values from the host makes sense because the > same thing that would happen if the host connects to the guest or > container with another implementation (veth, or tap). I think taking tcp_syn_retries from the host makes sense. I'm a bit less sure about tcp_syn_linear_timeouts, since that requires implementing the more complex and specific linear backoff behaviour. > It's also the least surprising behaviour for any kind of application > that was previously running outside guest or containers and now it's > moved there. Well, probably the least surprising we can achieve. It's not possible for us to match the peer's SYN retry behaviour if it's not Linux or has different settings to the host. > We have just 3 bits here, so we can only try 9 times (retry 8 times), > but other than that we can use tcp_syn_retries and > tcp_syn_linear_timeouts as they are. > > Summing up, I would propose that we do something like this: > > 1. (optional, and might be in another series, but keeping it together > with the rest might be more convenient): read tcp_syn_retries, limit > to 8, and also read tcp_syn_linear_timeouts > > 2. always use one second as initial RTO (retransmission timeout). That's > what the kernel does (even though rto_initial should be 3 seconds by > default...? I'm not sure) > > 3. for SYN, implement the tcp_syn_linear_timeouts thing. That is, > in tcp_timer_ctl(), use this timeout: > > if (conn->retries < c->tcp_ctx.syn_linear_timeouts) > [one second] > else > [1 << conn->retries] 1 << conn->retries, or 1 << (conn->retries - syn_linear_timeouts) ? > 4. do the same for data retransmissions, but without the > tcp_syn_linear_timeouts thing, start from one second (see Appendix A > in RFC 6298)... and maybe limit it to 60 seconds as allowed by the > same RFC: > > (2.5) A maximum value MAY be placed on RTO provided it is at least 60 > seconds. > > ? Retransmitting data after 256 seconds doesn't make a lot of sense > to me. > > It shouldn't be much more complicated than the current patch, it just > involves some extra changes in tcp_timer_ctl(), I guess. > > -- > Stefano > -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson