Subject: Re: sctp_get[lp]addrs() and socklen_t

From: Kacheong Poon <[email-masked]>
Date: Thu, 01 Apr 2004 17:51:34 -0800

Jun-ichiro itojun Hagino wrote:

> 	the compatibility mode (IPv4 mapped address) has certain caveats, see
> 	draft-cmetz-v6ops-v4mapped-api-harmful-01.txt
> 	draft-itojun-v6ops-v4mapped-harmful-02.txt

The first one is about API issues and the second one is more
about packet format.  We can skip the second one in this
discussion because SCTP already defines how to handle a
mix of IPv4 and IPv6 addresses, unless of course we want to
talk about a change in specification.  More on this below.

There are three concerns in the first draft above, under
specification, complexity in code, and access control.  Under
specification can always be corrected.  Complexity is in the
hands of implementors, different people see things differently.
But the third one actually contradicts with what SCTP can do.

SCTP by design works with both IPv4 and IPv6 address simultaneously.
The third concern actually asks for an SCTP specification change.
An IPv6 SCTP endpoint should not send IPv4 address to the peer.
This is not how SCTP works today.  Unless the SCTP specification
is changed, the socket API has to support it.  And using IPv4 mapped
address is probably the easiest solution.  I have not heard a
proposal to have this change in SCTP.  And even if the SCTP spec is
changed, the sctp_get*addrs() still work as in the draft.  The only
change is that sctp_get*addrs() will not return v4 mapped address
as there will not be any.

> 	if IPv7 designers learn things from the past, they wouldn't include
> 	IPv6 compatible address into the IPv7 specification, i guess.

As I mentioned in the previous email, it does not matter if
there is no compatibility mode.  The sctp_get*addrs() will still
work.  The length will be sizeof the new IPv7 socket address
structure.  The only caveat is when the address length is a variable.

> 	there was an architecture which uses variable-length address in one of
> 	original proposals for IPng (= IPv6), so it is not that rare to have
> 	variable-length address.

A proposal is just a proposal.  But is there a deployed network
architecture with variable address length?  This is more
interesting.

-- 

						K. Poon.
						[email-masked]

---

From: KOZUKA Masahiro <[email-masked]>
Date: Sun, 4 Apr 2004 20:27:17 +0900

> as there will not be any.
It is impossible to change the socket API, but the user of the API doesn't 
necessarily change the usage.
And it must be avoided that the user has to change, I think.

> structure.  The only caveat is when the address length is a variable.
We should use IPv7 without application's modification if IPv7 appears,
while we must change the kernel and standard library(ex. libc).

# Of course it is possible that IPv7 needs the fundamental change 
# of the socket API, ex.) bind() or connect(), I think.
# But we can't know if IPv7 requires it or not. So we should do effort?

Regards, Masahiro.
--
{^-^}/@kozuka.jp / KOZUKA Masahiro

---

From: Kacheong Poon <[email-masked]>
Date: Tue, 06 Apr 2004 14:48:15 -0700

> while we must change the kernel and standard library(ex. libc).

Is the above possible?  For example, a current app using IPv6
socket has sockaddr_in6/AF_INET6 hard coded in it.  When IPv7
comes along, can the above app just work with IPv7 address
without modification?

-- 

						K. Poon.
						[email-masked]

---

From: KOZUKA Masahiro <[email-masked]>
Date: Wed, 7 Apr 2004 10:14:18 +0900

> comes along, can the above app just work with IPv7 address
If sockaddr_in6/AF_INET6 hard code exits, it is impossible.
In the Protocol Independent Programing the hard code doesn't exists,
so it is possible, I think.
	http://www.mew.org/~kazu/doc/piprog.html

# It is a thorny issue that a current app has the hard code.
# We promoted the Protocol Independent Programing, but many apps still have
# the hard code ex.) wget....

Regards, Masahiro.

---

From: Kacheong Poon <[email-masked]>
Date: Tue, 06 Apr 2004 20:00:27 -0700

> 	http://www.mew.org/~kazu/doc/piprog.html

Because of the contraint that an SCTP endpoint has to support
both IPv4 and IPv6 address simultaneously, to do what you suggested
above means that all the calls which handle a list of addresses
should be changed to take a linked list as argument, as in the
getaddinfo().  In fact, to make it work as in the program on tha page,
sctp_connectx() has to take struct addrinfo as the argument so that an
app can just pass in the resulting list from getaddrinfo() directly.

What do SCTP implementors think about this?

-- 

						K. Poon.
						[email-masked]

---

From: "Caitlin Bestler" <[email-masked]>
Date: Wed, 7 Apr 2004 00:44:11 -0500 (CDT)

> What do SCTP implementors think about this?

On an IPv6 capable system, the application can specify either IPv4
or IPv6 addresses within the IPv6 format.

The only benefit I can see of a "mixed format" listing is that it
would ensure that a "IPv4 only" program would at least be aware
that there were other addresses, even if it did not know how to
use them yet.

Of course, "IPv4 only" programs exist largely through inertia and
failure to update code. So I don't see much benefit in defining an
API extension on their behalf.

I am wondering if the only thing that might be needed is an advisory
section in the Implementers Guide on proper use of IPv6 address
encoding.

---

From: Kacheong Poon <[email-masked]>
Date: Wed, 07 Apr 2004 20:48:36 -0700

> or IPv6 addresses within the IPv6 format.

I think the goal is that the app should not even know if it is
using IPv4 or IPv6 address.

> section in the Implementers Guide on proper use of IPv6 address

The current SCTP socket API draft has that.  But it is not the
intention of this discussion thread.

-- 

						K. Poon.
						[email-masked]

---

From: KOZUKA Masahiro <[email-masked]>
Date: Thu, 8 Apr 2004 15:27:56 +0900

> app can just pass in the resulting list from getaddrinfo() directly.
Um.... I can't agree with the sctp_connectx()'s specification, too.
This specification uses addrs as the array of "struct sockaddr *",
but in sctp_connectx() it isn't treated as the array.
 --
int
sctp_connectx(int fd, struct sockaddr *addrs, int addrcnt)
{
	int i,len,ret,cnt;
	struct sockaddr *at;
	len = sizeof(int);
	at = addrs;
	cnt = 0;
	/* validate all the addresses and get the size */
	for (i=0; i < addrcnt; i++) {
		if ((at->sa_family != AF_INET) &&
		    (at->sa_family != AF_INET6)) {
			errno = EINVAL;
			return (-1);
		}
		len += at->sa_len;
		at = (struct sockaddr *)((caddr_t)at + at->sa_len);
		cnt++;
	}
 --
This way is strange, I think....
And on the Linix systems, without sa_len, we have to know socklen_t's
information in the use of sa_family, the way which we should avoid.

So, it should be avoided that addrs is the sockaddr's pointer.
Well, what should we use as sctp_connectx()'s addrs?

1) No change:)
 But this way is bad for the Protocol Independent Programing....

2) Use the pointer of "struct sockaddr *", struct sockaddr **?
 But sctp_connectx() is a system call or in sctp_connectx() use a system call,
 we have to use copyin() to get the actual data, and we have to have the length
 of the actual data.
 So this way is impossible, I think.

3) Create a new struct and use it.
 An example.
 --
struct sctp_address {
	struct sockaddr *sa_addr;
	socklen_t *sa_addrlen;
	struct sctp_address *sa_next;
};
int
sctp_connectx(int fd, struct sctp_address *addrs);
 --

 Users use sctp_connectx() as below....
 --
	int s;
	struct addrinfo hints, *res0, *res;
	struct sctp_address *addr0, *addr;
	/* Get s and res using getaddrinfo() and socket() */
	addr0 = addr = NULL;
	for (res = res0; res; res = res->ai_next) {
		if (addr == NULL) {
			addr = (struct sctp_address *)malloc(sizeof(struct sctp_address));
			addr0 = addr;
		} else {
			addr->sa_next = (struct sctp_address *)malloc(sizeof(struct sctp_address));
			addr = addr->sa_next;
		}
		memset(addr, 0 sizeof(*addr));
		addr->sa_addr = res->ai_addr;
		addr->sa_addrlen = res->ai_addrlen;
	}
	sctp_connectx(s, addr0);
	/* Free addr. */
	freeaddrinfo(res0);
 --
Comment?

Regards, Masahiro.

---

From: KOZUKA Masahiro <[email-masked]>
Date: Thu, 8 Apr 2004 16:36:09 +0900

> Well, what should we use as sctp_connectx()'s addrs?
I have a mistake.
On Linux systems if this process is executed in kernel or the shared library,
it will not make the Protocl Independent Programing impossible.

To convert from addrinfo{} to sockaddr[], we can do bellow...
 --
	sz = 0;
	for (res = res0; res; res = res->ai_next)
		sz += res->ai_addrlen;
	addr0 = (struct sockaddr *)malloc(sz);
	addr = addr0;
	for (res = res0; res; res = res->ai_next) {
		memmove(addr, res->ai_addr, res->ai_addrlen);
		addr = (struct sockaddr *)((caddr_t)addr + res->ai_addrlen);
	}
	sctp_connectx(s, addr0, sz);
 --
>  But this way is bad for the Protocol Independent Programing....
So, above is wrong but this way isn't smart, I think.

Regards, Masahiro.

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Thu, 08 Apr 2004 08:40:43 -0500

Masahiro-san:

You are confusing a general discussion for the way
I chose to implement this function.. I did NOT have
to implement it this way .. and Kacheong would say
I did it wrong...

Just because one particular implementation does
a library one way or another is not relevant to the
discussion... And of course this was NEVER meant
to run on Linux systems.. in fact a linux system may
just do a true syscall.. I did not since they are
harder to get in, in BSD... and besides.. If I was
doing a linux implementation I would do it
differently...

I might be looking at AF_INET/AF_INET6 .. and don't
tell me no one has to look at these.. the calls you emphasis
in your web page do... i.e. the library calls your code
example calls.. and these are library calls so they are
free to look at AF_INET/AF_INET6 or even AF_INET7 if that
ever shows up...

R

-- 
Randall R. Stewart
ITD - Transport Technologies
815-477-2127(o) or 815-342-5222(c)

---

From: KOZUKA Masahiro <[email-masked]>
Date: Fri, 9 Apr 2004 02:48:56 +0900

> to implement it this way .. and Kacheong would say
Yes, I made a mistake for sctp_connectx(), this function doesn't make 
the Protocol Independent Programing impossible, I think, as 
http://www.sctp.org/archive/2053.html
So, I don't think that sctp_connectx() should be changed.

> free to look at AF_INET/AF_INET6 or even AF_INET7 if that
Yes, I don't think that the implementation must be in a way.
sctp_connectx() is a system call or a library function, is a choice for
the implementer, bacause this choice doesn't affect the Protocol Independent.

It is a problem that the specification will make the application programer
have to do Protocol "Dependent" Programing.
In the internal code, the protocol dependent code is harmless.
I confused that the latter was harm.... I'm sorry.

But sctp_get[lp]addrs() affects the Protocol Independent.
So sctp_get[lp]addrs() should be changed to return socklen_t too, I think.

Regards, Masahiro.

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Thu, 08 Apr 2004 13:41:42 -0500

>So sctp_get[lp]addrs() should be changed to return socklen_t too, I think.

Ok, so how do you propose returning the socklen_t... I have
seen you state this.. please be more specific...

I have an array of X structures to send up from the
kernel... where do the socklen_t's go for all of these?

R

---

From: KOZUKA Masahiro <[email-masked]>
Date: Mon, 12 Apr 2004 00:18:48 +0900

> kernel... where do the socklen_t's go for all of these?
It is a possible way to use a linked list as getaddrinfo(), I think.
ex.)
 --
struct addrlist {
	struct sockaddr *al_addr;
	socklen_t	 al_len;
	struct addrlist	*al_next;
};
int sctp_get[lp]addrs(int s, struct addrlist **list);
int sctp_free[lp]addrs(struct addrlist *list);
 --
This way may be more incompatible with system calls.
But the current way, sctp_get[lp]addrs() allocates the memory and
sctp_free[lp]addrs() destroy it, is incompatible too
i.e.) it has to be a library function, I think.
So this way isn't so bad?

Regards, Masahiro.