Skip to content

Commit 21684dc

Browse files
stefan-baranoffdavem330
authored andcommitted
tcp: fix sequence numbers for repaired sockets re-using TIME-WAIT sockets
This patch fixes a bug where the sequence numbers of a socket created using TCP repair functionality are lower than set after connect is called. This occurs when the repair socket overlaps with a TIME-WAIT socket and triggers the re-use code. The amount lower is equal to the number of times that a particular IP/port set is re-used and then put back into TIME-WAIT. Re-using the first time the sequence number is 1 lower, closing that socket and then re-opening (with repair) a new socket with the same addresses/ports puts the sequence number 2 lower than set via setsockopt. The third time is 3 lower, etc. I have not tested what the limit of this acrewal is, if any. The fix is, if a socket is in repair mode, to respect the already set sequence number and timestamp when it would have already re-used the TIME-WAIT socket. Signed-off-by: Stefan Baranoff <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 83fe6b8 commit 21684dc

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

net/ipv4/tcp_ipv4.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,24 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
156156
*/
157157
if (tcptw->tw_ts_recent_stamp &&
158158
(!twp || (reuse && get_seconds() - tcptw->tw_ts_recent_stamp > 1))) {
159-
tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
160-
if (tp->write_seq == 0)
161-
tp->write_seq = 1;
162-
tp->rx_opt.ts_recent = tcptw->tw_ts_recent;
163-
tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
159+
/* In case of repair and re-using TIME-WAIT sockets we still
160+
* want to be sure that it is safe as above but honor the
161+
* sequence numbers and time stamps set as part of the repair
162+
* process.
163+
*
164+
* Without this check re-using a TIME-WAIT socket with TCP
165+
* repair would accumulate a -1 on the repair assigned
166+
* sequence number. The first time it is reused the sequence
167+
* is -1, the second time -2, etc. This fixes that issue
168+
* without appearing to create any others.
169+
*/
170+
if (likely(!tp->repair)) {
171+
tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
172+
if (tp->write_seq == 0)
173+
tp->write_seq = 1;
174+
tp->rx_opt.ts_recent = tcptw->tw_ts_recent;
175+
tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
176+
}
164177
sock_hold(sktw);
165178
return 1;
166179
}

0 commit comments

Comments
 (0)