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, ¤t_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