001/* 002 * Copyright 2015-2024 the original author or authors 003 * 004 * This software is licensed under the Apache License, Version 2.0, 005 * the GNU Lesser General Public License version 2 or later ("LGPL") 006 * and the WTFPL. 007 * You may choose either license to govern your use of this software only 008 * upon the condition that you accept all of the terms of either 009 * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 010 */ 011package org.minidns.dnsserverlookup; 012 013import org.minidns.util.PlatformDetection; 014 015import java.lang.reflect.InvocationTargetException; 016import java.lang.reflect.Method; 017import java.net.InetAddress; 018import java.net.UnknownHostException; 019import java.util.ArrayList; 020import java.util.List; 021import java.util.logging.Level; 022 023/** 024 * Try to retrieve the list of DNS server by calling SystemProperties. 025 */ 026public class AndroidUsingReflection extends AbstractDnsServerLookupMechanism { 027 028 public static final DnsServerLookupMechanism INSTANCE = new AndroidUsingReflection(); 029 public static final int PRIORITY = 1000; 030 031 private final Method systemPropertiesGet; 032 033 protected AndroidUsingReflection() { 034 super(AndroidUsingReflection.class.getSimpleName(), PRIORITY); 035 Method systemPropertiesGet = null; 036 if (PlatformDetection.isAndroid()) { 037 try { 038 Class<?> SystemProperties = Class.forName("android.os.SystemProperties"); 039 systemPropertiesGet = SystemProperties.getMethod("get", new Class<?>[] { String.class }); 040 } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) { 041 // This is not unexpected, as newer Android versions do not provide access to it any more. 042 LOGGER.log(Level.FINE, "Can not get method handle for android.os.SystemProperties.get(String).", e); 043 } 044 } 045 this.systemPropertiesGet = systemPropertiesGet; 046 } 047 048 @Override 049 public List<String> getDnsServerAddresses() { 050 ArrayList<String> servers = new ArrayList<String>(5); 051 052 for (String propKey : new String[] { 053 "net.dns1", "net.dns2", "net.dns3", "net.dns4"}) { 054 055 String value; 056 try { 057 value = (String) systemPropertiesGet.invoke(null, propKey); 058 } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 059 LOGGER.log(Level.WARNING, "Exception in findDNSByReflection", e); 060 return null; 061 } 062 063 if (value == null) continue; 064 if (value.length() == 0) continue; 065 if (servers.contains(value)) continue; 066 067 InetAddress ip; 068 try { 069 ip = InetAddress.getByName(value); 070 } catch (UnknownHostException e) { 071 LOGGER.log(Level.WARNING, "Exception in findDNSByReflection", e); 072 continue; 073 } 074 075 if (ip == null) continue; 076 077 value = ip.getHostAddress(); 078 079 if (value == null) continue; 080 if (value.length() == 0) continue; 081 if (servers.contains(value)) continue; 082 083 servers.add(value); 084 } 085 086 if (servers.size() > 0) { 087 return servers; 088 } 089 090 return null; 091 } 092 093 @Override 094 public boolean isAvailable() { 095 return systemPropertiesGet != null; 096 } 097 098}