Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Nov 2005 12:48:02 GMT
From:      Maxim Podberezny <diascan@mail.ru>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   ports/88450: SYN+ACK reports strange size of window
Message-ID:  <200511031248.jA3Cm29W094048@www.freebsd.org>
Resent-Message-ID: <200511031250.jA3CoRNh015905@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         88450
>Category:       ports
>Synopsis:       SYN+ACK reports strange size of window
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Nov 03 12:50:26 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Maxim Podberezny
>Release:        4.11
>Organization:
Diascan
>Environment:
peculiar OS, uses FreeBSD TCP/IP stack 'as is'
>Description:
              I test a newly ported FreeBSD TCP/IP stack at our OS. Stack was ported 'as is'. The test is performed with ANVL test suite.
The problem is that one of ANVL test performes the follows:
1. ANVL sends SYN to DUT (target with our OS)
2. DUT sends SYN+ACK with Window_From_DUT=0x4000
3. ANVL sends ACK to DUT.

now the state of the connection is ESTABLISHED.

4. ANVL sends SYN packet to DUT with unacceptable sequence number.
ANVL calculates the sequence number as follows:
SEQ = Seq_From_DUT + Window_From_DUT + 2

ANVL expects from DUT to receive ACK with some sequence number, but it receives RST. I investigated the issue and found that the size of window is calculated in syncache_add()-function:
1.1          (jlemon   22-Nov-01):      /* Initial receive window: clip sbspace to [0 .. TCP_MAXWIN] */
1.1          (jlemon   22-Nov-01):      win = sbspace(&so->so_rcv);
1.1          (jlemon   22-Nov-01):      win = imax(win, 0);
1.1          (jlemon   22-Nov-01):      win = imin(win, TCP_MAXWIN);
1.1          (jlemon   22-Nov-01):      sc->sc_wnd = win;

and uses this value when send the SYN+ACK in syncache_respond():
1.1          (jlemon   22-Nov-01):      th->th_x2 = 0;
1.1          (jlemon   22-Nov-01):      th->th_flags = TH_SYN|TH_ACK;
1.1          (jlemon   22-Nov-01):      th->th_win = htons(sc->sc_wnd);
1.1          (jlemon   22-Nov-01):      th->th_urp = 0;

After DUT has sended the SYN+ACK and received the last ACK, the size of window changed to a value of 0x40e8 in tcp_input.c file.

So, finally the unacceptable sequence number from ANVL is accepted in by DUT window, since 0x40e8 is bigger than 0x4000+2. DUT sends RST instead of ACK packet.

The situation that the window size has changed is correct, I now, but why this size is also changed by another algorithm in another file absolutely independently?

Before syncache was developed the receive window size was calculated always in one file in tcp_input.c.
The chain was as follows:
tcp_input()
 |
 |->tcp_dooptions()
   |
   |->tcp_mss()
The latter function changed the window size keeping integrity of the value.
>How-To-Repeat:
              Establish a connection with FreeBSD and send SYN packet with sequence number bigger than in packet plus window and plus 2.
>Fix:
              If it's a bug or "wrong' issue I suggest to use the code from tcp_mss() function which was used earlier.

What do you think?
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200511031248.jA3Cm29W094048>