Subject: Re: IPv6 extenstion to RPC

From: Sumandra Majee <[email-masked]>
Date: Fri, 02 Mar 2001 18:06:37 -0800

sorry for the delay. I am also copying this nfsv4wg since it is a v4 WG 
doc. now.

At 01:38 PM 2/27/01 -0500, you wrote:

>Hello,
>
>Include at end is some comments on the draft dated February 21, 2001.
>
>A more general question, is there an intent to propose this RFC
>(once approved) to standard govern bodies such as the Open Group ?
>At COMPAQ, we are working on modifying RPC to support IPv6.
>We see benefits in having this particular RFC and would like
>to work with you to make it a reality.
>
>Does either one of you plan to attend Connectathon at the
>end of this week ? I will be there on Thursday.

No this connetathon.

>Regards,
>Piyanai
>
>******************
>Page 8:
>
>    must determine the address type by looking into the sin_family first.
>
>             if (((struct sockaddr_in *)raddr)->sin_family == AF_INET6) {
>                        ......
>             }
>
>The if statement assumes a valid sin_family in raddr passing to
>the api clnt create all. However, in the case of older programs
>and/or new program where sin_len is not specify and/or use,
>raddr->sin_family will be wrong. As a result, we can't alway depend on
>raddr->sin_family passing from the caller (which can be old programs).
>There need to be a more realiable way to determine the address family.

In the event of  old v4 based programs the raddr->sin_family should have 
been set to IPv4 (AF_INET) anyway.
That will work perfectly on a machine which has both IPv4 and IPv6 stack. 
This could be a problem
if the node only has IPv6 stack.  The suggested order for dual stack node 
is to try IPv6 before IPv4. However
it is better if users can configure this order thru some api or environment 
varibale(as you said it later).

>/* main.c */
>struct len {
>#ifdef LENGTH
>   unsigned char sin_len;
>   unsigned char sin_fam;
>#else
>   int sin_fam;
>#endif
>   int me;
>};
>
>extern void calla(struct len *);
>
>main()
>{
>   struct len LEN = {0,0};
>
>   LEN.sin_fam = 26;
>
>   api(&LEN);
>
>}
>
>/* sub.c */
>#define LENGTH
>struct len {
>#ifdef LENGTH
>   unsigned char sin_len;
>   unsigned char sin_fam;
>#else
>   int sin_fam;
>#endif
>   int me;
>};
>
>void api (struct len *addr)
>{
>   printf("\n");
>}
>
>
>Perhaps in addition to the above, the set/getnetconfig() idea used
>in TI-RPC can be of some use here... New IPv6 program can call the
>set routine to set the default address family. The api calls the get
>routine whenever it needs to know what the caller intention is.
>This should also solve the backward compatibility issue.
>
>             rpc_get_default_af(&af);
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
I guess this is the API to register the order (IPv6 or IPv4 first).

>             sf = ((struct sockaddr_in *)raddr)->sin_family
>             if (sf != AF_INET6 || sf != AF_INET) {
>                  ((struct sockaddr_in *)raddr)->sin_family = af;
>                       ...
>             }
>
>By default, af is set to AF_INET unless the system supports
>IPv6. This is similar to how the svc*_create() call determines
>the af on page 9, last paragraph of section 5.2.
>
>    if *sockp is not defined i.e. (sockp == RPC_ANYSOCK) then a
>    appropriate socket must be created. Again the socket type created is
>    AF_INET6 if raddr points to a IPv6 protocol address. The next step
>    for all types of clnt_create() is to contact the remote servers
>    portmapper to get the port number for the remote service. Since
>    portmapper protocol does not distinguish between IPv4 or IPv6 the
>    returned port number might not be valid one for IPv4 client. This
>    possesses a difficulty for UDP based communication. Suppose service A
>    on server Y is only registered over UDP/IPv4 and listening to port
>    23. Client X(IPv6 enabled) portmap request to Y for A will return 23.
>    But subsequent clntudp_call() will fail because A is not listening
>    over IPv6. To avoid this situation udp based clnt_create() shall send
>    a NULL RPC call to the remote server(Y). If the remote server returns
>    ICMP port unreachable error then clntudp_create() shall fail and RPC
>
>This retunring of "ICMP port unreachable error" is a new behavior for
>the server ie. IPv6 capable server, correct ?

Yes, that is right. This is a fundamental change from the  way we use 
portmapper service today. Most RPC stack
(i don't know of one) which tries to validate the port number it received 
from portmapper running on remote server, before
using it.

>    application is expected to retry using IPv4 address. However this
>    retry is done automatically by clnt_create() and it returns a handle
>    which can be used for IPv4 based UDP service.

------------------------------------------------------------------------------------------------------------

Sumandra Majee
CISCO SYSTEMS INC.
[email-masked]
Direct: 408/853-2541
----------------------------------------------------------------------------------------------------------------------------------------