[jitsi-dev] BindException on IPv6 link local interfaces


#1

I notice one of the devices I'm testing has enabled IPv6, although only
IPv4 is in use on the network

ice4j works, but I get many BindExceptions as it tries to harvest host
candidates

Have problems been seen before with the IPv6 support, or it is expected
to be fully functional? It could well be a platform issue: I notice
dnsjava is also giving exceptions on the same device.

Should the HostCandidateHarvester be skipping any interfaces or addresses?

I/HostCandidateHarvester( 2652): Retrying a bind because of a failure to
bind to address /fe80::64ad:ddff:fe5f:87b6%dummy0 and port 21000
(Invalid argument)
I/HostCandidateHarvester( 3909): Retrying a bind because of a failure to
bind to address /fe80::64ad:ddff:fe5f:87b6%dummy0 and port 21000
(Invalid argument)
I/HostCandidateHarvester( 3909): Retrying a bind because of a failure to
bind to address /fe80::f208:f1ff:fe55:9904%eth0 and port 21000 (Invalid
argument)
I/HostCandidateHarvester( 3909): Retrying a bind because of a failure to
bind to address /fe80::f208:f1ff:fe55:9904%ip6tnl0 and port 21000
(Invalid argument)

I/HostCandidateHarvester( 2652): java.net.BindException: Invalid argument
I/HostCandidateHarvester( 2652): at
org.apache.harmony.luni.platform.OSNetworkSystem.bind(Native Method)
I/HostCandidateHarvester( 2652): at
dalvik.system.BlockGuard$WrappedNetworkSystem.bind(BlockGuard.java:275)
I/HostCandidateHarvester( 2652): at
org.apache.harmony.luni.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:77)
I/HostCandidateHarvester( 2652): at
java.net.DatagramSocket.createSocket(DatagramSocket.java:190)
I/HostCandidateHarvester( 2652): at
java.net.DatagramSocket.<init>(DatagramSocket.java:92)
I/HostCandidateHarvester( 2652): at
org.ice4j.socket.DelegatingDatagramSocket.<init>(DelegatingDatagramSocket.java:162)
I/HostCandidateHarvester( 2652): at
org.ice4j.socket.SafeCloseDatagramSocket.<init>(SafeCloseDatagramSocket.java:101)
I/HostCandidateHarvester( 2652): at
org.ice4j.socket.MultiplexingDatagramSocket.<init>(MultiplexingDatagramSocket.java:142)
I/HostCandidateHarvester( 2652): at
org.ice4j.ice.harvest.HostCandidateHarvester.createDatagramSocket(HostCandidateHarvester.java:334)
I/HostCandidateHarvester( 2652): at
org.ice4j.ice.harvest.HostCandidateHarvester.harvest(HostCandidateHarvester.java:99)
I/HostCandidateHarvester( 2652): at
org.ice4j.ice.Agent.gatherCandidates(Agent.java:420)
I/HostCandidateHarvester( 2652): at
org.ice4j.ice.Agent.createComponent(Agent.java:330)


#2

Hey Daniel,

I notice one of the devices I'm testing has enabled IPv6, although only
IPv4 is in use on the network

ice4j works, but I get many BindExceptions as it tries to harvest host
candidates

Have problems been seen before with the IPv6 support, or it is expected
to be fully functional?

It is expected to work, yes. I regularly see it used in my calls.

I suppose there could be something wrong with the link-local addresses or
their configuration, that prevents apps from binding on them.

Cheers,
Emil

It could well be a platform issue: I notice
dnsjava is also giving exceptions on the same device.

Should the HostCandidateHarvester be skipping any interfaces or addresses?

I/HostCandidateHarvester( 2652): Retrying a bind because of a failure to
bind to address /fe80::64ad:ddff:fe5f:87b6%dummy0 and port 21000
(Invalid argument)
I/HostCandidateHarvester( 3909): Retrying a bind because of a failure to
bind to address /fe80::64ad:ddff:fe5f:87b6%dummy0 and port 21000
(Invalid argument)
I/HostCandidateHarvester( 3909): Retrying a bind because of a failure to
bind to address /fe80::f208:f1ff:fe55:9904%eth0 and port 21000 (Invalid
argument)
I/HostCandidateHarvester( 3909): Retrying a bind because of a failure to
bind to address /fe80::f208:f1ff:fe55:9904%ip6tnl0 and port 21000
(Invalid argument)

I/HostCandidateHarvester( 2652): java.net.BindException: Invalid argument
I/HostCandidateHarvester( 2652): at
org.apache.harmony.luni.platform.OSNetworkSystem.bind(Native Method)
I/HostCandidateHarvester( 2652): at
dalvik.system.BlockGuard$WrappedNetworkSystem.bind(BlockGuard.java:275)
I/HostCandidateHarvester( 2652): at

org.apache.harmony.luni.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:77)

I/HostCandidateHarvester( 2652): at
java.net.DatagramSocket.createSocket(DatagramSocket.java:190)
I/HostCandidateHarvester( 2652): at
java.net.DatagramSocket.<init>(DatagramSocket.java:92)
I/HostCandidateHarvester( 2652): at

org.ice4j.socket.DelegatingDatagramSocket.<init>(DelegatingDatagramSocket.java:162)

I/HostCandidateHarvester( 2652): at

org.ice4j.socket.SafeCloseDatagramSocket.<init>(SafeCloseDatagramSocket.java:101)

I/HostCandidateHarvester( 2652): at

org.ice4j.socket.MultiplexingDatagramSocket.<init>(MultiplexingDatagramSocket.java:142)

I/HostCandidateHarvester( 2652): at

org.ice4j.ice.harvest.HostCandidateHarvester.createDatagramSocket(HostCandidateHarvester.java:334)

I/HostCandidateHarvester( 2652): at

org.ice4j.ice.harvest.HostCandidateHarvester.harvest(HostCandidateHarvester.java:99)

···

On Feb 7, 2012 8:10 PM, "Daniel Pocock" <daniel@pocock.com.au> wrote:

I/HostCandidateHarvester( 2652): at
org.ice4j.ice.Agent.gatherCandidates(Agent.java:420)
I/HostCandidateHarvester( 2652): at
org.ice4j.ice.Agent.createComponent(Agent.java:330)


#3

Looking more closely at this today...

The issue is on a Samsung Galaxy Tab 10.1 (Android)

In addition to the bind exceptions in the earlier email, I also notice that

a) it finds 127.0.0.1 as a host candidate,
b) it finds 192.168.1.127 (the wifi IP) twice as a host candidate

I believe that problem (b) is the root cause of another exception (see
below)

I made another small patch to disable harvesting IPv6 (based on a system
property) and the exceptions all disappear.

What is your impression?
- Should the interface scanning code test the equivalence of the
addresses and not consider the same address twice?
- or should the harvest code be more tolerant to using both an IPv4 and
and IPv6 version of the same address?

I/org.ice4j.ice.Agent(31513): host+harvested candidate count (after
elimination): 6
I/org.ice4j.ice.Agent(31513): /::127.0.0.1:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /::192.168.1.127:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /192.168.1.127:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /169.254.8.122:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /188.62.165.55:21001/udp (srflx)
I/org.ice4j.ice.Agent(31513): /195.8.117.59:49460/udp (relay)

I/ConnectivityCheckServer(31513): Failed to send
BINDING-RESPONSE(0x101)[attrib.count=3 len=52] through
/192.168.1.127:21000/udp
I/ConnectivityCheckServer(31513): org.ice4j.StunException: The
transaction specified in the response (tid=0x3332F5813501868242C53892)
has already seen a previous response. Response was:
I/ConnectivityCheckServer(31513): BINDING-RESPONSE(0x101)[attrib.count=5
len=72 tranID=0x3332F5813501868242C53892]
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.StunStack.sendResponse(StunStack.java:492)
I/ConnectivityCheckServer(31513): at
org.ice4j.ice.ConnectivityCheckServer.processRequest(ConnectivityCheckServer.java:214)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.EventDispatcher$RequestListenerMessageEventHandler.handleMessageEvent(EventDispatcher.java:500)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.EventDispatcher.fireMessageEvent(EventDispatcher.java:257)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.StunStack.handleMessageEvent(StunStack.java:686)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.MessageProcessor.run(MessageProcessor.java:161)
I/ConnectivityCheckServer(31513): at
java.lang.Thread.run(Thread.java:1020)

···

On 08/02/12 09:18, Emil Ivov wrote:

Hey Daniel,

On Feb 7, 2012 8:10 PM, "Daniel Pocock" <daniel@pocock.com.au > <mailto:daniel@pocock.com.au>> wrote:

I notice one of the devices I'm testing has enabled IPv6, although only
IPv4 is in use on the network

ice4j works, but I get many BindExceptions as it tries to harvest host
candidates

Have problems been seen before with the IPv6 support, or it is expected
to be fully functional?

It is expected to work, yes. I regularly see it used in my calls.

I suppose there could be something wrong with the link-local addresses
or their configuration, that prevents apps from binding on them.


#4

Hey Daniel,

Hey Daniel,

I notice one of the devices I'm testing has enabled IPv6, although only
IPv4 is in use on the network

ice4j works, but I get many BindExceptions as it tries to harvest host
candidates

Have problems been seen before with the IPv6 support, or it is expected
to be fully functional?

It is expected to work, yes. I regularly see it used in my calls.

I suppose there could be something wrong with the link-local addresses
or their configuration, that prevents apps from binding on them.

Looking more closely at this today...

The issue is on a Samsung Galaxy Tab 10.1 (Android)

In addition to the bind exceptions in the earlier email, I also notice that

a) it finds 127.0.0.1 as a host candidate,
b) it finds 192.168.1.127 (the wifi IP) twice as a host candidate

I believe that problem (b) is the root cause of another exception (see
below)

I made another small patch to disable harvesting IPv6 (based on a system
property) and the exceptions all disappear.

What is your impression?
- Should the interface scanning code test the equivalence of the
addresses and not consider the same address twice?
- or should the harvest code be more tolerant to using both an IPv4 and
and IPv6 version of the same address?

I/org.ice4j.ice.Agent(31513): host+harvested candidate count (after
elimination): 6
I/org.ice4j.ice.Agent(31513): /::127.0.0.1:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /::192.168.1.127:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /192.168.1.127:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /169.254.8.122:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /188.62.165.55:21001/udp (srflx)
I/org.ice4j.ice.Agent(31513): /195.8.117.59:49460/udp (relay)

Oh OK. So this is about the 6to4 addresses, right? I didn't know there
were devices out there that still used those. Well, that kind of
explains it (personally, I've never seen a network with working 6to4
addresses).

So, if there are addresses on the device that are unusable, it is normal
that we try to bind on them and then fail. The actual problem is that
the addresses are there. As long as this doesn't prevent ice4j from
moving on (Which, if I understood correctly is what happens in your
case), then we should be fine.

Or did I miss something?

As for detecting the double addresses. Having the same address on two
different interfaces is a valid use case and we have no way of knowing
which one to take until we run the connectivity checks. Wouldn't you agree?

Cheers,
Emil

···

On 15.02.12 18:45, Daniel Pocock wrote:

On 08/02/12 09:18, Emil Ivov wrote:

On Feb 7, 2012 8:10 PM, "Daniel Pocock" <daniel@pocock.com.au >> <mailto:daniel@pocock.com.au>> wrote:

I/ConnectivityCheckServer(31513): Failed to send
BINDING-RESPONSE(0x101)[attrib.count=3 len=52] through
/192.168.1.127:21000/udp
I/ConnectivityCheckServer(31513): org.ice4j.StunException: The
transaction specified in the response (tid=0x3332F5813501868242C53892)
has already seen a previous response. Response was:
I/ConnectivityCheckServer(31513): BINDING-RESPONSE(0x101)[attrib.count=5
len=72 tranID=0x3332F5813501868242C53892]
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.StunStack.sendResponse(StunStack.java:492)
I/ConnectivityCheckServer(31513): at
org.ice4j.ice.ConnectivityCheckServer.processRequest(ConnectivityCheckServer.java:214)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.EventDispatcher$RequestListenerMessageEventHandler.handleMessageEvent(EventDispatcher.java:500)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.EventDispatcher.fireMessageEvent(EventDispatcher.java:257)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.StunStack.handleMessageEvent(StunStack.java:686)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.MessageProcessor.run(MessageProcessor.java:161)
I/ConnectivityCheckServer(31513): at
java.lang.Thread.run(Thread.java:1020)

--
Emil Ivov, Ph.D. 67000 Strasbourg,
Project Lead France
Jitsi
emcho@jitsi.org PHONE: +33.1.77.62.43.30
http://jitsi.org FAX: +33.1.77.62.47.31


#5

As a simple way for people to work around this issue, I've added a
config property to tell ice4j to ignore the IPv6 interfaces

To use it, just

  System.setProperty(StackProperties.ENABLE_IPv6, "false");

I've attached a copy of the patch

It defaults to the existing behavior

Lumicall uses this to eliminate these exceptions on the Samsung Galaxy Tab

0001-IPv6-add-system-property-for-disabling-IPv6-host-can.patch (2.2 KB)

···

On 15/02/12 22:03, Emil Ivov wrote:

Hey Daniel,

On 15.02.12 18:45, Daniel Pocock wrote:

On 08/02/12 09:18, Emil Ivov wrote:

Hey Daniel,

On Feb 7, 2012 8:10 PM, "Daniel Pocock" <daniel@pocock.com.au >>> <mailto:daniel@pocock.com.au>> wrote:

I notice one of the devices I'm testing has enabled IPv6, although only
IPv4 is in use on the network

ice4j works, but I get many BindExceptions as it tries to harvest host
candidates

Have problems been seen before with the IPv6 support, or it is expected
to be fully functional?

It is expected to work, yes. I regularly see it used in my calls.

I suppose there could be something wrong with the link-local addresses
or their configuration, that prevents apps from binding on them.

Looking more closely at this today...

The issue is on a Samsung Galaxy Tab 10.1 (Android)

In addition to the bind exceptions in the earlier email, I also notice that

a) it finds 127.0.0.1 as a host candidate,
b) it finds 192.168.1.127 (the wifi IP) twice as a host candidate

I believe that problem (b) is the root cause of another exception (see
below)

I made another small patch to disable harvesting IPv6 (based on a system
property) and the exceptions all disappear.

What is your impression?
- Should the interface scanning code test the equivalence of the
addresses and not consider the same address twice?
- or should the harvest code be more tolerant to using both an IPv4 and
and IPv6 version of the same address?

I/org.ice4j.ice.Agent(31513): host+harvested candidate count (after
elimination): 6
I/org.ice4j.ice.Agent(31513): /::127.0.0.1:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /::192.168.1.127:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /192.168.1.127:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /169.254.8.122:21001/udp (host)
I/org.ice4j.ice.Agent(31513): /188.62.165.55:21001/udp (srflx)
I/org.ice4j.ice.Agent(31513): /195.8.117.59:49460/udp (relay)

Oh OK. So this is about the 6to4 addresses, right? I didn't know there
were devices out there that still used those. Well, that kind of
explains it (personally, I've never seen a network with working 6to4
addresses).

So, if there are addresses on the device that are unusable, it is normal
that we try to bind on them and then fail. The actual problem is that
the addresses are there. As long as this doesn't prevent ice4j from
moving on (Which, if I understood correctly is what happens in your
case), then we should be fine.

Or did I miss something?

As for detecting the double addresses. Having the same address on two
different interfaces is a valid use case and we have no way of knowing
which one to take until we run the connectivity checks. Wouldn't you agree?

Cheers,
Emil

I/ConnectivityCheckServer(31513): Failed to send
BINDING-RESPONSE(0x101)[attrib.count=3 len=52] through
/192.168.1.127:21000/udp
I/ConnectivityCheckServer(31513): org.ice4j.StunException: The
transaction specified in the response (tid=0x3332F5813501868242C53892)
has already seen a previous response. Response was:
I/ConnectivityCheckServer(31513): BINDING-RESPONSE(0x101)[attrib.count=5
len=72 tranID=0x3332F5813501868242C53892]
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.StunStack.sendResponse(StunStack.java:492)
I/ConnectivityCheckServer(31513): at
org.ice4j.ice.ConnectivityCheckServer.processRequest(ConnectivityCheckServer.java:214)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.EventDispatcher$RequestListenerMessageEventHandler.handleMessageEvent(EventDispatcher.java:500)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.EventDispatcher.fireMessageEvent(EventDispatcher.java:257)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.StunStack.handleMessageEvent(StunStack.java:686)
I/ConnectivityCheckServer(31513): at
org.ice4j.stack.MessageProcessor.run(MessageProcessor.java:161)
I/ConnectivityCheckServer(31513): at
java.lang.Thread.run(Thread.java:1020)