protected synchronized void ensureAclsUptodate() {

    if (lastLoadTime > aclFile.lastModified()) {
      return;
    }

    try {
      aclEntries = load();

      println("ACLs reloaded from file");

      return;
    } catch (Exception e) {
      println("Failed to reload ACL file.  Retaining old ACLs.  " + e);
    }
  }
  /**
   * Uses system network libraries to resolve the given String to an IP addr, then determine whether
   * this address is permitted or denied.
   *
   * <p>Specified name may be a numerical-based String like "1.2.3.4", a constant known to the
   * networking libraries, or a host name to be resolved by the systems name resolution system.
   *
   * <p>If the given String can't be resolved to an IP addr, false is returned.
   *
   * @see #permitAccess(byte[])
   */
  public boolean permitAccess(String s) {

    try {
      return permitAccess(InetAddress.getByName(s).getAddress());
    } catch (UnknownHostException uke) {
      println("'" + s + "' denied because failed to resolve to an addr");

      return false; // Resolution of candidate failed
    }
  }
  /**
   * @return true if access for the candidate address should be permitted, false if access should be
   *     denied.
   * @throws RuntimeException if no rule covers the candidate address. This would be the case if
   *     this class is applied to some network protocol other than ipv4 or ipv6, without adding a
   *     default rule for it.
   */
  public boolean permitAccess(byte[] addr) {

    ensureAclsUptodate();

    for (int i = 0; i < aclEntries.size(); i++) {
      if (((AclEntry) aclEntries.get(i)).matches(addr)) {
        AclEntry hit = (AclEntry) aclEntries.get(i);

        println(
            "Addr '" + ServerAcl.dottedNotation(addr) + "' matched rule #" + (i + 1) + ":  " + hit);

        return hit.allow;
      }
    }

    throw new RuntimeException("No rule matches address '" + ServerAcl.dottedNotation(addr) + "'");
  }