NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/37864: when requesting TCP rcp-service port numbers UDP is used



>Number:         37864
>Category:       lib
>Synopsis:       when requesting TCP rcp-service port numbers UDP is used
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 24 14:40:00 +0000 2008
>Originator:     Wolfgang Stukenbrock
>Release:        NetBSD 4.0
>Organization:
Dr. Nagler & Company GmbH
        
>Environment:
        
        
System: NetBSD s012 2.1 NetBSD 2.1 (NSW-S012) #10: Mon Dec 12 12:03:54 CET 2005 
wgstuken@s011:/export/netbsd-2.1/usr/src/sys/arch/i386/compile/NSW-S012 i386
Architecture: i386
Machine: i386
>Description:
        When TCP-Port numbers for RPC-services are requested from rpcbind, UDP
        is used in any case. This may fail on busy WAN connections and makes the
        request to rpcbind unrelyable.
        rpcbind also supports TCP for the request, so it would be better to use 
TCP
        for the port-question if a TCP service is ask for.
>How-To-Repeat:
        try to request a port number from rcpbind on a very busy connection.
        UDP-services will not work at all on this kind of connections, but TCP 
will
        do so. Due to the fact of the UDP request for the port number, the call 
will
        fail some times even if the TCP service would do it's work.
>Fix:
        The following fix changes the unconditional use of UDP for rpcbind 
queries
        to UDP or TCP dependent on the type of service requested.
        If the TCP request will fail due to no rpcbind listening, the code will
        fall back to the UDP request.
        The affected file is /usr/src/lib/libc/rpc/pmap_getport.c


*** /export/NetBSD-4.0/src/lib/libc/rpc/pmap_getport.c  Thu Jul  6 05:10:34 2000
--- ./src/lib/libc/rpc/pmap_getport.c   Fri Oct 20 14:40:29 2006
***************
*** 72,77 ****
--- 72,91 ----
   * Calls the pmap service remotely to do the lookup.
   * Returns 0 if no map exists.
   */
+ 
+ static void x_pmap_getport(CLIENT *client, struct pmap *parms, u_short *port)
+ {
+   if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap,
+               parms, (xdrproc_t)xdr_u_short, port, tottimeout) != RPC_SUCCESS)
+     {
+       rpc_createerr.cf_stat = RPC_PMAPFAILURE;
+       clnt_geterr(client, &rpc_createerr.cf_error);
+     }
+   else if (*port == 0)
+     rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
+   CLNT_DESTROY(client);
+ }
+ 
  u_short
  pmap_getport(address, program, version, protocol)
        struct sockaddr_in *address;
***************
*** 86,110 ****
  
        _DIAGASSERT(address != NULL);
  
        address->sin_port = htons(PMAPPORT);
!       client = clntudp_bufcreate(address, PMAPPROG,
!           PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
!       if (client != NULL) {
!               parms.pm_prog = program;
!               parms.pm_vers = version;
!               parms.pm_prot = protocol;
!               parms.pm_port = 0;  /* not needed or used */
!               if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_GETPORT,
!                   (xdrproc_t)xdr_pmap,
!                   &parms, (xdrproc_t)xdr_u_short, &port, tottimeout) !=
!                   RPC_SUCCESS){
!                       rpc_createerr.cf_stat = RPC_PMAPFAILURE;
!                       clnt_geterr(client, &rpc_createerr.cf_error);
!               } else if (port == 0) {
!                       rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
!               }
!               CLNT_DESTROY(client);
!       }
        address->sin_port = 0;
        return (port);
  }
--- 100,122 ----
  
        _DIAGASSERT(address != NULL);
  
+       parms.pm_prog = program;
+       parms.pm_vers = version;
+       parms.pm_prot = protocol;
+       parms.pm_port = 0;  /* not needed or used */
+ 
        address->sin_port = htons(PMAPPORT);
!       if (protocol == IPPROTO_TCP)
!         {
!           client = clnttcp_create(address, PMAPPROG, PMAPVERS, &sock, 0, 0);
!           if (client != NULL) x_pmap_getport(client, &parms, &port);
!         }
!       if (port == 0)
!         {
!           client = clntudp_bufcreate(address, PMAPPROG,
!               PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
!           if (client != NULL) x_pmap_getport(client, &parms, &port);
!         }
        address->sin_port = 0;
        return (port);
  }

>Unformatted:
        
        



Home | Main Index | Thread Index | Old Index