xref: /linux/net/core/stream.c (revision 01b944fe1cd4e21a2a9ed51adbdbafe2d5e905ba)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *     SUCS NET3:
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  *     Generic stream handling routines. These are generic for most
51da177e4SLinus Torvalds  *     protocols. Even IP. Tonight 8-).
61da177e4SLinus Torvalds  *     This is used because TCP, LLC (others too) layer all have mostly
71da177e4SLinus Torvalds  *     identical sendmsg() and recvmsg() code.
81da177e4SLinus Torvalds  *     So we (will) share it here.
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  *     Authors:        Arnaldo Carvalho de Melo <acme@conectiva.com.br>
111da177e4SLinus Torvalds  *                     (from old tcp.c code)
12113aa838SAlan Cox  *                     Alan Cox <alan@lxorguk.ukuu.org.uk> (Borrowed comments 8-))
131da177e4SLinus Torvalds  */
141da177e4SLinus Torvalds 
151da177e4SLinus Torvalds #include <linux/module.h>
161da177e4SLinus Torvalds #include <linux/net.h>
171da177e4SLinus Torvalds #include <linux/signal.h>
181da177e4SLinus Torvalds #include <linux/tcp.h>
191da177e4SLinus Torvalds #include <linux/wait.h>
201da177e4SLinus Torvalds #include <net/sock.h>
211da177e4SLinus Torvalds 
221da177e4SLinus Torvalds /**
231da177e4SLinus Torvalds  * sk_stream_write_space - stream socket write_space callback.
244dc3b16bSPavel Pisa  * @sk: socket
251da177e4SLinus Torvalds  *
261da177e4SLinus Torvalds  * FIXME: write proper description
271da177e4SLinus Torvalds  */
281da177e4SLinus Torvalds void sk_stream_write_space(struct sock *sk)
291da177e4SLinus Torvalds {
301da177e4SLinus Torvalds 	struct socket *sock = sk->sk_socket;
3143815482SEric Dumazet 	struct socket_wq *wq;
321da177e4SLinus Torvalds 
3364dc6130SEric Dumazet 	if (sk_stream_is_writeable(sk) && sock) {
341da177e4SLinus Torvalds 		clear_bit(SOCK_NOSPACE, &sock->flags);
351da177e4SLinus Torvalds 
3643815482SEric Dumazet 		rcu_read_lock();
3743815482SEric Dumazet 		wq = rcu_dereference(sk->sk_wq);
3843815482SEric Dumazet 		if (wq_has_sleeper(wq))
3943815482SEric Dumazet 			wake_up_interruptible_poll(&wq->wait, POLLOUT |
409dc20c5fSJohn Dykstra 						POLLWRNORM | POLLWRBAND);
4143815482SEric Dumazet 		if (wq && wq->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
428d8ad9d7SPavel Emelyanov 			sock_wake_async(sock, SOCK_WAKE_SPACE, POLL_OUT);
4343815482SEric Dumazet 		rcu_read_unlock();
441da177e4SLinus Torvalds 	}
451da177e4SLinus Torvalds }
461da177e4SLinus Torvalds EXPORT_SYMBOL(sk_stream_write_space);
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds /**
491da177e4SLinus Torvalds  * sk_stream_wait_connect - Wait for a socket to get into the connected state
504dc3b16bSPavel Pisa  * @sk: sock to wait on
514dc3b16bSPavel Pisa  * @timeo_p: for how long to wait
521da177e4SLinus Torvalds  *
531da177e4SLinus Torvalds  * Must be called with the socket locked.
541da177e4SLinus Torvalds  */
551da177e4SLinus Torvalds int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
561da177e4SLinus Torvalds {
571da177e4SLinus Torvalds 	struct task_struct *tsk = current;
581da177e4SLinus Torvalds 	DEFINE_WAIT(wait);
596151b31cSHerbert Xu 	int done;
601da177e4SLinus Torvalds 
616151b31cSHerbert Xu 	do {
62c1cbe4b7SBenjamin LaHaise 		int err = sock_error(sk);
63c1cbe4b7SBenjamin LaHaise 		if (err)
64c1cbe4b7SBenjamin LaHaise 			return err;
651da177e4SLinus Torvalds 		if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
661da177e4SLinus Torvalds 			return -EPIPE;
671da177e4SLinus Torvalds 		if (!*timeo_p)
681da177e4SLinus Torvalds 			return -EAGAIN;
691da177e4SLinus Torvalds 		if (signal_pending(tsk))
701da177e4SLinus Torvalds 			return sock_intr_errno(*timeo_p);
711da177e4SLinus Torvalds 
72aa395145SEric Dumazet 		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
731da177e4SLinus Torvalds 		sk->sk_write_pending++;
746151b31cSHerbert Xu 		done = sk_wait_event(sk, timeo_p,
75c1cbe4b7SBenjamin LaHaise 				     !sk->sk_err &&
761da177e4SLinus Torvalds 				     !((1 << sk->sk_state) &
776151b31cSHerbert Xu 				       ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
78aa395145SEric Dumazet 		finish_wait(sk_sleep(sk), &wait);
791da177e4SLinus Torvalds 		sk->sk_write_pending--;
806151b31cSHerbert Xu 	} while (!done);
811da177e4SLinus Torvalds 	return 0;
821da177e4SLinus Torvalds }
831da177e4SLinus Torvalds EXPORT_SYMBOL(sk_stream_wait_connect);
841da177e4SLinus Torvalds 
851da177e4SLinus Torvalds /**
861da177e4SLinus Torvalds  * sk_stream_closing - Return 1 if we still have things to send in our buffers.
874dc3b16bSPavel Pisa  * @sk: socket to verify
881da177e4SLinus Torvalds  */
891da177e4SLinus Torvalds static inline int sk_stream_closing(struct sock *sk)
901da177e4SLinus Torvalds {
911da177e4SLinus Torvalds 	return (1 << sk->sk_state) &
921da177e4SLinus Torvalds 	       (TCPF_FIN_WAIT1 | TCPF_CLOSING | TCPF_LAST_ACK);
931da177e4SLinus Torvalds }
941da177e4SLinus Torvalds 
951da177e4SLinus Torvalds void sk_stream_wait_close(struct sock *sk, long timeout)
961da177e4SLinus Torvalds {
971da177e4SLinus Torvalds 	if (timeout) {
981da177e4SLinus Torvalds 		DEFINE_WAIT(wait);
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds 		do {
101aa395145SEric Dumazet 			prepare_to_wait(sk_sleep(sk), &wait,
1021da177e4SLinus Torvalds 					TASK_INTERRUPTIBLE);
1031da177e4SLinus Torvalds 			if (sk_wait_event(sk, &timeout, !sk_stream_closing(sk)))
1041da177e4SLinus Torvalds 				break;
1051da177e4SLinus Torvalds 		} while (!signal_pending(current) && timeout);
1061da177e4SLinus Torvalds 
107aa395145SEric Dumazet 		finish_wait(sk_sleep(sk), &wait);
1081da177e4SLinus Torvalds 	}
1091da177e4SLinus Torvalds }
1101da177e4SLinus Torvalds EXPORT_SYMBOL(sk_stream_wait_close);
1111da177e4SLinus Torvalds 
1121da177e4SLinus Torvalds /**
1131da177e4SLinus Torvalds  * sk_stream_wait_memory - Wait for more memory for a socket
1144dc3b16bSPavel Pisa  * @sk: socket to wait for memory
1154dc3b16bSPavel Pisa  * @timeo_p: for how long
1161da177e4SLinus Torvalds  */
1171da177e4SLinus Torvalds int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
1181da177e4SLinus Torvalds {
1191da177e4SLinus Torvalds 	int err = 0;
1201da177e4SLinus Torvalds 	long vm_wait = 0;
1211da177e4SLinus Torvalds 	long current_timeo = *timeo_p;
122790ba456SJason Baron 	bool noblock = (*timeo_p ? false : true);
1231da177e4SLinus Torvalds 	DEFINE_WAIT(wait);
1241da177e4SLinus Torvalds 
1251da177e4SLinus Torvalds 	if (sk_stream_memory_free(sk))
12663862b5bSAruna-Hewapathirane 		current_timeo = vm_wait = (prandom_u32() % (HZ / 5)) + 2;
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds 	while (1) {
1291da177e4SLinus Torvalds 		set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
1301da177e4SLinus Torvalds 
131aa395145SEric Dumazet 		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds 		if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
1341da177e4SLinus Torvalds 			goto do_error;
135790ba456SJason Baron 		if (!*timeo_p) {
136790ba456SJason Baron 			if (noblock)
137790ba456SJason Baron 				set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1381da177e4SLinus Torvalds 			goto do_nonblock;
139790ba456SJason Baron 		}
1401da177e4SLinus Torvalds 		if (signal_pending(current))
1411da177e4SLinus Torvalds 			goto do_interrupted;
1421da177e4SLinus Torvalds 		clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
1431da177e4SLinus Torvalds 		if (sk_stream_memory_free(sk) && !vm_wait)
1441da177e4SLinus Torvalds 			break;
1451da177e4SLinus Torvalds 
1461da177e4SLinus Torvalds 		set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1471da177e4SLinus Torvalds 		sk->sk_write_pending++;
148482964e5SNagendra Tomar 		sk_wait_event(sk, &current_timeo, sk->sk_err ||
149482964e5SNagendra Tomar 						  (sk->sk_shutdown & SEND_SHUTDOWN) ||
150482964e5SNagendra Tomar 						  (sk_stream_memory_free(sk) &&
151482964e5SNagendra Tomar 						  !vm_wait));
1521da177e4SLinus Torvalds 		sk->sk_write_pending--;
1531da177e4SLinus Torvalds 
1541da177e4SLinus Torvalds 		if (vm_wait) {
1551da177e4SLinus Torvalds 			vm_wait -= current_timeo;
1561da177e4SLinus Torvalds 			current_timeo = *timeo_p;
1571da177e4SLinus Torvalds 			if (current_timeo != MAX_SCHEDULE_TIMEOUT &&
1581da177e4SLinus Torvalds 			    (current_timeo -= vm_wait) < 0)
1591da177e4SLinus Torvalds 				current_timeo = 0;
1601da177e4SLinus Torvalds 			vm_wait = 0;
1611da177e4SLinus Torvalds 		}
1621da177e4SLinus Torvalds 		*timeo_p = current_timeo;
1631da177e4SLinus Torvalds 	}
1641da177e4SLinus Torvalds out:
165aa395145SEric Dumazet 	finish_wait(sk_sleep(sk), &wait);
1661da177e4SLinus Torvalds 	return err;
1671da177e4SLinus Torvalds 
1681da177e4SLinus Torvalds do_error:
1691da177e4SLinus Torvalds 	err = -EPIPE;
1701da177e4SLinus Torvalds 	goto out;
1711da177e4SLinus Torvalds do_nonblock:
1721da177e4SLinus Torvalds 	err = -EAGAIN;
1731da177e4SLinus Torvalds 	goto out;
1741da177e4SLinus Torvalds do_interrupted:
1751da177e4SLinus Torvalds 	err = sock_intr_errno(*timeo_p);
1761da177e4SLinus Torvalds 	goto out;
1771da177e4SLinus Torvalds }
1781da177e4SLinus Torvalds EXPORT_SYMBOL(sk_stream_wait_memory);
1791da177e4SLinus Torvalds 
1801da177e4SLinus Torvalds int sk_stream_error(struct sock *sk, int flags, int err)
1811da177e4SLinus Torvalds {
1821da177e4SLinus Torvalds 	if (err == -EPIPE)
1831da177e4SLinus Torvalds 		err = sock_error(sk) ? : -EPIPE;
1841da177e4SLinus Torvalds 	if (err == -EPIPE && !(flags & MSG_NOSIGNAL))
1851da177e4SLinus Torvalds 		send_sig(SIGPIPE, current, 0);
1861da177e4SLinus Torvalds 	return err;
1871da177e4SLinus Torvalds }
1881da177e4SLinus Torvalds EXPORT_SYMBOL(sk_stream_error);
1891da177e4SLinus Torvalds 
1901da177e4SLinus Torvalds void sk_stream_kill_queues(struct sock *sk)
1911da177e4SLinus Torvalds {
1921da177e4SLinus Torvalds 	/* First the read buffer. */
1931da177e4SLinus Torvalds 	__skb_queue_purge(&sk->sk_receive_queue);
1941da177e4SLinus Torvalds 
1951da177e4SLinus Torvalds 	/* Next, the error queue. */
1961da177e4SLinus Torvalds 	__skb_queue_purge(&sk->sk_error_queue);
1971da177e4SLinus Torvalds 
1981da177e4SLinus Torvalds 	/* Next, the write queue. */
199547b792cSIlpo Järvinen 	WARN_ON(!skb_queue_empty(&sk->sk_write_queue));
2001da177e4SLinus Torvalds 
2011da177e4SLinus Torvalds 	/* Account for returned memory. */
2023ab224beSHideo Aoki 	sk_mem_reclaim(sk);
2031da177e4SLinus Torvalds 
204547b792cSIlpo Järvinen 	WARN_ON(sk->sk_wmem_queued);
205547b792cSIlpo Järvinen 	WARN_ON(sk->sk_forward_alloc);
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds 	/* It is _impossible_ for the backlog to contain anything
2081da177e4SLinus Torvalds 	 * when we get here.  All user references to this socket
2091da177e4SLinus Torvalds 	 * have gone away, only the net layer knows can touch it.
2101da177e4SLinus Torvalds 	 */
2111da177e4SLinus Torvalds }
2121da177e4SLinus Torvalds EXPORT_SYMBOL(sk_stream_kill_queues);
213