Subject: Re: bin/24940: rcp doesn't like ipv6-only hosts
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,>
From: Dave Tyson <Dave.Tyson@liverpool.ac.uk>
List: netbsd-bugs
Date: 09/28/2006 16:35:02
The following reply was made to PR bin/24940; it has been noted by GNATS.
From: Dave Tyson <Dave.Tyson@liverpool.ac.uk>
To: Manuel Bouyer <bouyer@antioche.eu.org>
Cc: gnats-bugs@NetBSD.org
Subject: Re: bin/24940: rcp doesn't like ipv6-only hosts
Date: Thu, 28 Sep 2006 16:24:31 +0100
We have the same problems as you and it has bugged me sufficiently to
have a stab at fixing it.
The following patch to /usr/src/lib/libc/net/rcmd.c will help in that rcp will
now correctly obey the -4 and -6 options documented in the man page. This
means at least you can force a transfer with IPV4 if the IPV6 address is
unresponsive on a dual stack host. I think a fix to automatically make rcp
use IPV4 if the IPV6 connection fails is going to be very messy because of
the way a sub-process is spawned to do the copying. Arguably the fix should
be in rcmd.c as this is where the problem is solved for rsh, however, because
of the sub-process the only thing which knows if the connection has failed is
the rcp command itself. Changing this to check the available address families
and invoking the connection with IPV6 and falling back to IPV4 is an option,
but I view it as a kludge as the real problem is the sub-process. Other
*BSD's seem to have done away with this to avoid this issue. Maybe an import
of the OpenBSD/FreeBSD code is the most satisfactory solution. In the
meantime the fix below should apply cleanly to 3, 4 and current - If people
think its OK could it be pulled up into the 3 & 4 branches?
--- rcmd.c.orig 2005-07-09 23:51:22.000000000 +0100
+++ rcmd.c 2006-09-27 22:27:41.000000000 +0100
@@ -78,7 +78,7 @@
int __ivaliduser_sa __P((FILE *, struct sockaddr *, socklen_t, const char
*,
const char *));
static int rshrcmd __P((char **, u_int32_t, const char *, const char *,
- const char *, int *, const char *));
+ const char *, int *, const char *, const int));
static int resrcmd __P((struct addrinfo *, char **, u_int32_t, const char *,
const char *, const char *, int *));
static int __icheckhost __P((struct sockaddr *, socklen_t, const char *));
@@ -142,7 +142,7 @@
sp = getservbyname("shell", "tcp");
if (sp != NULL && sp->s_port == rport)
error = rshrcmd(ahost, (u_int32_t)rport,
- locuser, remuser, cmd, fd2p, getenv("RCMD_CMD"));
+ locuser, remuser, cmd, fd2p, getenv("RCMD_CMD"), af);
else
error = resrcmd(res, ahost, (u_int32_t)rport,
locuser, remuser, cmd, fd2p);
@@ -379,12 +379,13 @@
*/
/* ARGSUSED */
static int
-rshrcmd(ahost, rport, locuser, remuser, cmd, fd2p, rshcmd)
+rshrcmd(ahost, rport, locuser, remuser, cmd, fd2p, rshcmd, af)
char **ahost;
u_int32_t rport;
const char *locuser, *remuser, *cmd;
int *fd2p;
const char *rshcmd;
+ const int af;
{
pid_t pid;
int sp[2], ep[2];
@@ -476,11 +477,18 @@
else
rshcmd = pw->pw_shell;
p = strrchr(rshcmd, '/');
- execlp(rshcmd, p ? p + 1 : rshcmd, "-c", cmd, NULL);
+ if (af == AF_UNSPEC)
+ execlp(rshcmd, p ? p + 1 : rshcmd, "-c", cmd,
NULL);
+ else
+ execlp(rshcmd, p ? p + 1 : rshcmd, af ==
AF_INET ? "-4" : "-6", "-c",
+ cmd, NULL);
} else {
p = strrchr(rshcmd, '/');
- execlp(rshcmd, p ? p + 1 : rshcmd, *ahost, "-l",
- remuser, cmd, NULL);
+ if (af == AF_UNSPEC)
+ execlp(rshcmd, p ? p + 1 : rshcmd, *ahost,
"-l", remuser, cmd, NULL);
+ else
+ execlp(rshcmd, p ? p + 1 : rshcmd, *ahost, af
== AF_INET ? "-4" : "-6",
+ "-l", remuser, cmd, NULL);
}
warn("rshrcmd: exec %s", rshcmd);
_exit(1);
--
=====================================================================
Computing Services Dept Phone/Fax: 0151-794-3731/3759
The University of Liverpool Email: dtyson@liv.ac.uk
Chadwick Tower, Peach Street WWW: http://www.liv.ac.uk/~dtyson
Liverpool L69 7ZF Open Source O/S: www.netbsd.org
=====================================================================