1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net.cts;
18 
19 import android.content.Context;
20 import android.content.pm.PackageManager;
21 import android.net.ConnectivityManager;
22 import android.net.NetworkInfo;
23 import android.os.SystemClock;
24 import android.test.AndroidTestCase;
25 import android.util.Log;
26 
27 import java.net.Inet4Address;
28 import java.net.Inet6Address;
29 import java.net.InetAddress;
30 import java.net.UnknownHostException;
31 import java.util.ArrayList;
32 
33 public class DnsTest extends AndroidTestCase {
34 
35     static {
36         System.loadLibrary("nativedns_jni");
37     }
38 
39     private static final boolean DBG = false;
40     private static final String TAG = "DnsTest";
41     private static final String PROXY_NETWORK_TYPE = "PROXY";
42 
43     /**
44      * @return true on success
45      */
testNativeDns()46     private static native boolean testNativeDns();
47 
48     /**
49      * Verify:
50      * DNS works - forwards and backwards, giving ipv4 and ipv6
51      * Test that DNS work on v4 and v6 networks
52      * Test Native dns calls (4)
53      * Todo:
54      * Cache is flushed when we change networks
55      * have per-network caches
56      * No cache when there's no network
57      * Perf - measure size of first and second tier caches and their effect
58      * Assert requires network permission
59      */
testDnsWorks()60     public void testDnsWorks() {
61         InetAddress addrs[] = {};
62         try {
63             addrs = InetAddress.getAllByName("www.google.com");
64         } catch (UnknownHostException e) {}
65         assertTrue("[RERUN] DNS could not resolve www.google.com. Check internet connection",
66                 addrs.length != 0);
67         boolean foundV4 = false, foundV6 = false;
68         for (InetAddress addr : addrs) {
69             if (addr instanceof Inet4Address) foundV4 = true;
70             else if (addr instanceof Inet6Address) foundV6 = true;
71             if (DBG) Log.e(TAG, "www.google.com gave " + addr.toString());
72         }
73 
74         // We should have at least one of the addresses to connect!
75         assertTrue("www.google.com must have IPv4 and/or IPv6 address", foundV4 || foundV6);
76 
77         // Skip the rest of the test if the active network for watch is PROXY.
78         // TODO: Check NetworkInfo type in addition to type name once ag/601257 is merged.
79         if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)
80                 && activeNetworkInfoIsProxy()) {
81             Log.i(TAG, "Skipping test because the active network type name is PROXY.");
82             return;
83         }
84 
85         // Clear test state so we don't get confused with the previous results.
86         addrs = new InetAddress[0];
87         foundV4 = foundV6 = false;
88         try {
89             addrs = InetAddress.getAllByName("ipv6.google.com");
90         } catch (UnknownHostException e) {}
91         assertTrue("[RERUN] DNS could not resolve ipv6.google.com, check the network supports IPv6",
92                 addrs.length != 0);
93         for (InetAddress addr : addrs) {
94             assertFalse ("[RERUN] ipv6.google.com returned IPv4 address: " + addr.getHostAddress() +
95                     ", check your network's DNS server", addr instanceof Inet4Address);
96             foundV6 |= (addr instanceof Inet6Address);
97             if (DBG) Log.e(TAG, "ipv6.google.com gave " + addr.toString());
98         }
99 
100         assertTrue(foundV6);
101 
102         assertTrue(testNativeDns());
103     }
104 
105     private static final String[] URLS = { "www.google.com", "ipv6.google.com", "www.yahoo.com",
106             "facebook.com", "youtube.com", "blogspot.com", "baidu.com", "wikipedia.org",
107 // live.com fails rev lookup.
108             "twitter.com", "qq.com", "msn.com", "yahoo.co.jp", "linkedin.com",
109             "taobao.com", "google.co.in", "sina.com.cn", "amazon.com", "wordpress.com",
110             "google.co.uk", "ebay.com", "yandex.ru", "163.com", "google.co.jp", "google.fr",
111             "microsoft.com", "paypal.com", "google.com.br", "flickr.com",
112             "mail.ru", "craigslist.org", "fc2.com", "google.it",
113 // "apple.com", fails rev lookup
114             "google.es",
115             "imdb.com", "google.ru", "soho.com", "bbc.co.uk", "vkontakte.ru", "ask.com",
116             "tumblr.com", "weibo.com", "go.com", "xvideos.com", "livejasmin.com", "cnn.com",
117             "youku.com", "blogspot.com", "soso.com", "google.ca", "aol.com", "tudou.com",
118             "xhamster.com", "megaupload.com", "ifeng.com", "zedo.com", "mediafire.com", "ameblo.jp",
119             "pornhub.com", "google.co.id", "godaddy.com", "adobe.com", "rakuten.co.jp", "about.com",
120             "espn.go.com", "4shared.com", "alibaba.com","ebay.de", "yieldmanager.com",
121             "wordpress.org", "livejournal.com", "google.com.tr", "google.com.mx", "renren.com",
122            "livedoor.com", "google.com.au", "youporn.com", "uol.com.br", "cnet.com", "conduit.com",
123             "google.pl", "myspace.com", "nytimes.com", "ebay.co.uk", "chinaz.com", "hao123.com",
124             "thepiratebay.org", "doubleclick.com", "alipay.com", "netflix.com", "cnzz.com",
125             "huffingtonpost.com", "twitpic.com", "weather.com", "babylon.com", "amazon.de",
126             "dailymotion.com", "orkut.com", "orkut.com.br", "google.com.sa", "odnoklassniki.ru",
127             "amazon.co.jp", "google.nl", "goo.ne.jp", "stumbleupon.com", "tube8.com", "tmall.com",
128             "imgur.com", "globo.com", "secureserver.net", "fileserve.com", "tianya.cn", "badoo.com",
129             "ehow.com", "photobucket.com", "imageshack.us", "xnxx.com", "deviantart.com",
130             "filestube.com", "addthis.com", "douban.com", "vimeo.com", "sogou.com",
131             "stackoverflow.com", "reddit.com", "dailymail.co.uk", "redtube.com", "megavideo.com",
132             "taringa.net", "pengyou.com", "amazon.co.uk", "fbcdn.net", "aweber.com", "spiegel.de",
133             "rapidshare.com", "mixi.jp", "360buy.com", "google.cn", "digg.com", "answers.com",
134             "bit.ly", "indiatimes.com", "skype.com", "yfrog.com", "optmd.com", "google.com.eg",
135             "google.com.pk", "58.com", "hotfile.com", "google.co.th",
136             "bankofamerica.com", "sourceforge.net", "maktoob.com", "warriorforum.com", "rediff.com",
137             "google.co.za", "56.com", "torrentz.eu", "clicksor.com", "avg.com",
138             "download.com", "ku6.com", "statcounter.com", "foxnews.com", "google.com.ar",
139             "nicovideo.jp", "reference.com", "liveinternet.ru", "ucoz.ru", "xinhuanet.com",
140             "xtendmedia.com", "naver.com", "youjizz.com", "domaintools.com", "sparkstudios.com",
141             "rambler.ru", "scribd.com", "kaixin001.com", "mashable.com", "adultfirendfinder.com",
142             "files.wordpress.com", "guardian.co.uk", "bild.de", "yelp.com", "wikimedia.org",
143             "chase.com", "onet.pl", "ameba.jp", "pconline.com.cn", "free.fr", "etsy.com",
144             "typepad.com", "youdao.com", "megaclick.com", "digitalpoint.com", "blogfa.com",
145             "salesforce.com", "adf.ly", "ganji.com", "wikia.com", "archive.org", "terra.com.br",
146             "w3schools.com", "ezinearticles.com", "wjs.com", "google.com.my", "clickbank.com",
147             "squidoo.com", "hulu.com", "repubblica.it", "google.be", "allegro.pl", "comcast.net",
148             "narod.ru", "zol.com.cn", "orange.fr", "soufun.com", "hatena.ne.jp", "google.gr",
149             "in.com", "techcrunch.com", "orkut.co.in", "xunlei.com",
150             "reuters.com", "google.com.vn", "hostgator.com", "kaskus.us", "espncricinfo.com",
151             "hootsuite.com", "qiyi.com", "gmx.net", "xing.com", "php.net", "soku.com", "web.de",
152             "libero.it", "groupon.com", "51.la", "slideshare.net", "booking.com", "seesaa.net",
153             "126.com", "telegraph.co.uk", "wretch.cc", "twimg.com", "rutracker.org", "angege.com",
154             "nba.com", "dell.com", "leboncoin.fr", "people.com", "google.com.tw", "walmart.com",
155             "daum.net", "2ch.net", "constantcontact.com", "nifty.com", "mywebsearch.com",
156             "tripadvisor.com", "google.se", "paipai.com", "google.com.ua", "ning.com", "hp.com",
157             "google.at", "joomla.org", "icio.us", "hudong.com", "csdn.net", "getfirebug.com",
158             "ups.com", "cj.com", "google.ch", "camzap.com", "wordreference.com", "tagged.com",
159             "wp.pl", "mozilla.com", "google.ru", "usps.com", "china.com", "themeforest.net",
160             "search-results.com", "tribalfusion.com", "thefreedictionary.com", "isohunt.com",
161             "linkwithin.com", "cam4.com", "plentyoffish.com", "wellsfargo.com", "metacafe.com",
162             "depositfiles.com", "freelancer.com", "opendns.com", "homeway.com", "engadget.com",
163             "10086.cn", "360.cn", "marca.com", "dropbox.com", "ign.com", "match.com", "google.pt",
164             "facemoods.com", "hardsextube.com", "google.com.ph", "lockerz.com", "istockphoto.com",
165             "partypoker.com", "netlog.com", "outbrain.com", "elpais.com", "fiverr.com",
166             "biglobe.ne.jp", "corriere.it", "love21cn.com", "yesky.com", "spankwire.com",
167             "ig.com.br", "imagevenue.com", "hubpages.com", "google.co.ve"};
168 
169 // TODO - this works, but is slow and cts doesn't do anything with the result.
170 // Maybe require a min performance, a min cache size (detectable) and/or move
171 // to perf testing
172     private static final int LOOKUP_COUNT_GOAL = URLS.length;
skiptestDnsPerf()173     public void skiptestDnsPerf() {
174         ArrayList<String> results = new ArrayList<String>();
175         int failures = 0;
176         try {
177             for (int numberOfUrls = URLS.length; numberOfUrls > 0; numberOfUrls--) {
178                 failures = 0;
179                 int iterationLimit = LOOKUP_COUNT_GOAL / numberOfUrls;
180                 long startTime = SystemClock.elapsedRealtimeNanos();
181                 for (int iteration = 0; iteration < iterationLimit; iteration++) {
182                     for (int urlIndex = 0; urlIndex < numberOfUrls; urlIndex++) {
183                         try {
184                             InetAddress addr = InetAddress.getByName(URLS[urlIndex]);
185                         } catch (UnknownHostException e) {
186                             Log.e(TAG, "failed first lookup of " + URLS[urlIndex]);
187                             failures++;
188                             try {
189                                 InetAddress addr = InetAddress.getByName(URLS[urlIndex]);
190                             } catch (UnknownHostException ee) {
191                                 failures++;
192                                 Log.e(TAG, "failed SECOND lookup of " + URLS[urlIndex]);
193                             }
194                         }
195                     }
196                 }
197                 long endTime = SystemClock.elapsedRealtimeNanos();
198                 float nsPer = ((float)(endTime-startTime) / iterationLimit) / numberOfUrls/ 1000;
199                 String thisResult = new String("getByName for " + numberOfUrls + " took " +
200                         (endTime - startTime)/1000 + "(" + nsPer + ") with " +
201                         failures + " failures\n");
202                 Log.d(TAG, thisResult);
203                 results.add(thisResult);
204             }
205             // build up a list of addresses
206             ArrayList<byte[]> addressList = new ArrayList<byte[]>();
207             for (String url : URLS) {
208                 try {
209                     InetAddress addr = InetAddress.getByName(url);
210                     addressList.add(addr.getAddress());
211                 } catch (UnknownHostException e) {
212                     Log.e(TAG, "Exception making reverseDNS list: " + e.toString());
213                 }
214             }
215             for (int numberOfAddrs = addressList.size(); numberOfAddrs > 0; numberOfAddrs--) {
216                 int iterationLimit = LOOKUP_COUNT_GOAL / numberOfAddrs;
217                 failures = 0;
218                 long startTime = SystemClock.elapsedRealtimeNanos();
219                 for (int iteration = 0; iteration < iterationLimit; iteration++) {
220                     for (int addrIndex = 0; addrIndex < numberOfAddrs; addrIndex++) {
221                         try {
222                             InetAddress addr = InetAddress.getByAddress(addressList.get(addrIndex));
223                             String hostname = addr.getHostName();
224                         } catch (UnknownHostException e) {
225                             failures++;
226                             Log.e(TAG, "Failure doing reverse DNS lookup: " + e.toString());
227                             try {
228                                 InetAddress addr =
229                                         InetAddress.getByAddress(addressList.get(addrIndex));
230                                 String hostname = addr.getHostName();
231 
232                             } catch (UnknownHostException ee) {
233                                 failures++;
234                                 Log.e(TAG, "Failure doing SECOND reverse DNS lookup: " +
235                                         ee.toString());
236                             }
237                         }
238                     }
239                 }
240                 long endTime = SystemClock.elapsedRealtimeNanos();
241                 float nsPer = ((endTime-startTime) / iterationLimit) / numberOfAddrs / 1000;
242                 String thisResult = new String("getHostName for " + numberOfAddrs + " took " +
243                         (endTime - startTime)/1000 + "(" + nsPer + ") with " +
244                         failures + " failures\n");
245                 Log.d(TAG, thisResult);
246                 results.add(thisResult);
247             }
248             for (String result : results) Log.d(TAG, result);
249 
250             InetAddress exit = InetAddress.getByName("exitrightnow.com");
251             Log.e(TAG, " exit address= "+exit.toString());
252 
253         } catch (Exception e) {
254             Log.e(TAG, "bad URL in testDnsPerf: " + e.toString());
255         }
256     }
257 
activeNetworkInfoIsProxy()258     private boolean activeNetworkInfoIsProxy() {
259         ConnectivityManager cm = (ConnectivityManager)
260                 getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
261         NetworkInfo info = cm.getActiveNetworkInfo();
262         if (PROXY_NETWORK_TYPE.equals(info.getTypeName())) {
263             return true;
264         }
265 
266         return false;
267     }
268 }
269