IPv6 and FreeBSD
Julien ÉLIE
julien at trigofacile.com
Tue Oct 21 19:21:02 UTC 2008
Hi Johan,
First of all, thanks for your answer.
> EINVAL is returned if the addrlen argument to bind is wrong.
>
> Looking at the source of nnrpd.c (INN 2.4.3 that is), it seems that
> if the -b option is missing, ListenAddress will never be initialized(!)
Thanks. I will add "if (ListenAddr != NULL)" conditions.
> The 'ssa' address storage variable is then first used to store an IPv6
> address (with inet_pton - this fails) and then an IPv4 address
> (INADDR_ANY). The socket is then bound with:
>
> bind(lfd, (struct sockaddr *) &ssa, sizeof(ssa))
>
> In this call ssa points to a sockaddr_storage variable, which means the
> wrong third argument is passed for an IPv4 address (since ssa now has
> the correct size for storing an IPv6 address).
>
> The third argument to bind() should be sizeof(struct sockaddr_in) when
> an IPv4 address is stored in 'ssa' and sizeof(struct sockaddr_in6) when
> an IPv6 address is used.
The size is good because ssa has the right size:
if (DaemonMode) {
#ifdef HAVE_INET6
memset(&ssa, '\0', sizeof(struct sockaddr_in6));
if (inet_pton(AF_INET6, ListenAddr, ssa6->sin6_addr.s6_addr) > 0) {
[...]
} else {
#endif
memset(&ssa, '\0', sizeof(struct sockaddr_in));
if (inet_aton(ListenAddr, &ssa4->sin_addr) <= 0)
[...]
#ifdef HAVE_INET6
}
#endif
if (bind(lfd, (struct sockaddr *) &ssa, sizeof(ssa)) < 0) {
syslog(L_FATAL, "can't bind local address (%m)");
exit(1);
}
memset ajusts it for IPv6 and then IPv4 ,if it fails.
> This problem is not really OS-dependant, but I guess Linux doesn't care
> if the specified size is larger than what it expected.
I do not see why the size is not right here in bind().
--
Julien ÉLIE
« Avez-vous remarqué qu'à table les mets que l'on vous sert vous mettent
les mots à la bouche ? » (Raymond Devos)
More information about the inn-workers
mailing list