Commit d43a3fb3 authored by Tigran Mkrtchyan's avatar Tigran Mkrtchyan
Browse files

nfs: update ip matcher to evaluate all ip addresses for a given host name

+ javadoc update
parent 10281080
......@@ -17,6 +17,8 @@
package org.dcache.chimera.nfs;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
......@@ -25,47 +27,73 @@ import java.util.regex.Pattern;
public class IPMatcher {
// FIXME: make it more elegant
public static boolean match(String pattern, InetAddress ip) {
private static final int IPv4_FULL_MASK = 32;
private static final int IPv6_FULL_MASK = 128;
/**
* Match a String pattern with given IP address.
* The provided pattern can be in the the following form:
* <pre>
* ipv4: a.b.c.b[/mask],
* for example 192.168.2.124 or 192.168.2.0/24
* ipv6: a:b:c:d:e:f[/mask],
* for example fe80::21c:c0ff:fea0:caf4 or fe80::21c:c0ff:fea0:caf4/64
* host name:
* some.host.name, for example www.dcache.org
* patterns like:
* *.dcache.org
* node?.dcache.org
* </pre>
* @param pattern to match
* @param ip to match pattern with.
* @return @{code true} if given ip matches provided pattern.
*/
public static boolean match(String pattern, InetAddress ip) {
if( pattern.indexOf('*') != -1 || pattern.indexOf('?') != -1) {
if( pattern.indexOf('*') != -1 || pattern.indexOf('?') != -1 ){
// regexp
String hostName = ip.getHostName();
return match(pattern, hostName);
}
}else{
// ip
try {
String ipMask[] = pattern.split("/");
if( ipMask.length > 2 ){
// invalid record - deny
return false;
}
int mask = 32;
String ipMask[] = pattern.split("/");
if(ipMask.length > 2 ) {
// invalid record - deny
return false;
}
/*
* if subnet mask defined
*/
int mask;
if( ipMask.length == 2 ){
mask = Integer.parseInt(ipMask[1]);
} else {
mask = fullMaskOf(ip);
}
if(ipMask.length == 2) {
mask = Integer.parseInt(ipMask[1]);
}
InetAddress[] addresses;
try{
addresses = InetAddress.getAllByName(ipMask[0]);
}catch( UnknownHostException uhe ){
return false;
}
return match(InetAddress.getByName(ipMask[0]), ip, mask);
}catch(UnknownHostException uhe) {
return false;
}
for(InetAddress address : addresses){
if( match(address, ip, mask) )
return true;
}
return false;
}
public static boolean match(String pattern, String hostName ) {
Pattern p = Pattern.compile(toRegExp(pattern));
Matcher m = p.matcher(hostName);
return m.matches();
}
......@@ -100,9 +128,9 @@ public class IPMatcher {
int lastBits = mask % 8;
/*
* if there are no partial defined bytes we are done, other vise check them.
* if there are no partial defined bytes we are done, otherwise check them.
*/
return lastBits == 0 ? true :
return lastBits == 0 ||
(ipBytes[fullBytes] >> (8 - lastBits)) == (netBytes[fullBytes] >> (8 - lastBits));
}
......@@ -110,4 +138,12 @@ public class IPMatcher {
private static String toRegExp(String s) {
return s.replace(".", "\\.").replace("?", ".").replace("*", ".*");
}
private static int fullMaskOf(InetAddress address) {
if(address instanceof Inet4Address)
return IPv4_FULL_MASK;
if(address instanceof Inet6Address)
return IPv6_FULL_MASK;
throw new IllegalArgumentException("Unsupported Inet type: " + address.getClass().getName());
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment