aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 2451aeb5ac23..7a0f0b27bf1f 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1081,8 +1081,7 @@ out_err:
1081 * this, no blocking and very strange errors 8) 1081 * this, no blocking and very strange errors 8)
1082 */ 1082 */
1083 1083
1084static int tcp_recv_urg(struct sock *sk, long timeo, 1084static int tcp_recv_urg(struct sock *sk, struct msghdr *msg, int len, int flags)
1085 struct msghdr *msg, int len, int flags)
1086{ 1085{
1087 struct tcp_sock *tp = tcp_sk(sk); 1086 struct tcp_sock *tp = tcp_sk(sk);
1088 1087
@@ -1322,6 +1321,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
1322 struct task_struct *user_recv = NULL; 1321 struct task_struct *user_recv = NULL;
1323 int copied_early = 0; 1322 int copied_early = 0;
1324 struct sk_buff *skb; 1323 struct sk_buff *skb;
1324 u32 urg_hole = 0;
1325 1325
1326 lock_sock(sk); 1326 lock_sock(sk);
1327 1327
@@ -1533,7 +1533,8 @@ do_prequeue:
1533 } 1533 }
1534 } 1534 }
1535 } 1535 }
1536 if ((flags & MSG_PEEK) && peek_seq != tp->copied_seq) { 1536 if ((flags & MSG_PEEK) &&
1537 (peek_seq - copied - urg_hole != tp->copied_seq)) {
1537 if (net_ratelimit()) 1538 if (net_ratelimit())
1538 printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n", 1539 printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n",
1539 current->comm, task_pid_nr(current)); 1540 current->comm, task_pid_nr(current));
@@ -1554,6 +1555,7 @@ do_prequeue:
1554 if (!urg_offset) { 1555 if (!urg_offset) {
1555 if (!sock_flag(sk, SOCK_URGINLINE)) { 1556 if (!sock_flag(sk, SOCK_URGINLINE)) {
1556 ++*seq; 1557 ++*seq;
1558 urg_hole++;
1557 offset++; 1559 offset++;
1558 used--; 1560 used--;
1559 if (!used) 1561 if (!used)
@@ -1697,7 +1699,7 @@ out:
1697 return err; 1699 return err;
1698 1700
1699recv_urg: 1701recv_urg:
1700 err = tcp_recv_urg(sk, timeo, msg, len, flags); 1702 err = tcp_recv_urg(sk, msg, len, flags);
1701 goto out; 1703 goto out;
1702} 1704}
1703 1705
@@ -2512,6 +2514,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb)
2512 struct sk_buff *p; 2514 struct sk_buff *p;
2513 struct tcphdr *th; 2515 struct tcphdr *th;
2514 struct tcphdr *th2; 2516 struct tcphdr *th2;
2517 unsigned int len;
2515 unsigned int thlen; 2518 unsigned int thlen;
2516 unsigned int flags; 2519 unsigned int flags;
2517 unsigned int mss = 1; 2520 unsigned int mss = 1;
@@ -2532,6 +2535,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb)
2532 2535
2533 skb_gro_pull(skb, thlen); 2536 skb_gro_pull(skb, thlen);
2534 2537
2538 len = skb_gro_len(skb);
2535 flags = tcp_flag_word(th); 2539 flags = tcp_flag_word(th);
2536 2540
2537 for (; (p = *head); head = &p->next) { 2541 for (; (p = *head); head = &p->next) {
@@ -2562,7 +2566,7 @@ found:
2562 2566
2563 mss = skb_shinfo(p)->gso_size; 2567 mss = skb_shinfo(p)->gso_size;
2564 2568
2565 flush |= (skb_gro_len(skb) > mss) | !skb_gro_len(skb); 2569 flush |= (len > mss) | !len;
2566 flush |= (ntohl(th2->seq) + skb_gro_len(p)) ^ ntohl(th->seq); 2570 flush |= (ntohl(th2->seq) + skb_gro_len(p)) ^ ntohl(th->seq);
2567 2571
2568 if (flush || skb_gro_receive(head, skb)) { 2572 if (flush || skb_gro_receive(head, skb)) {
@@ -2575,7 +2579,7 @@ found:
2575 tcp_flag_word(th2) |= flags & (TCP_FLAG_FIN | TCP_FLAG_PSH); 2579 tcp_flag_word(th2) |= flags & (TCP_FLAG_FIN | TCP_FLAG_PSH);
2576 2580
2577out_check_final: 2581out_check_final:
2578 flush = skb_gro_len(skb) < mss; 2582 flush = len < mss;
2579 flush |= flags & (TCP_FLAG_URG | TCP_FLAG_PSH | TCP_FLAG_RST | 2583 flush |= flags & (TCP_FLAG_URG | TCP_FLAG_PSH | TCP_FLAG_RST |
2580 TCP_FLAG_SYN | TCP_FLAG_FIN); 2584 TCP_FLAG_SYN | TCP_FLAG_FIN);
2581 2585