diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c index 37bf69c3a..ae1d8a256 100644 --- a/criu/sk-tcp.c +++ b/criu/sk-tcp.c @@ -319,6 +319,34 @@ err_sopt: return -1; } +static int tcp_get_window(int sk, TcpStreamEntry *tse) +{ + struct tcp_repair_window opt; + socklen_t optlen = sizeof(opt); + + if (!kdat.has_tcp_window) + return 0; + + if (getsockopt(sk, SOL_TCP, + TCP_REPAIR_WINDOW, &opt, &optlen)) { + pr_perror("Unable to get window properties"); + return -1; + } + + tse->has_snd_wl1 = true; + tse->has_snd_wnd = true; + tse->has_max_window = true; + tse->has_rcv_wnd = true; + tse->has_rcv_wup = true; + tse->snd_wl1 = opt.snd_wl1; + tse->snd_wnd = opt.snd_wnd; + tse->max_window = opt.max_window; + tse->rcv_wnd = opt.rcv_wnd; + tse->rcv_wup = opt.rcv_wup; + + return 0; +} + static int dump_tcp_conn_state(struct inet_sk_desc *sk) { int ret, aux; @@ -364,6 +392,9 @@ static int dump_tcp_conn_state(struct inet_sk_desc *sk) if (ret < 0) goto err_opt; + if (tcp_get_window(sk->rfd, &tse)) + goto err_opt; + /* * TCP socket options */ @@ -624,6 +655,29 @@ static int restore_tcp_opts(int sk, TcpStreamEntry *tse) return 0; } +static int restore_tcp_window(int sk, TcpStreamEntry *tse) +{ + struct tcp_repair_window opt = { + .snd_wl1 = tse->snd_wl1, + .snd_wnd = tse->snd_wnd, + .max_window = tse->max_window, + .rcv_wnd = tse->rcv_wnd, + .rcv_wup = tse->rcv_wup, + }; + + if (!kdat.has_tcp_window || !tse->has_snd_wnd) { + pr_warn_once("Window parameters are not restored\n"); + return 0; + } + + if (setsockopt(sk, SOL_TCP, TCP_REPAIR_WINDOW, &opt, sizeof(opt))) { + pr_perror("Unable to set window parameters"); + return -1; + } + + return 0; +} + static int restore_tcp_conn_state(int sk, struct inet_sk_info *ii) { int aux; @@ -657,6 +711,9 @@ static int restore_tcp_conn_state(int sk, struct inet_sk_info *ii) if (restore_tcp_queues(sk, tse, img)) goto err_c; + if (restore_tcp_window(sk, tse)) + goto err_c; + if (tse->has_nodelay && tse->nodelay) { aux = 1; if (restore_opt(sk, SOL_TCP, TCP_NODELAY, &aux)) diff --git a/images/tcp-stream.proto b/images/tcp-stream.proto index 60ba123de..174078305 100644 --- a/images/tcp-stream.proto +++ b/images/tcp-stream.proto @@ -18,4 +18,10 @@ message tcp_stream_entry { optional bool nodelay = 11; optional uint32 unsq_len = 12; /* unsent data in the send queue */ + + optional uint32 snd_wl1 = 13; + optional uint32 snd_wnd = 14; + optional uint32 max_window = 15; + optional uint32 rcv_wnd = 16; + optional uint32 rcv_wup = 17; }