HostInfo.java
Go to the documentation of this file.
00001 // Copyright 2003-2005 Arthur van Hoff, Rick Blair
00002 // Licensed under Apache License version 2.0
00003 // Original license LGPL
00004 
00005 package javax.jmdns.impl;
00006 
00007 import java.io.IOException;
00008 import java.net.DatagramPacket;
00009 import java.net.Inet4Address;
00010 import java.net.Inet6Address;
00011 import java.net.InetAddress;
00012 import java.net.NetworkInterface;
00013 import java.net.UnknownHostException;
00014 import java.util.ArrayList;
00015 import java.util.Collection;
00016 import java.util.List;
00017 import java.util.logging.Level;
00018 import java.util.logging.Logger;
00019 
00020 import javax.jmdns.NetworkTopologyDiscovery;
00021 import javax.jmdns.impl.constants.DNSConstants;
00022 import javax.jmdns.impl.constants.DNSRecordClass;
00023 import javax.jmdns.impl.constants.DNSRecordType;
00024 import javax.jmdns.impl.constants.DNSState;
00025 import javax.jmdns.impl.tasks.DNSTask;
00026 
00032 public class HostInfo implements DNSStatefulObject {
00033     private static Logger       logger = Logger.getLogger(HostInfo.class.getName());
00034 
00035     protected String            _name;
00036 
00037     protected InetAddress       _address;
00038 
00039     protected NetworkInterface  _interfaze;
00040 
00041     private final HostInfoState _state;
00042 
00043     private final static class HostInfoState extends DNSStatefulObject.DefaultImplementation {
00044 
00045         private static final long serialVersionUID = -8191476803620402088L;
00046 
00050         public HostInfoState(JmDNSImpl dns) {
00051             super();
00052             this.setDns(dns);
00053         }
00054 
00055     }
00056 
00066     public static HostInfo newHostInfo(InetAddress address, JmDNSImpl dns, String jmdnsName) {
00067         HostInfo localhost = null;
00068         String aName = "";
00069         InetAddress addr = address;
00070         try {
00071             if (addr == null) {
00072                 String ip = System.getProperty("net.mdns.interface");
00073                 if (ip != null) {
00074                     addr = InetAddress.getByName(ip);
00075                 } else {
00076                     addr = InetAddress.getLocalHost();
00077                     if (addr.isLoopbackAddress()) {
00078                         // Find local address that isn't a loopback address
00079                         InetAddress[] addresses = NetworkTopologyDiscovery.Factory.getInstance().getInetAddresses();
00080                         if (addresses.length > 0) {
00081                             addr = addresses[0];
00082                         }
00083                     }
00084                 }
00085                 aName = addr.getHostName();
00086                 if (addr.isLoopbackAddress()) {
00087                     logger.warning("Could not find any address beside the loopback.");
00088                 }
00089             } else {
00090                 aName = addr.getHostName();
00091             }
00092             if (aName.contains("in-addr.arpa") || (aName.equals(addr.getHostAddress()))) {
00093                 aName = ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : addr.getHostAddress());
00094             }
00095         } catch (final IOException e) {
00096             logger.log(Level.WARNING, "Could not intialize the host network interface on " + address + "because of an error: " + e.getMessage(), e);
00097             // This is only used for running unit test on Debian / Ubuntu
00098             addr = loopbackAddress();
00099             aName = ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : "computer");
00100         }
00101         // A host name with "." is illegal. so strip off everything and append .local.
00102         aName = aName.replace('.', '-');
00103         aName += ".local.";
00104         localhost = new HostInfo(addr, aName, dns);
00105         return localhost;
00106     }
00107 
00108     private static InetAddress loopbackAddress() {
00109         try {
00110             return InetAddress.getByName(null);
00111         } catch (UnknownHostException exception) {
00112             return null;
00113         }
00114     }
00115 
00119     private int hostNameCount;
00120 
00121     private HostInfo(final InetAddress address, final String name, final JmDNSImpl dns) {
00122         super();
00123         this._state = new HostInfoState(dns);
00124         this._address = address;
00125         this._name = name;
00126         if (address != null) {
00127             try {
00128                 _interfaze = NetworkInterface.getByInetAddress(address);
00129             } catch (Exception exception) {
00130                 logger.log(Level.SEVERE, "LocalHostInfo() exception ", exception);
00131             }
00132         }
00133     }
00134 
00135     public String getName() {
00136         return _name;
00137     }
00138 
00139     public InetAddress getInetAddress() {
00140         return _address;
00141     }
00142 
00143     Inet4Address getInet4Address() {
00144         if (this.getInetAddress() instanceof Inet4Address) {
00145             return (Inet4Address) _address;
00146         }
00147         return null;
00148     }
00149 
00150     Inet6Address getInet6Address() {
00151         if (this.getInetAddress() instanceof Inet6Address) {
00152             return (Inet6Address) _address;
00153         }
00154         return null;
00155     }
00156 
00157     public NetworkInterface getInterface() {
00158         return _interfaze;
00159     }
00160 
00161     public boolean conflictWithRecord(DNSRecord.Address record) {
00162         DNSRecord.Address hostAddress = this.getDNSAddressRecord(record.getRecordType(), record.isUnique(), DNSConstants.DNS_TTL);
00163         if (hostAddress != null) {
00164             return hostAddress.sameType(record) && hostAddress.sameName(record) && (!hostAddress.sameValue(record));
00165         }
00166         return false;
00167     }
00168 
00169     synchronized String incrementHostName() {
00170         hostNameCount++;
00171         int plocal = _name.indexOf(".local.");
00172         int punder = _name.lastIndexOf('-');
00173         _name = _name.substring(0, (punder == -1 ? plocal : punder)) + "-" + hostNameCount + ".local.";
00174         return _name;
00175     }
00176 
00177     boolean shouldIgnorePacket(DatagramPacket packet) {
00178         boolean result = false;
00179         if (this.getInetAddress() != null) {
00180             InetAddress from = packet.getAddress();
00181             if (from != null) {
00182                 if (from.isLinkLocalAddress() && (!this.getInetAddress().isLinkLocalAddress())) {
00183                     // Ignore linklocal packets on regular interfaces, unless this is
00184                     // also a linklocal interface. This is to avoid duplicates. This is
00185                     // a terrible hack caused by the lack of an API to get the address
00186                     // of the interface on which the packet was received.
00187                     result = true;
00188                 }
00189                 if (from.isLoopbackAddress() && (!this.getInetAddress().isLoopbackAddress())) {
00190                     // Ignore loopback packets on a regular interface unless this is also a loopback interface.
00191                     result = true;
00192                 }
00193             }
00194         }
00195         return result;
00196     }
00197 
00198     DNSRecord.Address getDNSAddressRecord(DNSRecordType type, boolean unique, int ttl) {
00199         switch (type) {
00200             case TYPE_A:
00201                 return this.getDNS4AddressRecord(unique, ttl);
00202             case TYPE_A6:
00203             case TYPE_AAAA:
00204                 return this.getDNS6AddressRecord(unique, ttl);
00205             default:
00206         }
00207         return null;
00208     }
00209 
00210     private DNSRecord.Address getDNS4AddressRecord(boolean unique, int ttl) {
00211         if ((this.getInetAddress() instanceof Inet4Address) || ((this.getInetAddress() instanceof Inet6Address) && (((Inet6Address) this.getInetAddress()).isIPv4CompatibleAddress()))) {
00212             return new DNSRecord.IPv4Address(this.getName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getInetAddress());
00213         }
00214         return null;
00215     }
00216 
00217     private DNSRecord.Address getDNS6AddressRecord(boolean unique, int ttl) {
00218         if (this.getInetAddress() instanceof Inet6Address) {
00219             return new DNSRecord.IPv6Address(this.getName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getInetAddress());
00220         }
00221         return null;
00222     }
00223 
00224     DNSRecord.Pointer getDNSReverseAddressRecord(DNSRecordType type, boolean unique, int ttl) {
00225         switch (type) {
00226             case TYPE_A:
00227                 return this.getDNS4ReverseAddressRecord(unique, ttl);
00228             case TYPE_A6:
00229             case TYPE_AAAA:
00230                 return this.getDNS6ReverseAddressRecord(unique, ttl);
00231             default:
00232         }
00233         return null;
00234     }
00235 
00236     private DNSRecord.Pointer getDNS4ReverseAddressRecord(boolean unique, int ttl) {
00237         if (this.getInetAddress() instanceof Inet4Address) {
00238             return new DNSRecord.Pointer(this.getInetAddress().getHostAddress() + ".in-addr.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName());
00239         }
00240         if ((this.getInetAddress() instanceof Inet6Address) && (((Inet6Address) this.getInetAddress()).isIPv4CompatibleAddress())) {
00241             byte[] rawAddress = this.getInetAddress().getAddress();
00242             String address = (rawAddress[12] & 0xff) + "." + (rawAddress[13] & 0xff) + "." + (rawAddress[14] & 0xff) + "." + (rawAddress[15] & 0xff);
00243             return new DNSRecord.Pointer(address + ".in-addr.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName());
00244         }
00245         return null;
00246     }
00247 
00248     private DNSRecord.Pointer getDNS6ReverseAddressRecord(boolean unique, int ttl) {
00249         if (this.getInetAddress() instanceof Inet6Address) {
00250             return new DNSRecord.Pointer(this.getInetAddress().getHostAddress() + ".ip6.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName());
00251         }
00252         return null;
00253     }
00254 
00255     @Override
00256     public String toString() {
00257         StringBuilder buf = new StringBuilder(1024);
00258         buf.append("local host info[");
00259         buf.append(getName() != null ? getName() : "no name");
00260         buf.append(", ");
00261         buf.append(getInterface() != null ? getInterface().getDisplayName() : "???");
00262         buf.append(":");
00263         buf.append(getInetAddress() != null ? getInetAddress().getHostAddress() : "no address");
00264         buf.append(", ");
00265         buf.append(_state);
00266         buf.append("]");
00267         return buf.toString();
00268     }
00269 
00270     public Collection<DNSRecord> answers(boolean unique, int ttl) {
00271         List<DNSRecord> list = new ArrayList<DNSRecord>();
00272         DNSRecord answer = this.getDNS4AddressRecord(unique, ttl);
00273         if (answer != null) {
00274             list.add(answer);
00275         }
00276         answer = this.getDNS6AddressRecord(unique, ttl);
00277         if (answer != null) {
00278             list.add(answer);
00279         }
00280         return list;
00281     }
00282 
00286     @Override
00287     public JmDNSImpl getDns() {
00288         return this._state.getDns();
00289     }
00290 
00294     @Override
00295     public boolean advanceState(DNSTask task) {
00296         return this._state.advanceState(task);
00297     }
00298 
00302     @Override
00303     public void removeAssociationWithTask(DNSTask task) {
00304         this._state.removeAssociationWithTask(task);
00305     }
00306 
00310     @Override
00311     public boolean revertState() {
00312         return this._state.revertState();
00313     }
00314 
00318     @Override
00319     public void associateWithTask(DNSTask task, DNSState state) {
00320         this._state.associateWithTask(task, state);
00321     }
00322 
00326     @Override
00327     public boolean isAssociatedWithTask(DNSTask task, DNSState state) {
00328         return this._state.isAssociatedWithTask(task, state);
00329     }
00330 
00334     @Override
00335     public boolean cancelState() {
00336         return this._state.cancelState();
00337     }
00338 
00342     @Override
00343     public boolean closeState() {
00344         return this._state.closeState();
00345     }
00346 
00350     @Override
00351     public boolean recoverState() {
00352         return this._state.recoverState();
00353     }
00354 
00358     @Override
00359     public boolean isProbing() {
00360         return this._state.isProbing();
00361     }
00362 
00366     @Override
00367     public boolean isAnnouncing() {
00368         return this._state.isAnnouncing();
00369     }
00370 
00374     @Override
00375     public boolean isAnnounced() {
00376         return this._state.isAnnounced();
00377     }
00378 
00382     @Override
00383     public boolean isCanceling() {
00384         return this._state.isCanceling();
00385     }
00386 
00390     @Override
00391     public boolean isCanceled() {
00392         return this._state.isCanceled();
00393     }
00394 
00398     @Override
00399     public boolean isClosing() {
00400         return this._state.isClosing();
00401     }
00402 
00406     @Override
00407     public boolean isClosed() {
00408         return this._state.isClosed();
00409     }
00410 
00414     @Override
00415     public boolean waitForAnnounced(long timeout) {
00416         return _state.waitForAnnounced(timeout);
00417     }
00418 
00422     @Override
00423     public boolean waitForCanceled(long timeout) {
00424         if (_address == null) {
00425             // No need to wait this was never announced.
00426             return true;
00427         }
00428         return _state.waitForCanceled(timeout);
00429     }
00430 
00431 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends


zeroconf_jmdns
Author(s): Daniel Stonier
autogenerated on Tue Nov 6 2012 13:08:26