patch-2.2.15 linux/net/ipv4/tcp_timer.c
Next file: linux/net/ipv4/udp.c
Previous file: linux/net/ipv4/tcp_output.c
Back to the patch index
Back to the overall index
- Lines: 88
- Date:
Fri Apr 21 12:47:15 2000
- Orig file:
v2.2.14/net/ipv4/tcp_timer.c
- Orig date:
Tue Jan 4 21:19:03 2000
diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_timer.c,v 1.62.2.4 1999/09/23 19:21:39 davem Exp $
+ * Version: $Id: tcp_timer.c,v 1.62.2.6 2000/01/13 04:28:06 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -131,6 +131,7 @@
} else {
/* Clean up time. */
tcp_set_state(sk, TCP_CLOSE);
+ sk->shutdown |= SHUTDOWN_MASK;
return 0;
}
return 1;
@@ -140,26 +141,46 @@
static int tcp_write_timeout(struct sock *sk)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ unsigned char orig_state = sk->state;
+ int ret;
/* Look for a 'soft' timeout. */
- if ((sk->state == TCP_ESTABLISHED &&
+ if ((orig_state == TCP_ESTABLISHED &&
tp->retransmits && (tp->retransmits % TCP_QUICK_TRIES) == 0) ||
- (sk->state != TCP_ESTABLISHED && tp->retransmits > sysctl_tcp_retries1)) {
+ (orig_state != TCP_ESTABLISHED && tp->retransmits > sysctl_tcp_retries1)) {
dst_negative_advice(&sk->dst_cache);
}
/* Have we tried to SYN too many times (repent repent 8)) */
- if(tp->retransmits > sysctl_tcp_syn_retries && sk->state==TCP_SYN_SENT) {
+ if(tp->retransmits > sysctl_tcp_syn_retries && orig_state==TCP_SYN_SENT) {
tcp_write_err(sk, 1);
+
/* Don't FIN, we got nothing back */
- return 0;
+ ret = 0;
+ } else {
+ /* Has it gone just too far? */
+ if (tp->retransmits > sysctl_tcp_retries2)
+ ret = tcp_write_err(sk, 0);
+ else
+ ret = 1;
}
- /* Has it gone just too far? */
- if (tp->retransmits > sysctl_tcp_retries2)
- return tcp_write_err(sk, 0);
+ /* Did we timeout a connecting socket? The check must be
+ * like this just in case someone sets syn_retries larger
+ * than retries2, which is silly but handle it. -DaveM
+ */
+ if (orig_state == TCP_SYN_SENT && sk->state == TCP_CLOSE) {
+ /* Back out identity changes done by connect.
+ * The move to TCP_CLOSE has unhashed us and
+ * killed the bind bucket reference, making this
+ * safe. -DaveM
+ */
+ sk->dport = 0;
+ sk->daddr = 0;
+ sk->num = 0;
+ }
- return 1;
+ return ret;
}
void tcp_delack_timer(unsigned long data)
@@ -366,12 +387,14 @@
for(i = chain_start; i < (chain_start + ((tcp_ehash_size/2) >> 2)); i++) {
struct sock *sk = tcp_ehash[i];
while(sk) {
+ struct sock *sk_next = sk->next;
+
if(!atomic_read(&sk->sock_readers) && sk->keepopen) {
count += tcp_keepopen_proc(sk);
if(count == sysctl_tcp_max_ka_probes)
goto out;
}
- sk = sk->next;
+ sk = sk_next;
}
}
out:
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)