Author: aidan
Date: Mon Mar 16 16:32:50 2009
New Revision: 754934
URL: http://svn.apache.org/viewvc?rev=754934&view=rev
Log:
QPID-1736: Timeout DNS lookups if they take more than 30 seconds.
Modified:
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java
Modified:
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java?rev=754934&r1=754933&r2=754934&view=diff
==============================================================================
---
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java
(original)
+++
qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java
Mon Mar 16 16:32:50 2009
@@ -25,6 +25,7 @@
import java.net.SocketAddress;
import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import org.apache.commons.configuration.CompositeConfiguration;
@@ -42,6 +43,8 @@
public class FirewallPlugin extends AbstractACLPlugin
{
+ public class FirewallPluginException extends Exception {}
+
public static final ACLPluginFactory FACTORY = new ACLPluginFactory()
{
public boolean supportsTag(String name)
@@ -60,6 +63,7 @@
public class FirewallRule
{
+ private static final long DNS_TIMEOUT = 30000;
private AuthzResult _access;
private NetMatcher _network;
private Pattern[] _hostnamePatterns;
@@ -97,11 +101,15 @@
return networkStrings;
}
- public boolean match(InetAddress remote)
+ public boolean match(InetAddress remote) throws FirewallPluginException
{
if (_hostnamePatterns != null)
{
- String hostname = remote.getCanonicalHostName();
+ String hostname = getHostname(remote);
+ if (hostname == null)
+ {
+ throw new FirewallPluginException();
+ }
for (Pattern pattern : _hostnamePatterns)
{
if (pattern.matcher(hostname).matches())
@@ -117,6 +125,48 @@
}
}
+ /**
+ * @param remote the InetAddress to look up
+ * @return the hostname, null if not found or takes longer than 30s to
find
+ */
+ private String getHostname(final InetAddress remote)
+ {
+ final String[] hostname = new String[]{null};
+ final AtomicBoolean done = new AtomicBoolean(false);
+ // Spawn thread
+ Thread thread = new Thread(new Runnable()
+ {
+ public void run()
+ {
+ hostname[0] = remote.getCanonicalHostName();
+ done.getAndSet(true);
+ synchronized (done)
+ {
+ done.notifyAll();
+ }
+ }
+ });
+
+ thread.run();
+ long endTime = System.currentTimeMillis() + DNS_TIMEOUT;
+
+ while (System.currentTimeMillis() < endTime && !done.get())
+ {
+ try
+ {
+ synchronized (done)
+ {
+ done.wait(endTime - System.currentTimeMillis());
+ }
+ }
+ catch (InterruptedException e)
+ {
+ // Check the time and if necessary sleep for a bit longer
+ }
+ }
+ return hostname[0];
+ }
+
public AuthzResult getAccess()
{
return _access;
@@ -146,7 +196,14 @@
boolean match = false;
for (FirewallRule rule : _rules)
{
- match = rule.match(addr);
+ try
+ {
+ match = rule.match(addr);
+ }
+ catch (FirewallPluginException e)
+ {
+ return AuthzResult.DENIED;
+ }
if (match)
{
return rule.getAccess();
---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project: http://qpid.apache.org
Use/Interact: mailto:[email protected]