Subject: TCP MSS option value

From: [email-masked]
Date: Fri, 21 Jan 2000 14:34:19 -0500

Please help me understand what RFC2581 intends regarding the value
advertised in the MSS option when other options (e.g., Timestamp) are going
to be used.

Suppose the MTU is 1500 bytes, and after the 3-way handshake a host is
going to be sending on each segment 12 bytes of TCP options:  Timestamp
plus two NOPs.  RFC879, "TCP Maximum Segment Size," says "THE TCP MAXIMUM
SEGMENT SIZE IS THE IP MAXIMUM DATAGRAM SIZE MINUS FORTY" (all capital
letters in  RFC879).  This implies that the host should advertise MSS=1460,
but as  RFC 879 notes, when it was written there were "no TCP header
options ... defined that would normally be sent at the same time as data
segments."  RFC 1011 states "The TCP Maximum Segment Size is the IP Maximum
Datagram Size minus forty," but sending TCP options with data segments was
still an obscure subject when that was written.   Section 4.2.2.6, "Maximum
Segment Size Option," of RFC1122, "Host Requirements -- Communications
Layers,"  does not explicitly say what value to advertise in the MSS
option, but it gives a formula for Eff.snd.MSS, "the maximum size of a
segment that TCP really sends," that is based on SendMSS, "the MSS value
received from the remote host," and the TCPhdrsize.  If one solves that
formula for SendMSS, and notes the RFC's comment that "TCPhdrsize is the
size of the TCP header; this is normally 20, but may be larger if TCP
options are to be sent,"  then it seems to say for a 1500 byte MTU the MSS
option value should be 1460, and each segment will carry 1448 byte of data
in addition to the 12 bytes of options.  Section 2.18, "Options missing
from TCP MSS calculation," of RFC 2525, "Known TCP Implementation
Problems," reiterates that RFC1122's formula for effective send MSS should
be applied in order to avoid fragmentation (or worse problems if Path MTU
is being used).  Most of the implementations with which I am familiar do
indeed send MSS option value of 1460 when the MTU is 1500 and Timestamp
option is being used.  Similarly, section 18.4, "Maximum Segment Size," of
W. Richard Stevens's "TCP/IP Illustrated, Vol. 1" says, "When TCP sends a
SYN segment ... it can send an MSS value up to the outgoing interface's
MTU, minus the size of the fixed TCP and IP headers."

However, RFC2581, "TCP Congestion Control," says "RECEIVER MAXIMUM SEGMENT
SIZE (RMSS):  The RMSS is the size of the largest segment the receiver is
willing to accept.  This is the value specified in the MSS option sent by
the receiver during connection startup.  ...  The size does not include the
TCP/IP headers and options."  This seems to say that if the MTU is 1500
bytes, the IP header is 20, the TCP header is 20, and the TCP option field
is 12, then the RMSS (and therefore the MSS option value to advertise)
should be 1448.  Furthermore, RFC2581 also says "SENDER MAXIMUM SEGMENT
SIZE (SMSS):  The SMSS is the size of the largest segment that the sender
can transmit.  This value can be based on the maximum transmission unit of
the network, the path MTU discovery [MD90] algorithm, RMSS ... , or other
factors.  The size does not include the TCP/IP headers and options."  Is
SMSS the same as RFC1122's Eff.snd.MSS?  If so, then if the received MSS
advertisement is 1448, wouldn't the SMSS be 1436 (i.e., min
(1448+20,1480)-32)?

If I understand correctly that RFC2851 says TCP should advertise MSS opt
value of 1448 when MTU=1500 and TCPoptionLength=12, then I have some
further questions about how to calculate Eff.snd.MSS, the number of data
bytes to send in a segment along with the headers and options:

1) Does the effective send MSS calculation of RFC1122 still apply?  If so,
then when the local host advertises MSS option value of 1448, the remote
host will calculate an effective send MSS of 1436 (=min(1448+20,1480)--32),
and therefore send segments with 1436 bytes of data even though the local
host can handle segments of 1448 bytes of data.  While I heartily agree
with the suggestion later in RFC2851 that implementations should be liberal
in interpreting what constitutes two full-sized segments when deciding when
to ACK, I am concerned that existing implementations are not so liberal and
that hosts sending 1436 bytes of data to them will get into the
Nagel-DelayedAck standoff described on page 204 of Stevens's second edition
of UNIX Network Programming.

2) If the effective send MSS calculation of RFC1122 no longer should be
used, and the remote host has an old implementation that calculates the MSS
value to advertise by merely subtracting 40 from its MTU, then the local
host could wind up sending datagrams larger than the remote host's MTU.
For example, suppose the local host has MTU=2000 and the remote host has
MTU=1500.  If the remote host advertises MSS option=1460 (i.e., MTU-40,
ignoring the TCP option bytes),  and the local host interprets that
received MSS option value of 1460 per RFC2581, i.e., as if it did not
include TCP header and TCP option bytes, then the local host would send
datagrams 1512 bytes long (20 for IPheader + 20 for TCPfixedHeader+12 for
TCPoptions+1460 for data).  That of course can lead to performance-reducing
fragmentation or even complete communication failure.

I hope I have misinterpreted RFC2581's intentions regarding MSS option
value.  If not, can you give me any advice on how to interoperate with the
existing implementations that calculate MSS option value by subtracting 40
from the MTU even when other TCP options are going to be used.

Regards,
Ed Britton

---

From: David Borman <[email-masked]>
Date: Fri, 28 Jan 2000 14:01:30 -0600 (CST)

John,

> Date: Fri, 28 Jan 2000 14:24:11 -0500
> From: John Hawkinson <[email-masked]>
> Subject: Re: TCP MSS option value
...
> Err, you're saying that an the MTU of one side of the interface does
> not agree with the MTU of the other side of the interface, and because
> IOS assumes it will never get a packet on an interface that is larger
> than the MTU for that interface, it has a problem when it receives
> such a packet?

Yes, they get tossed.

> > UUNET thinks 4K is just fine and sends the packet, the ISP box drops
> > it in hardware.  Because it doesn't get dropped by IP, no ICMP
> > message gets generated, and you have a black hole.
>
> Hmm...yes, though a counter does get incremented, I think.

On Cisco routers, there is a "giants" statistic that gets
incremented when this happens.  But you need access to the
router to see that...

...
> > There are various tests you can do from your local side to
> > verify that this is indeed what is happening, and then you
> > can call up and complain to your ISP about having their
> > hardware misconfigured.
> > 	1) Ping the web server, if that works:
> > 	2) ping again with large packets (-s 10000)
> > 	3) Try the test to your ISP's router
> > 	4) try "traceroute www.XXX.com 10000", because
> > 	   the return packets are small, that will
> > 	   succeed where pint -s 10000 won't.
>
> This is indistinguishable from an ICMP-filtering-induced
> PMTU blackhole, though.

Not neccessarily.  If the web site is behind an ICMP-filtering
router at the remote end, you'll be able to do "ping -s 10000"
to the machines in front of the firewall.  If it is the ISP's
router that is misconfigured, the "ping -s 10000" will fail on
anything after your local ISP router, but the traceroute will
succeed.
		-David Borman, [email-masked]