Thursday, November 05, 2009

IPv6 addresses in JGroups

I finished code to support scoped IPv6 link local addresses [1]. A link local address is an address that's not guaranteed to be unique on a given host (althougbh in most cases it will be), so it can be assigned on different interfaces of the same host.

To differentiate between interfaces, a scope-id can be added, e.g. fe80::216:cbff:fea9:c3b5%en0 or fe80::216:cbff:fea9:c3b5%3, where the %X suffix denotes the interface.

Note that this is only relevant for TCP sockets, multicast or datagram sockets are not affected.

Now, on the server side, we can bind to a scoped or unscoped link-local socket, e.g.

ServerSocket srv_sock=new ServerSocket(7500, 50, InetAddress.getByName("fe80::216:cbff:fea9:c3b5"))

binds to an unscoped link-local address, and

ServerSocket srv_sock=new ServerSocket(7500, 50, InetAddress.getByName("fe80::216:cbff:fea9:c3b5%en0"))

binds to the scoped equivalent.

This is all fine, but on the client side, we cannot use scoped link-local addresses, e.g.

Socket sock=new Socket(InetAddress.getByName("fe80::216:cbff:fea9:c3b5%en0"), 7500)

fails !

The reason is that a scope-id "en0" does not mean anything on a client, which might run on a different host.

The correct code is

Socket sock=new Socket(InetAddress.getByName("fe80::216:cbff:fea9:c3b5"), 7500),

with the scope-id removed.

JGroups runs into this problem, too: whenever we have a bind_addr which is a scoped link-local IPv6 address, certain discovery protocols (e.g. MPING, TCPGOSSIP) will return the scoped addresses, and the joiners will then try to connect to the existing members using the scoped addresses.

To fix this, all Socket.connect() calls in JGroups have been replaced with Util.connect(Socket, SocketAddress, port). This method checks for scoped link-local IPv6 addresses and simply removes the scope-id from the destination address, so the connect() call will work.

Note that this problem doesn't occur with global IPv6 addresses.

I need to test whether this solution works on other operating systems, too, .e.g. on Windows, Solaris and MacOS.

OK, I'm off to http://www.davidoffswissindoors.ch, hope to see some good tennis !

[1] http://www.jboss.org/community/wiki/IPv6

3 comments:

  1. Nice articles...keep posting..

    http://javaj2eeplanet.blogspot.com
    http://funkyxone.blogspot.com

    ReplyDelete
  2. Windows is diffence,
    ServerSocket srv_sock=new ServerSocket(7500, 50, InetAddress.getByName("fe80::216:cbff:fea9:c3b5%en0"))
    will fail.

    sun say:
    In the Linux native code, we use the kernel IPv6 routing table
    to figure out which scope_id value to use when a given Inet6Address
    has no scope_id set. For the local link-local address, this
    always points to the "lo" loopback interface, which is correct
    for destination addresses, ie. packets are sent out the loopback
    interface when the destination is the local LL address.

    if like this,link local address can not communicate.
    some advice?

    ReplyDelete
  3. ServerSocket srv_sock=new ServerSocket(7500, 50, InetAddress.getByName("fe80::216:cbff:fea9:c3b5"))
    does not work in windows.

    another,http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6206527
    sun say:
    In the Linux native code, we use the kernel IPv6 routing table
    to figure out which scope_id value to use when a given Inet6Address
    has no scope_id set. For the local link-local address, this
    always points to the "lo" loopback interface, which is correct
    for destination addresses, ie. packets are sent out the loopback
    interface when the destination is the local LL address.

    it think the local link-local address can not communicate.
    some advice?

    ReplyDelete