Documentation/networking/tcp-thin.txt
        Default: 0
 
+tcp_thin_dupack - BOOLEAN
+       Enable dynamic triggering of retransmissions after one dupACK
+       for thin streams. If set, a check is performed upon reception
+       of a dupACK to determine if the stream is thin (less than 4
+       packets in flight). As long as the stream is found to be thin,
+       data is retransmitted on the first received dupACK. This
+       improves retransmission latency for non-aggressive thin
+       streams, often found to be time-dependent.
+       For more information on thin streams, see
+       Documentation/networking/tcp-thin.txt
+       Default: 0
+
 UDP variables:
 
 udp_mem - vector of 3 INTEGERs: min, pressure, max
 
 #define TCP_MD5SIG             14      /* TCP MD5 Signature (RFC2385) */
 #define TCP_COOKIE_TRANSACTIONS        15      /* TCP Cookie Transactions */
 #define TCP_THIN_LINEAR_TIMEOUTS 16      /* Use linear timeouts for thin streams*/
+#define TCP_THIN_DUPACK         17      /* Fast retrans. after 1 dupack */
 
 /* for TCP_INFO socket option */
 #define TCPI_OPT_TIMESTAMPS    1
        u8      frto_counter;   /* Number of new acks after RTO */
        u8      nonagle     : 4,/* Disable Nagle algorithm?             */
                thin_lto    : 1,/* Use linear timeouts for thin streams */
-               unused      : 3;
+               thin_dupack : 1,/* Fast retransmit on first dupack      */
+               unused      : 2;
 
 /* RTT measurement */
        u32     srtt;           /* smoothed round trip time << 3        */
 
 extern int sysctl_tcp_max_ssthresh;
 extern int sysctl_tcp_cookie_size;
 extern int sysctl_tcp_thin_linear_timeouts;
+extern int sysctl_tcp_thin_dupack;
 
 extern atomic_t tcp_memory_allocated;
 extern struct percpu_counter tcp_sockets_allocated;
 
                .mode           = 0644,
                .proc_handler   = proc_dointvec
        },
+        {
+               .procname       = "tcp_thin_dupack",
+               .data           = &sysctl_tcp_thin_dupack,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec
+       },
        {
                .procname       = "udp_mem",
                .data           = &sysctl_udp_mem,
 
                        tp->thin_lto = val;
                break;
 
+       case TCP_THIN_DUPACK:
+               if (val < 0 || val > 1)
+                       err = -EINVAL;
+               else
+                       tp->thin_dupack = val;
+               break;
+
        case TCP_CORK:
                /* When set indicates to always queue non-full frames.
                 * Later the user clears this option and we transmit
 
 int sysctl_tcp_frto_response __read_mostly;
 int sysctl_tcp_nometrics_save __read_mostly;
 
+int sysctl_tcp_thin_dupack __read_mostly;
+
 int sysctl_tcp_moderate_rcvbuf __read_mostly = 1;
 int sysctl_tcp_abc __read_mostly;
 
                return 1;
        }
 
+       /* If a thin stream is detected, retransmit after first
+        * received dupack. Employ only if SACK is supported in order
+        * to avoid possible corner-case series of spurious retransmissions
+        * Use only if there are no unsent data.
+        */
+       if ((tp->thin_dupack || sysctl_tcp_thin_dupack) &&
+           tcp_stream_is_thin(tp) && tcp_dupack_heuristics(tp) > 1 &&
+           tcp_is_sack(tp) && !tcp_send_head(sk))
+               return 1;
+
        return 0;
 }