xref: /openbmc/linux/net/core/stream.c (revision 3e7759b94a0fcfdd6771caa64a37dda7ce825874)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *     SUCS NET3:
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  *     Generic stream handling routines. These are generic for most
61da177e4SLinus Torvalds  *     protocols. Even IP. Tonight 8-).
71da177e4SLinus Torvalds  *     This is used because TCP, LLC (others too) layer all have mostly
81da177e4SLinus Torvalds  *     identical sendmsg() and recvmsg() code.
91da177e4SLinus Torvalds  *     So we (will) share it here.
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  *     Authors:        Arnaldo Carvalho de Melo <acme@conectiva.com.br>
121da177e4SLinus Torvalds  *                     (from old tcp.c code)
13113aa838SAlan Cox  *                     Alan Cox <alan@lxorguk.ukuu.org.uk> (Borrowed comments 8-))
141da177e4SLinus Torvalds  */
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds #include <linux/module.h>
173f07c014SIngo Molnar #include <linux/sched/signal.h>
181da177e4SLinus Torvalds #include <linux/net.h>
191da177e4SLinus Torvalds #include <linux/signal.h>
201da177e4SLinus Torvalds #include <linux/tcp.h>
211da177e4SLinus Torvalds #include <linux/wait.h>
221da177e4SLinus Torvalds #include <net/sock.h>
231da177e4SLinus Torvalds 
241da177e4SLinus Torvalds /**
251da177e4SLinus Torvalds  * sk_stream_write_space - stream socket write_space callback.
264dc3b16bSPavel Pisa  * @sk: socket
271da177e4SLinus Torvalds  *
281da177e4SLinus Torvalds  * FIXME: write proper description
291da177e4SLinus Torvalds  */
sk_stream_write_space(struct sock * sk)301da177e4SLinus Torvalds void sk_stream_write_space(struct sock *sk)
311da177e4SLinus Torvalds {
321da177e4SLinus Torvalds 	struct socket *sock = sk->sk_socket;
3343815482SEric Dumazet 	struct socket_wq *wq;
341da177e4SLinus Torvalds 
35a74f0fa0SEric Dumazet 	if (__sk_stream_is_writeable(sk, 1) && sock) {
361da177e4SLinus Torvalds 		clear_bit(SOCK_NOSPACE, &sock->flags);
371da177e4SLinus Torvalds 
3843815482SEric Dumazet 		rcu_read_lock();
3943815482SEric Dumazet 		wq = rcu_dereference(sk->sk_wq);
401ce0bf50SHerbert Xu 		if (skwq_has_sleeper(wq))
41a9a08845SLinus Torvalds 			wake_up_interruptible_poll(&wq->wait, EPOLLOUT |
42a9a08845SLinus Torvalds 						EPOLLWRNORM | EPOLLWRBAND);
4343815482SEric Dumazet 		if (wq && wq->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
44ceb5d58bSEric Dumazet 			sock_wake_async(wq, SOCK_WAKE_SPACE, POLL_OUT);
4543815482SEric Dumazet 		rcu_read_unlock();
461da177e4SLinus Torvalds 	}
471da177e4SLinus Torvalds }
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds /**
501da177e4SLinus Torvalds  * sk_stream_wait_connect - Wait for a socket to get into the connected state
514dc3b16bSPavel Pisa  * @sk: sock to wait on
524dc3b16bSPavel Pisa  * @timeo_p: for how long to wait
531da177e4SLinus Torvalds  *
541da177e4SLinus Torvalds  * Must be called with the socket locked.
551da177e4SLinus Torvalds  */
sk_stream_wait_connect(struct sock * sk,long * timeo_p)561da177e4SLinus Torvalds int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
571da177e4SLinus Torvalds {
58d9dc8b0fSWANG Cong 	DEFINE_WAIT_FUNC(wait, woken_wake_function);
591da177e4SLinus Torvalds 	struct task_struct *tsk = current;
606151b31cSHerbert Xu 	int done;
611da177e4SLinus Torvalds 
626151b31cSHerbert Xu 	do {
63c1cbe4b7SBenjamin LaHaise 		int err = sock_error(sk);
64c1cbe4b7SBenjamin LaHaise 		if (err)
65c1cbe4b7SBenjamin LaHaise 			return err;
661da177e4SLinus Torvalds 		if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
671da177e4SLinus Torvalds 			return -EPIPE;
681da177e4SLinus Torvalds 		if (!*timeo_p)
691da177e4SLinus Torvalds 			return -EAGAIN;
701da177e4SLinus Torvalds 		if (signal_pending(tsk))
711da177e4SLinus Torvalds 			return sock_intr_errno(*timeo_p);
721da177e4SLinus Torvalds 
73d9dc8b0fSWANG Cong 		add_wait_queue(sk_sleep(sk), &wait);
741da177e4SLinus Torvalds 		sk->sk_write_pending++;
756151b31cSHerbert Xu 		done = sk_wait_event(sk, timeo_p,
76d0ac89f6SEric Dumazet 				     !READ_ONCE(sk->sk_err) &&
77d0ac89f6SEric Dumazet 				     !((1 << READ_ONCE(sk->sk_state)) &
78d9dc8b0fSWANG Cong 				       ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)), &wait);
79d9dc8b0fSWANG Cong 		remove_wait_queue(sk_sleep(sk), &wait);
801da177e4SLinus Torvalds 		sk->sk_write_pending--;
816151b31cSHerbert Xu 	} while (!done);
82*2ef87ac5SShigeru Yoshida 	return done < 0 ? done : 0;
831da177e4SLinus Torvalds }
841da177e4SLinus Torvalds EXPORT_SYMBOL(sk_stream_wait_connect);
851da177e4SLinus Torvalds 
861da177e4SLinus Torvalds /**
871da177e4SLinus Torvalds  * sk_stream_closing - Return 1 if we still have things to send in our buffers.
884dc3b16bSPavel Pisa  * @sk: socket to verify
891da177e4SLinus Torvalds  */
sk_stream_closing(const struct sock * sk)90d0ac89f6SEric Dumazet static int sk_stream_closing(const struct sock *sk)
911da177e4SLinus Torvalds {
92d0ac89f6SEric Dumazet 	return (1 << READ_ONCE(sk->sk_state)) &
931da177e4SLinus Torvalds 	       (TCPF_FIN_WAIT1 | TCPF_CLOSING | TCPF_LAST_ACK);
941da177e4SLinus Torvalds }
951da177e4SLinus Torvalds 
sk_stream_wait_close(struct sock * sk,long timeout)961da177e4SLinus Torvalds void sk_stream_wait_close(struct sock *sk, long timeout)
971da177e4SLinus Torvalds {
981da177e4SLinus Torvalds 	if (timeout) {
99d9dc8b0fSWANG Cong 		DEFINE_WAIT_FUNC(wait, woken_wake_function);
100d9dc8b0fSWANG Cong 
101d9dc8b0fSWANG Cong 		add_wait_queue(sk_sleep(sk), &wait);
1021da177e4SLinus Torvalds 
1031da177e4SLinus Torvalds 		do {
104d9dc8b0fSWANG Cong 			if (sk_wait_event(sk, &timeout, !sk_stream_closing(sk), &wait))
1051da177e4SLinus Torvalds 				break;
1061da177e4SLinus Torvalds 		} while (!signal_pending(current) && timeout);
1071da177e4SLinus Torvalds 
108d9dc8b0fSWANG Cong 		remove_wait_queue(sk_sleep(sk), &wait);
1091da177e4SLinus Torvalds 	}
1101da177e4SLinus Torvalds }
1111da177e4SLinus Torvalds EXPORT_SYMBOL(sk_stream_wait_close);
1121da177e4SLinus Torvalds 
1131da177e4SLinus Torvalds /**
1141da177e4SLinus Torvalds  * sk_stream_wait_memory - Wait for more memory for a socket
1154dc3b16bSPavel Pisa  * @sk: socket to wait for memory
1164dc3b16bSPavel Pisa  * @timeo_p: for how long
1171da177e4SLinus Torvalds  */
sk_stream_wait_memory(struct sock * sk,long * timeo_p)1181da177e4SLinus Torvalds int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
1191da177e4SLinus Torvalds {
120419ce133SPaolo Abeni 	int ret, err = 0;
1211da177e4SLinus Torvalds 	long vm_wait = 0;
1221da177e4SLinus Torvalds 	long current_timeo = *timeo_p;
123d9dc8b0fSWANG Cong 	DEFINE_WAIT_FUNC(wait, woken_wake_function);
1241da177e4SLinus Torvalds 
1251da177e4SLinus Torvalds 	if (sk_stream_memory_free(sk))
1268032bf12SJason A. Donenfeld 		current_timeo = vm_wait = get_random_u32_below(HZ / 5) + 2;
1271da177e4SLinus Torvalds 
128d9dc8b0fSWANG Cong 	add_wait_queue(sk_sleep(sk), &wait);
129d9dc8b0fSWANG Cong 
1301da177e4SLinus Torvalds 	while (1) {
1319cd3e072SEric Dumazet 		sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds 		if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
1341da177e4SLinus Torvalds 			goto do_error;
135ef8d8ccdSEric Dumazet 		if (!*timeo_p)
136ef8d8ccdSEric Dumazet 			goto do_eagain;
1371da177e4SLinus Torvalds 		if (signal_pending(current))
1381da177e4SLinus Torvalds 			goto do_interrupted;
1399cd3e072SEric Dumazet 		sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
1401da177e4SLinus Torvalds 		if (sk_stream_memory_free(sk) && !vm_wait)
1411da177e4SLinus Torvalds 			break;
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds 		set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1441da177e4SLinus Torvalds 		sk->sk_write_pending++;
145419ce133SPaolo Abeni 		ret = sk_wait_event(sk, &current_timeo, READ_ONCE(sk->sk_err) ||
146d0ac89f6SEric Dumazet 				    (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) ||
147419ce133SPaolo Abeni 				    (sk_stream_memory_free(sk) && !vm_wait),
148419ce133SPaolo Abeni 				    &wait);
1491da177e4SLinus Torvalds 		sk->sk_write_pending--;
150419ce133SPaolo Abeni 		if (ret < 0)
151419ce133SPaolo Abeni 			goto do_error;
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds 		if (vm_wait) {
1541da177e4SLinus Torvalds 			vm_wait -= current_timeo;
1551da177e4SLinus Torvalds 			current_timeo = *timeo_p;
1561da177e4SLinus Torvalds 			if (current_timeo != MAX_SCHEDULE_TIMEOUT &&
1571da177e4SLinus Torvalds 			    (current_timeo -= vm_wait) < 0)
1581da177e4SLinus Torvalds 				current_timeo = 0;
1591da177e4SLinus Torvalds 			vm_wait = 0;
1601da177e4SLinus Torvalds 		}
1611da177e4SLinus Torvalds 		*timeo_p = current_timeo;
1621da177e4SLinus Torvalds 	}
1631da177e4SLinus Torvalds out:
1643f8ef65aSLiu Jian 	if (!sock_flag(sk, SOCK_DEAD))
165d9dc8b0fSWANG Cong 		remove_wait_queue(sk_sleep(sk), &wait);
1661da177e4SLinus Torvalds 	return err;
1671da177e4SLinus Torvalds 
1681da177e4SLinus Torvalds do_error:
1691da177e4SLinus Torvalds 	err = -EPIPE;
1701da177e4SLinus Torvalds 	goto out;
171ef8d8ccdSEric Dumazet do_eagain:
172ef8d8ccdSEric Dumazet 	/* Make sure that whenever EAGAIN is returned, EPOLLOUT event can
173ef8d8ccdSEric Dumazet 	 * be generated later.
174ef8d8ccdSEric Dumazet 	 * When TCP receives ACK packets that make room, tcp_check_space()
175ef8d8ccdSEric Dumazet 	 * only calls tcp_new_space() if SOCK_NOSPACE is set.
176ef8d8ccdSEric Dumazet 	 */
177ef8d8ccdSEric Dumazet 	set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1781da177e4SLinus Torvalds 	err = -EAGAIN;
1791da177e4SLinus Torvalds 	goto out;
1801da177e4SLinus Torvalds do_interrupted:
1811da177e4SLinus Torvalds 	err = sock_intr_errno(*timeo_p);
1821da177e4SLinus Torvalds 	goto out;
1831da177e4SLinus Torvalds }
1841da177e4SLinus Torvalds EXPORT_SYMBOL(sk_stream_wait_memory);
1851da177e4SLinus Torvalds 
sk_stream_error(struct sock * sk,int flags,int err)1861da177e4SLinus Torvalds int sk_stream_error(struct sock *sk, int flags, int err)
1871da177e4SLinus Torvalds {
1881da177e4SLinus Torvalds 	if (err == -EPIPE)
1891da177e4SLinus Torvalds 		err = sock_error(sk) ? : -EPIPE;
1901da177e4SLinus Torvalds 	if (err == -EPIPE && !(flags & MSG_NOSIGNAL))
1911da177e4SLinus Torvalds 		send_sig(SIGPIPE, current, 0);
1921da177e4SLinus Torvalds 	return err;
1931da177e4SLinus Torvalds }
1941da177e4SLinus Torvalds EXPORT_SYMBOL(sk_stream_error);
1951da177e4SLinus Torvalds 
sk_stream_kill_queues(struct sock * sk)1961da177e4SLinus Torvalds void sk_stream_kill_queues(struct sock *sk)
1971da177e4SLinus Torvalds {
1981da177e4SLinus Torvalds 	/* First the read buffer. */
1991da177e4SLinus Torvalds 	__skb_queue_purge(&sk->sk_receive_queue);
2001da177e4SLinus Torvalds 
201e0c8bccdSEric Dumazet 	/* Next, the error queue.
202e0c8bccdSEric Dumazet 	 * We need to use queue lock, because other threads might
203e0c8bccdSEric Dumazet 	 * add packets to the queue without socket lock being held.
204e0c8bccdSEric Dumazet 	 */
205e0c8bccdSEric Dumazet 	skb_queue_purge(&sk->sk_error_queue);
206e0c8bccdSEric Dumazet 
2071da177e4SLinus Torvalds 	/* Next, the write queue. */
208c59f02f8SEric Dumazet 	WARN_ON_ONCE(!skb_queue_empty(&sk->sk_write_queue));
2091da177e4SLinus Torvalds 
2101da177e4SLinus Torvalds 	/* Account for returned memory. */
2112bb2f5fbSWei Wang 	sk_mem_reclaim_final(sk);
2121da177e4SLinus Torvalds 
213c59f02f8SEric Dumazet 	WARN_ON_ONCE(sk->sk_wmem_queued);
2141da177e4SLinus Torvalds 
2151da177e4SLinus Torvalds 	/* It is _impossible_ for the backlog to contain anything
2161da177e4SLinus Torvalds 	 * when we get here.  All user references to this socket
2171da177e4SLinus Torvalds 	 * have gone away, only the net layer knows can touch it.
2181da177e4SLinus Torvalds 	 */
2191da177e4SLinus Torvalds }
2201da177e4SLinus Torvalds EXPORT_SYMBOL(sk_stream_kill_queues);
221