|
Ian Kent |
48c41b |
autofs-5.0.5 - fix rpc fail on large export list
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
From: Ian Kent <raven@themaw.net>
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
If the export list on a server is larger than the UDP transport packet
|
|
Ian Kent |
48c41b |
size the transfer will fail and autofs will try TCP instead, but there
|
|
Ian Kent |
48c41b |
were some problems with the conversion to allow for IPv6 using libtirpc.
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
When creating the local socket for an RPC connection we incorrectly
|
|
Ian Kent |
48c41b |
performed a connect instead of a bind to the ilocal TCP socket. Aslo the
|
|
Ian Kent |
48c41b |
timed connect, which should be done before creating the RPC client was
|
|
Ian Kent |
48c41b |
not being done, which can lead to lengthy timeouts.
|
|
Ian Kent |
48c41b |
---
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
CHANGELOG | 1 +
|
|
Ian Kent |
48c41b |
lib/rpc_subs.c | 47 ++++++++++++++++++++++++-----------------------
|
|
Ian Kent |
48c41b |
2 files changed, 25 insertions(+), 23 deletions(-)
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
diff --git a/CHANGELOG b/CHANGELOG
|
|
Ian Kent |
48c41b |
index 88bcc1b..20566a6 100644
|
|
Ian Kent |
48c41b |
--- a/CHANGELOG
|
|
Ian Kent |
48c41b |
+++ b/CHANGELOG
|
|
Ian Kent |
48c41b |
@@ -15,6 +15,7 @@
|
|
Ian Kent |
48c41b |
- fix pidof init script usage.
|
|
Ian Kent |
48c41b |
- check for path mount location in generic module.
|
|
Ian Kent |
48c41b |
- dont fail mount on access fail.
|
|
Ian Kent |
48c41b |
+- fix rpc fail on large export list.
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
03/09/2009 autofs-5.0.5
|
|
Ian Kent |
48c41b |
-----------------------
|
|
Ian Kent |
48c41b |
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
|
|
Ian Kent |
48c41b |
index 628f0fc..3b11dce 100644
|
|
Ian Kent |
48c41b |
--- a/lib/rpc_subs.c
|
|
Ian Kent |
48c41b |
+++ b/lib/rpc_subs.c
|
|
Ian Kent |
48c41b |
@@ -53,6 +53,7 @@
|
|
Ian Kent |
48c41b |
/* Get numeric value of the n bits starting at position p */
|
|
Ian Kent |
48c41b |
#define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n))
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
+static int connect_nb(int, struct sockaddr *, socklen_t, struct timeval *);
|
|
Ian Kent |
48c41b |
inline void dump_core(void);
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
static CLIENT *rpc_clntudp_create(struct sockaddr *addr, struct conn_info *info, int *fd)
|
|
Ian Kent |
48c41b |
@@ -97,11 +98,17 @@ static CLIENT *rpc_clnttcp_create(struct sockaddr *addr, struct conn_info *info,
|
|
Ian Kent |
48c41b |
struct sockaddr_in *in4_raddr;
|
|
Ian Kent |
48c41b |
struct sockaddr_in6 *in6_raddr;
|
|
Ian Kent |
48c41b |
CLIENT *client = NULL;
|
|
Ian Kent |
48c41b |
+ socklen_t slen;
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
switch (addr->sa_family) {
|
|
Ian Kent |
48c41b |
case AF_INET:
|
|
Ian Kent |
48c41b |
in4_raddr = (struct sockaddr_in *) addr;
|
|
Ian Kent |
48c41b |
in4_raddr->sin_port = htons(info->port);
|
|
Ian Kent |
48c41b |
+ slen = sizeof(struct sockaddr_in);
|
|
Ian Kent |
48c41b |
+
|
|
Ian Kent |
48c41b |
+ if (connect_nb(*fd, addr, slen, &info->timeout) < 0)
|
|
Ian Kent |
48c41b |
+ break;
|
|
Ian Kent |
48c41b |
+
|
|
Ian Kent |
48c41b |
client = clnttcp_create(in4_raddr,
|
|
Ian Kent |
48c41b |
info->program, info->version, fd,
|
|
Ian Kent |
48c41b |
info->send_sz, info->recv_sz);
|
|
Ian Kent |
48c41b |
@@ -114,6 +121,11 @@ static CLIENT *rpc_clnttcp_create(struct sockaddr *addr, struct conn_info *info,
|
|
Ian Kent |
48c41b |
#else
|
|
Ian Kent |
48c41b |
in6_raddr = (struct sockaddr_in6 *) addr;
|
|
Ian Kent |
48c41b |
in6_raddr->sin6_port = htons(info->port);
|
|
Ian Kent |
48c41b |
+ slen = sizeof(struct sockaddr_in6);
|
|
Ian Kent |
48c41b |
+
|
|
Ian Kent |
48c41b |
+ if (connect_nb(*fd, addr, slen, &info->timeout) < 0)
|
|
Ian Kent |
48c41b |
+ break;
|
|
Ian Kent |
48c41b |
+
|
|
Ian Kent |
48c41b |
client = clnttcp6_create(in6_raddr,
|
|
Ian Kent |
48c41b |
info->program, info->version, fd,
|
|
Ian Kent |
48c41b |
info->send_sz, info->recv_sz);
|
|
Ian Kent |
48c41b |
@@ -260,32 +272,21 @@ static CLIENT *rpc_do_create_client(struct sockaddr *addr, struct conn_info *inf
|
|
Ian Kent |
48c41b |
return NULL;
|
|
Ian Kent |
48c41b |
}
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
+ if (!info->client) {
|
|
Ian Kent |
48c41b |
+ *fd = open_sock(addr->sa_family, type, proto);
|
|
Ian Kent |
48c41b |
+ if (*fd < 0)
|
|
Ian Kent |
48c41b |
+ return NULL;
|
|
Ian Kent |
48c41b |
+
|
|
Ian Kent |
48c41b |
+ if (bind(*fd, laddr, slen) < 0)
|
|
Ian Kent |
48c41b |
+ return NULL;
|
|
Ian Kent |
48c41b |
+ }
|
|
Ian Kent |
48c41b |
+
|
|
Ian Kent |
48c41b |
switch (info->proto->p_proto) {
|
|
Ian Kent |
48c41b |
case IPPROTO_UDP:
|
|
Ian Kent |
48c41b |
- if (!info->client) {
|
|
Ian Kent |
48c41b |
- *fd = open_sock(addr->sa_family, type, proto);
|
|
Ian Kent |
48c41b |
- if (*fd < 0)
|
|
Ian Kent |
48c41b |
- return NULL;
|
|
Ian Kent |
48c41b |
-
|
|
Ian Kent |
48c41b |
- if (bind(*fd, laddr, slen) < 0) {
|
|
Ian Kent |
48c41b |
- close(*fd);
|
|
Ian Kent |
48c41b |
- return NULL;
|
|
Ian Kent |
48c41b |
- }
|
|
Ian Kent |
48c41b |
- }
|
|
Ian Kent |
48c41b |
client = rpc_clntudp_create(addr, info, fd);
|
|
Ian Kent |
48c41b |
break;
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
case IPPROTO_TCP:
|
|
Ian Kent |
48c41b |
- if (!info->client) {
|
|
Ian Kent |
48c41b |
- *fd = open_sock(addr->sa_family, type, proto);
|
|
Ian Kent |
48c41b |
- if (*fd < 0)
|
|
Ian Kent |
48c41b |
- return NULL;
|
|
Ian Kent |
48c41b |
-
|
|
Ian Kent |
48c41b |
- if (connect_nb(*fd, laddr, slen, &info->timeout) < 0) {
|
|
Ian Kent |
48c41b |
- close(*fd);
|
|
Ian Kent |
48c41b |
- return NULL;
|
|
Ian Kent |
48c41b |
- }
|
|
Ian Kent |
48c41b |
- }
|
|
Ian Kent |
48c41b |
client = rpc_clnttcp_create(addr, info, fd);
|
|
Ian Kent |
48c41b |
break;
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
@@ -327,7 +328,7 @@ static CLIENT *create_udp_client(struct conn_info *info)
|
|
Ian Kent |
48c41b |
if (client)
|
|
Ian Kent |
48c41b |
goto done;
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
- if (!info->client) {
|
|
Ian Kent |
48c41b |
+ if (!info->client && fd != RPC_ANYSOCK) {
|
|
Ian Kent |
48c41b |
close(fd);
|
|
Ian Kent |
48c41b |
fd = RPC_ANYSOCK;
|
|
Ian Kent |
48c41b |
}
|
|
Ian Kent |
48c41b |
@@ -352,7 +353,7 @@ static CLIENT *create_udp_client(struct conn_info *info)
|
|
Ian Kent |
48c41b |
if (client)
|
|
Ian Kent |
48c41b |
break;
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
- if (!info->client) {
|
|
Ian Kent |
48c41b |
+ if (!info->client && fd != RPC_ANYSOCK) {
|
|
Ian Kent |
48c41b |
close(fd);
|
|
Ian Kent |
48c41b |
fd = RPC_ANYSOCK;
|
|
Ian Kent |
48c41b |
}
|
|
Ian Kent |
48c41b |
@@ -477,7 +478,7 @@ static CLIENT *create_tcp_client(struct conn_info *info)
|
|
Ian Kent |
48c41b |
if (client)
|
|
Ian Kent |
48c41b |
break;
|
|
Ian Kent |
48c41b |
|
|
Ian Kent |
48c41b |
- if (!info->client) {
|
|
Ian Kent |
48c41b |
+ if (!info->client && fd != RPC_ANYSOCK) {
|
|
Ian Kent |
48c41b |
close(fd);
|
|
Ian Kent |
48c41b |
fd = RPC_ANYSOCK;
|
|
Ian Kent |
48c41b |
}
|