/* * Initialize cache and insert anyLocalAddress into the * unknown array with no expiry. */ private static void cacheInitIfNeeded() { assert Thread.holdsLock(addressCache); if (addressCacheInit) { return; } unknown_array = new InetAddress[1]; unknown_array[0] = impl.anyLocalAddress(); addressCache.put(impl.anyLocalAddress().getHostName(), unknown_array); addressCacheInit = true; }
/** * Returns the address of the local host. This is achieved by retrieving the name of the host from * the system, then resolving that name into an <code>InetAddress</code>. * * <p>Note: The resolved address may be cached for a short period of time. * * <p>If there is a security manager, its <code>checkConnect</code> method is called with the * local host name and <code>-1</code> as its arguments to see if the operation is allowed. If the * operation is not allowed, an InetAddress representing the loopback address is returned. * * @return the address of the local host. * @exception UnknownHostException if the local host name could not be resolved into an address. * @see SecurityManager#checkConnect * @see java.net.InetAddress#getByName(java.lang.String) */ public static InetAddress getLocalHost() throws UnknownHostException { SecurityManager security = System.getSecurityManager(); try { String local = impl.getLocalHostName(); if (security != null) { security.checkConnect(local, -1); } if (local.equals("localhost")) { return impl.loopbackAddress(); } InetAddress ret = null; synchronized (cacheLock) { long now = System.currentTimeMillis(); if (cachedLocalHost != null) { if ((now - cacheTime) < maxCacheTime) // Less than 5s old? ret = cachedLocalHost; else cachedLocalHost = null; } // we are calling getAddressFromNameService directly // to avoid getting localHost from cache if (ret == null) { InetAddress[] localAddrs; try { localAddrs = (InetAddress[]) InetAddress.getAddressFromNameService(local, null); } catch (UnknownHostException uhe) { throw new UnknownHostException(local + ": " + uhe.getMessage()); } cachedLocalHost = localAddrs[0]; cacheTime = now; ret = localAddrs[0]; } } return ret; } catch (java.lang.SecurityException e) { return impl.loopbackAddress(); } }
private static InetAddress[] getAllByName(String host, InetAddress reqAddr) throws UnknownHostException { if (host == null || host.length() == 0) { InetAddress[] ret = new InetAddress[1]; ret[0] = impl.loopbackAddress(); return ret; } boolean ipv6Expected = false; if (host.charAt(0) == '[') { // This is supposed to be an IPv6 litteral if (host.length() > 2 && host.charAt(host.length() - 1) == ']') { host = host.substring(1, host.length() - 1); ipv6Expected = true; } else { // This was supposed to be a IPv6 address, but it's not! throw new UnknownHostException(host); } } // if host is an IP address, we won't do further lookup if (Character.digit(host.charAt(0), 16) != -1 || (host.charAt(0) == ':')) { byte[] addr = null; int numericZone = -1; String ifname = null; // see if it is IPv4 address addr = IPAddressUtil.textToNumericFormatV4(host); if (addr == null) { // see if it is IPv6 address // Check if a numeric or string zone id is present int pos; if ((pos = host.indexOf("%")) != -1) { numericZone = checkNumericZone(host); if (numericZone == -1) { /* remainder of string must be an ifname */ ifname = host.substring(pos + 1); } } addr = IPAddressUtil.textToNumericFormatV6(host); } else if (ipv6Expected) { // Means an IPv4 litteral between brackets! throw new UnknownHostException("[" + host + "]"); } InetAddress[] ret = new InetAddress[1]; if (addr != null) { if (addr.length == Inet4Address.INADDRSZ) { ret[0] = new Inet4Address(null, addr); } else { if (ifname != null) { ret[0] = new Inet6Address(null, addr, ifname); } else { ret[0] = new Inet6Address(null, addr, numericZone); } } return ret; } } else if (ipv6Expected) { // We were expecting an IPv6 Litteral, but got something else throw new UnknownHostException("[" + host + "]"); } return getAllByName0(host, reqAddr, true); }
/* * Returns the InetAddress representing anyLocalAddress * (typically 0.0.0.0 or ::0) */ static InetAddress anyLocalAddress() { return impl.anyLocalAddress(); }
private static Object getAddressFromNameService(String host, InetAddress reqAddr) throws UnknownHostException { Object obj = null; boolean success = false; UnknownHostException ex = null; // Check whether the host is in the lookupTable. // 1) If the host isn't in the lookupTable when // checkLookupTable() is called, checkLookupTable() // would add the host in the lookupTable and // return null. So we will do the lookup. // 2) If the host is in the lookupTable when // checkLookupTable() is called, the current thread // would be blocked until the host is removed // from the lookupTable. Then this thread // should try to look up the addressCache. // i) if it found the address in the // addressCache, checkLookupTable() would // return the address. // ii) if it didn't find the address in the // addressCache for any reason, // it should add the host in the // lookupTable and return null so the // following code would do a lookup itself. if ((obj = checkLookupTable(host)) == null) { // This is the first thread which looks up the address // this host or the cache entry for this host has been // expired so this thread should do the lookup. for (NameService nameService : nameServices) { try { /* * Do not put the call to lookup() inside the * constructor. if you do you will still be * allocating space when the lookup fails. */ obj = nameService.lookupAllHostAddr(host); success = true; break; } catch (UnknownHostException uhe) { if (host.equalsIgnoreCase("localhost")) { InetAddress[] local = new InetAddress[] {impl.loopbackAddress()}; obj = local; success = true; break; } else { obj = unknown_array; success = false; ex = uhe; } } } // More to do? InetAddress[] addrs = (InetAddress[]) obj; if (reqAddr != null && addrs.length > 1 && !addrs[0].equals(reqAddr)) { // Find it? int i = 1; for (; i < addrs.length; i++) { if (addrs[i].equals(reqAddr)) { break; } } // Rotate if (i < addrs.length) { InetAddress tmp, tmp2 = reqAddr; for (int j = 0; j < i; j++) { tmp = addrs[j]; addrs[j] = tmp2; tmp2 = tmp; } addrs[i] = tmp2; } } // Cache the address. cacheAddress(host, obj, success); // Delete the host from the lookupTable, and // notify all threads waiting for the monitor // for lookupTable. updateLookupTable(host); if (!success && ex != null) throw ex; } return obj; }