diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-12-03 22:46:54 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-08 23:17:51 -0500 |
commit | 9327f7053e3993c125944fdb137a0618319ef2a0 (patch) | |
tree | 3cee7de049a2468bef930b1832c42bd1b2e69e9a /include/net/inet_hashtables.h | |
parent | 74757d49016a8b06ca028196886641d7aeb78de5 (diff) |
tcp: Fix a connect() race with timewait sockets
First patch changes __inet_hash_nolisten() and __inet6_hash()
to get a timewait parameter to be able to unhash it from ehash
at same time the new socket is inserted in hash.
This makes sure timewait socket wont be found by a concurrent
writer in __inet_check_established()
Reported-by: kapil dakhane <kdakhane@gmail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/inet_hashtables.h')
-rw-r--r-- | include/net/inet_hashtables.h | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 41cbddd25b70..74358d1b3f43 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h | |||
@@ -251,7 +251,7 @@ extern void inet_put_port(struct sock *sk); | |||
251 | 251 | ||
252 | void inet_hashinfo_init(struct inet_hashinfo *h); | 252 | void inet_hashinfo_init(struct inet_hashinfo *h); |
253 | 253 | ||
254 | extern void __inet_hash_nolisten(struct sock *sk); | 254 | extern int __inet_hash_nolisten(struct sock *sk, struct inet_timewait_sock *tw); |
255 | extern void inet_hash(struct sock *sk); | 255 | extern void inet_hash(struct sock *sk); |
256 | extern void inet_unhash(struct sock *sk); | 256 | extern void inet_unhash(struct sock *sk); |
257 | 257 | ||
@@ -391,10 +391,12 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, | |||
391 | } | 391 | } |
392 | 392 | ||
393 | extern int __inet_hash_connect(struct inet_timewait_death_row *death_row, | 393 | extern int __inet_hash_connect(struct inet_timewait_death_row *death_row, |
394 | struct sock *sk, u32 port_offset, | 394 | struct sock *sk, |
395 | u32 port_offset, | ||
395 | int (*check_established)(struct inet_timewait_death_row *, | 396 | int (*check_established)(struct inet_timewait_death_row *, |
396 | struct sock *, __u16, struct inet_timewait_sock **), | 397 | struct sock *, __u16, struct inet_timewait_sock **), |
397 | void (*hash)(struct sock *sk)); | 398 | int (*hash)(struct sock *sk, struct inet_timewait_sock *twp)); |
399 | |||
398 | extern int inet_hash_connect(struct inet_timewait_death_row *death_row, | 400 | extern int inet_hash_connect(struct inet_timewait_death_row *death_row, |
399 | struct sock *sk); | 401 | struct sock *sk); |
400 | #endif /* _INET_HASHTABLES_H */ | 402 | #endif /* _INET_HASHTABLES_H */ |