-
Bug
-
Resolution: Fixed
-
P3
-
6
-
b85
-
x86
-
windows_xp
FULL PRODUCT VERSION :
java version "1.6.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-beta-b59g)
Java HotSpot(TM) Client VM (build 1.6.0-beta-b59g, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
After about 3960 calls to java.net.InetAddress.isReachable() that has timed out I get the following exception. Running under 1.5.0_06 does not give this exception (if it is because it isn't thrown, or if it is because it doesn't occur is a different question).
java.net.ConnectException: An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full
at java.net.Inet6AddressImpl.isReachable0(Native Method)
at java.net.Inet6AddressImpl.isReachable(Inet6AddressImpl.java:59)
at java.net.InetAddress.isReachable(InetAddress.java:418)
at java.net.InetAddress.isReachable(InetAddress.java:377)
at com.myprog.NodeManager$AliveProber.run(NodeManager.java:316)
The timeout has been set to 1 second (1000 ms) and varying the number of outstanding calls to isReachable() does not cause any major change in how many calls that are needed for the exception to occur.
I intended to use this call to discover devices in a local network by looping through all IP addresses for the subnetwork when I hit this problem.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Code used to re-create the bug is executed in:
network: 10.2.2.40
subnetmask: 255.255.240.0
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect that this error only should occur if I have too many outstanding requests at a time and not after a certain number of requests.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.teleca.monitor.server;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
public class NodeManager
{
private final static int MAX_OUTSTANDING=8; // Tune for number of outstanding requests, tried values have been up to 256.
static Hashtable<InetAddress, Object> aliveHosts = new Hashtable<InetAddress, Object>();
static Object lockObj=new Object();
static int calls=0;
public NodeManager()
{
}
/**
* Get all nodes available on given network interface.
* <p>
* Notice that this utilizes ICMP PING and/or TCP/ECHO to detect nodes.
* If the node is configured to not respond to PING and/or TCP/ECHO
* requests it will not be detected.
*
* @param ni Interface to scan.
* @return Array of InetAddress.
*/
// public static InetAddress[] discoverNodes(NetworkInterface ni)
// {
// InetAddress[] iaa = null;
// List<InterfaceAddress> ifl = ni.getInterfaceAddresses();
// for (Iterator<InterfaceAddress> i = ifl.iterator(); i.hasNext();)
// {
// InterfaceAddress ifa = i.next();
// short prefix = ifa.getNetworkPrefixLength();
// InetAddress ina = ifa.getAddress();
// iaa = discoverNodes(ina, prefix);
// }
// return iaa;
// }
/**
* Get all nodes on a given network masked by given prefix.
* <p>
* Notice that this utilizes ICMP PING and/or TCP/ECHO to detect nodes.
* If the node is configured to not respond to PING and/or TCP/ECHO
* requests it will not be detected.
*
* @param ina Address to scan for nodes, masked by 'prefix' bits.
* @param prefix Number of bits that are network prefix.
* @return Array of InetAddress.
*/
private static InetAddress[] discoverNodes(InetAddress ina, short prefix)
{
InetAddress[] iaa = null;
if (ina instanceof Inet4Address && prefix > 0)
{
byte[] addr = ina.getAddress();
System.out.println("prefix=" + prefix);
System.out.println("addr.length=" + addr.length);
System.out.print("addr=");
for (int i = 0; i < addr.length; i++)
{
if (ina instanceof Inet4Address)
{
System.out.print(Integer.toString(addr[i] & 0xff) + ".");
} else
{
System.out.print(Integer.toHexString(addr[i] & 0xff) + ":");
}
}
System.out.print(" ; ");
int nodebits = (addr.length * 8) - prefix;
if (nodebits <= 0)
{
iaa = new InetAddress[1];
iaa[0] = ina;
} else
{
byte[] firstAddr = new byte[addr.length];
int bitsLeft = prefix;
int mask = 0;
int maskByte = -1;
for (int i = 0; i < addr.length; i++)
{
if (bitsLeft >= 8)
{
firstAddr[i] = addr[i];
bitsLeft -= 8;
} else
{
if (bitsLeft > 0)
{
maskByte = i;
for (int j = 0; j < 8 && bitsLeft > 0; j++)
{
mask <<= 1;
mask |= 1;
bitsLeft--;
}
firstAddr[i] = (byte) ((addr[i] & ~mask) & 0xff);
} else
{
if (maskByte == -1)
{
maskByte = i;
}
firstAddr[i] = 0;
}
}
}
firstAddr[addr.length - 1] |= 1;
System.out.print("Mask[" + maskByte + "]=" + Integer.toHexString(mask & 0xff) + " ; ");
System.out.print("~Mask[" + maskByte + "]=" + Integer.toString(~mask & 0xff) + " ; ");
byte[] lastAddr = new byte[addr.length];
if (maskByte >= 0)
{
for (int i = 0; i <= maskByte; i++)
{
lastAddr[i] = firstAddr[i];
}
lastAddr[maskByte] |= mask;
for (int i = maskByte + 1; i < addr.length; i++)
{
lastAddr[i] |= 0xff;
}
lastAddr[addr.length - 1] &= 254;
} else
{
for (int i = 0; i < addr.length; i++)
{
lastAddr[i] = firstAddr[i];
}
}
if (ina instanceof Inet4Address)
{
for (int i = 0; i < addr.length; i++)
{
System.out.print(Integer.toString(firstAddr[i] & 0xff) + ".");
}
System.out.print(" - ");
for (int i = 0; i < addr.length; i++)
{
System.out.print(Integer.toString(lastAddr[i] & 0xff) + ".");
}
System.out.println();
Vector v1 = new Vector();
// firstAddr=new byte []{10, 2, 2, 30};
// lastAddr=new byte []{10, 2, 2, 50};
probe(firstAddr, lastAddr, new byte[firstAddr.length], 0, v1);
for (Enumeration e = v1.elements(); e.hasMoreElements();)
{
AliveProber ap = (AliveProber) e.nextElement();
try
{
ap.join();
} catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
if (ina instanceof Inet6Address)
{
System.out.print("firstAddr=");
for (int i = 0; i < addr.length; i++)
{
System.out.print(Integer.toHexString(firstAddr[i] & 0xff) + ":");
}
System.out.print(" - ");
System.out.print("lastAddr=");
for (int i = 0; i < addr.length; i++)
{
System.out.print(Integer.toHexString(lastAddr[i] & 0xff) + ":");
}
System.out.println();
}
}
int n = 0;
for (Enumeration e = aliveHosts.keys(); e.hasMoreElements();)
{
InetAddress ia = (InetAddress) e.nextElement();
System.out.println("ia[" + n + "]=" + ia + " ; " + ia.getCanonicalHostName());
n++;
}
}
return iaa;
}
private static void probe(byte[] firstAddr, byte[] lastAddr, byte[] curAddr, int level, Vector v1)
{
if (level == firstAddr.length)
{
AliveProber ap=new AliveProber(curAddr);
v1.add(ap);
} else
{
int start = (firstAddr[level] & 0xff);
int end = (lastAddr[level] & 0xff);
if ((level + 1) == firstAddr.length)
{
for (int i = 0; i < level; i++)
{
if (curAddr[i] != firstAddr[i])
{
start = 0;
}
if (curAddr[i] != lastAddr[i])
{
end = 255;
}
}
}
for (int i = start; i <= end; i++)
{
curAddr[level] = (byte) (i & 0xff);
probe(firstAddr, lastAddr, curAddr, level + 1, v1);
}
}
if (v1.size() >= MAX_OUTSTANDING)
{
for (Enumeration e = v1.elements(); e.hasMoreElements();)
{
AliveProber ap = (AliveProber) e.nextElement();
if (!ap.isAlive())
{
v1.remove(ap);
}
}
for (Enumeration e = v1.elements(); e.hasMoreElements() && v1.size() >= MAX_OUTSTANDING;)
{
AliveProber ap = (AliveProber) e.nextElement();
try
{
ap.join();
v1.remove(ap);
} catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
private static class AliveProber
extends Thread
{
InetAddress ia = null;
public AliveProber(byte[] addr)
{
if (addr.length != 4)
{
System.err.println("Not INET4 address!");
new Throwable().printStackTrace();
System.exit(9);
} else
{
try
{
ia = InetAddress.getByAddress(addr);
} catch (UnknownHostException e)
{
}
}
this.start();
}
public void run()
{
try
{
StringBuffer sb=new StringBuffer();
calls++;
if (ia.isReachable(1000))
{
sb.append("ia=" + ia);
sb.append(" - Alive");
aliveHosts.put(ia, "");
} else
{
sb.append("ia=" + ia);
sb.append(" - DEAD");
}
synchronized(lockObj)
{
System.out.println(sb.toString());
}
} catch (IOException e)
{
synchronized(lockObj)
{
System.err.println("calls="+calls+", "+e.getClass().getName() + ":" + e.getMessage() + ":" + ia);
e.printStackTrace();
System.exit(9);
}
}
}
}
/**
* @param args
*/
public static void main(String[] args)
{
try
{
for (Enumeration<NetworkInterface> nie = NetworkInterface.getNetworkInterfaces(); nie.hasMoreElements();)
{
NetworkInterface ni = nie.nextElement();
System.out.println("ni=" + ni.getName() + ":" + ni.getDisplayName());
// discoverNodes(ni);
discoverNodes(InetAddress.getByAddress(new byte[]{10,2,2,40}), (short)20);
}
} catch (SocketException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Currently this problem doesn't seem to occur when running Java 1.5.0_06, but the problem may as well not be visualized there.
Release Regression From : 5.0u6
The above release value was the last known release where this
bug was known to work. Since then there has been a regression.
java version "1.6.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-beta-b59g)
Java HotSpot(TM) Client VM (build 1.6.0-beta-b59g, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
After about 3960 calls to java.net.InetAddress.isReachable() that has timed out I get the following exception. Running under 1.5.0_06 does not give this exception (if it is because it isn't thrown, or if it is because it doesn't occur is a different question).
java.net.ConnectException: An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full
at java.net.Inet6AddressImpl.isReachable0(Native Method)
at java.net.Inet6AddressImpl.isReachable(Inet6AddressImpl.java:59)
at java.net.InetAddress.isReachable(InetAddress.java:418)
at java.net.InetAddress.isReachable(InetAddress.java:377)
at com.myprog.NodeManager$AliveProber.run(NodeManager.java:316)
The timeout has been set to 1 second (1000 ms) and varying the number of outstanding calls to isReachable() does not cause any major change in how many calls that are needed for the exception to occur.
I intended to use this call to discover devices in a local network by looping through all IP addresses for the subnetwork when I hit this problem.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Code used to re-create the bug is executed in:
network: 10.2.2.40
subnetmask: 255.255.240.0
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect that this error only should occur if I have too many outstanding requests at a time and not after a certain number of requests.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.teleca.monitor.server;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
public class NodeManager
{
private final static int MAX_OUTSTANDING=8; // Tune for number of outstanding requests, tried values have been up to 256.
static Hashtable<InetAddress, Object> aliveHosts = new Hashtable<InetAddress, Object>();
static Object lockObj=new Object();
static int calls=0;
public NodeManager()
{
}
/**
* Get all nodes available on given network interface.
* <p>
* Notice that this utilizes ICMP PING and/or TCP/ECHO to detect nodes.
* If the node is configured to not respond to PING and/or TCP/ECHO
* requests it will not be detected.
*
* @param ni Interface to scan.
* @return Array of InetAddress.
*/
// public static InetAddress[] discoverNodes(NetworkInterface ni)
// {
// InetAddress[] iaa = null;
// List<InterfaceAddress> ifl = ni.getInterfaceAddresses();
// for (Iterator<InterfaceAddress> i = ifl.iterator(); i.hasNext();)
// {
// InterfaceAddress ifa = i.next();
// short prefix = ifa.getNetworkPrefixLength();
// InetAddress ina = ifa.getAddress();
// iaa = discoverNodes(ina, prefix);
// }
// return iaa;
// }
/**
* Get all nodes on a given network masked by given prefix.
* <p>
* Notice that this utilizes ICMP PING and/or TCP/ECHO to detect nodes.
* If the node is configured to not respond to PING and/or TCP/ECHO
* requests it will not be detected.
*
* @param ina Address to scan for nodes, masked by 'prefix' bits.
* @param prefix Number of bits that are network prefix.
* @return Array of InetAddress.
*/
private static InetAddress[] discoverNodes(InetAddress ina, short prefix)
{
InetAddress[] iaa = null;
if (ina instanceof Inet4Address && prefix > 0)
{
byte[] addr = ina.getAddress();
System.out.println("prefix=" + prefix);
System.out.println("addr.length=" + addr.length);
System.out.print("addr=");
for (int i = 0; i < addr.length; i++)
{
if (ina instanceof Inet4Address)
{
System.out.print(Integer.toString(addr[i] & 0xff) + ".");
} else
{
System.out.print(Integer.toHexString(addr[i] & 0xff) + ":");
}
}
System.out.print(" ; ");
int nodebits = (addr.length * 8) - prefix;
if (nodebits <= 0)
{
iaa = new InetAddress[1];
iaa[0] = ina;
} else
{
byte[] firstAddr = new byte[addr.length];
int bitsLeft = prefix;
int mask = 0;
int maskByte = -1;
for (int i = 0; i < addr.length; i++)
{
if (bitsLeft >= 8)
{
firstAddr[i] = addr[i];
bitsLeft -= 8;
} else
{
if (bitsLeft > 0)
{
maskByte = i;
for (int j = 0; j < 8 && bitsLeft > 0; j++)
{
mask <<= 1;
mask |= 1;
bitsLeft--;
}
firstAddr[i] = (byte) ((addr[i] & ~mask) & 0xff);
} else
{
if (maskByte == -1)
{
maskByte = i;
}
firstAddr[i] = 0;
}
}
}
firstAddr[addr.length - 1] |= 1;
System.out.print("Mask[" + maskByte + "]=" + Integer.toHexString(mask & 0xff) + " ; ");
System.out.print("~Mask[" + maskByte + "]=" + Integer.toString(~mask & 0xff) + " ; ");
byte[] lastAddr = new byte[addr.length];
if (maskByte >= 0)
{
for (int i = 0; i <= maskByte; i++)
{
lastAddr[i] = firstAddr[i];
}
lastAddr[maskByte] |= mask;
for (int i = maskByte + 1; i < addr.length; i++)
{
lastAddr[i] |= 0xff;
}
lastAddr[addr.length - 1] &= 254;
} else
{
for (int i = 0; i < addr.length; i++)
{
lastAddr[i] = firstAddr[i];
}
}
if (ina instanceof Inet4Address)
{
for (int i = 0; i < addr.length; i++)
{
System.out.print(Integer.toString(firstAddr[i] & 0xff) + ".");
}
System.out.print(" - ");
for (int i = 0; i < addr.length; i++)
{
System.out.print(Integer.toString(lastAddr[i] & 0xff) + ".");
}
System.out.println();
Vector v1 = new Vector();
// firstAddr=new byte []{10, 2, 2, 30};
// lastAddr=new byte []{10, 2, 2, 50};
probe(firstAddr, lastAddr, new byte[firstAddr.length], 0, v1);
for (Enumeration e = v1.elements(); e.hasMoreElements();)
{
AliveProber ap = (AliveProber) e.nextElement();
try
{
ap.join();
} catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
if (ina instanceof Inet6Address)
{
System.out.print("firstAddr=");
for (int i = 0; i < addr.length; i++)
{
System.out.print(Integer.toHexString(firstAddr[i] & 0xff) + ":");
}
System.out.print(" - ");
System.out.print("lastAddr=");
for (int i = 0; i < addr.length; i++)
{
System.out.print(Integer.toHexString(lastAddr[i] & 0xff) + ":");
}
System.out.println();
}
}
int n = 0;
for (Enumeration e = aliveHosts.keys(); e.hasMoreElements();)
{
InetAddress ia = (InetAddress) e.nextElement();
System.out.println("ia[" + n + "]=" + ia + " ; " + ia.getCanonicalHostName());
n++;
}
}
return iaa;
}
private static void probe(byte[] firstAddr, byte[] lastAddr, byte[] curAddr, int level, Vector v1)
{
if (level == firstAddr.length)
{
AliveProber ap=new AliveProber(curAddr);
v1.add(ap);
} else
{
int start = (firstAddr[level] & 0xff);
int end = (lastAddr[level] & 0xff);
if ((level + 1) == firstAddr.length)
{
for (int i = 0; i < level; i++)
{
if (curAddr[i] != firstAddr[i])
{
start = 0;
}
if (curAddr[i] != lastAddr[i])
{
end = 255;
}
}
}
for (int i = start; i <= end; i++)
{
curAddr[level] = (byte) (i & 0xff);
probe(firstAddr, lastAddr, curAddr, level + 1, v1);
}
}
if (v1.size() >= MAX_OUTSTANDING)
{
for (Enumeration e = v1.elements(); e.hasMoreElements();)
{
AliveProber ap = (AliveProber) e.nextElement();
if (!ap.isAlive())
{
v1.remove(ap);
}
}
for (Enumeration e = v1.elements(); e.hasMoreElements() && v1.size() >= MAX_OUTSTANDING;)
{
AliveProber ap = (AliveProber) e.nextElement();
try
{
ap.join();
v1.remove(ap);
} catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
private static class AliveProber
extends Thread
{
InetAddress ia = null;
public AliveProber(byte[] addr)
{
if (addr.length != 4)
{
System.err.println("Not INET4 address!");
new Throwable().printStackTrace();
System.exit(9);
} else
{
try
{
ia = InetAddress.getByAddress(addr);
} catch (UnknownHostException e)
{
}
}
this.start();
}
public void run()
{
try
{
StringBuffer sb=new StringBuffer();
calls++;
if (ia.isReachable(1000))
{
sb.append("ia=" + ia);
sb.append(" - Alive");
aliveHosts.put(ia, "");
} else
{
sb.append("ia=" + ia);
sb.append(" - DEAD");
}
synchronized(lockObj)
{
System.out.println(sb.toString());
}
} catch (IOException e)
{
synchronized(lockObj)
{
System.err.println("calls="+calls+", "+e.getClass().getName() + ":" + e.getMessage() + ":" + ia);
e.printStackTrace();
System.exit(9);
}
}
}
}
/**
* @param args
*/
public static void main(String[] args)
{
try
{
for (Enumeration<NetworkInterface> nie = NetworkInterface.getNetworkInterfaces(); nie.hasMoreElements();)
{
NetworkInterface ni = nie.nextElement();
System.out.println("ni=" + ni.getName() + ":" + ni.getDisplayName());
// discoverNodes(ni);
discoverNodes(InetAddress.getByAddress(new byte[]{10,2,2,40}), (short)20);
}
} catch (SocketException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Currently this problem doesn't seem to occur when running Java 1.5.0_06, but the problem may as well not be visualized there.
Release Regression From : 5.0u6
The above release value was the last known release where this
bug was known to work. Since then there has been a regression.