>From 57c320998feb2e1e705a4ab6d3bbcb74c6ae65f0 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sat, 22 Oct 2016 12:10:53 +0200 Subject: [PATCH] net: autobind UDP on recv Signed-off-by: Jiri Slaby --- include/net/inet_common.h | 1 + net/ipv4/af_inet.c | 3 ++- net/ipv4/udp.c | 5 +++++ net/ipv6/udp.c | 5 +++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/net/inet_common.h b/include/net/inet_common.h index 5d683428fced..ba224ed3dd36 100644 --- a/include/net/inet_common.h +++ b/include/net/inet_common.h @@ -27,6 +27,7 @@ ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, int inet_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, int flags); int inet_shutdown(struct socket *sock, int how); +int inet_autobind(struct sock *sk); int inet_listen(struct socket *sock, int backlog); void inet_sock_destruct(struct sock *sk); int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 9648c97e541f..d23acb11cdb0 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -171,7 +171,7 @@ EXPORT_SYMBOL(inet_sock_destruct); * Automatically bind an unbound socket. */ -static int inet_autobind(struct sock *sk) +int inet_autobind(struct sock *sk) { struct inet_sock *inet; /* We may need to bind the socket. */ @@ -187,6 +187,7 @@ static int inet_autobind(struct sock *sk) release_sock(sk); return 0; } +EXPORT_SYMBOL_GPL(inet_autobind); /* * Move a socket into listening state. diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 82fb78265f4b..ceb07c83af17 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1360,6 +1360,11 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, if (flags & MSG_ERRQUEUE) return ip_recv_error(sk, msg, len, addr_len); + /* We may need to bind the socket. */ + if (!inet_sk(sk)->inet_num && !sk->sk_prot->no_autobind && + inet_autobind(sk)) + return -EAGAIN; + try_again: peeking = off = sk_peek_offset(sk, flags); skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 71963b23d5a5..1c3dafc3d91e 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -341,6 +341,11 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, if (np->rxpmtu && np->rxopt.bits.rxpmtu) return ipv6_recv_rxpmtu(sk, msg, len, addr_len); + /* We may need to bind the socket. */ + if (!inet_sk(sk)->inet_num && !sk->sk_prot->no_autobind && + inet_autobind(sk)) + return -EAGAIN; + try_again: peeking = off = sk_peek_offset(sk, flags); skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), -- 2.10.1