Subject: lib/13082: clnt_control option CLGET_SVC_ADDR does not work with rpc vc transport
To: None <gnats-bugs@gnats.netbsd.org>
From: Jean-Luc Richier <Jean-Luc.Richier@imag.fr>
List: netbsd-bugs
Date: 06/01/2001 18:20:12
>Number: 13082
>Category: lib
>Synopsis: clnt_control option CLGET_SVC_ADDR does not work with rpc vc transport
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Jun 01 09:28:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Jean-Luc Richier
>Release: NetBSD 1.5
>Organization:
IMAG
>Environment:
System: NetBSD oban.imag.fr 1.5 NetBSD 1.5 (IPv6) #24: Fri Apr 20 17:36:52 MEST 2001 richier@oban.imag.fr:/usr/src/sys/arch/sparc/compile/IPv6 sparc
>Description:
In the RPC libc code, the control call which allows clients to
find the address of the server (clnt_control(clnt, CLGET_SVC_ADDR, ..)
return an incorrect value.
Bug was detected in NetBSD1.5, and in still in the NetBSD-current source
>How-To-Repeat:
Consider the code at the end, which allows to test rpc calls (unicast or
not) on different transports, compile it (cc -o tstrpc tstrpc.c)
- on udp: it works:
% tstrpc tuna.imag.fr
response from: tuna.imag.fr
- on tcp there is an error
% tstrpc -t tuna.imag.fr
incorrect response
test program tstrpc.c:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <rpc/rpc.h>
#define RPCBPROC_NULL 0
char *transp;
int
reply(caddr_t replyp, struct netbuf *raddrp, struct netconfig *nconf)
{
char host[NI_MAXHOST];
struct sockaddr *sock = raddrp->buf;
if (getnameinfo(sock, sock->sa_len, host, sizeof (host), NULL, 0, 0))
printf("incorrect response\n");
else
printf("response from: %s\n", host);
return(0);
}
void
onehost(char *host)
{
CLIENT *clnt;
struct netbuf addr;
struct timeval tv;
if ((clnt = clnt_create(host, RPCBPROG, RPCBVERS, transp)) == NULL)
errx(1, "%s", clnt_spcreateerror(""));
tv.tv_sec = 15;
tv.tv_usec = 0;
if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv)
!= RPC_SUCCESS)
errx(1, "%s", clnt_sperror(clnt, ""));
clnt_control(clnt, CLGET_SVC_ADDR, (char *)&addr);
reply(NULL, &addr, NULL);
}
void
allhosts()
{
enum clnt_stat clnt_stat;
clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL,
xdr_void, NULL, xdr_void, NULL,
(resultproc_t)reply, transp);
if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT)
errx(1, "%s", clnt_sperrno(clnt_stat));
}
int
main(int argc, char *argv[])
{
int ch;
transp = "udp";
while ((ch = getopt(argc, argv, "ut")) != -1)
switch (ch) {
case 't':
transp = "tcp";
break;
case 'u':
transp = "udp";
break;
default:
errx(1, "tstrpc -[u|t] ...");
}
if (argc == optind)
allhosts();
else for (; optind < argc; optind++)
onehost(argv[optind]);
exit(0);
}
>Fix:
The problem is in lib/libc/rpc/clnt_vc.c, an incorrect reference.
To correct:
*** /usr/src/lib/libc/rpc/clnt_vc.c.DIST Fri Jul 14 18:48:12 2000
--- /usr/src/lib/libc/rpc/clnt_vc.c Fri Jun 1 18:05:33 2001
***************
*** 263,269 ****
ct->ct_addr.buf = malloc(raddr->maxlen);
if (ct->ct_addr.buf == NULL)
goto fooy;
! memcpy(ct->ct_addr.buf, &raddr->buf, raddr->len);
ct->ct_addr.len = raddr->maxlen;
ct->ct_addr.maxlen = raddr->maxlen;
--- 263,269 ----
ct->ct_addr.buf = malloc(raddr->maxlen);
if (ct->ct_addr.buf == NULL)
goto fooy;
! memcpy(ct->ct_addr.buf, raddr->buf, raddr->len);
ct->ct_addr.len = raddr->maxlen;
ct->ct_addr.maxlen = raddr->maxlen;
>Release-Note:
>Audit-Trail:
>Unformatted: