Subject: Window Scale option

From: David Borman <[email-masked]>
Date: Mon, 4 May 1998 15:15:58 -0500 (CDT)

There is a change that I would like to add to RFC 1323 about
the Window Scale Option.  The current text on page 10 has:

      *    The connection state is augmented by two window shift counts,
           Snd.Wind.Scale and Rcv.Wind.Scale, to be applied to the
           incoming and outgoing window fields, respectively.

      *    If a TCP receives a <SYN> segment containing a Window Scale
           option, it sends its own Window Scale option in the <SYN,ACK>
           segment.

      *    The Window Scale option is sent with shift.cnt = R, where R
           is the value that the TCP would like to use for its receive
           window.

      *    Upon receiving a SYN segment with a Window Scale option
           containing shift.cnt = S, a TCP sets Snd.Wind.Scale to S and
           sets Rcv.Wind.Scale to R; otherwise, it sets both
           Snd.Wind.Scale and Rcv.Wind.Scale to zero.

I'd like to change this to:

      *    The connection state is augmented by two window shift counts,
           Snd.Wind.Scale and Rcv.Wind.Scale, to be applied to the
           incoming and outgoing window fields, respectively.

!     *    When sending a <SYN> segment, the Window Scale option is
!          sent with shift.cnt = R, where R is the value that the TCP
!          would like to use for its receive window.

!     *    If a TCP receives a <SYN> segment with a Window Scale option
!          containing shift.cnt = S, it sends its own Window Scale option
!          with shift.cnt = R in the <SYN,ACK>.  If R has not been set by
!          the application, either explicitly or implicitly by changing
!          the receive buffer space from its default value, a TCP may set
!          R = S before generating the <SYN,ACK>.  The TCP then sets
!          Snd.Wind.Scale to S and sets Rcv.Wind.Scale to R.

!     *    Upon receiving a <SYN,ACK> segment with a Window Scale option
           containing shift.cnt = S, a TCP sets Snd.Wind.Scale to S and
           sets Rcv.Wind.Scale to R; otherwise, it sets both
           Snd.Wind.Scale and Rcv.Wind.Scale to zero.

I have implemented this in both UNICOS and BSD/OS, with no ill
effects.  The reason for wanting to recommend turning around the
scale value is that it can only be negotiated during the initial
3-way handshake, and on the passive side, the application that is
doing the listen()/accept() may not be the one that knows that the
receive buffer should be increased to get the a window scale value
sent as non-zero.  E.g, it is inetd that accepts the connection,
which then execs rshd, which in turn execs rcp, which is the
application that knows we're doing a bulk data transfer so the
buffers should be made larger, but by then its too late.  One way
to address this is to modify inetd to allow it to set the receive
buffers large for rshd.  However, rshd is used for other things
besides rcp.  If the receive buffers are made large in inetd, and
the application changes them back to the default values, then you
have an outstanding advertised window from the initial window when
the buffers were larger, which TCP can't retract.

		-David Borman, [email-masked]

---

From: [email-masked]
Date: Mon, 4 May 1998 15:51:48 -0700

*> 
  *> An intersting idea.  But it would be even more complicated than
  *> that if you start talking about multiple changes to (S,R'') before
  *> you get the ack for (R',S).  And sending (S,R') would probably be
  *> in an ACK only packet, requiring the other side to either ACK an
  *> ACK, or defer (S,R') until it has data to send.  I'd rather put
  *> my effort into doing TCPng.
  *> 

I resonate with that...

  *> So, assuming that we are not going to be changing how the Window
  *> Scale option works, do you have any problems with recommending
  *> the ability to turn around the window scale option?  And should
  *> it be a MAY or a SHOULD (I'll settle for MAY, but would like
  *> it to be SHOULD)?
  *> 

I dunno... In some circumstances, it forces both ends to reserve large
buffers even though the data flow is only in one direction.  That might
make the transfer fail unnecessarily, if the server does not have
buffer space to devote, right?

Bob

  *> 		-David Borman, [email-masked]
  *> 
  *>

---

From: [email-masked]
Date: Mon, 4 May 1998 15:58:36 -0700

*> 
  *> I guess what I'm really saying is that if you have a user interface
  *> to TCP to allow the application to specify the window scale value
  *> without having to set the buffer size,

Dave,

Why would you want to do that?  It seems to me that the window scale
itself should be *completely* hidden from the application; it is after
all a kludge; as you noted earlier, we want to obsolete it eventually
with a sensible window size.  The application should know ONLY about
buffer sizes!

  *> and the server turns around
  *> the window scale value, then you can make TCP connections that are
  *> ready to use large buffers if the application wants them, without
  *> having to pre-allocate any extra buffer space on either the client
  *> or the server (and thus have an initial large window).  But typically

Oh, you mean that there could be a system call that set the buffer max,
without pre-allocation of buffers.  But since it has to be ABLE to
allocate that buffer space, you can still lose at the beginning.

  *> the client will know whether or not large buffers are wanted, so
  *> having it set a large receive buffer, and having the server turn around
  *> the scale option (without changing the buffer size) is usually sufficient.
  *> 

Bob

---

From: Jason Thorpe <[email-masked]>
Date: Mon, 04 May 1998 16:37:10 -0700

> with a sensible window size.  The application should know ONLY about

I agree completely.

In some ways, I like with Kevin's suggestion of setting this on a per-route
basis, but that has the problem of being a little too "global"; it catches
things which really have no reason to advertise large windows (e.g.
interactive sessions).

On the other hand, I also have a problem with modifying every application
that might want to do this (although I've started doing this in NetBSD just
to see how annoying it might turn out to be...).  Consider just the FTP case:

	- Modify inetd(8) so that ftpd(8) can be handed a control
	  socket with a large recieve buffer (for passive upload).

	- Modify ftp(1) to allow a larger rcvbuf to be specified
	  (for normal [data socket] and passive [control socket]
	  download).

	- Modify ftpd(8) to allow a larger rcvbuf to be specified
	  (for normal upload).

 > allocate that buffer space, you can still lose at the beginning.

Um, isn't that what the BSD stack already does?  setsockopt of SO_RCVBUF
simply sets so->so_rcv.sb_hiwat to the specified value; buffers are allocated
lazily upon packet reception, and simply hung off the socket buffer until
the high water mark is reached... In the even the buffer can't be allocated,
the packet is simply dropped at the NIC level, an ACK is never transmitted,
the sender's retransmit timer fires, and its congestion window closes (icky,
but it works).

Jason R. Thorpe                                       [email-masked]
NASA Ames Research Center                            Home: +1 408 866 1912
NAS: M/S 258-5                                       Work: +1 650 604 0935
Moffett Field, CA 94035                             Pager: +1 415 428 6939

---

From: [email-masked]
Date: Tue, 5 May 1998 13:03:06 -0700

*> 
  *> I considered this approach, but the difficulty is that there is no
  *> distiction between "timestamp" and "timestamp reply".  Thus turning
  *> off timestamps requires having some way to discover that the other end
  *> isn't using them.  For example the value zero could be used to indicate
  *> that a reply is not needed.
  *> 
  *> I have long since forgotten the details....
  *> 

Me too.

  *> --MM--
  *> 
  *> 
  *>

---

From: [email-masked]
Date: Tue, 5 May 1998 14:48:31 -0700

*> 

It isn't clear to me that any bad thing happens if one end simply
refrains from sending a TSopt even though it could send it.
The other end could take this as a signal to itself stop sending
TSopts.  (We would have to make sure this cannot confuse PAWS).

Bob