patch-2.3.51 linux/net/ipv4/tcp.c
Next file: linux/net/ipv4/tcp_ipv4.c
Previous file: linux/net/econet/sysctl_net_ec.c
Back to the patch index
Back to the overall index
- Lines: 57
- Date:
Thu Mar 9 06:57:17 2000
- Orig file:
v2.3.50/linux/net/ipv4/tcp.c
- Orig date:
Thu Feb 10 17:11:24 2000
diff -u --recursive --new-file v2.3.50/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp.c,v 1.163 2000/02/08 21:27:13 davem Exp $
+ * Version: $Id: tcp.c,v 1.164 2000/03/08 19:36:40 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -624,28 +624,29 @@
tp->listen_opt = lopt;
write_unlock_bh(&tp->syn_wait_lock);
+ /* There is race window here: we announce ourselves listening,
+ * but this transition is still not validated by get_port().
+ * It is OK, because this socket enters to hash table only
+ * after validation is complete.
+ */
sk->state = TCP_LISTEN;
- if (sk->num == 0) {
- if (sk->prot->get_port(sk, 0) != 0) {
- sk->state = TCP_CLOSE;
- write_lock_bh(&tp->syn_wait_lock);
- tp->listen_opt = NULL;
- write_unlock_bh(&tp->syn_wait_lock);
- kfree(lopt);
- return -EAGAIN;
- }
+ if (sk->prot->get_port(sk, sk->num) == 0) {
sk->sport = htons(sk->num);
- } else {
- if (sk->prev)
- ((struct tcp_bind_bucket*)sk->prev)->fastreuse = 0;
- }
- sk_dst_reset(sk);
- sk->prot->hash(sk);
- sk->socket->flags |= SO_ACCEPTCON;
- sk->write_space = tcp_listen_write_space;
+ sk->write_space = tcp_listen_write_space;
+ sk_dst_reset(sk);
+ sk->prot->hash(sk);
+ sk->socket->flags |= SO_ACCEPTCON;
- return 0;
+ return 0;
+ }
+
+ sk->state = TCP_CLOSE;
+ write_lock_bh(&tp->syn_wait_lock);
+ tp->listen_opt = NULL;
+ write_unlock_bh(&tp->syn_wait_lock);
+ kfree(lopt);
+ return -EADDRINUSE;
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)