Subject: RE: getaddrinfo with numeric port number and hints->ai_socktype = = 0

From: Brian Zill <[email-masked]>
Date: Wed, 16 Feb 2000 21:04:57 -0800

> Why shouldn't we assume that the programmer actually knows what (s)he
> is doing?  If you want udp or tcp you can specify it in
> `hints.ai_socktype'.  If you _do_ want both, should you have to
> perform two (at least) calls to getaddrinfo?

Yes, this was one of the issues that came up a couple of weeks ago in a
thread I started called "Clarifications wanted on basic API (RFC 2553)"
(started 1/28).

I had the same interpretation that you did, if you leave things unspecified
going into getaddrinfo, they will be unspecified coming out unless there was
reason to limit them (i.e. if you ask for a service name that is only valid
for TCP and not UDP the record coming out will have the ai_socktype set to
SOCK_STREAM instead of left unspecified).  Today for IPv4, the socket call
is responsible for verifying that you gave it a valid triple of address
family, socket type and protocol, and will pick a default for you if you
leave things unspecified (e.g. lots of people call socket(AF_INET,
SOCK_STREAM, 0) instead of explicitly putting IP_PROTOCOL_TCP in the last
argument).  Thus, I felt the right thing to do was to pass the unspecified
values on through getaddrinfo so that the user would eventually call the
kernel with them.

According to Itojun's mail, however, KAME apparantly enumerates all the
possible combinations for you and gives you a seperate addrinfo record for
each!  He wrote:
> When KAME getaddrinfo is called with the following parameter:
>     host = "foo.internet.host"
>     serv = "daytime"
>     hints.ai_family = PF_UNSPEC
>     hints.ai_socktype = hints.ai_protocol = 0
> the code would return the following four entries:
>     AF_INET, port 13, SOCK_STREAM, IPPROTO_TCP
>     AF_INET, port 13, SOCK_DGRAM, IPPROTO_UDP
>     AF_INET6, port 13, SOCK_STREAM, IPPROTO_TCP
>     AF_INET6, port 13, SOCK_DGRAM, IPPROTO_UDP
> Past KAME code returned SOCK_STREAM only (2 entries), like:
>     AF_INET, port 13, SOCK_STREAM, IPPROTO_TCP
>     AF_INET6, port 13, SOCK_STREAM, IPPROTO_TCP
> Which behavior the spec prefer?

I replied:
We don't do either of those.  You're right, the spec isn't clear here at all
and we're doing quite different things.  For your example (assuming
foo.internet.host resolves to both a v4 and a v6 address) we'll return two
entries:
    AF_INET6, port 13, socktype 0, protocol 0
    AF_INET, port 13, socktype 0, protocol 0

Thus leaving it up to the socket call.  If the user wants something
specific, they need to specify it in the hints passed to getaddrinfo, just
as they specify it in the socket arguments for IPv4 today.  There appears to
be no way to get this behavior from KAME.

I think the working group needs to decide upon a behavior here.  I would
think the different records coming out of getaddrinfo would differ only in
address (type and value) returned and that ai_socktype and ai_protocol would
be the same for all.  This makes round-robining or failover between multiple
servers easy for client code.

BTW, as for your original question...
> I think that all socket types should be considered as supported for a
numeric servname.
So do I.  That's exactly how we do it.  Otherwise you'd have to perform
extraneous service lookups - and, as you point out, are limited to
binding/connecting to sockets with ports that are in the services database!
Upon reflection, I think this just adds to the argument that enumerating the
unspecified socktypes and protocols is the wrong thing to do.  Because
they're inherently incompatible.

--Brian
--------------------------------------------------------------------
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, 17 Feb 2000 14:28:40 +0900

>    AF_INET, port 13, socktype 0, protocol 0

	Just checking, your example is when you passed "daytime" as servname,
	not "13"?

	If I pass
	- servname = "daytime" (registered as 13/tcp and 13/udp)
	- hints.ai_family = PF_UNSPEC
	- hints.ai_socktype = 0
	I can think of three behaviors.  since "daytime = port 13" is valid
	only for TCP and UDP, I would think getaddrinfo should give some
	guidance to the caller.

	behavior 1: (current KAME)
		AF_INET6, port 13, socktype SOCK_STREAM, protocol IPPROTO_TCP
		AF_INET6, port 13, socktype SOCK_DGRAM, protocol IPPROTO_UDP
		AF_INET, port 13, socktype SOCK_STREAM, protocol IPPROTO_TCP
		AF_INET, port 13, socktype SOCK_DGRAM, protocol IPPROTO_UDP
	behavior 2: (I thought you would do this)
		AF_INET6, port 13, socktype SOCK_STREAM, protocol 0
		AF_INET6, port 13, socktype SOCK_DGRAM, protocol 0
		AF_INET, port 13, socktype SOCK_STREAM, protocol 0
		AF_INET, port 13, socktype SOCK_DGRAM, protocol 0
	behavior 3: (your example)
		AF_INET6, port 13, socktype 0, protocol 0
		AF_INET, port 13, socktype 0, protocol 0

	If we do not glob ai_socktype like behavior 3, it looks to me to be
	incompatible with cases with servname "ftp" (21/tcp, not udp), where
	behavior 1-3 will return the following:

	behavior 1: (current KAME)
		AF_INET6, port 21, socktype SOCK_STREAM, protocol IPPROTO_TCP
		AF_INET, port 21, socktype SOCK_STREAM, protocol IPPROTO_TCP
	behavior 2: (I thought you would do this)
		AF_INET6, port 21, socktype SOCK_STREAM, protocol 0
		AF_INET, port 21, socktype SOCK_STREAM, protocol 0
	behavior 3: (do you do this?)
		AF_INET6, port 21, socktype 0, protocol 0
		AF_INET, port 21, socktype 0, protocol 0

	We really need some clarification about what is opaque for getaddrinfo
	and what is not.
	- It looks to me that PF_UNSPEC is clearly one of items which is NOT
	  opaque.
	- ai_socktype = 0 is not clear enough for me.  RFC2553 says "the caller
	  accepts any socket type".  it says nothing about what getaddrinfo
	  should do.  For me it looks to be "getaddrinfo should glob it"
	  and it is the behavior we have now in KAME.

itojun

---

From: Robert Elz <[email-masked]>
Date: Thu, 17 Feb 2000 16:48:30 +1100

Date:        Thu, 17 Feb 2000 14:28:40 +0900
    From:        [email-masked]
    Message-ID:  <[email-masked]>

This is not directly to the point, but ...

  | 	If we do not glob ai_socktype like behavior 3, it looks to me to be
  | 	incompatible with cases with servname "ftp" (21/tcp, not udp),

According to iana/assignments/port-numbers ...

ftp-data         20/tcp    File Transfer [Default Data]
ftp-data         20/udp    File Transfer [Default Data]
ftp              21/tcp    File Transfer [Control]
ftp              21/udp    File Transfer [Control]

The theory always was that a port number was assigned for both TCP and UDP
usage, and then the protocol could decide how to use it.   Aside from the
noise protocols (daytime, chargen, etc) I think only the DNS actually
makes use of both protocols for its port, but that was still the theory.

The BSD assignments (in the 500) range messed that up a bit, and your
average BSD services file lists only TCP for FTP (and UDP for TFTP,
thogh again, 69/tcp is assigned to tftp by the IANA), but that's just
leaving out the variations that aren't generally used.   It would certainly
be a mistake to do anything which would deped upon the "unused"
protocol being missing - applications do need to specify the protocol
they want to use, and not rely upon finding it from the service name.

This means, I think, that I believe Brian's implementation makes
a little more sense.

kre

---

From: [email-masked]
Date: Thu, 17 Feb 2000 15:01:22 +0900

>This is not directly to the point, but ...

	I agree, my comment is not directly related to getaddrinfo discussion,

>ftp              21/udp    File Transfer [Control]

	Just checking, have you ever seen ftp client/server that works on top
	of UDP layer?  RFC959 do refer TCP, but not UDP.  I believe the above
	assignments just mean that they are "reserved"....

itojun

---

From: Robert Elz <[email-masked]>
Date: Fri, 18 Feb 2000 02:13:30 +1100

Date:        Thu, 17 Feb 2000 15:01:22 +0900
    From:        [email-masked]
    Message-ID:  <[email-masked]>

  | 	Just checking, have you ever seen ftp client/server that works on top
  | 	of UDP layer?  RFC959 do refer TCP, but not UDP.  I believe the above
  | 	assignments just mean that they are "reserved"....

No, the protocol uses only TCP.   The uses are "reserved" in the sense
that when port numbers were allocted (in the old days anyway) both udp
and tcp were assigned the same number, and then the protocol can choose
which to use, and when.   I could imagine that sometime in the future
a protocol enhancement to FTP might add some UDP elements.  I have no
idea what for, but the possibility is always there.

The point was that you can't assume that you can take just a host name
and "ftp" and return something which a naive application can use to
make a correct tcp (control) connection - the ftp application has to
know that TCP is the transport protocol to be used for this application
protocol.    Given that the application must know this, and cannot
rely upon someone else providing that information, having the application
either provide it to the library in the hints, or supply it later,
with the library providing no hints, and either the application filling in
the missing bits, or leaving it to the kernel to add them seems like
the better solution to me.

Unless the application exxpressly asks for a UDP assignment when
calling getaddrinfo() for "ftp", I think it is a mistake to return
that (whatever is in the services file).   That helps no-one.

kre

---

From: [email-masked]
Date: Fri, 18 Feb 2000 00:57:38 +0900

>the better solution to me.

	I don't see what you are arguing here.

	We have /etc/services table, which is the only data source getaddrinfo
	(or getservbyname) can trust.  When we have "ftp" entry with tcp only
	in there (which was the example I meant), getaddrinfo have no idea
	if it is usable for udp as well.

itojun

---

From: [email-masked] (Niels M�ller)
Date: 17 Feb 2000 17:33:10 +0100

> 	if it is usable for udp as well.

I think the point was this: A portable ftp application should work
both on a system with only ftp-by-tcp listed in /etc/services, and on
a system that lists both ftp-by-tcp and ftp-by-udp (or do you think
the latter system is broken? I think it is reasonable to have
/etc/services include reserved but currently not commonly used ports).

So the application has to *know* that the ftp protocol uses tcp, and
apply that knowledge at some time before calling socket(). It can't
*rely* on getaddrinfo knowing that.

One way is apply that knowledge is by using the hints argument to
getaddrinfo, and then pass the values from getaddrinfo to socket()
unmodified. Another is to massage the information from getaddrinfo
before calling socket(), e.g. by explicitly saying SOCKET_STREAM,
IPPROTO_TCP, ignoring some of the data returned by getaddrinfo. 

And Assar's original question was about the behaviour when an
application asks for a *numerical* port. I think it makes a lot of
sense in this case to not consult /etc/services at all.

/Niels

---

From: Robert Elz <[email-masked]>
Date: Fri, 18 Feb 2000 03:51:45 +1100

Date:        17 Feb 2000 17:33:10 +0100
    From:        [email-masked] (Niels Mvller)
    Message-ID:  <[email-masked]>

  | I think the point was this:

Yes, exactly.   Thanks.

kre

---

From: [email-masked]
Date: Fri, 18 Feb 2000 01:58:17 +0900

>/etc/services include reserved but currently not commonly used ports).

	I see, I gave a bad example.

	I still believe getaddrinfo should glob ai_socktype for non-numeric.
	When I call getaddrinfo with
		hostname = "10.1.1.1"
		servname = "echo"
		ai_family = PF_UNSPEC
		ai_socktype = 0
	I would like to try all the possibilities below:
		AF_INET, 10.1.1.1, ai_socktype = SOCK_STREAM, port 7
		AF_INET, 10.1.1.1, ai_socktype = SOCK_DGRAM, port 7
	not just:
		AF_INET, 10.1.1.1, ai_socktype = 0, port 7

>sense in this case to not consult /etc/services at all.

	KAME getaddrinfo does not consult /etc/services.
	Since KAME getaddrinfo's mindset is with "ai_socktype should be
	globbed", numeric port does not give me any indication of the right
	ai_socktype to return.  it is ambiguous to it and it would raise error.

	In other words, KAME getaddrinfo believes that it is not consistent
	to do the following:
	- treat ai_socktype as opaque when servname is numeric
	- globbing ai_socktype when servname is non-numeric

itojun

---

From: [email-masked]
Date: Fri, 18 Feb 2000 02:03:38 +0900

>	- globbing ai_socktype when servname is non-numeric

	I think I wasn't clear enough.
	The point I would like to make here is the following:
	- RFC2553 does not give indication about how far getaddrinfo should
	  glob the result.  It should be made more clear on 2553bis.
	- I think it makes more sense to glob ai_socktype with non-numeric
	  socktype.  Vladislav's quote from X/Net looks like globbing
	  ai_socktype is what X/Net prefers.
	- when we glob ai_socktype, numeric servname with ai_socktype = 0 is
	  ambiguous, and it makes more sense to raise error
	- I'm happy to be convinced otherwise ("ai_socktype is opaque").
	  if majority thinks so.

itojun

---

From: Jim Bound <[email-masked]>
Date: Fri, 18 Feb 2000 22:33:46 -0500

Itojun and WG List,

As I said when we started the rfc2553bis discussion we will be in synch
with XNS 5.2 100%, except in one place right now on truncation we
previously discussed.  So do not worry about that, in fact assume it.
Also this spec will not discuss the use of AF_LOCAL and AF_UNIX as I
said previously.  But we should make sure we do nothing with getaddrinfo
that would negatively impacts its use.

>	- I'm happy to be convinced otherwise ("ai_socktype is opaque").

Now the bad news about all this discussion.

   RFC2553 pretty much just lifted getaddrinfo from the IEEE POSIX 
   Committee now referenced as the Austin Group and who works with
   XNS Team.  We cannot alter at this time the syntax or semantics 
   of getaddrinfo so it is not RFC 2553's fault for lack of
   specification here.  We just globbed it into RFC 2553 with some
   editing and some new flags (which is OK).  The IETF and this
   working group don't own this API.  It is like someone in 
   ETSI tweaking TCP or UDP.  We have to be careful here.
  
   We did not have this problem with getipnodebyname we invented 
   that and gave it to XNS.  

   What I need to do is speak with Chris Harding offline and see 
   what the rules are here and get back to you.  I am sure we
   can come to some agreement.  

   But I think we need to understand we cannot specify the behavior
   of this API and what is returned within the datatypes based on 
   assuming knowledge of things like /etc/services, they are not
   dejure standards and are implementation defined.  Where we can
   specify we pretty much have at this point.  Getaddrinfo obviously
   needs to nail this down so the basics are implemented for the
   behavior we needed for getipbnodebyname, the fact that it does
   much more is serendipity and not an action from this IETF WG.
   Again I have to speak with Chris who knows the XNS and Austin
   Group logistics and what we can do and cannot do.

regards,
/jim