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.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 4028ddd14dd5..868ed74a76a8 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1889,6 +1889,22 @@ static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
1889 } 1889 }
1890} 1890}
1891 1891
1892static int tcp_inq_hint(struct sock *sk)
1893{
1894 const struct tcp_sock *tp = tcp_sk(sk);
1895 u32 copied_seq = READ_ONCE(tp->copied_seq);
1896 u32 rcv_nxt = READ_ONCE(tp->rcv_nxt);
1897 int inq;
1898
1899 inq = rcv_nxt - copied_seq;
1900 if (unlikely(inq < 0 || copied_seq != READ_ONCE(tp->copied_seq))) {
1901 lock_sock(sk);
1902 inq = tp->rcv_nxt - tp->copied_seq;
1903 release_sock(sk);
1904 }
1905 return inq;
1906}
1907
1892/* 1908/*
1893 * This routine copies from a sock struct into the user buffer. 1909 * This routine copies from a sock struct into the user buffer.
1894 * 1910 *
@@ -1905,13 +1921,14 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
1905 u32 peek_seq; 1921 u32 peek_seq;
1906 u32 *seq; 1922 u32 *seq;
1907 unsigned long used; 1923 unsigned long used;
1908 int err; 1924 int err, inq;
1909 int target; /* Read at least this many bytes */ 1925 int target; /* Read at least this many bytes */
1910 long timeo; 1926 long timeo;
1911 struct sk_buff *skb, *last; 1927 struct sk_buff *skb, *last;
1912 u32 urg_hole = 0; 1928 u32 urg_hole = 0;
1913 struct scm_timestamping tss; 1929 struct scm_timestamping tss;
1914 bool has_tss = false; 1930 bool has_tss = false;
1931 bool has_cmsg;
1915 1932
1916 if (unlikely(flags & MSG_ERRQUEUE)) 1933 if (unlikely(flags & MSG_ERRQUEUE))
1917 return inet_recv_error(sk, msg, len, addr_len); 1934 return inet_recv_error(sk, msg, len, addr_len);
@@ -1926,6 +1943,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
1926 if (sk->sk_state == TCP_LISTEN) 1943 if (sk->sk_state == TCP_LISTEN)
1927 goto out; 1944 goto out;
1928 1945
1946 has_cmsg = tp->recvmsg_inq;
1929 timeo = sock_rcvtimeo(sk, nonblock); 1947 timeo = sock_rcvtimeo(sk, nonblock);
1930 1948
1931 /* Urgent data needs to be handled specially. */ 1949 /* Urgent data needs to be handled specially. */
@@ -2112,6 +2130,7 @@ skip_copy:
2112 if (TCP_SKB_CB(skb)->has_rxtstamp) { 2130 if (TCP_SKB_CB(skb)->has_rxtstamp) {
2113 tcp_update_recv_tstamps(skb, &tss); 2131 tcp_update_recv_tstamps(skb, &tss);
2114 has_tss = true; 2132 has_tss = true;
2133 has_cmsg = true;
2115 } 2134 }
2116 if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) 2135 if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
2117 goto found_fin_ok; 2136 goto found_fin_ok;
@@ -2131,13 +2150,20 @@ skip_copy:
2131 * on connected socket. I was just happy when found this 8) --ANK 2150 * on connected socket. I was just happy when found this 8) --ANK
2132 */ 2151 */
2133 2152
2134 if (has_tss)
2135 tcp_recv_timestamp(msg, sk, &tss);
2136
2137 /* Clean up data we have read: This will do ACK frames. */ 2153 /* Clean up data we have read: This will do ACK frames. */
2138 tcp_cleanup_rbuf(sk, copied); 2154 tcp_cleanup_rbuf(sk, copied);
2139 2155
2140 release_sock(sk); 2156 release_sock(sk);
2157
2158 if (has_cmsg) {
2159 if (has_tss)
2160 tcp_recv_timestamp(msg, sk, &tss);
2161 if (tp->recvmsg_inq) {
2162 inq = tcp_inq_hint(sk);
2163 put_cmsg(msg, SOL_TCP, TCP_CM_INQ, sizeof(inq), &inq);
2164 }
2165 }
2166
2141 return copied; 2167 return copied;
2142 2168
2143out: 2169out:
@@ -3006,6 +3032,12 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
3006 tp->notsent_lowat = val; 3032 tp->notsent_lowat = val;
3007 sk->sk_write_space(sk); 3033 sk->sk_write_space(sk);
3008 break; 3034 break;
3035 case TCP_INQ:
3036 if (val > 1 || val < 0)
3037 err = -EINVAL;
3038 else
3039 tp->recvmsg_inq = val;
3040 break;
3009 default: 3041 default:
3010 err = -ENOPROTOOPT; 3042 err = -ENOPROTOOPT;
3011 break; 3043 break;
@@ -3431,6 +3463,9 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
3431 case TCP_NOTSENT_LOWAT: 3463 case TCP_NOTSENT_LOWAT:
3432 val = tp->notsent_lowat; 3464 val = tp->notsent_lowat;
3433 break; 3465 break;
3466 case TCP_INQ:
3467 val = tp->recvmsg_inq;
3468 break;
3434 case TCP_SAVE_SYN: 3469 case TCP_SAVE_SYN:
3435 val = tp->save_syn; 3470 val = tp->save_syn;
3436 break; 3471 break;