Subject: Re: draft-ietf-ipngwg-scopedaddr-format-00.txt

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Tue, 02 Nov 1999 11:52:28 +0900

>>>>> On Sun, 31 Oct 1999 13:55:12 -0800 (PST), 
>>>>> [email-masked] (Sam Manthorpe) said:

> Jack McCann wrote:
>> A stray thought...
>> 
>> [S|s]<scope-id>:<scoped_address>
>> 
>> where "S" is for "Scope" but it could be any character not
>> currently allowed in a literal IPv6 address.

> I like this proposal a lot.  I agree scope-id should come first, for
> the reasons already posted here

Do you mean by "the reasons posted here" that scope-id should be the
most significant part of the address? If so, what do you think of the
question that I posted here:

>>>>> On Thu, 28 Oct 1999 01:26:49 +0900, I said:

> Is it so obvious that the scope_id part is the most significant part?
> I'm not sure. It seems to me that we could recognize (for example) a
> link-local address as follows:

> 1. Look at the 1st 16 (or at least 10) bits of the address (fe80) and
>    recognize that this is a link-local address. i.e. this is the most
>    significant part.
> 2. Then look at the scope identifier and recognize to which link the
>    address should belong. (In this scenario, the scope id is the 2nd
>    significant part)
> 3. Finally use the host id part of the address (i.e. the last 64 bits)
>    to identify the node that the address specifies in the link.

> So I feel the appropriate portion for the scope_id is subtle. However,
> I don't stick to the idea that the scope id should be after an
> address. I'd respect others' opinions.

[back to your original message]

> and using [s|S] instead of punctuation
> mark avoids the old `but in <x>shell this is interpreted as a <y>'
> discussions.

Hmm...I agree that using an alphabetical character would be safe in
order to avoid the useless discussion. One thing that I fear is that a
combination of alphabetical and numerical characters before (or after)
an IPv6 address separated by ":" would incur less readability. For
example, isn't the following address

S12A:FEC0::123:4567:89AB:CDEF

a bit confusing? Though it's not syntactically ambiguous (because "S"
never appears in an IPv6 literal address), people might misread the
syntax and think it represents an IPv6 address *without* any scope
identifier. Am I a worrier?

> Since <draft-ietf-ipngwg-scopedaddr-format-00.txt> is very generic
> in terms of what one uses for delimiters and scope-ids, the only
> real difference here is the sequence of the three elements, so this
> is a minor change.

That's right. As I said in an earlier message, I intentionally opened
the specific syntax in the initial revision of the draft, because I
knew we needed more discussion on this point. When we get a consensus,
I'll wrap up the discussion and revise the draft with a more specific
syntax (including the sequence of the elements).

> Now, if only struct hostent used sockaddrs porting apps to IPv6 would
> be easy.

Exactly (though I believe we should use struct addrinfo instead of
struct hostent). This is the goal we intended in the draft.

					JINMEI, Tatuya
					Communication Platform Lab.
					Corporate R&D Center, Toshiba Corp.
					[email-masked]
--------------------------------------------------------------------
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] (Sam Manthorpe)
Date: Mon, 1 Nov 1999 20:48:57 -0800 (PST)

Hi Jinmei,

> question that I posted here:

Yes.

> > address. I'd respect others' opinions.

Yes, I kind of agree with you about the `2nd most significant part' but
not 100% (as you say, it's subtle :-) In the prototype implementation we
have in IRIX, scope-ids are unique system wide, over all address types.
i.e. you cannot have a site-local and link-local with the same scope-id.
Intuitively, I feel the scope-id belongs -somewhere- up there near
the address type end of the address descriptor and putting it before
the start of the address is clearly preferable to trying to incorporate
it in 2nd order position.  Putting the scope-id at the tail address goes
against my personal intuition, but this is clearly a grey area.

> identifier. Am I a worrier?

I agree it kind of looks like that.  Is this a bad thing?  I suppose it
is in the sense that IPv6 addresses are free to be sent between
hosts by applications or humans whereas scope-ids are not.

> struct hostent). This is the goal we intended in the draft.

Yes, using getaddrinfo() does solve that problem.  Personally I 
don't like getaddrinfo() but I'm clearly in the minority :-) 
(actually I don't like scoped addresses either :-)

As I said before, it is far preferable to me when explaining to
programmers how to port to IPv6 to use simple things like
replace gethostbyname() with getipnodebyname() etc, rather than
having to explain the complexity of getaddrinfo() with all its
semantic knobs and whistles and the non-trivial code reworking it 
requires.  But that's another thread...

If there was a way to avoid obsoleting getipnodeby*() due to
scoped-address complexity, I would be happy.

Cheers,
Sam.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sam Manthorpe, SGI.  tel: (650)933-2856 fax: (650)932-2856  [email-masked]
--------------------------------------------------------------------
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: Erik Nordmark <[email-masked]>
Date: Wed, 3 Nov 1999 22:04:46 -0800 (PST)

> Now, if only struct hostent used sockaddrs porting apps to IPv6 would

Why not just use getaddrinfo instead of getipnodebyname?
This might mean changing 20 lines of code compared to 10 lines of code
with getipnodebyname (for a port of trivial example code to the new API).

   Erik

---

From: [email-masked] (Sam Manthorpe)
Date: Wed, 3 Nov 1999 22:39:29 -0800 (PST)

> with getipnodebyname (for a port of trivial example code to the new API).

Because the semantics of getipnodebyname() are very similar to those
of gethostbyname() whereas the semantics of getaddrinfo() are not
only more complex but _different_.  I'm not disputing that getaddrinfo()
is a nice, powerful function that solves the problem in an elegant
fashion, but I would be happier if porting applications to use IPv6
were made as easy as possible.  I think at the very least 
getipnodebyname() should ignore scope-ids in a literal address; what
I would really like would be for it to be able to pass the scope-id
back to the app somehow.  Why not add a field to struct hostent?

As an aside, has anybody implemented scope-ids in their name resolution
code?  How does NIS handle this for example?

Thanks,
Sam.

---

From: [email-masked] (Niels Möller)
Date: 04 Nov 1999 13:44:45 +0100

Jack McCann <[email-masked]> writes:

> > Through the discussion so far, '@' seems bad for the delimiter and '-'
> > seems acceptable. Does anyone have any other suggestions?
> 
> A stray thought...
> 

I'll throw in a cent or two as well...

I'm not entirely sure in which contexts these siteid+address strings
will be used. There are many contexts where you can use an "address"
which can be either an ip4 address, an ip6 address, or a _dns_name_.
Optionally followed by a separator (typically :) and a numeric port
number or symbolic service name. 

If there is any chance that a site+address string will be useful in
those contexts, it's important that the namespaces don't intersect,
and that they are reasonably simple to distinguish. Using a character
that is valid in a dns name ("s" "S" and "-" are all in this category)
seems suboptimal.

I would almost suggest using site/address. But perhaps that collides
with the address/bits notation?

/Niels

---

From: Jim Bound <[email-masked]>
Date: Thu, 04 Nov 1999 10:40:13 -0500

>with getipnodebyname (for a port of trivial example code to the new API).

I don't agree.  the inline code to change from gethostbyname to
getipnodebyname is much more explicable and supporting addded trans
mechanisms.  

see our programming examples at: www.ipv6.zk3-x.dec.com
click on "Porting Guide"

using getipnodebyname is more familiar to most programmers who use
sockets we keep the semantics and the core inline logic of the code
remains in tact you add the conditions of v4/v6.

getaddrinfo and friends changes the programming paradigm a bit and what
you must feed that api engine.

I predict most will stay with getipnodebyname and as Sam stated
previously its a pain.

/jim

---

From: [email-masked]
Date: Fri, 05 Nov 1999 00:53:41 +0900

>see our programming examples at: www.ipv6.zk3-x.dec.com

	I believe it is up to readers to choose, so I would like to show
	you URLs describing migration to getaddrinfo/getnameinfo:
	http://playground.iijlab.net/newsletter/19990630/
	http://www.kame.net/newsletter/19980604/ (bit dated, need update)

	I personally prefer getaddrinfo/getnameinfo.  It made my code much
	simpler, since you always manipulate sockaddr_xx (as res->ai-addr),
	not in_addr nor in6_addr.  I use getaddrinfo/getnameinfo everywhere
	and am trying very hard to stay away from gethostby* or getipnodeby*.

itojun

---

From: Jim Bound <[email-masked]>
Date: Thu, 04 Nov 1999 11:09:23 -0500

and i find it simpler to use getipnodebyname.........

no one is going to win this discussion..........

/jim

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Fri, 05 Nov 1999 00:46:11 +0900

>>>>> On Mon, 1 Nov 1999 20:48:57 -0800 (PST), 

> against my personal intuition, but this is clearly a grey area.

Okay, I understand your point, but I'd like to keep this issue opened
for a while. It's a minor detail and the difference is in intuition of
each implementor, so we'll not be able to get a consensus easily...

> hosts by applications or humans whereas scope-ids are not.

I didn't mean that this was bad, but I just meant it was confusing for
a user. Even if a user (mis)types the above address instead of

  A12A:FEC0::123:4567:89AB:CDEF,

the system will not return an error (at least about the syntax) and
it'll be a hard work for the user to find what's wrong.

> requires.  But that's another thread...

I understand your point, but as you (and others) already said,
getipnodebyname vs getaddrinfo will be another issue.

					JINMEI, Tatuya

---

From: JINMEI Tatuya / 神明達哉<[email-masked]>
Date: Fri, 05 Nov 1999 00:51:12 +0900

>>>>> On Wed, 3 Nov 1999 22:39:29 -0800 (PST), 

> code?  How does NIS handle this for example?

We (KAME) has implemented scope-id support as an extension to
getaddrinfo() and getnameinfo(), as described in the scopedaddr-format
draft. But it may not be what you want...

As for NIS, we don't take care of it for now.

					JINMEI, Tatuya

---

From: [email-masked] (Sam Manthorpe)
Date: Thu, 4 Nov 1999 10:36:48 -0800 (PST)

Apologies, it wasn't my intention to restart this getipnodebyname/getaddrinfo
discussion again; this is clearly a religious point and we need both
functions available.

However, what I was interested to know was if I am the only one who
sees sufficient need to add scope_id to hostent or add a parameter
to getipnodebyname(). [ given that I do _not_ want to use getaddrinfo() :-) ]
getipnodebyname() is almost useless IMO if it doesn't communicate the
scope-id.

Thanks,
Sam.

---

From: Jim Bound <[email-masked]>
Date: Thu, 04 Nov 1999 14:34:49 -0500

sam,

>getipnodebyname() is almost useless IMO if it doesn't communicate the

scope-id is communicated to the stack via sockaddr_in6.  

Sorry if I am missing your point.  But could tell us what you want to do
with the scope-id?

thanks
/jim

---

From: [email-masked] (Sam Manthorpe)
Date: Thu, 4 Nov 1999 12:24:24 -0800 (PST)

Jim,

> scope-id is communicated to the stack via sockaddr_in6.  

For example:

	telnet <link-local-address>

The way our implementation currently works is that the 
<link-local-address> gets passed to getipnodebyname() and
is converted to an IPv6 address in struct hostent.  However,
if <link-local-address> contains a scope-id, even if getipnodebyname()
ignores the scope-id and correctly translates the address, this
will fail later if the link-local address belongs to a link other
than the default link.  How can the application know what scope-id
to put in the sockaddr_in6?  I also assume that there should be some
support in DNS or icmp name lookups to get the correct scope-id,
and this also should be passed back from getipnodybyname().

Cheers,
Sam.

---

From: Jim Bound <[email-masked]>
Date: Thu, 04 Nov 1999 23:23:15 -0500

>and this also should be passed back from getipnodybyname().

Now I see the complication.  In the base api spec we state this is for
future work and from the pointers to the Japan meeting this came up
there too.  I think we will see a separate piece of work for scoping
which was what we decided when we added this field to sockaddr_in6. 
What we wanted to do was freeze the changes to the baseapi and define it
in a manner that adjunct work could be done on it as needed and by the
advanced API too.

Be careful with the term link above.  The sin6_scope_id

From rfc 2553:

   IPv6 addresses are scoped [2] so they could be link-local, site,
   organization, global, or other scopes at this time undefined.  To
   support applications that want to be able to identify a set of
   interfaces for a specific scope, the IPv6 sockaddr_in structure must
  support a field that can be used by an implementation to identify a
   set of interfaces identifying the scope for an IPv6 address.

and 

struct sockaddr_in6 {
    sa_family_t     sin6_family;    /* AF_INET6 */
    in_port_t       sin6_port;      /* transport layer port # */
    uint32_t        sin6_flowinfo;  /* IPv6 traffic class & flow info */
   struct in6_addr sin6_addr;      /* IPv6 address */
    uint32_t        sin6_scope_id;  /* set of interfaces for a scope */
};

It represents a set of interfaces for a scope.  I look at interfaces
equivalent to links.  

I believe once we define what the sin6_scope_id defines to the kernel
then I believe it will come back from the hostent structure.  If that
means DNS also I am not sure and not sure that should be the case.

For now I would leave the field as NULL and the default will take place
which will be the norm anyway.  If the field is undefined which it is
now that means NULL.

/jim

---

From: Erik Nordmark <[email-masked]>
Date: Thu, 4 Nov 1999 21:05:41 -0800 (PST)

> getipnodebyname is much more explicable and supporting addded trans

The only substancial difference is using a service name with getaddrinfo
instead of a port number.

If you check the diffs between the 3 examples below (gethostbyname, 
getipnodebyname, and getaddrinfo) and ignore the comment lines you'll see
10 differing lines between gethostbyname and getipnodebyname, 
and 21 differing lines between gethostbyname and getaddrinfo.

The point is: if we feel that getaddrinfo has advantages (like being able
to set sin6_scope_id) we can (either collectively or individually) recommend
programmers to use getaddrinfo. The difference in porting complexity
isn't very large. Thus the issue isn't which one is slightly simpler.
When porting an application (with 1000 or 1000000 lines of code)
to IPv6 the actual change to the source code is very minimal - all the cost
is associated with testing that the ported application still works (over both
IPv4 and IPv6).

If we decide to disagree and not recommend getaddrinfo I'm not going to
be upset. But it just seems odd to argue that because there are 11 lines less
of code changes most of the applications will use getipnodebyname - even
though we know there are some benefits for scope addresses if the applications
use getaddrinfo.

And as far as I can tell it is easier to make the loop over all addresses
with getaddrinfo than with getipnodebyname. Adds only 4 lines to the
getaddrinfo example.

   Erik

int
myconnect(char *hostname, int port)
{
	struct sockaddr_in	sin;
	struct hostent		*hp;
	int			sock;

	/* Get host address. */
	hp = gethostbyname(hostname);
	if (hp == NULL || hp->h_addrtype != AF_INET || hp->h_length != 4) {
		(void) fprintf(stderr, "Unknown host \"%s\"\n", hostname);
		return (-1);
	}

	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);
	(void) memcpy((void *)&sin.sin_addr, (void *)hp->h_addr,
	    hp->h_length);

	/* Open socket. */
	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == -1) {
		perror("socket");
		return (-1);
	}

	/* Connect to the host. */
	if (connect(sock, (struct sockaddr *)&sin, sizeof (sin)) == -1) {
		perror("connect");
		(void) close(sock);
		return (-1);
	}
	return (sock);
}
int
myconnect(char *hostname, int port)
{
	struct sockaddr_in6	sin;
	struct hostent		*hp;
	int			sock, errnum;

	/* Get host address.  An IPv4-mapped IPv6 address is okay. */
	hp = getipnodebyname(hostname, AF_INET6, AI_DEFAULT, &errnum);
	if (hp == NULL) {
		(void) fprintf(stderr, "Unknown host \"%s\"\n", hostname);
		return (-1);
	}

	/* Make sure all sockaddr_in6 fields are zero */
	bzero(&sin, sizeof (sin));
	sin.sin6_family = hp->h_addrtype;
	sin.sin6_port = htons(port);
	(void) memcpy((void *)&sin.sin6_addr, (void *)hp->h_addr,
	    hp->h_length);
	freehostent(hp);

	/* Open socket. */
	sock = socket(AF_INET6, SOCK_STREAM, 0);
	if (sock == -1) {
		perror("socket");
		return (-1);
	}

	/* Connect to the host. */
	if (connect(sock, (struct sockaddr *)&sin, sizeof (sin)) == -1) {
		perror("connect");
		(void) close(sock);
		return (-1);
	}
	return (sock);
}
int
myconnect(char *hostname, char *servicename)
{
	struct addrinfo		*res, *aip;
	struct addrinfo		hints;
	int			sock = -1;
	int			error;

	/* Get host address.  Any type of address will do. */
	bzero(&hints, sizeof (hints));
	hints.ai_flags = AI_ALL|AI_ADDRCONFIG;
	hints.ai_socktype = SOCK_STREAM;

	error = getaddrinfo(hostname, servicename, &hints, &aip);
	if (error != 0) {
		(void) fprintf(stderr,
		    "getaddrinfo: %s for host %s service %s\n",
		    gai_strerror(error), hostname, servicename);
		return (-1);
	}

	/* Open socket. */
	sock = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
	if (sock == -1) {
		perror("socket");
		freeaddrinfo(res);
		return (-1);
	}

	/* Connect to the host. */
	if (connect(sock, aip->ai_addr, aip->ai_addrlen) == -1) {
		perror("connect");
		(void) close(sock);
		return (-1);
	}
	freeaddrinfo(res);
	return (sock);
}

---

From: Jim Bound <[email-masked]>
Date: Fri, 05 Nov 1999 00:43:49 -0500

>instead of a port number.

So.  Not a reason to use getaddrinfo.

>and 21 differing lines between gethostbyname and getaddrinfo.

getaddrinfo also has more work within the API implementation.  its not
jsut the 21 differing lines but whats happening with the lib is called
to execute.

>is associated with testing that the ported application still works (over both

Agreed.  But I just sent my first mail to this thread and I think no
draft should specify behavior for scoping that does not include
getipnodebyname.  If it does I will have to write a counter proposal.
That would be stupid.  Folks are already using getipnodebyname.

Also getaddrinfo is far from proven to be useful its all theory till as
a model.  XNET is still fixing it and we had a bug just today that had
to be clarified.

>though we know there are some benefits for scope addresses if the applications

I will be upset and make a battle of it.  As far as I can take it.

>.And as far as I can tell it is easier to make the loop over all addresses

A loop can be done for the hostent structure too.  

Also getaddrinfo requires more pointer processing and passing in the
examples provided as it should.

getaddrinfo may be a good "middleware" api, getipnodebyname is for
system apps.

I would also like to see different independent test results on
performance for both if we must have this debate.

The process to try to kill getipnodebyname will be more work than
working with it.  

And the draft of this thread is in error not incluing getipnodebyname
IMO and I intend to make a point of this in D.C.

Do we want to start this battle?

/jim

---LA_F2156943608R-1A-941778346=:431NCE.IlHAFeR
Content-Type: TEXT/X-sun-c-file; name="myc.c"; charset=us-ascii
Content-Description: c-file

int

	/* Get host address. */

	/* Open socket. */

---LA_F2156943608R-1A-941778346=:431NCE.IlHAFeR
Content-Type: TEXT/X-sun-c-file; name="myc2.c"; charset=us-ascii
Content-Description: c-file

int

	/* Open socket. */

---LA_F2156943608R-1A-941778346=:431NCE.IlHAFeR
Content-Type: TEXT/X-sun-c-file; name="myc3.c"; charset=us-ascii
Content-Description: c-file

int

	/* Open socket. */

---LA_F2156943608R-1A-941778346=:431NCE.IlHAFeR--

---

From: Francis Dupont <[email-masked]>
Date: Fri, 05 Nov 1999 11:35:38 +0100

In your previous mail you wrote:

   to getipnodebyname().
   
=> I don't know if we should add a field in hostent or extend
the h_addr/h_addr_list[X] field. I am in favor of the second solution
because in fact the scope ID is a property of addresses, not of nodes.
Another point is the standard coding:
bcopy(hp->h_addr, &sin.sin6_addr, hp-h_length);
will copy both the address and its scope ID.

[email-masked]

PS: this is related to my idea of a new scoped address structure of course.

---

From: Jim Bound <[email-masked]>
Date: Fri, 05 Nov 1999 09:12:43 -0500

>PS: this is related to my idea of a new scoped address structure of course.

Well your code above won't work without the PS caveat.  

Well I don't we touch getipnodebyname again it is frozen.

Also I think this idea of a new scoped address structure sucks and a
very bad idea.  This is really really bad.  sockaddr_in6 must be left
alone 1) because we have a solution without messing with it and 2) your
now messing with deployed base.

Just define how sin6_scope_id should be used and what it should contain.

The default case is sin6_scope_id == ZERO or NULL.  

Applications that port to Ipv6 who are not scope aware should not be
affected by not setting sin6_scope_id to anything.

/jim

---

From: [email-masked] (Sam Manthorpe)
Date: Fri, 5 Nov 1999 12:33:01 -0800 (PST)

> in a manner that adjunct work could be done on it as needed and by the

Okay, I'm happier knowing that this issue is being addressed.  My
concern comes from the fact that in our implementation is it stands
today (we support scope-id in the kernel), I have no way of pinging
to a link-local address that is on a link other than the one pointed
to be the fe80::/10 default route.  I could solve this problem by
adding code to ping to parse a scope-id and set the sin6_scope_id
in the sockaddr but that's clearly not the way to go.  I could use
getaddrinfo(), but I would much prefer to have the required functionality
in getipnodebyname().

Thanks,
Sam.

---

From: Jim Bound <[email-masked]>
Date: Sat, 06 Nov 1999 08:47:31 -0500

sam,

this is good input to the work on scopes tbd.  

as jack mccann pointed out in our implementation if scopeid is non-null
and address is link-local then scope-id equals interface ID.

for now this is one way to do it and not break the spec.

note this works with getipnodebyname by just setting sin6_scope_id to
the value of the interface you would want to ping with link-local in
your case and previoius mail.

thanks
/jim

---

From: Jim Bound <[email-masked]>
Date: Sat, 06 Nov 1999 09:13:44 -0500

Folks I want to point out with getaddrinfo:
One of our engineers pointed this out and I also alluded to it in my
mail discussion with Dave.  XNET would have to add the necessary flags
in getaddrinfo that are used by getipnodebyname, but they are not part
of the getaddrinfo in rfc2553.

/jim

-----------------------------------------------------------
Jim

This is from ipng list battle about getipnode*/getaddrinfo.  Please
note that hints.ai_flags below is set to invalid flags (by my last understanding
of rfc 2553).  

-vlad

--