Subject: Re: send-pr IPv6 patches?
To: None <feico@pasta.cs.uit.no>
From: None <itojun@iijlab.net>
List: tech-net
Date: 12/03/1999 01:11:23
>I agree that would be nice. For my syslogd-patch I do have an AF
>dependency, because it simplified things quite a lot (I started out
>trying to do the most portable thing with AF independent code). The
>`problem' lies with the wildcard bind behaviour. Although NetBSD seems
>to support IPv4 mapped addresses now on a IPv6 socket, I got in
>trouble with recvfrom() giving me IPv4 addresses back instead of
>IPv4-mapped ones (maybe I was doing something wrong; it was getting
>late).

	I should check it.  Thanks.

>Now, I let syslogd do a wildcard bind for AF_INET and
>AF_INET6 separately and do a sendto on the one which matches the
>address family of the destination. It certainly can be done in
>a more AF independent manner, but I don't know how to do that really 
>elegantly in this case and I couldn't find a good example elsewhere 
>either.  (Most of userland uses AF_INET6 somewhere in the code). 

	It is better to bind(2) two sockets for both AFs, not single socket
	for AF_INET6.  Some kernel does not support IPv4 mapped address.
	Also, most of IPv4-only setsockopt() is not, and will not, be
	supported on AF_INET6 socket with IPv4 mapped address.
	Applications become simpler if you bind(2) two sockets.

	The best way to do this is, again, getaddrinfo(3).

	struct addrinfo hints, *res;
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;
	getaddrinfo(NULL, "syslog", &hints, &res);

	this would give us the following chain into "res" if the kernel is
	dual stacked:
		AF_INET6, :: port 514
		AF_INET, 0.0.0.0 port 514
	then you would loop through "res" for bind(2).

	n = 0;
	for (r = res; r; r = r->ai_next) {
		s[n] = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
		if (s[n] < 0)
			continue;

		if (bind(s[n], r->ai_addr, r->ai_addrlen) < 0) {
			close(s[n]);
			continue;
		}

		n++;	/* success */
	}
	freeaddrinfo(res);
	if (n == 0)
		errx(1, "no socket available");

>How important (i.e. at what price in complexity) is total AF
>independence (i.e. also supporting other, future?, AF than
>INET and INET6). I don't really see that in other userland
>code already supporting IPv6 (like inetd, telnet and ftp).
>So, instead of address *family* independence, in most cases
>I'd think `mere' address *format* independence would be 
>sufficient?

	When rewriting application, sometimes it need a big rewrite to
	be very independent from AFs (like the code assumes single socket).
	I sometimes need to compromise myself when rewriting other's code.

	anyway, it is very good to see more IPv6-aware applications.

itojun