org.eclipse.jetty.util.InetAddressSet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util;
import java.net.InetAddress;
import java.util.AbstractSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
/**
* A set of InetAddress patterns.
* This is a {@link Set} of String patterns that are used to match
* a {@link Predicate} over InetAddress for containment semantics.
* The patterns that may be set are:
*
*
* - InetAddress
- A single InetAddress either in hostname or address format.
* All formats supported by {@link InetAddress} are accepted. Not ethat using hostname
* matches may force domain lookups. eg. "[::1]", "1.2.3.4", "::ffff:127.0.0.1"
* - InetAddress/CIDR
- An InetAddress with a integer number of bits to indicate
* the significant prefix. eg. "192.168.0.0/16" will match from "192.168.0.0" to
* "192.168.255.255"
* - InetAddress-InetAddress
- An inclusive range of InetAddresses.
* eg. "[a000::1]-[afff::]", "192.168.128.0-192.168.128.255"
* - Legacy format
- The legacy format used by {@link IPAddressMap} for IPv4 only.
* eg. "10.10.10-14.0-128"
*
* This class is designed to work with {@link IncludeExcludeSet}
* @see IncludeExcludeSet
*/
public class InetAddressSet extends AbstractSet implements Set, Predicate
{
private Map _patterns = new HashMap<>();
@Override
public boolean add(String pattern)
{
return _patterns.put(pattern,newInetRange(pattern))==null;
}
protected InetPattern newInetRange(String pattern)
{
if (pattern==null)
return null;
int slash = pattern.lastIndexOf('/');
int dash = pattern.lastIndexOf('-');
try
{
if (slash>=0)
return new CidrInetRange(pattern,InetAddress.getByName(pattern.substring(0,slash).trim()),StringUtil.toInt(pattern,slash+1));
if (dash>=0)
return new MinMaxInetRange(pattern,InetAddress.getByName(pattern.substring(0,dash).trim()),InetAddress.getByName(pattern.substring(dash+1).trim()));
return new SingletonInetRange(pattern,InetAddress.getByName(pattern));
}
catch(Exception e)
{
try
{
if (slash<0 && dash>0)
return new LegacyInetRange(pattern);
}
catch(Exception e2)
{
e.addSuppressed(e2);
}
throw new IllegalArgumentException("Bad pattern: "+pattern,e);
}
}
@Override
public boolean remove(Object pattern)
{
return _patterns.remove(pattern)!=null;
}
@Override
public Iterator iterator()
{
return _patterns.keySet().iterator();
}
@Override
public int size()
{
return _patterns.size();
}
@Override
public boolean test(InetAddress address)
{
if (address==null)
return false;
byte[] raw = address.getAddress();
for (InetPattern pattern : _patterns.values())
if (pattern.test(address,raw))
return true;
return false;
}
abstract static class InetPattern
{
final String _pattern;
InetPattern(String pattern)
{
_pattern=pattern;
}
abstract boolean test(InetAddress address, byte[] raw);
@Override
public String toString()
{
return _pattern;
}
}
static class SingletonInetRange extends InetPattern
{
final InetAddress _address;
public SingletonInetRange(String pattern, InetAddress address)
{
super(pattern);
_address=address;
}
@Override
public boolean test(InetAddress address, byte[] raw)
{
return _address.equals(address);
}
}
static class MinMaxInetRange extends InetPattern
{
final int[] _min;
final int[] _max;
public MinMaxInetRange(String pattern, InetAddress min, InetAddress max)
{
super(pattern);
byte[] raw_min = min.getAddress();
byte[] raw_max = max.getAddress();
if (raw_min.length!=raw_max.length)
throw new IllegalArgumentException("Cannot mix IPv4 and IPv6: "+pattern);
if (raw_min.length==4)
{
// there must be 6 '.' or this is likely to be a legacy pattern
int count=0;
for (char c:pattern.toCharArray())
if (c=='.')
count++;
if (count!=6)
throw new IllegalArgumentException("Legacy pattern: "+pattern);
}
_min = new int[raw_min.length];
_max = new int[raw_min.length];
for (int i=0;i<_min.length;i++)
{
_min[i]=0xff&raw_min[i];
_max[i]=0xff&raw_max[i];
}
for (int i=0;i<_min.length;i++)
{
if (_min[i]>_max[i])
throw new IllegalArgumentException("min is greater than max: "+pattern);
if (_min[i]<_max[i])
break;
}
}
@Override
public boolean test(InetAddress item, byte[] raw)
{
if (raw.length!=_min.length)
return false;
boolean min_ok = false;
boolean max_ok = false;
for (int i=0;i<_min.length;i++)
{
int r = 0xff&raw[i];
if (!min_ok)
{
if (r<_min[i])
return false;
if (r>_min[i])
min_ok=true;
}
if (!max_ok)
{
if (r>_max[i])
return false;
if (r<_max[i])
max_ok=true;
}
if (min_ok && max_ok)
break;
}
return true;
}
}
static class CidrInetRange extends InetPattern
{
final byte[] _raw;
final int _octets;
final int _mask;
final int _masked;
public CidrInetRange(String pattern, InetAddress address, int cidr)
{
super(pattern);
_raw = address.getAddress();
_octets = cidr/8;
_mask = 0xff&(0xff<<(8-cidr%8));
_masked = _mask==0?0:_raw[_octets]&_mask;
if (cidr>(_raw.length*8))
throw new IllegalArgumentException("CIDR too large: "+pattern);
if (_mask!=0 && (0xff&_raw[_octets])!=_masked)
throw new IllegalArgumentException("CIDR bits non zero: "+pattern);
for (int o=_octets+(_mask==0?0:1);o<_raw.length;o++)
if (_raw[o]!=0)
throw new IllegalArgumentException("CIDR bits non zero: "+pattern);
}
@Override
public boolean test(InetAddress item, byte[] raw)
{
if (raw.length!=_raw.length)
return false;
for (int o=0;o<_octets;o++)
if (_raw[o]!=raw[o])
return false;
if (_mask!=0 && (raw[_octets]&_mask)!=_masked)
return false;
return true;
}
}
static class LegacyInetRange extends InetPattern
{
int[] _min = new int[4];
int[] _max = new int[4];
public LegacyInetRange(String pattern)
{
super(pattern);
String[] parts = pattern.split("\\.");
if (parts.length!=4)
throw new IllegalArgumentException("Bad legacy pattern: "+pattern);
for (int i=0;i<4;i++)
{
String part=parts[i].trim();
int dash = part.indexOf('-');
if (dash<0)
_min[i]=_max[i]=Integer.parseInt(part);
else
{
_min[i] = (dash==0)?0:StringUtil.toInt(part,0);
_max[i] = (dash==part.length()-1)?255:StringUtil.toInt(part,dash+1);
}
if (_min[i]<0 || _min[i]>_max[i] || _max[i]>255)
throw new IllegalArgumentException("Bad legacy pattern: "+pattern);
}
}
@Override
public boolean test(InetAddress item, byte[] raw)
{
if (raw.length!=4)
return false;
for (int i=0;i<4;i++)
if ((0xff&raw[i])<_min[i] || (0xff&raw[i])>_max[i])
return false;
return true;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy