kern/60889 - zero IP id change issues in 5.2RC2

Richard Wendland richard at starburst.demon.co.uk
Wed Jan 7 12:23:36 PST 2004


I've been asked (for freebsd-bugs) to open a discussion about PR
kern/60889 on freebsd-net, to decide if a recent change to IP should be
reversed before 5.2-RELEASE (scheduled this month) to give more time
for some serious issues and risks my PR has raised to be considered
and tested.  My proposal is to revert to 5.1 behaviour for now.

The recent change is to emit a zero fragmentation id when DF is set, with
the objective of improving privacy from external id sequence observation,
an issue raised by Steve Bellovin's paper in IMW'02.

I've identified 4 problems with this change:

1) Even with path_mtu_discovery set, for some reason TCP emits FIN-ACK
   without DF.  This causes two problems for this change:

   a) Currently the change doesn't really meet its objective for TCP,
      it just means FIN-ACK must be observed.

   b) Because now just one id is consumed per TCP connection on the
      FIN-ACK, for most/many systems id becomes a close approximate
      count of the number of TCP connections it has made, which external
      observers can see, not possible before this change.  To me this
      seems more of a privacy issue for all FreeBSD users than the NAT
      issue in Steve Bellovin's paper this change seeks to solve.

2) Linux made exactly this change some time ago, around Linux 2.4.4,
   but was forced to back-out the change because (I think) of practical
   connectivity issues related to the comment in include/net/ip.h
   ip_select_ident() where it now implements an incrementing ip_id for DF:

     /* This is only to work around buggy Windows95/2000
      * VJ compression implementations.  If the ID field
      * does not change, they drop every other packet in
      * a TCP stream using header compression.
      */

   I'm not aware that anyone checked that this buggy Windows95/2000 VJ
   compression problem is no longer an issue in practice.  I doubt that
   the large web hosters who use FreeBSD would be best-pleased if they
   ran into this for even just a few users - especially as there is no
   config option to disable this change.

3) This change causes ip_id for non-DF to be output in native
   byte order in ip_output.c.  Unfortunately ip_id is still output in
   Network Byte Order in ip_mroute.c and raw_ip.c, so this change risks
   little-endian machines emitting the same fragmentation id at about
   the same time from these different modules, rather than the usual
   64k cycle; creating a small but real risk of re-assembly errors.
   [This isn't in my PR, I've only just noticed it.]

I also have a suspicion that some middle-boxes (like HTTP load-balancers)
may clear DF without setting a fresh IP id - clearing DF would save them
the bother of routing ICMP fragmentation needed back to the source server.
If this is so this is another problem this change could show up which
may cause re-assembly errors.  I know the bug is elsewhere, but it would
still become a practical problem for some FreeBSD users.

So before going with this change I think four things need to be done:

1) TCP changed so FIN-ACK goes out with DF if path_mtu_discovery set.

2) Tests with Windows95/2000 TCP VJ compression (RFC1144) run.

3) ip_id should be emitted in the same byte order everywhere.

4) The change made a config option, so sites can disable it should
   they run into problems, just as RANDOM_IP_ID is an option.

This all seems too much to do for 5.2-RELEASE, and as I think the problems
and risks sufficiently serious, I propose reversing the change until this
can be done.  We need a quick decision on this to get it into 5.2-RELEASE.

The PR has some more detail and tcpdump output demonstrating the
issue:

    http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/60889

The change to be reversed can be seen at:

    http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/netinet/ip_output.c#rev1.189
    http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/netinet/ip_output.c.diff?r1=1.188&r2=1.189

NB If anyone can easily run tests with Windows95/2000 TCP VJ compression that
would be great (using tcpdump to see if there is abnormal retransmission).

NB2 If anyone knows why FIN-ACK goes out without DF that would be helpful.
I've quickly looked at the source, and I can't see why.  It's emitted
as TCP moves from FIN_WAIT_n state to TIME_WAIT probably at line 3091 of
tcp_input.c with a call to tcp_output().  tcp_output() always appears to
set IP_DF at line 998 of tcp_output.c, if path_mtu_discovery is enabled.
A puzzle.

Thanks to Boris Staeblow <bs at dva.in-berlin.de> and Tim Rylance
<tkr at puffball.demon.co.uk> for highlighting this change and helping me
diagnose the issues.

	Richard
-- 
Richard Wendland				richard at wendland.org.uk


More information about the freebsd-net mailing list