Bug 27813

Summary: clnt_control option CLGET_SVC_ADDR does not work with rpc vc transport
Product: Base System Reporter: Jean-Luc.Richier <Jean-Luc.Richier>
Component: miscAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description Jean-Luc.Richier 2001-06-01 14:00:02 UTC
With the new TI-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.

Fix: The problem is in lib/libc/rpc/clnt_vc.c, an incorrect reference.
To correct:


--- 257,263 ----
        ct->ct_addr.buf = malloc(raddr->maxlen);
        if (ct->ct_addr.buf == NULL)
                goto err;
!       memcpy(ct->ct_addr.buf, raddr->buf, raddr->len);
        ct->ct_addr.len = raddr->maxlen;
        ct->ct_addr.maxlen = raddr->maxlen;--wbueQ9ZvEZlk3QBKm3wRci5DOY1sMOBfqGxYimsue4pXLJFt
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

*** lib/libc/rpc/clnt_vc.c.DIST Wed Apr  4 01:34:45 2001
--- lib/libc/rpc/clnt_vc.c      Mon May  7 17:35:30 2001
***************
*** 257,263 ****
        ct->ct_addr.buf = malloc(raddr->maxlen);
        if (ct->ct_addr.buf == NULL)
                goto err;
!       memcpy(ct->ct_addr.buf, &raddr->buf, raddr->len);
        ct->ct_addr.len = raddr->maxlen;
        ct->ct_addr.maxlen = raddr->maxlen;
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 <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);
}
Comment 1 iedowse freebsd_committer freebsd_triage 2001-06-01 16:20:55 UTC
State Changed
From-To: open->closed

Fixed in revision 1.7 of clnt_vc.c. Thanks!