Subject: Re: TCP MSS not adhered to properly when options present
To: None <tech-net@netbsd.org>
From: Scott Barron <sb125499@oak.cats.ohiou.edu>
List: tech-net
Date: 11/30/2001 10:10:52
On Fri, Nov 30, 2001 at 09:30:15AM -0500, Rick Byers wrote:
> On Fri, 30 Nov 2001, Scott Barron wrote:
>
> > > NetBSD doesn't appear to be handling the TCP MSS option properly.
> > > According to RFC 1122, the MSS sent by a host is the maximum IP packet
> > > size its willing to receive minus 40. This correlates to the maximum
> > > tcp payload when no tcp or ip options are present. However, NetBSD
> > > appears to use it as the maximum tcp payload even when options are
> > > present.
> >
> > I am pretty much a novice when it comes to the networking code but the
> > way I understand it is the MSS options are exchanged when a connection
> > is created. However the option length may not be constant during the
> > lifetime of the connection (a host that sends SACK blocks, something I'm
> > currently working on, is a good example of this). So I see only two
> > things, set it to the size that is sent, which is what I think it
> > currently does (looking at tcp_input.c in 1.5.2) or set it to the size
> > advertised minus MAX_TCPOPTLEN and take and go for the "worst case" so
> > to speak. Personally, I'm not sure which is a better idea and I don't
> > know how other systems handle it (I suspect the same way). Maybe
> > somebody more experienced can chime in here (also please chime in if
> > I've gotten anything incorrect).
>
> Right. That is exactly why the RFCs define the MSS to be the maximum IP
> packet size minus 40. That way, the extra IP or TCP options count against
> the segment size to keep the total packet size bounded at a constant
> (MSS+40).
>
> > > I haven't had a chance to look into the source for either of theese
> > > problems, but I hope to have time this weekend if someone doesn't beat me
> > > to it.
> >
> > The sent MSS is recorded in tcp_dooptions() in tcp_input.c (grep for
> > TCPOPT_MAXSEG, my file is too hacked up to give you a valid line
> > number), to give you a starting point.
>
> Cool, thanks. I'll take a look this weekend and see if I can come up with
> a fix. All that should be required is to subtract the length of any TCP
> or IP options when desciding how much payload to include in a TCP
> packet...
>
> Thanks,
> Rick
Alright I broke out TCP/IP Illustrated v2 and noticed the following
snippet of code that is missing from the NetBSD code:
/*
* Adjust data length if insertion of options will
* bump the packet length beyond the t_maxseg length.
*/
if (len > tp->t_maxseg - optlen) {
len = tp->t_maxseg - optlen;
sendalot = 1;
}
This seems to do what you're talking about but I'm not sure why it was
removed (haven't been around that long). Would this do the trick?
(Against a -current checked out very early this morning (Nov 30)). This
built but I haven't tested it.
Index: tcp_output.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netinet/tcp_output.c,v
retrieving revision 1.75
diff -r1.75 tcp_output.c
745a746,750
>
> if (len > txsegsize - optlen) {
> len = txsegsize - optlen;
> sendalot = 1;
> }
-Scott