现在的位置: 首页 > 综合 > 正文

ipv6 bind() error

2012年10月18日 ⁄ 综合 ⁄ 共 4867字 ⁄ 字号 评论关闭

5down vote accepted
 

For link-local addresses, you also need to specify the scope ID of the network interface that is associated with the address... something like this:
server.sin6_scope_id = 5;   /* or whatever the scope ID is for the network interface you want to communicate over */

 You can use getifaddrs() to find the various scope IDs available on your systems, and the network interfaces they correspond to.

(Yes, it's a pain... alternatively you might be able to append something like "%en0" to the end of the string you pass to inet_pton(), and inet_pton() might do the work for you... I'm not sure if inet_pton() handles that syntax or not)

I’m running a slave DNS server on the machine that runs this website.  It is one of three DNS servers (one master, two slaves) that I have running for my multiple domains.  I recently noticed from my Logwatch output that it was having issues with IPv6 lookups
and these were causing timeouts and putting extra notices in my log files.  I decided the best route would be to just turn off IPv6 in BIND altogether.

Configuring named

The named man page (man named) lists two options for supporting IPv4 or IPv6.  Each of these commands are mutually exclusive, meaning using one of the options will not allow you to use the other.  Either IPv4 or iPv6, not both.  Now the default is to use
both, so if you want to continue supporting lookups on IPv4 and IPv6 there is nothing more you need to do.  If you want to *only* use one or the other you can use the -4 or -6 options in the configuration.

IPv4 only (/etc/default/bind9):

# run resolvconf?
RESOLVCONF=yes
# startup options for the server
OPTIONS="-4 -u bind"

IPv6 only (/etc/default/bind9):

# run resolvconf?
RESOLVCONF=yes
# startup options for the server
OPTIONS="-6 -u bind"

Once you have updated this file and defined the option you want, you’ll simply need to restart the BIND service and it’ll start listening on or or the other but, again, not both.

sudo /etc/init.d/bind9 restart

My BIND installation is now listening on only IPv4 and I have yet to see the same slowdown or amount of log output that I used to.  I guess, when we start using IPv6 one of these days I’ll need to change it, but I don’t have a lot of faith in that happening
anytime soon.
Categories: Server Tags: bind, ipv4, ipv6, named
Comments (2) Leave a comment
 
Derek Morr March 22nd, 2009 at 08:05 | #1 Reply | Quote What sort of IPv6 errors were you seeing in your logs? Do you mean that your resolver was trying to send queries over IPv6? Unless your box has a publicy routable IPv6 address, it shouldn’t do that. This
is a common bug in some older Linux distros, that’s been fixed in recent versions of glibc.
 
TomW April 19th, 2009 at 03:11 | #2 Reply | Quote Mercy! I've been combing for this bit of information all day. Apparently the options variable in the init.d script dont really get used, there where I dropped the "-4" at first. After undoing that change, and
dropping the "-4" argument into the default/bind9 file, all that ipv6 nonsense is gone.

Thanks

In article <AA70E30319FAD411AC6E00A0C95D7ABD01EE7692@xxxxxxxxxxxxxxxxxxxxx> (at

Fri, 19 Apr 2002 12:04:09 -0700), "Hossain, Mohammad" <m_hossain@xxxxxxxxxxxx>

says:

> Hello Hideaki,
>   It seems my IPv6 address has link scope only.
>   What value should be put in the scope id to pass the bind call?
>   Is it because of the address has scope link???

ifindex at this moment.

getaddrinfo() will help you.
give fe80::xxx%ethX as host where ethX is eth0
or whatever.

--yoshfuji

 
please set sin6_scope_id in the sockaddr_in6{}.

Well, I found the problem......apparently I forgot to zero the sin6_flowinfo and sin6_scope_id members (IPv4 doesn't have them).

netstat -ulpn

SandBox Description,

    Linux linux-009125090059 2.6.16.46-142-smp #1 SMP Fri Nov 2 14:59:14 PST 2007 i686 i686 i386 GNU/Linux

    1: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,NOTRAILERS,UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:0d:60:c4:8a:1b brd ff:ff:ff:ff:ff:ff
    inet 9.125.90.59/24 brd 9.125.90.255 scope global eth0
    inet6 fec0::201/64 scope site
       valid_lft forever preferred_lft forever
    inet6 2004::201/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::20d:60ff:fec4:8a1b/64 scope link
       valid_lft forever preferred_lft forever
    3: sit0: <NOARP> mtu 1480 qdisc noqueue
    link/sit 0.0.0.0 brd 0.0.0.0

The system call -bind- to bind the link-local address always fails.

The reason is that it can't bind to a link local IPv6 address without setting the sockaddr_in6.sin6_scope_id.

However, it can always bind to the site local  address even if the sin6_scope_id was not set.

 

I suppose the reason why the restriction exists for link-local addresses is that it's possible some vitual interfaces, such as vlan interfaces, may attach to the -real- interface.

For example,the 4095 vlan-tagged interface attached to eth0, maybe named eth0.4095, has the same link-local address as the eth0, since the virtual interfaces are supposed to have the same link layer address of the interface it attaches to

@@ -458,6 +458,11 @@ static char* scan_if(struct in6_addr* addr_target, int* plen_target,

   src_sin6.sin6_family = AF_INET6;

   src_sin6.sin6_addr = *src_ip;

   src_sin6.sin6_port = 0;

+  if (IN6_IS_ADDR_LINKLOCAL(&src_sin6.sin6_addr) ||

+    IN6_IS_ADDR_MC_LINKLOCAL(&src_sin6.sin6_addr)) {

+    src_sin6.sin6_scope_id = ifindex;

+  }

   if (bind(fd, (struct sockaddr *)&src_sin6, sizeof(src_sin6)) < 0) {

     cl_log(LOG_ERR, "bind() failed: %s", strerror(errno));
     goto err;

抱歉!评论已关闭.