1 7 8 package java.net; 9 10 import java.util.HashMap ; 11 import java.util.LinkedHashMap ; 12 import java.util.Random ; 13 import java.util.Iterator ; 14 import java.util.LinkedList ; 15 import java.security.AccessController ; 16 import java.io.ObjectStreamException ; 17 import java.io.IOException ; 18 import sun.security.action.*; 19 import sun.net.InetAddressCachePolicy; 20 import sun.net.util.IPAddressUtil; 21 import sun.misc.Service; 22 import sun.net.spi.nameservice.*; 23 24 162 public 163 class InetAddress implements java.io.Serializable { 164 168 static final int IPv4 = 1; 169 170 174 static final int IPv6 = 2; 175 176 177 static transient boolean preferIPv6Address = false; 178 179 182 String hostName; 183 184 189 int address; 190 191 197 int family; 198 199 200 private static NameService nameService = null; 201 202 203 private transient String canonicalHostName = null; 204 205 206 private static final long serialVersionUID = 3286316764910316507L; 207 208 211 static { 212 preferIPv6Address = 213 ((Boolean )java.security.AccessController.doPrivileged( 214 new GetBooleanAction("java.net.preferIPv6Addresses"))).booleanValue(); 215 AccessController.doPrivileged(new LoadLibraryAction("net")); 216 init(); 217 } 218 219 225 InetAddress() { 226 } 227 228 236 private Object readResolve() throws ObjectStreamException { 237 return new Inet4Address (this.hostName, this.address); 239 } 240 241 248 public boolean isMulticastAddress() { 249 return false; 250 } 251 252 258 public boolean isAnyLocalAddress() { 259 return false; 260 } 261 262 269 public boolean isLoopbackAddress() { 270 return false; 271 } 272 273 280 public boolean isLinkLocalAddress() { 281 return false; 282 } 283 284 291 public boolean isSiteLocalAddress() { 292 return false; 293 } 294 295 303 public boolean isMCGlobal() { 304 return false; 305 } 306 307 315 public boolean isMCNodeLocal() { 316 return false; 317 } 318 319 327 public boolean isMCLinkLocal() { 328 return false; 329 } 330 331 339 public boolean isMCSiteLocal() { 340 return false; 341 } 342 343 352 public boolean isMCOrgLocal() { 353 return false; 354 } 355 356 357 377 public boolean isReachable(int timeout) throws IOException { 378 return isReachable(null, 0 , timeout); 379 } 380 381 412 public boolean isReachable(NetworkInterface netif, int ttl, 413 int timeout) throws IOException { 414 if (ttl < 0) 415 throw new IllegalArgumentException ("ttl can't be negative"); 416 if (timeout < 0) 417 throw new IllegalArgumentException ("timeout can't be negative"); 418 419 return impl.isReachable(this, timeout, netif, ttl); 420 } 421 422 447 public String getHostName() { 448 return getHostName(true); 449 } 450 451 474 String getHostName(boolean check) { 475 if (hostName == null) { 476 hostName = InetAddress.getHostFromNameService(this, check); 477 } 478 return hostName; 479 } 480 481 502 public String getCanonicalHostName() { 503 if (canonicalHostName == null) { 504 canonicalHostName = 505 InetAddress.getHostFromNameService(this, true); 506 } 507 return canonicalHostName; 508 } 509 510 529 private static String getHostFromNameService(InetAddress addr, boolean check) { 530 String host; 531 try { 532 host = nameService.getHostByAddr(addr.getAddress()); 534 535 538 if (check) { 539 SecurityManager sec = System.getSecurityManager(); 540 if (sec != null) { 541 sec.checkConnect(host, -1); 542 } 543 } 544 545 549 550 InetAddress [] arr = InetAddress.getAllByName0(host, check); 551 boolean ok = false; 552 553 if(arr != null) { 554 for(int i = 0; !ok && i < arr.length; i++) { 555 ok = addr.equals(arr[i]); 556 } 557 } 558 559 if (!ok) { 561 host = addr.getHostAddress(); 562 return host; 563 } 564 565 } catch (SecurityException e) { 566 host = addr.getHostAddress(); 567 } catch (UnknownHostException e) { 568 host = addr.getHostAddress(); 569 } 570 return host; 571 } 572 573 580 public byte[] getAddress() { 581 return null; 582 } 583 584 590 public String getHostAddress() { 591 return null; 592 } 593 594 599 public int hashCode() { 600 return -1; 601 } 602 603 619 public boolean equals(Object obj) { 620 return false; 621 } 622 623 633 public String toString() { 634 return ((hostName != null) ? hostName : "") 635 + "/" + getHostAddress(); 636 } 637 638 641 private static Cache addressCache = new Cache(Cache.Type.Positive); 642 643 private static Cache negativeCache = new Cache(Cache.Type.Negative); 644 645 private static boolean addressCacheInit = false; 646 647 static InetAddress [] unknown_array; 649 static InetAddressImpl impl; 650 651 private static HashMap lookupTable = new HashMap (); 652 653 656 static final class CacheEntry { 657 658 CacheEntry(Object address, long expiration) { 659 this.address = address; 660 this.expiration = expiration; 661 } 662 663 Object address; 664 long expiration; 665 } 666 667 671 static final class Cache { 672 private LinkedHashMap cache; 673 private Type type; 674 675 enum Type {Positive, Negative}; 676 677 680 public Cache(Type type) { 681 this.type = type; 682 cache = new LinkedHashMap (); 683 } 684 685 private int getPolicy() { 686 if (type == Type.Positive) { 687 return InetAddressCachePolicy.get(); 688 } else { 689 return InetAddressCachePolicy.getNegative(); 690 } 691 } 692 693 698 public Cache put(String host, Object address) { 699 int policy = getPolicy(); 700 if (policy == InetAddressCachePolicy.NEVER) { 701 return this; 702 } 703 704 706 if (policy != InetAddressCachePolicy.FOREVER) { 707 708 LinkedList expired = new LinkedList (); 711 Iterator i = cache.keySet().iterator(); 712 long now = System.currentTimeMillis(); 713 while (i.hasNext()) { 714 String key = (String )i.next(); 715 CacheEntry entry = (CacheEntry)cache.get(key); 716 717 if (entry.expiration >= 0 && entry.expiration < now) { 718 expired.add(key); 719 } else { 720 break; 721 } 722 } 723 724 i = expired.iterator(); 725 while (i.hasNext()) { 726 cache.remove(i.next()); 727 } 728 } 729 730 long expiration; 735 if (policy == InetAddressCachePolicy.FOREVER) { 736 expiration = -1; 737 } else { 738 expiration = System.currentTimeMillis() + (policy * 1000); 739 } 740 CacheEntry entry = new CacheEntry(address, expiration); 741 cache.put(host, entry); 742 return this; 743 } 744 745 749 public CacheEntry get(String host) { 750 int policy = getPolicy(); 751 if (policy == InetAddressCachePolicy.NEVER) { 752 return null; 753 } 754 CacheEntry entry = (CacheEntry)cache.get(host); 755 756 if (entry != null && policy != InetAddressCachePolicy.FOREVER) { 758 if (entry.expiration >= 0 && 759 entry.expiration < System.currentTimeMillis()) { 760 cache.remove(host); 761 entry = null; 762 } 763 } 764 765 return entry; 766 } 767 } 768 769 773 private static void cacheInitIfNeeded() { 774 assert Thread.holdsLock(addressCache); 775 if (addressCacheInit) { 776 return; 777 } 778 unknown_array = new InetAddress [1]; 779 unknown_array[0] = impl.anyLocalAddress(); 780 781 addressCache.put(impl.anyLocalAddress().getHostName(), 782 unknown_array); 783 784 addressCacheInit = true; 785 } 786 787 790 private static void cacheAddress(String hostname, Object address, 791 boolean success) { 792 hostname = hostname.toLowerCase(); 793 synchronized (addressCache) { 794 cacheInitIfNeeded(); 795 if (success) { 796 addressCache.put(hostname, address); 797 } else { 798 negativeCache.put(hostname, address); 799 } 800 } 801 } 802 803 807 private static Object getCachedAddress(String hostname) { 808 hostname = hostname.toLowerCase(); 809 810 812 synchronized (addressCache) { 813 CacheEntry entry; 814 815 cacheInitIfNeeded(); 816 817 entry = (CacheEntry)addressCache.get(hostname); 818 if (entry == null) { 819 entry = (CacheEntry)negativeCache.get(hostname); 820 } 821 822 if (entry != null) { 823 return entry.address; 824 } 825 } 826 827 return null; 829 } 830 831 static { 832 impl = (new InetAddressImplFactory()).create(); 834 835 String provider = null;; 837 String propPrefix = "sun.net.spi.nameservice.provider."; 838 int n = 1; 839 while (nameService == null) { 840 provider 841 = (String )AccessController.doPrivileged( 842 new GetPropertyAction(propPrefix+n, "default")); 843 n++; 844 if (provider.equals("default")) { 845 nameService = new NameService() { 847 public InetAddress [] lookupAllHostAddr(String host) 848 throws UnknownHostException { 849 return impl.lookupAllHostAddr(host); 850 } 851 public String getHostByAddr(byte[] addr) 852 throws UnknownHostException { 853 return impl.getHostByAddr(addr); 854 } 855 }; 856 break; 857 } 858 859 final String providerName = provider; 860 861 try { 862 java.security.AccessController.doPrivileged( 863 new java.security.PrivilegedExceptionAction () { 864 public Object run() { 865 Iterator itr 866 = Service.providers(NameServiceDescriptor.class); 867 while (itr.hasNext()) { 868 NameServiceDescriptor nsd 869 = (NameServiceDescriptor)itr.next(); 870 if (providerName. 871 equalsIgnoreCase(nsd.getType()+"," 872 +nsd.getProviderName())) { 873 try { 874 nameService = nsd.createNameService(); 875 break; 876 } catch (Exception e) { 877 e.printStackTrace(); 878 System.err.println( 879 "Cannot create name service:" 880 +providerName+": " + e); 881 } 882 } 883 } 884 return null; 885 } 886 }); 887 } catch (java.security.PrivilegedActionException e) { 888 } 889 890 } 891 } 892 893 915 public static InetAddress getByAddress(String host, byte[] addr) 916 throws UnknownHostException { 917 if (host != null && host.length() > 0 && host.charAt(0) == '[') { 918 if (host.charAt(host.length()-1) == ']') { 919 host = host.substring(1, host.length() -1); 920 } 921 } 922 if (addr != null) { 923 if (addr.length == Inet4Address.INADDRSZ) { 924 return new Inet4Address (host, addr); 925 } else if (addr.length == Inet6Address.INADDRSZ) { 926 byte[] newAddr 927 = IPAddressUtil.convertFromIPv4MappedAddress(addr); 928 if (newAddr != null) { 929 return new Inet4Address (host, newAddr); 930 } else { 931 return new Inet6Address (host, addr); 932 } 933 } 934 } 935 throw new UnknownHostException ("addr is of illegal length"); 936 } 937 938 939 967 public static InetAddress getByName(String host) 968 throws UnknownHostException { 969 return InetAddress.getAllByName(host)[0]; 970 } 971 972 private static InetAddress getByName(String host, InetAddress reqAddr) 974 throws UnknownHostException { 975 return InetAddress.getAllByName(host, reqAddr)[0]; 976 } 977 978 1017 public static InetAddress [] getAllByName(String host) 1018 throws UnknownHostException { 1019 return getAllByName(host, null); 1020 } 1021 1022 private static InetAddress [] getAllByName(String host, InetAddress reqAddr) 1023 throws UnknownHostException { 1024 1025 if (host == null || host.length() == 0) { 1026 InetAddress [] ret = new InetAddress [1]; 1027 ret[0] = impl.loopbackAddress(); 1028 return ret; 1029 } 1030 1031 boolean ipv6Expected = false; 1032 if (host.charAt(0) == '[') { 1033 if (host.length() > 2 && host.charAt(host.length()-1) == ']') { 1035 host = host.substring(1, host.length() -1); 1036 ipv6Expected = true; 1037 } else { 1038 throw new UnknownHostException (host); 1040 } 1041 } 1042 1043 if (Character.digit(host.charAt(0), 16) != -1 1045 || (host.charAt(0) == ':')) { 1046 byte[] addr = null; 1047 int numericZone = -1; 1048 String ifname = null; 1049 addr = IPAddressUtil.textToNumericFormatV4(host); 1051 if (addr == null) { 1052 int pos; 1055 if ((pos=host.indexOf ("%")) != -1) { 1056 numericZone = checkNumericZone (host); 1057 if (numericZone == -1) { 1058 ifname = host.substring (pos+1); 1059 } 1060 } 1061 addr = IPAddressUtil.textToNumericFormatV6(host); 1062 } else if (ipv6Expected) { 1063 throw new UnknownHostException ("["+host+"]"); 1065 } 1066 InetAddress [] ret = new InetAddress [1]; 1067 if(addr != null) { 1068 if (addr.length == Inet4Address.INADDRSZ) { 1069 ret[0] = new Inet4Address (null, addr); 1070 } else { 1071 if (ifname != null) { 1072 ret[0] = new Inet6Address (null, addr, ifname); 1073 } else { 1074 ret[0] = new Inet6Address (null, addr, numericZone); 1075 } 1076 } 1077 return ret; 1078 } 1079 } else if (ipv6Expected) { 1080 throw new UnknownHostException ("["+host+"]"); 1082 } 1083 return getAllByName0(host, reqAddr, true); 1084 } 1085 1086 1093 private static int checkNumericZone (String s) throws UnknownHostException { 1094 int percent = s.indexOf ('%'); 1095 int slen = s.length(); 1096 int digit, zone=0; 1097 if (percent == -1) { 1098 return -1; 1099 } 1100 for (int i=percent+1; i<slen; i++) { 1101 char c = s.charAt(i); 1102 if (c == ']') { 1103 if (i == percent+1) { 1104 1105 return -1; 1106 } 1107 break; 1108 } 1109 if ((digit = Character.digit (c, 10)) < 0) { 1110 return -1; 1111 } 1112 zone = (zone * 10) + digit; 1113 } 1114 return zone; 1115 } 1116 1117 private static InetAddress [] getAllByName0 (String host) 1118 throws UnknownHostException 1119 { 1120 return getAllByName0(host, true); 1121 } 1122 1123 1126 static InetAddress [] getAllByName0 (String host, boolean check) 1127 throws UnknownHostException { 1128 return getAllByName0 (host, null, check); 1129 } 1130 1131 private static InetAddress [] getAllByName0 (String host, InetAddress reqAddr, boolean check) 1132 throws UnknownHostException { 1133 1134 1135 1136 Object obj = null; 1137 Object objcopy = null; 1138 1139 1142 if (check) { 1143 SecurityManager security = System.getSecurityManager(); 1144 if (security != null) { 1145 security.checkConnect(host, -1); 1146 } 1147 } 1148 1149 obj = getCachedAddress(host); 1150 1151 1152 if (obj == null) { 1153 obj = getAddressFromNameService(host, reqAddr); 1154 } 1155 1156 if (obj == unknown_array) 1157 throw new UnknownHostException (host); 1158 1159 1160 objcopy = ((InetAddress [])obj).clone(); 1161 1162 return (InetAddress [])objcopy; 1163 } 1164 1165 private static Object getAddressFromNameService(String host, InetAddress reqAddr) 1166 throws UnknownHostException 1167 { 1168 Object obj = null; 1169 boolean success = false; 1170 1171 if ((obj = checkLookupTable(host)) == null) { 1190 try { 1194 1199 1200 obj = nameService.lookupAllHostAddr(host); 1201 success = true; 1202 } catch (UnknownHostException uhe) { 1203 if (host.equalsIgnoreCase("localhost")) { 1204 InetAddress [] local = new InetAddress [] { impl.loopbackAddress() }; 1205 obj = local; 1206 success = true; 1207 } 1208 else { 1209 obj = unknown_array; 1210 success = false; 1211 throw uhe; 1212 } 1213 } finally { 1214 InetAddress [] addrs = (InetAddress [])obj; 1216 if (reqAddr != null && addrs.length > 1 && !addrs[0].equals(reqAddr)) { 1217 int i = 1; 1219 for (; i < addrs.length; i++) { 1220 if (addrs[i].equals(reqAddr)) { 1221 break; 1222 } 1223 } 1224 if (i < addrs.length) { 1226 InetAddress tmp, tmp2 = reqAddr; 1227 for (int j = 0; j < i; j++) { 1228 tmp = addrs[j]; 1229 addrs[j] = tmp2; 1230 tmp2 = tmp; 1231 } 1232 addrs[i] = tmp2; 1233 } 1234 } 1235 cacheAddress(host, obj, success); 1237 updateLookupTable(host); 1241 } 1242 } 1243 1244 return obj; 1245 } 1246 1247 1248 private static Object checkLookupTable(String host) { 1249 Object obj = null; 1251 1252 synchronized (lookupTable) { 1253 if (lookupTable.containsKey(host) == false) { 1257 lookupTable.put(host, null); 1258 return obj; 1259 } 1260 1261 while (lookupTable.containsKey(host)) { 1265 try { 1266 lookupTable.wait(); 1267 } catch (InterruptedException e) { 1268 } 1269 } 1270 } 1271 1272 obj = getCachedAddress(host); 1277 if (obj == null) { 1278 synchronized (lookupTable) { 1279 lookupTable.put(host, null); 1280 } 1281 } 1282 1283 return obj; 1284 } 1285 1286 private static void updateLookupTable(String host) { 1287 synchronized (lookupTable) { 1288 lookupTable.remove(host); 1289 lookupTable.notifyAll(); 1290 } 1291 } 1292 1293 1309 public static InetAddress getByAddress(byte[] addr) 1310 throws UnknownHostException { 1311 return getByAddress(null, addr); 1312 } 1313 1314 1331 public static InetAddress getLocalHost() throws UnknownHostException { 1332 1333 SecurityManager security = System.getSecurityManager(); 1334 try { 1335 String local = impl.getLocalHostName(); 1336 1337 if (security != null) { 1338 security.checkConnect(local, -1); 1339 } 1340 1341 if (local.equals("localhost")) { 1342 return impl.loopbackAddress(); 1343 } 1344 1345 1348 InetAddress [] localAddrs; 1349 try { 1350 localAddrs = 1351 (InetAddress []) InetAddress.getAddressFromNameService(local, null); 1352 } catch (UnknownHostException uhe) { 1353 throw new UnknownHostException (local + ": " + uhe.getMessage()); 1354 } 1355 return localAddrs[0]; 1356 } catch (java.lang.SecurityException e) { 1357 return impl.loopbackAddress(); 1358 } 1359 } 1360 1361 1362 1365 private static native void init(); 1366 1367 1368 1372 static InetAddress anyLocalAddress() { 1373 return impl.anyLocalAddress(); 1374 } 1375 1376 1379 static Object loadImpl(String implName) { 1380 Object impl; 1381 1382 1389 String prefix = (String )AccessController.doPrivileged( 1390 new GetPropertyAction("impl.prefix", "")); 1391 impl = null; 1392 try { 1393 impl = Class.forName("java.net." + prefix + implName).newInstance(); 1394 } catch (ClassNotFoundException e) { 1395 System.err.println("Class not found: java.net." + prefix + 1396 implName + ":\ncheck impl.prefix property " + 1397 "in your properties file."); 1398 } catch (InstantiationException e) { 1399 System.err.println("Could not instantiate: java.net." + prefix + 1400 implName + ":\ncheck impl.prefix property " + 1401 "in your properties file."); 1402 } catch (IllegalAccessException e) { 1403 System.err.println("Cannot access class: java.net." + prefix + 1404 implName + ":\ncheck impl.prefix property " + 1405 "in your properties file."); 1406 } 1407 1408 if (impl == null) { 1409 try { 1410 impl = Class.forName(implName).newInstance(); 1411 } catch (Exception e) { 1412 throw new Error ("System property impl.prefix incorrect"); 1413 } 1414 } 1415 1416 return impl; 1417 } 1418} 1419 1420 1423class InetAddressImplFactory { 1424 1425 static InetAddressImpl create() { 1426 Object o; 1427 if (isIPv6Supported()) { 1428 o = InetAddress.loadImpl("Inet6AddressImpl"); 1429 } else { 1430 o = InetAddress.loadImpl("Inet4AddressImpl"); 1431 } 1432 return (InetAddressImpl )o; 1433 } 1434 1435 static native boolean isIPv6Supported(); 1436} 1437 | Popular Tags |