enum {
TCP_ESTABLISHED = 1,
TCP_SYN_SENT,
TCP_SYN_RECV,
TCP_FIN_WAIT1,
TCP_FIN_WAIT2,
TCP_TIME_WAIT,
TCP_CLOSE,
TCP_CLOSE_WAIT,
TCP_LAST_ACK,
TCP_LISTEN,
TCP_CLOSING, /* Now a valid state */
TCP_MAX_STATES /* Leave at the end! */
};
enum {
TCPF_ESTABLISHED = (1 << 1),
TCPF_SYN_SENT = (1 << 2),
TCPF_SYN_RECV = (1 << 3),
TCPF_FIN_WAIT1 = (1 << 4),
TCPF_FIN_WAIT2 = (1 << 5),
TCPF_TIME_WAIT = (1 << 6),
TCPF_CLOSE = (1 << 7),
TCPF_CLOSE_WAIT = (1 << 8),
TCPF_LAST_ACK = (1 << 9),
TCPF_LISTEN = (1 << 10),
TCPF_CLOSING = (1 << 11)
};
linux-2.6.20/net/ipv4/tcp_timer.c
119~167行:
/* A write timeout has occurred. Process the after effects. */
static int tcp_write_timeout(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct tcp_sock *tp = tcp_sk(sk);
int retry_until;
int mss;
if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
// tcp_syn_retries //
if (icsk->icsk_retransmits)
dst_negative_advice(&sk->sk_dst_cache);
retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
} else {
if (icsk->icsk_retransmits >= sysctl_tcp_retries1) {
// tcp_retries1 //
/* Black hole detection */
if (sysctl_tcp_mtu_probing) {
if (!icsk->icsk_mtup.enabled) {
icsk->icsk_mtup.enabled = 1;
tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
} else {
mss = min(sysctl_tcp_base_mss,
tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low)/2);
mss = max(mss, 68 - tp->tcp_header_len);
icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss);
tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
}
}
dst_negative_advice(&sk->sk_dst_cache);
}
// tcp_retries2 //
retry_until = sysctl_tcp_retries2;
if (sock_flag(sk, SOCK_DEAD)) {
const int alive = (icsk->icsk_rto < TCP_RTO_MAX);
retry_until = tcp_orphan_retries(sk, alive);
if (tcp_out_of_resources(sk, alive || icsk->icsk_retransmits < retry_until))
return 1;
}
}
if (icsk->icsk_retransmits >= retry_until) {
/* Has it gone just too far? */
tcp_write_err(sk);
return 1;
}
return 0;
}
tcp_syn_retries:
(1)主动新建一个连接时(也就是sock处于SYN_SEND状态时),内核要重试发送多少个SYN请求包后才决定放弃;
(2)收到了SYN连接请求后(也就是sock处于SYN_RECV状态时),内核要重试发送多少个ACK确认包才决定放弃? tcp_synack_retries参数一样?
tcp_retries1:
在连接建立过程中(未激活的sock),除了上面的情况以外,内核要重试多少次后才决定放弃连接。
http://blog.csdn.net/zhongruixian/article/details/52488358
tcp_retries2:
在通讯过程中(已激活的sock),数据包发送失败后,内核要重试发送多少次后才决定放弃连接。