diff options
Diffstat (limited to 'usr/src/uts/common/inet/tcp/tcp_input.c')
-rw-r--r-- | usr/src/uts/common/inet/tcp/tcp_input.c | 10 |
1 files changed, 9 insertions, 1 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)) { /* |