diff options
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 1ab341e5d3e0..eccb7165a80c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -384,13 +384,17 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
384 | 384 | ||
385 | /* Connected? */ | 385 | /* Connected? */ |
386 | if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) { | 386 | if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) { |
387 | int target = sock_rcvlowat(sk, 0, INT_MAX); | ||
388 | |||
389 | if (tp->urg_seq == tp->copied_seq && | ||
390 | !sock_flag(sk, SOCK_URGINLINE) && | ||
391 | tp->urg_data) | ||
392 | target--; | ||
393 | |||
387 | /* Potential race condition. If read of tp below will | 394 | /* Potential race condition. If read of tp below will |
388 | * escape above sk->sk_state, we can be illegally awaken | 395 | * escape above sk->sk_state, we can be illegally awaken |
389 | * in SYN_* states. */ | 396 | * in SYN_* states. */ |
390 | if ((tp->rcv_nxt != tp->copied_seq) && | 397 | if (tp->rcv_nxt - tp->copied_seq >= target) |
391 | (tp->urg_seq != tp->copied_seq || | ||
392 | tp->rcv_nxt != tp->copied_seq + 1 || | ||
393 | sock_flag(sk, SOCK_URGINLINE) || !tp->urg_data)) | ||
394 | mask |= POLLIN | POLLRDNORM; | 398 | mask |= POLLIN | POLLRDNORM; |
395 | 399 | ||
396 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { | 400 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { |
@@ -493,10 +497,8 @@ static inline void skb_entail(struct sock *sk, struct sk_buff *skb) | |||
493 | static inline void tcp_mark_urg(struct tcp_sock *tp, int flags, | 497 | static inline void tcp_mark_urg(struct tcp_sock *tp, int flags, |
494 | struct sk_buff *skb) | 498 | struct sk_buff *skb) |
495 | { | 499 | { |
496 | if (flags & MSG_OOB) { | 500 | if (flags & MSG_OOB) |
497 | tp->urg_mode = 1; | ||
498 | tp->snd_up = tp->write_seq; | 501 | tp->snd_up = tp->write_seq; |
499 | } | ||
500 | } | 502 | } |
501 | 503 | ||
502 | static inline void tcp_push(struct sock *sk, int flags, int mss_now, | 504 | static inline void tcp_push(struct sock *sk, int flags, int mss_now, |
@@ -1157,7 +1159,7 @@ static void tcp_prequeue_process(struct sock *sk) | |||
1157 | * necessary */ | 1159 | * necessary */ |
1158 | local_bh_disable(); | 1160 | local_bh_disable(); |
1159 | while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) | 1161 | while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) |
1160 | sk->sk_backlog_rcv(sk, skb); | 1162 | sk_backlog_rcv(sk, skb); |
1161 | local_bh_enable(); | 1163 | local_bh_enable(); |
1162 | 1164 | ||
1163 | /* Clear memory counter. */ | 1165 | /* Clear memory counter. */ |