tcp: Derive MSS announced to guest/namespace from configured MTU if present

...and from the sending socket only if the MTU is not configured.

Otherwise, a connection to a host from a local guest, with a
non-loopback destination address, will get its MSS from the MTU of the
outbound interface with that address, which is unnecessary as we know
the guest can send us larger segments.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
Stefano Brivio 2021-09-29 16:46:58 +02:00
parent 4e5129719d
commit 2408ddffa3

15
tcp.c
View file

@ -1187,10 +1187,23 @@ static int tcp_send_to_tap(struct ctx *c, struct tcp_tap_conn *conn, int flags,
th->doff = sizeof(*th) / 4; th->doff = sizeof(*th) / 4;
if (flags & SYN) { if (flags & SYN) {
uint16_t mss;
/* Options: MSS, NOP and window scale if allowed (4-8 bytes) */ /* Options: MSS, NOP and window scale if allowed (4-8 bytes) */
*data++ = OPT_MSS; *data++ = OPT_MSS;
*data++ = OPT_MSS_LEN; *data++ = OPT_MSS_LEN;
*(uint16_t *)data = htons(info.tcpi_snd_mss);
if (c->mtu == -1) {
mss = info.tcpi_snd_mss;
} else {
mss = c->mtu - sizeof(sizeof *th);
if (IN6_IS_ADDR_V4MAPPED(&conn->a.a6))
mss -= sizeof(struct iphdr);
else
mss -= sizeof(struct ipv6hdr);
}
*(uint16_t *)data = htons(mss);
data += OPT_MSS_LEN - 2; data += OPT_MSS_LEN - 2;
th->doff += OPT_MSS_LEN / 4; th->doff += OPT_MSS_LEN / 4;