Subject: Re: iruserok() with address-family independence

From: Jean-Luc Richier <[email-masked]>
Date: Fri, 14 Jan 2000 12:27:55 +0100 (MET)

Dans votre courrier du 14 Jan  2:59 vous ecrivez :
>
>>>	I vote against
>>>		int bindresvport_sa(int sd, struct sockaddr *sa)
>>>	(which takes "af" from sa->sa_family).   bindresvport() allows 
>>>	"sin" to be NULL so we always need to pass address family even in
>>>	this case.  I do not want behavior change here.
>>I do not agree, bindresvport_sa does not take  "af" from sa->sa_family,
>>it already know the family from the socket argument sd. So even it sa is
>>NULL, bindresvport - or bindresvport_sa still works. For exemple do a
>>getsockname of sd to find the family.
>
>	Could you tell me more about your behavior in sa == NULL case?

if sa == NULL, the distrib bindresvport code do
	struct sockaddr_in myaddr;
	int sinlen = sizeof(struct sockaddr_in);

	if (sin == (struct sockaddr_in *)0) {
		sin = &myaddr;
		memset(sin, 0, sinlen);
		sin->sin_len = sinlen;
		sin->sin_family = AF_INET;
	}
	if (sin->sin_family != AF_INET) {
		errno = EPFNOSUPPORT;
		return (-1);
	}

My code do (not the actual code, but the idea)
        RPC_SOCKADDR_IN myaddr;
        int sinaf, sinlen;

        if (sin == (RPC_SOCKADDR_IN *)0) {
                sinlen = sizeof (myaddr);
                if (getsockname(sd, (struct sockaddr *)&myaddr, &sinlen) != 0)
                        return (-1);
                sinaf = S_FAMILY(&myaddr);
		sin = &myaddr;
		memset(sin, 0, sizeof (myaddr));
                S_FAMILY(sin) = sinaf;
		S_LEN(sin) = sinlen;
        }

also for the case sin != NULL but sin->sa_family = AF_UNSPEC
(sa is only a buffer for returned value)
        else if (sin && S_FAMILY(sin) == AF_UNSPEC) {
                sinlen = sizeof (myaddr);
                if (getsockname(sd, (struct sockaddr *)&myaddr, &sinlen) != 0)
                        return (-1);
                S_FAMILY(sin) = sinaf = S_FAMILY(&myaddr);
		S_LEN(sin) = sinlen;
        }

>	Also, please do not assume IPv4 mapped address for discussion,
>	there are systems which does not (and will not) have it.  AF_INET6
>	socket does not grab IPv4 connections, so you need to be explicit
>	about address family, or use getaddrinfo to make a loop.

I know about this kame choice, but in bindresvport, only sa_family code are
used. I do not try to accept bind between INET6 socket and INET sockaddr or
between INET socket and INET6 sockaddr.
I do not even suppose that a sa_len field exists (I can add #ifdef SIN6_LEN
tests). I only suppose that getsockname works on all open sockets and returns
correct sa->sa_family and length arguments.

-- 
Jean-Luc RICHIER ([email-masked]  [email-masked])
Laboratoire Logiciels, Systemes et Reseaux (LSR-IMAG)
IMAG-CAMPUS, BP 72, F-38402 St Martin d'Heres Cedex
Tel : +33 4 76 82 72 32 Fax : +33 4 76 82 72 87
--------------------------------------------------------------------
IETF IPng Working Group Mailing List
IPng Home Page:                      http://playground.sun.com/ipng
FTP archive:                      ftp://playground.sun.com/pub/ipng
Direct all administrative requests to [email-masked]
--------------------------------------------------------------------

---

From: [email-masked]
Date: Thu, 27 Jan 2000 18:43:03 +0900

just for the record.  for netbsd/freebsd/openbsd, after long 
	iscussion we've picked the following:

	int bindresvport(int sd, sockaddr_in *sin);
	int bindresvport_sa(int sd, sockaddr *sa);

	they both support AF_INET6.  the only difference between them is
	function prototype.

	- when 2nd arg is NULL, it obeys address family of "sd"
	- when 2nd arg is not NULL, "family" field must properly be initialized,
	  and it must match address family of "sd".

	this does not add additional requirements to old applications.

	see openbsd/netbsd/freebsd manpage for more details.

	thanks for all those participated in the discussion, including
	Jean-Luc, Inoue-san of KAME, and Theo de Raadt.

itojun