13742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman// Copyright 2003-2005 Arthur van Hoff, Rick Blair 23742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman// Licensed under Apache License version 2.0 33742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman// Original license LGPL 43742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 53742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpackage javax.jmdns.impl; 63742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 73742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.io.IOException; 83742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.DatagramPacket; 93742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.Inet4Address; 103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.Inet6Address; 113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.InetAddress; 123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.NetworkInterface; 133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.UnknownHostException; 143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.ArrayList; 153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Collection; 163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.List; 173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.logging.Level; 183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.logging.Logger; 193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.NetworkTopologyDiscovery; 213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.constants.DNSConstants; 223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.constants.DNSRecordClass; 233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.constants.DNSRecordType; 243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.constants.DNSState; 253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.tasks.DNSTask; 263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman/** 283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * HostInfo information on the local host to be able to cope with change of addresses. 293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @author Pierre Frisch, Werner Randelshofer 313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpublic class HostInfo implements DNSStatefulObject { 333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static Logger logger = Logger.getLogger(HostInfo.class.getName()); 343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman protected String _name; 363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman protected InetAddress _address; 383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman protected NetworkInterface _interfaze; 403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final HostInfoState _state; 423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final static class HostInfoState extends DNSStatefulObject.DefaultImplementation { 443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static final long serialVersionUID = -8191476803620402088L; 463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param dns 493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public HostInfoState(JmDNSImpl dns) { 513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman super(); 523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.setDns(dns); 533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param address 593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * IP address to bind 603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param dns 613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * JmDNS instance 623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param jmdnsName 633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * JmDNS name 643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return new HostInfo 653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public static HostInfo newHostInfo(InetAddress address, JmDNSImpl dns, String jmdnsName) { 673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman HostInfo localhost = null; 683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String aName = ""; 693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman InetAddress addr = address; 703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (addr == null) { 723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String ip = System.getProperty("net.mdns.interface"); 733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (ip != null) { 743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman addr = InetAddress.getByName(ip); 753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman addr = InetAddress.getLocalHost(); 773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (addr.isLoopbackAddress()) { 783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // Find local address that isn't a loopback address 793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman InetAddress[] addresses = NetworkTopologyDiscovery.Factory.getInstance().getInetAddresses(); 803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (addresses.length > 0) { 813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman addr = addresses[0]; 823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aName = addr.getHostName(); 863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (addr.isLoopbackAddress()) { 873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.warning("Could not find any address beside the loopback."); 883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aName = addr.getHostName(); 913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (aName.contains("in-addr.arpa") || (aName.equals(addr.getHostAddress()))) { 933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aName = ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : addr.getHostAddress()); 943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (final IOException e) { 963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.log(Level.WARNING, "Could not intialize the host network interface on " + address + "because of an error: " + e.getMessage(), e); 973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // This is only used for running unit test on Debian / Ubuntu 983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman addr = loopbackAddress(); 993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aName = ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : "computer"); 1003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // A host name with "." is illegal. so strip off everything and append .local. 1023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aName = aName.replace('.', '-'); 1033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aName += ".local."; 1043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman localhost = new HostInfo(addr, aName, dns); 1053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return localhost; 1063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static InetAddress loopbackAddress() { 1093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 1103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return InetAddress.getByName(null); 1113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (UnknownHostException exception) { 1123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 1133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * This is used to create a unique name for the host name. 1183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private int hostNameCount; 1203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private HostInfo(final InetAddress address, final String name, final JmDNSImpl dns) { 1223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman super(); 1233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._state = new HostInfoState(dns); 1243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._address = address; 1253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._name = name; 1263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (address != null) { 1273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 1283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _interfaze = NetworkInterface.getByInetAddress(address); 1293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (Exception exception) { 1303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.log(Level.SEVERE, "LocalHostInfo() exception ", exception); 1313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getName() { 1363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _name; 1373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public InetAddress getInetAddress() { 1403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _address; 1413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Inet4Address getInet4Address() { 1443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this.getInetAddress() instanceof Inet4Address) { 1453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (Inet4Address) _address; 1463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 1483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Inet6Address getInet6Address() { 1513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this.getInetAddress() instanceof Inet6Address) { 1523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (Inet6Address) _address; 1533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 1553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public NetworkInterface getInterface() { 1583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _interfaze; 1593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean conflictWithRecord(DNSRecord.Address record) { 1623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman DNSRecord.Address hostAddress = this.getDNSAddressRecord(record.getRecordType(), record.isUnique(), DNSConstants.DNS_TTL); 1633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (hostAddress != null) { 1643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return hostAddress.sameType(record) && hostAddress.sameName(record) && (!hostAddress.sameValue(record)); 1653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return false; 1673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman synchronized String incrementHostName() { 1703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman hostNameCount++; 1713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int plocal = _name.indexOf(".local."); 1723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int punder = _name.lastIndexOf('-'); 1733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _name = _name.substring(0, (punder == -1 ? plocal : punder)) + "-" + hostNameCount + ".local."; 1743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _name; 1753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman boolean shouldIgnorePacket(DatagramPacket packet) { 1783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman boolean result = false; 1793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this.getInetAddress() != null) { 1803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman InetAddress from = packet.getAddress(); 1813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (from != null) { 1823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (from.isLinkLocalAddress() && (!this.getInetAddress().isLinkLocalAddress())) { 1833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // Ignore linklocal packets on regular interfaces, unless this is 1843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // also a linklocal interface. This is to avoid duplicates. This is 1853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // a terrible hack caused by the lack of an API to get the address 1863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // of the interface on which the packet was received. 1873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman result = true; 1883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (from.isLoopbackAddress() && (!this.getInetAddress().isLoopbackAddress())) { 1903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // Ignore loopback packets on a regular interface unless this is also a loopback interface. 1913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman result = true; 1923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return result; 1963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman DNSRecord.Address getDNSAddressRecord(DNSRecordType type, boolean unique, int ttl) { 1993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman switch (type) { 2003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case TYPE_A: 2013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getDNS4AddressRecord(unique, ttl); 2023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case TYPE_A6: 2033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case TYPE_AAAA: 2043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getDNS6AddressRecord(unique, ttl); 2053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman default: 2063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 2083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private DNSRecord.Address getDNS4AddressRecord(boolean unique, int ttl) { 2113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((this.getInetAddress() instanceof Inet4Address) || ((this.getInetAddress() instanceof Inet6Address) && (((Inet6Address) this.getInetAddress()).isIPv4CompatibleAddress()))) { 2123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return new DNSRecord.IPv4Address(this.getName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getInetAddress()); 2133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 2153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private DNSRecord.Address getDNS6AddressRecord(boolean unique, int ttl) { 2183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this.getInetAddress() instanceof Inet6Address) { 2193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return new DNSRecord.IPv6Address(this.getName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getInetAddress()); 2203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 2223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman DNSRecord.Pointer getDNSReverseAddressRecord(DNSRecordType type, boolean unique, int ttl) { 2253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman switch (type) { 2263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case TYPE_A: 2273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getDNS4ReverseAddressRecord(unique, ttl); 2283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case TYPE_A6: 2293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case TYPE_AAAA: 2303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getDNS6ReverseAddressRecord(unique, ttl); 2313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman default: 2323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 2343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private DNSRecord.Pointer getDNS4ReverseAddressRecord(boolean unique, int ttl) { 2373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this.getInetAddress() instanceof Inet4Address) { 2383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return new DNSRecord.Pointer(this.getInetAddress().getHostAddress() + ".in-addr.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName()); 2393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((this.getInetAddress() instanceof Inet6Address) && (((Inet6Address) this.getInetAddress()).isIPv4CompatibleAddress())) { 2413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman byte[] rawAddress = this.getInetAddress().getAddress(); 2423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String address = (rawAddress[12] & 0xff) + "." + (rawAddress[13] & 0xff) + "." + (rawAddress[14] & 0xff) + "." + (rawAddress[15] & 0xff); 2433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return new DNSRecord.Pointer(address + ".in-addr.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName()); 2443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 2463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private DNSRecord.Pointer getDNS6ReverseAddressRecord(boolean unique, int ttl) { 2493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this.getInetAddress() instanceof Inet6Address) { 2503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return new DNSRecord.Pointer(this.getInetAddress().getHostAddress() + ".ip6.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName()); 2513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 2533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String toString() { 2573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman StringBuilder buf = new StringBuilder(1024); 2583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("local host info["); 2593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(getName() != null ? getName() : "no name"); 2603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(", "); 2613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(getInterface() != null ? getInterface().getDisplayName() : "???"); 2623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(":"); 2633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(getInetAddress() != null ? getInetAddress().getHostAddress() : "no address"); 2643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(", "); 2653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(_state); 2663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("]"); 2673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return buf.toString(); 2683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public Collection<DNSRecord> answers(boolean unique, int ttl) { 2713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman List<DNSRecord> list = new ArrayList<DNSRecord>(); 2723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman DNSRecord answer = this.getDNS4AddressRecord(unique, ttl); 2733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (answer != null) { 2743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman list.add(answer); 2753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman answer = this.getDNS6AddressRecord(unique, ttl); 2773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (answer != null) { 2783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman list.add(answer); 2793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return list; 2813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 2853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public JmDNSImpl getDns() { 2883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.getDns(); 2893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 2933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean advanceState(DNSTask task) { 2963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.advanceState(task); 2973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void removeAssociationWithTask(DNSTask task) { 3043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._state.removeAssociationWithTask(task); 3053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean revertState() { 3123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.revertState(); 3133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void associateWithTask(DNSTask task, DNSState state) { 3203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._state.associateWithTask(task, state); 3213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isAssociatedWithTask(DNSTask task, DNSState state) { 3283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.isAssociatedWithTask(task, state); 3293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean cancelState() { 3363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.cancelState(); 3373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean closeState() { 3443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.closeState(); 3453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean recoverState() { 3523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.recoverState(); 3533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isProbing() { 3603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.isProbing(); 3613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isAnnouncing() { 3683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.isAnnouncing(); 3693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isAnnounced() { 3763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.isAnnounced(); 3773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isCanceling() { 3843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.isCanceling(); 3853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isCanceled() { 3923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.isCanceled(); 3933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isClosing() { 4003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.isClosing(); 4013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 4053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isClosed() { 4083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.isClosed(); 4093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 4133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean waitForAnnounced(long timeout) { 4163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.waitForAnnounced(timeout); 4173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 4213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean waitForCanceled(long timeout) { 4243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (_address == null) { 4253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // No need to wait this was never announced. 4263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return true; 4273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.waitForCanceled(timeout); 4293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman} 432