tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Trimming TCP options



On 12/30/10 00:45, Greg Troxel wrote:
> Could you explain
>   how long you've been running this
>

This is my workstation, up since yesterday with normal tasks - browsing,
mail, radio, torrents, ssh/telnet/rdp client etc.

$ netstat -p tcp | head -n 30
tcp:
    28575080 packets sent
        22374753 data packets (8869011676 bytes)
        348177 data packets (169228304 bytes) retransmitted
        4891895 ack-only packets (5772157 delayed)
        0 URG only packets
        659 window probe packets
        805796 window update packets
        153802 control packets
        0 send attempts resulted in self-quench
    24712387 packets received
        11815518 acks (for 8297119379 bytes)
        0 duplicate acks
        0 acks for unsent data
        9557536 packets (4436243925 bytes) received in-sequence
        2824139 completely duplicate packets (26028580 bytes)
        1782 old duplicate packets
        19228 packets with some dup. data (4133666 bytes duped)
        273807 out-of-order packets (126071925 bytes)
        0 packets (0 bytes) of data after window
        0 window probes
        77704 window update packets
        92109 packets received after close
        216 discarded for bad checksums
        0 discarded for bad header offset fields
        0 discarded because packet too short
    18219 connection requests
    107319 connection accepts
    118912 connections established (including accepts)
    125808 connections closed (including 1134 drops)


>   the kinds of peers it's been tested against
>

windows, freebsd, linux, cisco, maemo

>   how other implementations behave?  (Specifically, does this make us
>   like the rest, or different?)
>
>
Bytes requested by each option:
          
           SACKP WScale Timestamps Use_EOL

NetBSD      4      4        12      N
FreeBSD*    2-3    3-4    10-13     Y     
Linux-2627  2      4        10      Y  
Win2003     4      4        12      N(?)
Cisco IOS   4      4        10      Y
WinXP       4      4        12      N(?)
Win7        4      4        ?       N(?)
Required    2      3        10**    Y

* - FreeBSD starts/ends SACKPERM at 2 bytes boundary
            ends WScale at 4 bytes boundary
            ends TS at 4 bytes boundary
            starts/ends MSS at 4 bytes boundary
** - 12 for non-SYN segments


Somehow I didn't add tcp_input.c patch in the first mail. I attached it now.

-- 
Mihai

Index: tcp_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v
retrieving revision 1.306
diff -u -p -r1.306 tcp_input.c
--- tcp_input.c 2 Dec 2010 19:07:27 -0000       1.306
+++ tcp_input.c 29 Dec 2010 21:43:04 -0000
@@ -4347,30 +4347,24 @@ syn_cache_respond(struct syn_cache *sc, 
        *optp++ = sc->sc_ourmaxseg & 0xff;
 
        if (sc->sc_request_r_scale != 15) {
-               *((u_int32_t *)optp) = htonl(TCPOPT_NOP << 24 |
-                   TCPOPT_WINDOW << 16 | TCPOLEN_WINDOW << 8 |
-                   sc->sc_request_r_scale);
-               optp += 4;
+               *((u_int32_t *)optp) = htonl(TCPOPT_WINDOW << 24 |
+                   TCPOLEN_WINDOW << 16 | sc->sc_request_r_scale << 8);
+               optp += 3;
        }
 
        if (sc->sc_flags & SCF_TIMESTAMP) {
+               *optp++ = TCPOPT_TIMESTAMP;
+               *optp++ = TCPOLEN_TIMESTAMP;
                u_int32_t *lp = (u_int32_t *)(optp);
-               /* Form timestamp option as shown in appendix A of RFC 1323. */
-               *lp++ = htonl(TCPOPT_TSTAMP_HDR);
                *lp++ = htonl(SYN_CACHE_TIMESTAMP(sc));
                *lp   = htonl(sc->sc_timestamp);
-               optp += TCPOLEN_TSTAMP_APPA;
+               optp += TCPOLEN_TIMESTAMP - 2;
        }
 
        if (sc->sc_flags & SCF_SACK_PERMIT) {
-               u_int8_t *p = optp;
-
                /* Let the peer know that we will SACK. */
-               p[0] = TCPOPT_SACK_PERMITTED;
-               p[1] = 2;
-               p[2] = TCPOPT_NOP;
-               p[3] = TCPOPT_NOP;
-               optp += 4;
+               *optp++ = TCPOPT_SACK_PERMITTED;
+               *optp++ = 2;
        }
 
        /*
@@ -4440,8 +4434,6 @@ syn_cache_respond(struct syn_cache *sc, 
                sigp = optp;
                memset(optp, 0, TCP_SIGLEN);
                optp += TCP_SIGLEN;
-               *optp++ = TCPOPT_NOP;
-               *optp++ = TCPOPT_EOL;
 
                (void)tcp_signature(m, th, hlen, sav, sigp);
 
@@ -4453,7 +4445,12 @@ syn_cache_respond(struct syn_cache *sc, 
 #endif
        }
 #endif
-
+       /* Align options to 32-bit boundary */
+       if ((optp - (u_int8_t *)(th + 1)) % 4) {
+               *optp++ = TCPOPT_EOL;
+               while((optp - (u_int8_t *)(th + 1)) % 4)
+                       *optp++ = 0;
+       }
        /* Compute the packet's checksum. */
        switch (sc->sc_src.sa.sa_family) {
        case AF_INET:


Home | Main Index | Thread Index | Old Index