예제 #1
0
  /*
   * 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;
  }
예제 #2
0
  /**
   * 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();
    }
  }
예제 #3
0
  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);
  }
예제 #4
0
 /*
  * Returns the InetAddress representing anyLocalAddress
  * (typically 0.0.0.0 or ::0)
  */
 static InetAddress anyLocalAddress() {
   return impl.anyLocalAddress();
 }
예제 #5
0
  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;
  }