[comp.protocols.tcp-ip] PUSH bit

BRUCE@UMDD.UMD.EDU (Bruce Crabill) (03/13/89)

I've noticed a quirk with a TCP/IP implementation that I'm working with.  It
has to do with how it handles the PUSH bit on TCP segments that it receives.
What is happening is that when a segment is received with the PUSH bit set,
it is placed in the client buffer and the client is notified as he should be.
However, if another segment comes in before the client picks up the data,
the new segment is also appended to the buffer.  When the client picks up
the buffer, it is marked as having been PUSHed.

The problems are that in some cases the second packet won't completely fit
in the buffer and will have to be split (or the second packet didn't have
the PUSH bit on it).  The client is seeing data that is marked as being
PUSHed, but in fact it was data earlier in the buffer.  I see three
possible solutions, do it as RFC 793 implied and don't allow anymore data
to be placed in the buffer.  This has the drawbacks of wasting buffer
space and causes more overhead in that the client needs to be notified
more times.  Second, don't set the PUSH flag for the buffer if the buffer
ends up with the final byte not being the last byte of a PUSHed segment
(but still give the buffer to the client ASAP).  Third, only allow data
to be appended to the buffer if they are also PUSHed and will fit within
the buffer.

What I guess I'm really asking is what is the exact purpose of the PUSH
bit.  You could interpret the PUSH bit as a end of logical record marker.
Or you could interpret is as simply a mechanism to make sure all the data
that is currently in the pipe is pushed out to the client.  Since TCP is
a stream oriented protocol, it would appear that the latter is the correct
interpretation.  In which case, any of the above 3 solutions will work.
However, the thing that is throwing me is the fact that PUSH data indications
are to be given to the client.  Why was this done?  Does this imply that
for every PUSH done on the sending side, their must be a corresponding
PUSH indication on the receiver's side?  If not, why bother with PUSH
indications at all?

                                       Bruce

barns@GATEWAY.MITRE.ORG (Bill Barns) (03/13/89)

OK, I'll bite, since I babbled about this in the Host Requirements WG.

The PSH bit is definitely NOT a record marker.  It is the sending
application's means of demanding that the data not be allowed to linger
in buffers somewhere between the sending and receiving application.

It is fine to deliver some 'non-PSHed' data in the same buffer as the
PUSHed data, if there is some of both kinds available for delivery.  It
is always permitted to deliver any (in-sequence) data that is on hand,
regardless of Push.  The ABSENCE of Push gives all the intermediate
processes permission to buffer the data until there is a Push (or until
some other event implying a Push occurs, such as a FIN arriving).

It is not required that PSH be transferred one-to-one.  Either the
sending or receiving TCP may 'collapse' them.  The HR RFC (coming
soon...) will clarify that providing notification of a Push to a
receiving application is optional rather than required.  Kindly note,
tiny minority of careless readers, that sending a PSH bit at
appropriate times is still mandatory.  This is important!!  Anyhow, the
service definition in RFC 793 is somewhat exemplary and contains a few
optional features.  It is hoped that the text in the HR RFC will
clarify all this.  (Draft available from venera.isi.edu by anonymous
ftp using filename /pub/ietf-hosts.rfc.txt)

All of your three solutions are legal, but somewhat distasteful to me,
especially #2, which probably "ought" to be illegal.  For the case you
describe, I think the preferred solution is to fill the buffer as full
as possible with any available data, and set the Push indication.

Why should a Push indication be passed from the destination TCP to the
client application?  True, it is often not very useful, and it should
never be NECESSARY (if it seems to be necessary to the application, the
application/TCP service mapping is flawed, given the facts described
above).  However, it has a little value once in a while.  Here is an
example.  A few years ago I was working with some timesharing host
software which used windows on a 24x80 display terminal and could have
connections to various other hosts whose output might be sent to
various windows.  This was originally designed for a different protocol
stack and I added support for TCP connections driving windows.  Since
bandwidth to the terminal and CPU usage (context switches..) were of
some concern, I contrived code such that window repaints were only
scheduled when a Push came in for that window.  This resulted in fewer
process wakeups, better efficiency on the terminal-host interface, and
yet allowed a window to be updated pretty promptly when a remote host
felt the need to do that.  Also, it saved me the nuisance of
timer-driven connection polling or some other algorithm which would
have taken more effort to code.  I thought it worked out pretty well.

Bill Barns / MITRE-Washington / barns@gateway.mitre.org

smb@ulysses.homer.nj.att.com (Steven M. Bellovin) (03/13/89)

In article <8903130939.AA05138@ucbvax.Berkeley.EDU>, BRUCE@UMDD.UMD.EDU (Bruce Crabill) writes:
> You could interpret the PUSH bit as a end of logical record marker.

That is definitely the wrong interpretation.  The spec says, many
times in many places, that the PUSH bit is *not* a record marker.
See, for example, the bottom of page 7 of RFC 1011:

         Push:  There are still some phrases in the document that give a
         "record mark" flavor to the push.  These should be further
         clarified.  The push is not a record mark.

> Or you could interpret is as simply a mechanism to make sure all the data
> that is currently in the pipe is pushed out to the client.

The proper interpretation is that at least all data up to the PUSH point
must be delivered promptly.  Whether or not more data is delivered is
entirely up to the implementation; any interpretation is in conformance
with the spec.  Applications that assume that the PUSH bit is an end-of-
record mark are non-conforming.