Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DNS Cache Manager always reads in resolv.config when using custom DNS resolver #3515

Closed
asfimport opened this issue Jan 15, 2015 · 14 comments
Closed

Comments

@asfimport
Copy link
Collaborator

Yifan Cai (Bug 57447):
The "use custom DNS resolver" option means ONLY use the DNS severs add to the list in the DNS Manager component.
In the Unix environment, the behavior is not as described (not tried in other OSs, but from the view of the code, I think, the other OSs have the same issue). It will read in the DNS servers specified in the /etc/resolv.config file first, then add the DNS servers from the DNS Manager list.

The reason, I believe, is because that ExtendedResolver, which is used by DNS Manager, reads in the system DNS settings first, when instantiating.


public ExtendedResolver()
throws UnknownHostException
{
init();
String[] servers = ResolverConfig.getCurrentConfig().servers();
if (servers != null) {
for (int i = 0; i < servers.length; i++)
{
Resolver r = new SimpleResolver(servers[i]);
r.setTimeout(5);
this.resolvers.add(r);
}
} else {
this.resolvers.add(new SimpleResolver());
}
}

Please correct me, if I have a misunderstanding on how "custom DNS resolvers" should work.

Severity: normal
OS: All

@asfimport
Copy link
Collaborator Author

Sebb (migrated from Bugzilla):
This does not appear to have anything to do with JMeter.

It does not have an ExtendedResolver class.

@asfimport
Copy link
Collaborator Author

Yifan Cai (migrated from Bugzilla):
The resolver that DNSCacheManager uses is ExtendedResolver.
In its clone() method, clone.resolver = new ExtendedResolver();
I do not find any instantiation anywhere else. So I guess this is where the resolver got assigned.
The ExtendedResolver is from dnsjava lib. It is mentioned that "Custom DNS resolver(from dnsjava library) will be used."

Please consider it again.

(In reply to Sebb from comment 1)

This does not appear to have anything to do with JMeter.

It does not have an ExtendedResolver class.

@asfimport
Copy link
Collaborator Author

Sebb (migrated from Bugzilla):
Ah, I see now.

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
By using the constructor ExtendedResolver(String[]) we should be ignoring the contents of /etc/resolv.conf or similar things.

Two thing the attached patch solves:

  • NPE when no host ist found (Lookup#run returns null, when no host is found)
  • custom dns will not be used, if only one dns server was given ( expression >1 means at least two)

Created attachment 0001-Use-only-configured-DNS-Servers.patch: Use only the configured DNS servers

0001-Use-only-configured-DNS-Servers.patch
From 92ef52ca2031a33498b424fb204e27dfc78999d3 Mon Sep 17 00:00:00 2001
From: Felix Schumacher <felix.schumacher@internetallee.de>
Date: Fri, 16 Jan 2015 22:15:40 +0100
Subject: [PATCH] Use only configured DNS Servers

---
 .../protocol/http/control/DNSCacheManager.java     | 16 +++++++++------
 .../protocol/http/control/TestDNSCacheManager.java | 24 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 6 deletions(-)
 create mode 100644 test/src/org/apache/jmeter/protocol/http/control/TestDNSCacheManager.java

diff --git a/src/protocol/http/org/apache/jmeter/protocol/http/control/DNSCacheManager.java b/src/protocol/http/org/apache/jmeter/protocol/http/control/DNSCacheManager.java
index c3862b2..3cd31e9 100644
--- a/src/protocol/http/org/apache/jmeter/protocol/http/control/DNSCacheManager.java
+++ b/src/protocol/http/org/apache/jmeter/protocol/http/control/DNSCacheManager.java
@@ -42,7 +42,6 @@ import org.xbill.DNS.ExtendedResolver;
 import org.xbill.DNS.Lookup;
 import org.xbill.DNS.Record;
 import org.xbill.DNS.Resolver;
-import org.xbill.DNS.SimpleResolver;
 import org.xbill.DNS.TextParseException;
 import org.xbill.DNS.Type;
 
@@ -104,12 +103,17 @@ public class DNSCacheManager extends ConfigTestElement implements TestIterationL
         clone.cache = new LinkedHashMap<String, InetAddress[]>();
         CollectionProperty dnsServers = getServers();
         try {
-            clone.resolver = new ExtendedResolver();
+            String[] serverNames = new String[dnsServers.size()];
             PropertyIterator dnsServIt = dnsServers.iterator();
+            int index=0;
             while (dnsServIt.hasNext()) {
-                String dnsServer = dnsServIt.next().getStringValue();
-                ((ExtendedResolver) clone.resolver).addResolver(new SimpleResolver(dnsServer));
+                serverNames[index] = dnsServIt.next().getStringValue();
+                index++;
             }
+            clone.resolver = new ExtendedResolver(serverNames);
+            log.debug("Using DNS Resolvers: "
+                    + Arrays.asList(((ExtendedResolver) clone.resolver)
+                            .getResolvers()));
             // resolvers will be chosen via round-robin
             ((ExtendedResolver) clone.resolver).setLoadBalance(true);
         } catch (UnknownHostException uhe) {
@@ -146,13 +150,13 @@ public class DNSCacheManager extends ConfigTestElement implements TestIterationL
      */
     private InetAddress[] requestLookup(String host) throws UnknownHostException {
         InetAddress[] addresses = null;
-        if (isCustomResolver() && ((ExtendedResolver) resolver).getResolvers().length > 1) {
+        if (isCustomResolver() && ((ExtendedResolver) resolver).getResolvers().length > 0) {
             try {
                 Lookup lookup = new Lookup(host, Type.A);
                 lookup.setCache(lookupCache);
                 lookup.setResolver(resolver);
                 Record[] records = lookup.run();
-                if (records.length == 0) {
+                if (records == null || records.length == 0) {
                     throw new UnknownHostException("Failed to resolve host name: " + host);
                 }
                 addresses = new InetAddress[records.length];
diff --git a/test/src/org/apache/jmeter/protocol/http/control/TestDNSCacheManager.java b/test/src/org/apache/jmeter/protocol/http/control/TestDNSCacheManager.java
new file mode 100644
index 0000000..67a0c9f
--- /dev/null
+++ b/test/src/org/apache/jmeter/protocol/http/control/TestDNSCacheManager.java
@@ -0,0 +1,24 @@
+package org.apache.jmeter.protocol.http.control;
+
+import java.net.UnknownHostException;
+
+import org.apache.jmeter.junit.JMeterTestCase;
+import org.junit.Test;
+
+public class TestDNSCacheManager extends JMeterTestCase {
+
+    @Test
+    public void testCloneWithCustomResolverAndInvalidNameserver() throws UnknownHostException {
+        DNSCacheManager original = new DNSCacheManager();
+        original.setCustomResolver(true);
+        original.addServer("127.0.0.99");
+        DNSCacheManager clone = (DNSCacheManager) original.clone();
+        try {
+            clone.resolve("jmeter.apache.org");
+            fail();
+        } catch (UnknownHostException e) {
+            // OK
+        }
+    }
+
+}
-- 
1.9.1

@asfimport
Copy link
Collaborator Author

@milamberspace (migrated from Bugzilla):

Patch looks good, except the AL header on TestDNSCacheManager file.

I have uploaded the same patch with some formatting and the AL.

@felix, you can committing on the SVN (don't forget to add the bug record in changes.xml)

@asfimport
Copy link
Collaborator Author

@milamberspace (migrated from Bugzilla):
Created attachment dns.patch: Update patch v2

dns.patch
Index: src/protocol/http/org/apache/jmeter/protocol/http/control/DNSCacheManager.java
===================================================================
--- src/protocol/http/org/apache/jmeter/protocol/http/control/DNSCacheManager.java	(revision 1654553)
+++ src/protocol/http/org/apache/jmeter/protocol/http/control/DNSCacheManager.java	(working copy)
@@ -42,7 +42,6 @@
 import org.xbill.DNS.Lookup;
 import org.xbill.DNS.Record;
 import org.xbill.DNS.Resolver;
-import org.xbill.DNS.SimpleResolver;
 import org.xbill.DNS.TextParseException;
 import org.xbill.DNS.Type;
 
@@ -104,11 +103,16 @@
         clone.cache = new LinkedHashMap<String, InetAddress[]>();
         CollectionProperty dnsServers = getServers();
         try {
-            clone.resolver = new ExtendedResolver();
+            String[] serverNames = new String[dnsServers.size()];
             PropertyIterator dnsServIt = dnsServers.iterator();
+            int index = 0;
             while (dnsServIt.hasNext()) {
-                String dnsServer = dnsServIt.next().getStringValue();
-                ((ExtendedResolver) clone.resolver).addResolver(new SimpleResolver(dnsServer));
+                serverNames[index] = dnsServIt.next().getStringValue();
+                index++;
+            }
+            clone.resolver = new ExtendedResolver(serverNames);
+            if (log.isDebugEnabled()) {
+                log.debug("Using DNS Resolvers: " + Arrays.asList(((ExtendedResolver) clone.resolver).getResolvers()));
             }
             // resolvers will be chosen via round-robin
             ((ExtendedResolver) clone.resolver).setLoadBalance(true);
@@ -146,13 +150,13 @@
      */
     private InetAddress[] requestLookup(String host) throws UnknownHostException {
         InetAddress[] addresses = null;
-        if (isCustomResolver() && ((ExtendedResolver) resolver).getResolvers().length > 1) {
+        if (isCustomResolver() && ((ExtendedResolver) resolver).getResolvers().length > 0) {
             try {
                 Lookup lookup = new Lookup(host, Type.A);
                 lookup.setCache(lookupCache);
                 lookup.setResolver(resolver);
                 Record[] records = lookup.run();
-                if (records.length == 0) {
+                if (records == null || records.length == 0) {
                     throw new UnknownHostException("Failed to resolve host name: " + host);
                 }
                 addresses = new InetAddress[records.length];
Index: test/src/org/apache/jmeter/protocol/http/control/TestDNSCacheManager.java
===================================================================
--- test/src/org/apache/jmeter/protocol/http/control/TestDNSCacheManager.java	(revision 0)
+++ test/src/org/apache/jmeter/protocol/http/control/TestDNSCacheManager.java	(revision 0)
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jmeter.protocol.http.control;
+
+import java.net.UnknownHostException;
+import org.apache.jmeter.junit.JMeterTestCase;
+import org.junit.Test;
+
+public class TestDNSCacheManager extends JMeterTestCase {
+
+    @Test
+    public void testCloneWithCustomResolverAndInvalidNameserver() throws UnknownHostException {
+        DNSCacheManager original = new DNSCacheManager();
+        original.setCustomResolver(true);
+        original.addServer("127.0.0.99");
+        DNSCacheManager clone = (DNSCacheManager) original.clone();
+        try {
+            clone.resolve("jmeter.apache.org");
+            fail();
+        } catch (UnknownHostException e) {
+            // OK
+        }
+    }
+}
\ No newline at end of file

@asfimport
Copy link
Collaborator Author

@FSchumacher (migrated from Bugzilla):
Date: Sat Jan 24 19:51:20 2015
New Revision: 1654575

URL: http://svn.apache.org/r1654575
Log:
#3515 - Use only the user listed DNS Servers, when "use custom DNS resolver"
option is enabled.
#3515

Added:
jmeter/trunk/test/src/org/apache/jmeter/protocol/http/control/TestDNSCacheManager.java
Modified:
jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DNSCacheManager.java
jmeter/trunk/xdocs/changes.xml

@asfimport
Copy link
Collaborator Author

Sean Chang (migrated from Bugzilla):
Is this fix merged to 3.0 or 3.1? I found I could not use custom DNS on 3.0 and 3.1.

@asfimport
Copy link
Collaborator Author

@pmouawad (migrated from Bugzilla):
Hello,
It is merged since 3.0
Can you attach your test plan , put jmeter in debug. and attacj jmeter.log ?
Are you using http client implementation ? without any 3rd part plugin ?
Thanks

@asfimport
Copy link
Collaborator Author

Sean Chang (migrated from Bugzilla):
I'm not sure if I'm using any third party plugin because I got this test plan from other guy.
In DNS Cache Manager, 20.0.118.11 is not the right DNS server. I tried to use a wrong one, but found Jmeter will still use system DNS - the right one.

Created attachment Sean_A_Rio2_Case10_2billion.fill_w_swift.jmx: test plan

@asfimport
Copy link
Collaborator Author

Sean Chang (migrated from Bugzilla):
I only open log_level.jmeter.protocol.http.proxy.HttpRequestHdr=DEBUG and log_level.jmeter.report=DEBUG in user.properties, not sure if the log fit your debug requirement.

Created attachment jmeter.log: jmeter.log

jmeter.log
2017/01/18 23:44:16 INFO  - jmeter.util.JMeterUtils: Setting Locale to en_US 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: Loading user properties from: /home/cosben/apache-jmeter-2.13/bin/user.properties 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: Loading system properties from: /home/cosben/apache-jmeter-2.13/bin/system.properties 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: Copyright (c) 1998-2016 The Apache Software Foundation 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: Version 3.0 r1743807 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: java.version=1.8.0_101 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: java.vm.name=OpenJDK 64-Bit Server VM 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: os.name=Linux 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: os.arch=amd64 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: os.version=3.10.0-327.28.3.el7.x86_64 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: file.encoding=UTF-8 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: Max memory     =12348030976 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: Available Processors =8 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: Default Locale=English (United States) 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: JMeter  Locale=English (United States) 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: JMeterHome=/home/cosben/apache-jmeter-3.0 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: user.dir  =/home/cosben/apache-jmeter-2.13/bin 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: PWD       =/home/cosben/apache-jmeter-2.13/bin 
2017/01/18 23:44:16 INFO  - jmeter.JMeter: IP: 20.0.52.151 Name: vcosben-f65 FullName: vcosben-f65 
2017/01/18 23:44:17 INFO  - jmeter.gui.action.LookAndFeelCommand: Using look and feel: javax.swing.plaf.metal.MetalLookAndFeel [Metal, CrossPlatform, System] 
2017/01/18 23:44:17 INFO  - jmeter.JMeter: Loaded icon properties from org/apache/jmeter/images/icon.properties 
2017/01/18 23:44:18 INFO  - jmeter.engine.util.CompoundVariable: Note: Function class names must contain the string: '.functions.' 
2017/01/18 23:44:18 INFO  - jmeter.engine.util.CompoundVariable: Note: Function class names must not contain the string: '.gui.' 
2017/01/18 23:44:18 INFO  - kg.apc.jmeter.JMeterPluginsUtils: JMeter-Plugins.org v.1.4.0 
2017/01/18 23:44:19 INFO  - jmeter.util.BSFTestElement: Registering JMeter version of JavaScript engine as work-round for BSF-22 
2017/01/18 23:44:19 INFO  - jmeter.protocol.http.sampler.HTTPSamplerBase: Parser for text/html is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser 
2017/01/18 23:44:19 INFO  - jmeter.protocol.http.sampler.HTTPSamplerBase: Parser for application/xhtml+xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser 
2017/01/18 23:44:19 INFO  - jmeter.protocol.http.sampler.HTTPSamplerBase: Parser for application/xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser 
2017/01/18 23:44:19 INFO  - jmeter.protocol.http.sampler.HTTPSamplerBase: Parser for text/xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser 
2017/01/18 23:44:19 INFO  - jmeter.protocol.http.sampler.HTTPSamplerBase: Parser for text/vnd.wap.wml is org.apache.jmeter.protocol.http.parser.RegexpHTMLParser 
2017/01/18 23:44:19 INFO  - jmeter.protocol.http.sampler.HTTPSamplerBase: Parser for text/css is org.apache.jmeter.protocol.http.parser.CssParser 
2017/01/18 23:44:19 INFO  - jorphan.exec.KeyToolUtils: keytool found at 'keytool' 
2017/01/18 23:44:19 INFO  - jmeter.protocol.http.proxy.ProxyControl: HTTP(S) Test Script Recorder SSL Proxy will use keys that support embedded 3rd party resources in file /home/cosben/apache-jmeter-3.0/bin/proxyserver.jks 
2017/01/18 23:44:20 INFO  - jmeter.gui.util.MenuFactory: Skipping org.apache.jmeter.protocol.mongodb.config.MongoSourceElement 
2017/01/18 23:44:20 INFO  - jmeter.gui.util.MenuFactory: Skipping org.apache.jmeter.protocol.mongodb.sampler.MongoScriptSampler 
2017/01/18 23:44:20 INFO  - jmeter.gui.util.MenuFactory: Skipping org.apache.jmeter.visualizers.DistributionGraphVisualizer 
2017/01/18 23:44:20 INFO  - jmeter.samplers.SampleResult: Note: Sample TimeStamps are START times 
2017/01/18 23:44:20 INFO  - jmeter.samplers.SampleResult: sampleresult.default.encoding is set to ISO-8859-1 
2017/01/18 23:44:20 INFO  - jmeter.samplers.SampleResult: sampleresult.useNanoTime=true 
2017/01/18 23:44:20 INFO  - jmeter.samplers.SampleResult: sampleresult.nanoThreadSleep=5000 
2017/01/18 23:44:20 INFO  - jmeter.gui.util.MenuFactory: Skipping org.apache.jmeter.visualizers.SplineVisualizer 

@asfimport
Copy link
Collaborator Author

Sean Chang (migrated from Bugzilla):
I'm using httpclient4 implementation, this test plan do work for custom DNS on JMeter 2.13

@asfimport
Copy link
Collaborator Author

@pmouawad (migrated from Bugzilla):
Thanks for provided information.
I see you're using 3rd party plugins (Ultimate Thread Group).
Can you tell what jars you have in jmeter/lib folder and jmeter/lib/ext ?

Also , could you provide a simple test plan with only regular Thread Group and the minimal elements to reproduce your issue ?
Thank you

@asfimport
Copy link
Collaborator Author

@pmouawad (migrated from Bugzilla):
Hello,
It's ok, I reproduced.
I'll create a dedicated bug as it is a regression introduced in 3.0

Thanks for report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant