Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
libtirpc.24713
0001-rpcinfo-change-order-of-version-to-be-trie...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-rpcinfo-change-order-of-version-to-be-tried-to-4-3-2.patch of Package libtirpc.24713
From 42eb0d9ead5b15d9f2ac4b565c11a39ae19a1291 Mon Sep 17 00:00:00 2001 From: Thomas Blume <Thomas.Blume@suse.com> Date: Wed, 14 Mar 2018 09:51:51 -0400 Subject: [PATCH 1/3] rpcinfo: change order of version to be tried to 4, 3, 2 When specifying TCP as transport on rpcinfo getport command (-T tcp), the initial RPC getport packet is still sent as a UDP packet. This is due to rpc protocol version 2 is tried first and function getpmaphandle() states: /* * Try UDP only - there are some portmappers out * there that use UDP only. */ Even on systems with newer rpc versions, this will hang when the UDP port is blocked. That is a quite artifical limitation, because UDP only portmappert should be really rare by now. The attached code changes the order of versions to be tried to 4, then 3 and use version 2 only as fallback. Reviewed-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Thomas Blume <Thomas.Blume@suse.com> Signed-off-by: Steve Dickson <steved@redhat.com> (cherry picked from commit 5e7b57bc20bd9cadfffd6de52c3331a926ebdf92) --- src/rpcb_clnt.c | 148 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 80 insertions(+), 68 deletions(-) diff --git a/src/rpcb_clnt.c b/src/rpcb_clnt.c index 78b1534..a94fc73 100644 --- a/src/rpcb_clnt.c +++ b/src/rpcb_clnt.c @@ -729,14 +729,83 @@ __rpcbind_is_up() } #endif +#ifdef PORTMAP +static struct netbuf * +__try_protocol_version_2(program, version, nconf, host, tp) + rpcprog_t program; + rpcvers_t version; + const struct netconfig *nconf; + const char *host; + struct timeval *tp; +{ + u_short port = 0; + struct netbuf remote; + struct pmap pmapparms; + CLIENT *client = NULL; + enum clnt_stat clnt_st; + struct netbuf *pmapaddress; + RPCB parms; + + if (strcmp(nconf->nc_proto, NC_UDP) != 0 + && strcmp(nconf->nc_proto, NC_TCP) != 0) + return (NULL); + + client = getpmaphandle(nconf, host, &parms.r_addr); + if (client == NULL) + return (NULL); + + /* + * Set retry timeout. + */ + CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)&rpcbrmttime); + + pmapparms.pm_prog = program; + pmapparms.pm_vers = version; + pmapparms.pm_prot = strcmp(nconf->nc_proto, NC_TCP) ? + IPPROTO_UDP : IPPROTO_TCP; + pmapparms.pm_port = 0; /* not needed */ + clnt_st = CLNT_CALL(client, (rpcproc_t)PMAPPROC_GETPORT, + (xdrproc_t) xdr_pmap, (caddr_t)(void *)&pmapparms, + (xdrproc_t) xdr_u_short, (caddr_t)(void *)&port, + *tp); + if (clnt_st != RPC_SUCCESS) { + rpc_createerr.cf_stat = RPC_PMAPFAILURE; + clnt_geterr(client, &rpc_createerr.cf_error); + return (NULL); + } else if (port == 0) { + pmapaddress = NULL; + rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; + return (NULL); + } + port = htons(port); + CLNT_CONTROL(client, CLGET_SVC_ADDR, (char *)&remote); + if (((pmapaddress = (struct netbuf *) + malloc(sizeof (struct netbuf))) == NULL) || + ((pmapaddress->buf = (char *) + malloc(remote.len)) == NULL)) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + clnt_geterr(client, &rpc_createerr.cf_error); + if (pmapaddress) { + free(pmapaddress); + pmapaddress = NULL; + } + return (NULL); + } + memcpy(pmapaddress->buf, remote.buf, remote.len); + memcpy(&((char *)pmapaddress->buf)[sizeof (short)], + (char *)(void *)&port, sizeof (short)); + pmapaddress->len = pmapaddress->maxlen = remote.len; + + return pmapaddress; +} +#endif + /* * An internal function which optimizes rpcb_getaddr function. It also * returns the client handle that it uses to contact the remote rpcbind. * * The algorithm used: If the transports is TCP or UDP, it first tries - * version 2 (portmap), 4 and then 3 (svr4). This order should be - * changed in the next OS release to 4, 2 and 3. We are assuming that by - * that time, version 4 would be available on many machines on the network. + * version 4 (srv4), then 3 and then fall back to version 2 (portmap). * With this algorithm, we get performance as well as a plan for * obsoleting version 2. * @@ -781,71 +850,6 @@ __rpcb_findaddr_timed(program, version, nconf, host, clpp, tp) */ if (tp == NULL) tp = &tottimeout; - -#ifdef PORTMAP - /* Try version 2 for TCP or UDP */ - if (strcmp(nconf->nc_protofmly, NC_INET) == 0) { - u_short port = 0; - struct netbuf remote; - struct pmap pmapparms; - - if (strcmp(nconf->nc_proto, NC_UDP) != 0 - && strcmp(nconf->nc_proto, NC_TCP) != 0) - goto try_rpcbind; - - client = getpmaphandle(nconf, host, &parms.r_addr); - if (client == NULL) - return (NULL); - - /* - * Set retry timeout. - */ - CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, (char *)&rpcbrmttime); - - pmapparms.pm_prog = program; - pmapparms.pm_vers = version; - pmapparms.pm_prot = strcmp(nconf->nc_proto, NC_TCP) ? - IPPROTO_UDP : IPPROTO_TCP; - pmapparms.pm_port = 0; /* not needed */ - clnt_st = CLNT_CALL(client, (rpcproc_t)PMAPPROC_GETPORT, - (xdrproc_t) xdr_pmap, (caddr_t)(void *)&pmapparms, - (xdrproc_t) xdr_u_short, (caddr_t)(void *)&port, - *tp); - if (clnt_st != RPC_SUCCESS) { - if ((clnt_st == RPC_PROGVERSMISMATCH) || - (clnt_st == RPC_PROGUNAVAIL)) - goto try_rpcbind; - rpc_createerr.cf_stat = RPC_PMAPFAILURE; - clnt_geterr(client, &rpc_createerr.cf_error); - goto error; - } else if (port == 0) { - address = NULL; - rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; - goto error; - } - port = htons(port); - CLNT_CONTROL(client, CLGET_SVC_ADDR, (char *)&remote); - if (((address = (struct netbuf *) - malloc(sizeof (struct netbuf))) == NULL) || - ((address->buf = (char *) - malloc(remote.len)) == NULL)) { - rpc_createerr.cf_stat = RPC_SYSTEMERROR; - clnt_geterr(client, &rpc_createerr.cf_error); - if (address) { - free(address); - address = NULL; - } - goto error; - } - memcpy(address->buf, remote.buf, remote.len); - memcpy(&((char *)address->buf)[sizeof (short)], - (char *)(void *)&port, sizeof (short)); - address->len = address->maxlen = remote.len; - goto done; - } - -try_rpcbind: -#endif /* PORTMAP */ parms.r_prog = program; parms.r_vers = version; @@ -923,6 +927,14 @@ try_rpcbind: } } +#ifdef PORTMAP /* Try version 2 for TCP or UDP */ + if (strcmp(nconf->nc_protofmly, NC_INET) == 0) { + address = __try_protocol_version_2(program, 2, nconf, host, tp); + if (address == NULL) + goto error; + } +#endif /* PORTMAP */ + if ((address == NULL) || (address->len == 0)) { rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; clnt_geterr(client, &rpc_createerr.cf_error); -- 2.16.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor