diff options
author | Kacheong Poon <Kacheong.Poon@Sun.COM> | 2010-06-03 09:14:53 -0700 |
---|---|---|
committer | Kacheong Poon <Kacheong.Poon@Sun.COM> | 2010-06-03 09:14:53 -0700 |
commit | 707e74bc53cd429bcd731df722227c7dc2de47c6 (patch) | |
tree | 0f2a109c8010346e27f6d1836d8dca9444a89204 /usr/src/uts/common/inet/tcp/tcp_timers.c | |
parent | ef497ae340a97bcb1bdee3babfa67414def6d8ca (diff) | |
download | illumos-gate-707e74bc53cd429bcd731df722227c7dc2de47c6.tar.gz |
PSARC 2010/151 new socket options for TCP timers
6955557 Various new TCP socket options
Diffstat (limited to 'usr/src/uts/common/inet/tcp/tcp_timers.c')
-rw-r--r-- | usr/src/uts/common/inet/tcp/tcp_timers.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/usr/src/uts/common/inet/tcp/tcp_timers.c b/usr/src/uts/common/inet/tcp/tcp_timers.c index f2eaa3a958..d0e0401857 100644 --- a/usr/src/uts/common/inet/tcp/tcp_timers.c +++ b/usr/src/uts/common/inet/tcp/tcp_timers.c @@ -460,9 +460,9 @@ tcp_keepalive_timer(void *arg) /* * We should probe again at least * in ka_intrvl, but not more than - * tcp_rexmit_interval_max. + * tcp_rto_max. */ - max = tcps->tcps_rexmit_interval_max; + max = tcp->tcp_rto_max; firetime = MIN(ka_intrvl - 1, tcp->tcp_ka_last_intrvl << 1); if (firetime > max) @@ -624,6 +624,7 @@ tcp_timer(void *arg) conn_t *connp = (conn_t *)arg; tcp_t *tcp = connp->conn_tcp; tcp_stack_t *tcps = tcp->tcp_tcps; + boolean_t dont_timeout = B_FALSE; tcp->tcp_timer_tid = 0; @@ -693,11 +694,29 @@ tcp_timer(void *arg) case TCPS_SYN_SENT: first_threshold = tcp->tcp_first_ctimer_threshold; second_threshold = tcp->tcp_second_ctimer_threshold; + + /* Retransmit forever unless this is a passive open... */ + if (second_threshold == 0) { + if (!tcp->tcp_active_open) { + second_threshold = + tcps->tcps_ip_abort_linterval; + } else { + dont_timeout = B_TRUE; + } + } break; case TCPS_ESTABLISHED: + case TCPS_CLOSE_WAIT: + /* + * If the end point has not been closed, TCP can retransmit + * forever. But if the end point is closed, the normal + * timeout applies. + */ + if (second_threshold == 0) + dont_timeout = B_TRUE; + /* FALLTHRU */ case TCPS_FIN_WAIT_1: case TCPS_CLOSING: - case TCPS_CLOSE_WAIT: case TCPS_LAST_ACK: /* If we have data to rexmit */ if (tcp->tcp_suna != tcp->tcp_snxt) { @@ -844,7 +863,7 @@ tcp_timer(void *arg) (void) tcp_clean_death(tcp, 0); } else { TCP_TIMER_RESTART(tcp, - tcps->tcps_fin_wait_2_flush_interval); + tcp->tcp_fin_wait_2_flush_interval); } return; case TCPS_TIME_WAIT: @@ -868,8 +887,14 @@ tcp_timer(void *arg) if (tcps->tcps_reclaim || (tcp->tcp_listen_cnt != NULL && tcp->tcp_listen_cnt->tlc_cnt > tcp->tcp_listen_cnt->tlc_max)) { second_threshold = tcp_early_abort * SECONDS; + + /* We will ignore the never timeout promise in this case... */ + dont_timeout = B_FALSE; } + if (!dont_timeout && second_threshold == 0) + second_threshold = tcps->tcps_ip_abort_interval; + if ((ms = tcp->tcp_ms_we_have_waited) > second_threshold) { /* * Should not hold the zero-copy messages for too long. @@ -878,6 +903,9 @@ tcp_timer(void *arg) tcp->tcp_xmit_head = tcp_zcopy_backoff(tcp, tcp->tcp_xmit_head, B_TRUE); + if (dont_timeout) + goto timer_rexmit; + /* * For zero window probe, we need to send indefinitely, * unless we have not heard from the other side for some @@ -923,10 +951,10 @@ tcp_timer(void *arg) * We don't need to decrement tcp_timer_backoff * to avoid overflow because it will be decremented * later if new timeout value is greater than - * tcp_rexmit_interval_max. In the case when - * tcp_rexmit_interval_max is greater than - * second_threshold, it means that we will wait - * longer than second_threshold to send the next + * tcp_rto_max. In the case when tcp_rto_max is + * greater than second_threshold, it means that we + * will wait longer than second_threshold to send + * the next * window probe. */ tcp->tcp_ms_we_have_waited = second_threshold; @@ -955,21 +983,23 @@ tcp_timer(void *arg) tcp->tcp_rtt_update = 0; } } + +timer_rexmit: tcp->tcp_timer_backoff++; if ((ms = (tcp->tcp_rtt_sa >> 3) + tcp->tcp_rtt_sd + tcps->tcps_rexmit_interval_extra + (tcp->tcp_rtt_sa >> 5)) < - tcps->tcps_rexmit_interval_min) { + tcp->tcp_rto_min) { /* * This means the original RTO is tcp_rexmit_interval_min. * So we will use tcp_rexmit_interval_min as the RTO value * and do the backoff. */ - ms = tcps->tcps_rexmit_interval_min << tcp->tcp_timer_backoff; + ms = tcp->tcp_rto_min << tcp->tcp_timer_backoff; } else { ms <<= tcp->tcp_timer_backoff; } - if (ms > tcps->tcps_rexmit_interval_max) { - ms = tcps->tcps_rexmit_interval_max; + if (ms > tcp->tcp_rto_max) { + ms = tcp->tcp_rto_max; /* * ms is at max, decrement tcp_timer_backoff to avoid * overflow. |