diff --git a/NetworkPkg/TcpDxe/TcpInput.c b/NetworkPkg/TcpDxe/TcpInput.c index 04c8a8269e..f8845dca47 100644 --- a/NetworkPkg/TcpDxe/TcpInput.c +++ b/NetworkPkg/TcpDxe/TcpInput.c @@ -1,7 +1,7 @@ /** @file TCP input process routines. - Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -738,6 +738,7 @@ TcpInput ( TCP_SEQNO Right; TCP_SEQNO Urg; UINT16 Checksum; + INT32 Usable; ASSERT ((Version == IP_VERSION_4) || (Version == IP_VERSION_6)); @@ -1306,9 +1307,27 @@ TcpInput ( } if (TCP_SEQ_LT (Right, Tcb->SndNxt)) { - - Tcb->SndNxt = Right; - + // + // Check for Window Retraction in RFC7923 section 2.4. + // The lower n bits of the peer's actual receive window is wiped out if TCP + // window scale is enabled, it will look like the peer is shrinking the window. + // Check whether the SndNxt is out of the advertised receive window by more than + // 2^Rcv.Wind.Shift before moving the SndNxt to the left. + // + DEBUG ( + (EFI_D_WARN, + "TcpInput: peer advise negative useable window for connected TCB %p\n", + Tcb) + ); + Usable = TCP_SUB_SEQ (Tcb->SndNxt, Right); + if ((Usable >> Tcb->SndWndScale) > 0) { + DEBUG ( + (EFI_D_WARN, + "TcpInput: SndNxt is out of window by more than window scale for TCB %p\n", + Tcb) + ); + Tcb->SndNxt = Right; + } if (Right == Tcb->SndUna) { TcpClearTimer (Tcb, TCP_TIMER_REXMIT);