[PATCH] sunrpc: Only defer bind to ephemeral ports if a srcaddr has not been set

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The previous binding behavior ignores the possible need to bind to a
local ip address as well as a port in the event that an ephemeral port
is requested. In this event, the binding would be done at connect time,
where all information about desired source addresses is inaccessible.

Instead, we need to consider the case where a source address is given,
in which case the sockaddr will be given an address of 0.0.0.0 or ::0.
We can use these values as a second condition when choosing to defer
the socket binding.

Signed-off-by: Rory Little <rory@xxxxxxxxxxxxxxx>
---
 net/sunrpc/xprtsock.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index bb9b747d58a1..0139db7424aa 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1736,6 +1736,23 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
 	xs_update_peer_port(xprt);
 }
 
+static bool xs_is_anyaddr(const struct sockaddr *sap)
+{
+	switch (sap->sa_family) {
+	case AF_LOCAL:
+		return true;
+	case AF_INET:
+		return ((struct sockaddr_in *)sap)->sin_addr.s_addr == htonl(INADDR_ANY);
+	case AF_INET6:
+		return !memcmp(&((struct sockaddr_in6 *)sap)->sin6_addr, &in6addr_any,
+			       sizeof(struct in6_addr));
+	default:
+		dprintk("RPC:       %s: Bad address family %d\n", __func__, sap->sa_family);
+	}
+
+	return false;
+}
+
 static void xs_reset_srcport(struct sock_xprt *transport)
 {
 	transport->srcport = 0;
@@ -1818,8 +1835,11 @@ static int xs_bind(struct sock_xprt *transport, struct socket *sock)
 	 * transport->xprt.resvport == 1) xs_get_srcport above will
 	 * ensure that port is non-zero and we will bind as needed.
 	 */
-	if (port <= 0)
+	if (port <= 0 && xs_is_anyaddr((struct sockaddr *)&transport->srcaddr)) {
+		dprintk("RPC:       %s: Deferring bind to invalid or ephemeral port: %d\n",
+			__func__, port);
 		return port;
+	}
 
 	memcpy(&myaddr, &transport->srcaddr, transport->xprt.addrlen);
 	do {
-- 
2.34.1





[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux