package diskCacheV111.poolManager; import java.io.Serializable; import java.math.BigInteger; import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; class NetHandler implements Serializable { private static final long serialVersionUID = 8911153851483100573L; final Map<Long, NetUnit>[] _netList = new HashMap[33]; private final String[] _maskStrings = new String[33]; private final long[] _masks = new long[33]; final Map<BigInteger, NetUnit>[] _netListV6 = new HashMap[129]; private final String[] _maskStringsV6 = new String[129]; private final BigInteger[] _masksV6 = new BigInteger[129]; NetHandler() { long mask = 0; long xmask; long cursor = 1; for (int i = 0; i < _maskStrings.length; i++) { _masks[i] = xmask = ~mask; int a = (int) ((xmask >> 24) & 255); int b = (int) ((xmask >> 16) & 255); int c = (int) ((xmask >> 8) & 255); int d = (int) ((xmask) & 255); _maskStrings[i] = a + "." + b + "." + c + "." + d; mask |= cursor; cursor <<= 1; } BigInteger maskV6 = BigInteger.ZERO; BigInteger xmaskV6; BigInteger cursorV6 = BigInteger.ONE; for (int i = 0; i < _maskStringsV6.length; i++) { xmaskV6 = maskV6.not(); _masksV6[i] = xmaskV6; _maskStringsV6[i] = Integer.toString(xmaskV6.bitCount()); maskV6 = maskV6.or(cursorV6); cursorV6 = cursorV6.shiftLeft(1); } } void clear() { for (Map<Long, NetUnit> netMap : _netList) { if (netMap != null) { netMap.clear(); } } for (Map<BigInteger, NetUnit> netMap : _netListV6) { if (netMap != null) { netMap.clear(); } } } private BigInteger inetAddressToBigInteger(InetAddress address) { return new BigInteger(address.getAddress()); } private long inetAddressToLong(InetAddress address) { long value = 0; int i=24; for(byte b : address.getAddress()) { long bv = b >= 0 ? (long)b : (long)256+b; value |= bv << i; i -= 8; } return value; } void add(NetUnit net) { int bit = net.getHostBits(); if (net.getHostAddress() instanceof Inet4Address) { if (_netList[bit] == null) { _netList[bit] = new HashMap<>(); } long addr = inetAddressToLong(net.getHostAddress()); long maskedAddr = addr & _masks[bit]; _netList[bit].put(maskedAddr, net); } else { if (_netListV6[bit] == null) { _netListV6[bit] = new HashMap<>(); } BigInteger addr = inetAddressToBigInteger(net.getHostAddress()); _netListV6[bit].put(addr.and(_masksV6[bit]), net); } } void remove(NetUnit net) { int bit = net.getHostBits(); if (net.getHostAddress() instanceof Inet4Address) { if (_netList[bit] == null) { return; } long addr = inetAddressToLong(net.getHostAddress()); _netList[bit].remove(addr & _masks[bit]); if (_netList.length == 0) { _netList[bit] = null; } } else { if (_netListV6[bit] == null) { return; } BigInteger addr = inetAddressToBigInteger(net.getHostAddress()); _netListV6[bit].remove(addr.and(_masksV6[bit])); if (_netList.length == 0) { _netListV6[bit] = null; } } } NetUnit find(NetUnit net) { int bit = net.getHostBits(); NetUnit result = null; if (_netListV6[bit] != null) { BigInteger addr = inetAddressToBigInteger(net.getHostAddress()); result = _netListV6[bit].get(addr.and(_masksV6[bit])); } if (result == null && _netList[bit] != null) { long addr = inetAddressToLong(net.getHostAddress()); result = _netList[bit].get(addr & _masks[bit]); } return result; } NetUnit match(String inetAddress) throws UnknownHostException { InetAddress address = InetAddress.getByName(inetAddress); if (address instanceof Inet4Address) { long addr = inetAddressToLong(address); long mask = 0; long cursor = 1; NetUnit unit; for (Map<Long, NetUnit> map : _netList) { if (map != null) { Long l = addr & ~mask; unit = map.get(l); if (unit != null) { return unit; } } mask |= cursor; cursor <<= 1; } } else { BigInteger addr = inetAddressToBigInteger(address); BigInteger mask = BigInteger.ZERO; BigInteger cursor = BigInteger.ONE; NetUnit unit; for (Map<BigInteger, NetUnit> map : _netListV6) { if (map != null) { BigInteger l = addr.and(mask.not()); unit = map.get(l); if (unit != null) { return unit; } } mask = mask.or(cursor); cursor = cursor.shiftLeft(1); } } return null; } String bitsToString(int bits) { return _maskStringsV6[bits]; } }