Beispiel #1
0
  private static InetAddress[] getAllByName0(String host, InetAddress reqAddr, boolean check)
      throws UnknownHostException {
    /* If it gets here it is presumed to be a hostname */
    /* Cache.get can return: null, unknownAddress, or InetAddress[] */
    Object obj = null;
    Object objcopy = null;

    /* make sure the connection to the host is allowed, before we
     * give out a hostname
     */
    if (check) {
      SecurityManager security = System.getSecurityManager();
      if (security != null) {
        security.checkConnect(host, -1);
      }
    }

    obj = getCachedAddress(host);

    /* If no entry in cache, then do the host lookup */
    if (obj == null) {
      obj = getAddressFromNameService(host, reqAddr);
    }

    if (obj == unknown_array) throw new UnknownHostException(host);

    /* Make a copy of the InetAddress array */
    objcopy = ((InetAddress[]) obj).clone();

    return (InetAddress[]) objcopy;
  }
Beispiel #2
0
    /**
     * Add an entry to the cache. If there's already an entry then for this host then the entry will
     * be replaced.
     */
    public Cache put(String host, Object address) {
      int policy = getPolicy();
      if (policy == InetAddressCachePolicy.NEVER) {
        return this;
      }

      // purge any expired entries

      if (policy != InetAddressCachePolicy.FOREVER) {

        // As we iterate in insertion order we can
        // terminate when a non-expired entry is found.
        LinkedList expired = new LinkedList();
        Iterator i = cache.keySet().iterator();
        long now = System.currentTimeMillis();
        while (i.hasNext()) {
          String key = (String) i.next();
          CacheEntry entry = (CacheEntry) cache.get(key);

          if (entry.expiration >= 0 && entry.expiration < now) {
            expired.add(key);
          } else {
            break;
          }
        }

        i = expired.iterator();
        while (i.hasNext()) {
          cache.remove(i.next());
        }
      }

      // create new entry and add it to the cache
      // -- as a HashMap replaces existing entries we
      //    don't need to explicitly check if there is
      //    already an entry for this host.
      long expiration;
      if (policy == InetAddressCachePolicy.FOREVER) {
        expiration = -1;
      } else {
        expiration = System.currentTimeMillis() + (policy * 1000);
      }
      CacheEntry entry = new CacheEntry(address, expiration);
      cache.put(host, entry);
      return this;
    }
Beispiel #3
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();
    }
  }
Beispiel #4
0
  /**
   * Returns the hostname for this address.
   *
   * <p>If there is a security manager, this method first calls its <code>checkConnect</code> method
   * with the hostname and <code>-1</code> as its arguments to see if the calling code is allowed to
   * know the hostname for this IP address, i.e., to connect to the host. If the operation is not
   * allowed, it will return the textual representation of the IP address.
   *
   * @return the host name for this IP address, or if the operation is not allowed by the security
   *     check, the textual representation of the IP address.
   * @param check make security check if true
   * @see SecurityManager#checkConnect
   */
  private static String getHostFromNameService(InetAddress addr, boolean check) {
    String host = null;
    for (NameService nameService : nameServices) {
      try {
        // first lookup the hostname
        host = nameService.getHostByAddr(addr.getAddress());

        /* check to see if calling code is allowed to know
         * the hostname for this IP address, ie, connect to the host
         */
        if (check) {
          SecurityManager sec = System.getSecurityManager();
          if (sec != null) {
            sec.checkConnect(host, -1);
          }
        }

        /* now get all the IP addresses for this hostname,
         * and make sure one of them matches the original IP
         * address. We do this to try and prevent spoofing.
         */

        InetAddress[] arr = InetAddress.getAllByName0(host, check);
        boolean ok = false;

        if (arr != null) {
          for (int i = 0; !ok && i < arr.length; i++) {
            ok = addr.equals(arr[i]);
          }
        }

        // XXX: if it looks a spoof just return the address?
        if (!ok) {
          host = addr.getHostAddress();
          return host;
        }

        break;

      } catch (SecurityException e) {
        host = addr.getHostAddress();
        break;
      } catch (UnknownHostException e) {
        host = addr.getHostAddress();
        // let next provider resolve the hostname
      }
    }

    return host;
  }
Beispiel #5
0
    /**
     * Query the cache for the specific host. If found then return its CacheEntry, or null if not
     * found.
     */
    public CacheEntry get(String host) {
      int policy = getPolicy();
      if (policy == InetAddressCachePolicy.NEVER) {
        return null;
      }
      CacheEntry entry = (CacheEntry) cache.get(host);

      // check if entry has expired
      if (entry != null && policy != InetAddressCachePolicy.FOREVER) {
        if (entry.expiration >= 0 && entry.expiration < System.currentTimeMillis()) {
          cache.remove(host);
          entry = null;
        }
      }

      return entry;
    }