During migration we extract the limit on segment size using TCP_MAXSEG,
and set it on the other side with TCP_REPAIR_OPTIONS. However, unlike most
32-bit values we transfer we transfer it in native endian, not network
endian. This is not correct; add it to the list of endian fixups we make.
In addition, while MAXSEG will be 32-bits in practice, and is given as such
to TCP_REPAIR_OPTIONS, the TCP_MAXSEG sockopt treats it as an 'int'. It's
not strictly safe to pass a uint32_t to a getsockopt() expecting an int,
although we'll get away with it on most (maybe all) platforms. Correct
this as well.
Signed-off-by: David Gibson
---
tcp.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tcp.c b/tcp.c
index a4c840e6..163ddd60 100644
--- a/tcp.c
+++ b/tcp.c
@@ -2847,14 +2847,17 @@ static int tcp_flow_dump_tinfo(const struct tcp_tap_conn *conn,
static int tcp_flow_dump_mss(const struct tcp_tap_conn *conn,
struct tcp_tap_transfer_ext *t)
{
+ int val;
socklen_t sl = sizeof(t->mss);
- if (getsockopt(conn->sock, SOL_TCP, TCP_MAXSEG, &t->mss, &sl)) {
+ if (getsockopt(conn->sock, SOL_TCP, TCP_MAXSEG, &val, &sl)) {
int rc = -errno;
flow_perror(conn, "Getting MSS");
return rc;
}
+ t->mss = (uint32_t)val;
+
return 0;
}
@@ -3301,6 +3304,7 @@ int tcp_flow_migrate_source_ext(int fd, const struct tcp_tap_conn *conn)
t->sndq = htonl(t->sndq);
t->notsent = htonl(t->notsent);
t->rcvq = htonl(t->rcvq);
+ t->mss = htonl(t->mss);
t->snd_wl1 = htonl(t->snd_wl1);
t->snd_wnd = htonl(t->snd_wnd);
@@ -3514,6 +3518,7 @@ int tcp_flow_migrate_target_ext(struct ctx *c, struct tcp_tap_conn *conn, int fd
t.sndq = ntohl(t.sndq);
t.notsent = ntohl(t.notsent);
t.rcvq = ntohl(t.rcvq);
+ t.mss = ntohl(t.mss);
t.snd_wl1 = ntohl(t.snd_wl1);
t.snd_wnd = ntohl(t.snd_wnd);
--
2.48.1