diff options
Diffstat (limited to 'usr/src/uts/common/inet')
-rw-r--r-- | usr/src/uts/common/inet/tcp/tcp_input.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/inet/tcp/tcp_time_wait.c | 5 |
2 files changed, 13 insertions, 2 deletions
diff --git a/usr/src/uts/common/inet/tcp/tcp_input.c b/usr/src/uts/common/inet/tcp/tcp_input.c index 7cfdb9a4a2..6eab136ee5 100644 --- a/usr/src/uts/common/inet/tcp/tcp_input.c +++ b/usr/src/uts/common/inet/tcp/tcp_input.c @@ -2874,12 +2874,20 @@ tcp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira) /* * RST segments must not be subject to PAWS and are not * required to have timestamps. + * We do not drop keepalive segments without + * timestamps, to maintain compatibility with legacy TCP stacks. */ - if (tcp->tcp_snd_ts_ok && !(flags & TH_RST)) { + boolean_t keepalive = (seg_len == 0 || seg_len == 1) && + (seg_seq + 1 == tcp->tcp_rnxt); + if (tcp->tcp_snd_ts_ok && !(flags & TH_RST) && !keepalive) { /* * Per RFC 7323 section 3.2., silently drop non-RST * segments without expected TSopt. This is a 'SHOULD' * requirement. + * We accept keepalives without TSopt to maintain + * interoperability with tcp implementations that omit + * the TSopt on these. Keepalive data is discarded, so + * there is no risk corrupting data by accepting these. */ if (!(options & TCP_OPT_TSTAMP_PRESENT)) { /* diff --git a/usr/src/uts/common/inet/tcp/tcp_time_wait.c b/usr/src/uts/common/inet/tcp/tcp_time_wait.c index bbc819cb0d..72997de24a 100644 --- a/usr/src/uts/common/inet/tcp/tcp_time_wait.c +++ b/usr/src/uts/common/inet/tcp/tcp_time_wait.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2016 Joyent, Inc. + * Copyright (c) 2016 by Delphix. All rights reserved. */ /* @@ -614,7 +615,9 @@ tcp_time_wait_processing(tcp_t *tcp, mblk_t *mp, uint32_t seg_seq, new_swnd = ntohs(tcpha->tha_win) << ((tcpha->tha_flags & TH_SYN) ? 0 : tcp->tcp_snd_ws); - if (tcp->tcp_snd_ts_ok && !(tcpha->tha_flags & TH_RST)) { + boolean_t keepalive = (seg_len == 0 || seg_len == 1) && + (seg_seq + 1 == tcp->tcp_rnxt); + if (tcp->tcp_snd_ts_ok && !(flags & TH_RST) && !keepalive) { int options; if (tcp->tcp_snd_sack_ok) tcpopt.tcp = tcp; |