PageRenderTime 58ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/JmDNS/src/javax/jmdns/impl/HostInfo.java

https://github.com/masterpi314/dmix
Java | 422 lines | 286 code | 50 blank | 86 comment | 47 complexity | 68c4f08574bc2047f36f736f3c47875c MD5 | raw file
  1. // Copyright 2003-2005 Arthur van Hoff, Rick Blair
  2. // Licensed under Apache License version 2.0
  3. // Original license LGPL
  4. package javax.jmdns.impl;
  5. import java.io.IOException;
  6. import java.net.DatagramPacket;
  7. import java.net.Inet4Address;
  8. import java.net.Inet6Address;
  9. import java.net.InetAddress;
  10. import java.net.NetworkInterface;
  11. import java.net.UnknownHostException;
  12. import java.util.ArrayList;
  13. import java.util.Collection;
  14. import java.util.List;
  15. import java.util.logging.Level;
  16. import java.util.logging.Logger;
  17. import javax.jmdns.NetworkTopologyDiscovery;
  18. import javax.jmdns.impl.constants.DNSRecordClass;
  19. import javax.jmdns.impl.constants.DNSRecordType;
  20. import javax.jmdns.impl.constants.DNSState;
  21. import javax.jmdns.impl.tasks.DNSTask;
  22. /**
  23. * HostInfo information on the local host to be able to cope with change of addresses.
  24. *
  25. * @author Pierre Frisch, Werner Randelshofer
  26. */
  27. public class HostInfo implements DNSStatefulObject {
  28. private static Logger logger = Logger.getLogger(HostInfo.class.getName());
  29. protected String _name;
  30. protected InetAddress _address;
  31. protected NetworkInterface _interfaze;
  32. private final HostInfoState _state;
  33. private final static class HostInfoState extends DNSStatefulObject.DefaultImplementation {
  34. private static final long serialVersionUID = -8191476803620402088L;
  35. /**
  36. * @param dns
  37. */
  38. public HostInfoState(JmDNSImpl dns) {
  39. super();
  40. this.setDns(dns);
  41. }
  42. }
  43. /**
  44. * @param address
  45. * IP address to bind
  46. * @param dns
  47. * JmDNS instance
  48. * @param jmdnsName
  49. * JmDNS name
  50. * @return new HostInfo
  51. */
  52. public static HostInfo newHostInfo(InetAddress address, JmDNSImpl dns, String jmdnsName) {
  53. HostInfo localhost = null;
  54. String aName = "";
  55. InetAddress addr = address;
  56. try {
  57. if (addr == null) {
  58. String ip = System.getProperty("net.mdns.interface");
  59. if (ip != null) {
  60. addr = InetAddress.getByName(ip);
  61. } else {
  62. addr = InetAddress.getLocalHost();
  63. if (addr.isLoopbackAddress()) {
  64. // Find local address that isn't a loopback address
  65. InetAddress[] addresses = NetworkTopologyDiscovery.Factory.getInstance().getInetAddresses();
  66. if (addresses.length > 0) {
  67. addr = addresses[0];
  68. }
  69. }
  70. }
  71. aName = addr.getHostName();
  72. if (addr.isLoopbackAddress()) {
  73. logger.warning("Could not find any address beside the loopback.");
  74. }
  75. } else {
  76. aName = addr.getHostName();
  77. }
  78. if (aName.contains("in-addr.arpa") || (aName.equals(addr.getHostAddress()))) {
  79. aName = ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : addr.getHostAddress());
  80. }
  81. } catch (final IOException e) {
  82. logger.log(Level.WARNING, "Could not intialize the host network interface on " + address + "because of an error: " + e.getMessage(), e);
  83. // This is only used for running unit test on Debian / Ubuntu
  84. addr = loopbackAddress();
  85. aName = ((jmdnsName != null) && (jmdnsName.length() > 0) ? jmdnsName : "computer");
  86. }
  87. // A host name with "." is illegal. so strip off everything and append .local.
  88. aName = aName.replace('.', '-');
  89. aName += ".local.";
  90. localhost = new HostInfo(addr, aName, dns);
  91. return localhost;
  92. }
  93. private static InetAddress loopbackAddress() {
  94. try {
  95. return InetAddress.getByName(null);
  96. } catch (UnknownHostException exception) {
  97. return null;
  98. }
  99. }
  100. /**
  101. * This is used to create a unique name for the host name.
  102. */
  103. private int hostNameCount;
  104. private HostInfo(final InetAddress address, final String name, final JmDNSImpl dns) {
  105. super();
  106. this._state = new HostInfoState(dns);
  107. this._address = address;
  108. this._name = name;
  109. if (address != null) {
  110. try {
  111. _interfaze = NetworkInterface.getByInetAddress(address);
  112. } catch (Exception exception) {
  113. logger.log(Level.SEVERE, "LocalHostInfo() exception ", exception);
  114. }
  115. }
  116. }
  117. public String getName() {
  118. return _name;
  119. }
  120. public InetAddress getInetAddress() {
  121. return _address;
  122. }
  123. Inet4Address getInet4Address() {
  124. if (this.getInetAddress() instanceof Inet4Address) {
  125. return (Inet4Address) _address;
  126. }
  127. return null;
  128. }
  129. Inet6Address getInet6Address() {
  130. if (this.getInetAddress() instanceof Inet6Address) {
  131. return (Inet6Address) _address;
  132. }
  133. return null;
  134. }
  135. public NetworkInterface getInterface() {
  136. return _interfaze;
  137. }
  138. synchronized String incrementHostName() {
  139. hostNameCount++;
  140. int plocal = _name.indexOf(".local.");
  141. int punder = _name.lastIndexOf('-');
  142. _name = _name.substring(0, (punder == -1 ? plocal : punder)) + "-" + hostNameCount + ".local.";
  143. return _name;
  144. }
  145. boolean shouldIgnorePacket(DatagramPacket packet) {
  146. boolean result = false;
  147. if (this.getInetAddress() != null) {
  148. InetAddress from = packet.getAddress();
  149. if (from != null) {
  150. if (from.isLinkLocalAddress() && (!this.getInetAddress().isLinkLocalAddress())) {
  151. // Ignore linklocal packets on regular interfaces, unless this is
  152. // also a linklocal interface. This is to avoid duplicates. This is
  153. // a terrible hack caused by the lack of an API to get the address
  154. // of the interface on which the packet was received.
  155. result = true;
  156. }
  157. if (from.isLoopbackAddress() && (!this.getInetAddress().isLoopbackAddress())) {
  158. // Ignore loopback packets on a regular interface unless this is also a loopback interface.
  159. result = true;
  160. }
  161. }
  162. }
  163. return result;
  164. }
  165. DNSRecord.Address getDNSAddressRecord(DNSRecordType type, boolean unique, int ttl) {
  166. switch (type) {
  167. case TYPE_A:
  168. return this.getDNS4AddressRecord(unique, ttl);
  169. case TYPE_A6:
  170. case TYPE_AAAA:
  171. return this.getDNS6AddressRecord(unique, ttl);
  172. default:
  173. }
  174. return null;
  175. }
  176. private DNSRecord.Address getDNS4AddressRecord(boolean unique, int ttl) {
  177. if ((this.getInetAddress() instanceof Inet4Address) || ((this.getInetAddress() instanceof Inet6Address) && (((Inet6Address) this.getInetAddress()).isIPv4CompatibleAddress()))) {
  178. return new DNSRecord.IPv4Address(this.getName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getInetAddress());
  179. }
  180. return null;
  181. }
  182. private DNSRecord.Address getDNS6AddressRecord(boolean unique, int ttl) {
  183. if (this.getInetAddress() instanceof Inet6Address) {
  184. return new DNSRecord.IPv6Address(this.getName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getInetAddress());
  185. }
  186. return null;
  187. }
  188. DNSRecord.Pointer getDNSReverseAddressRecord(DNSRecordType type, boolean unique, int ttl) {
  189. switch (type) {
  190. case TYPE_A:
  191. return this.getDNS4ReverseAddressRecord(unique, ttl);
  192. case TYPE_A6:
  193. case TYPE_AAAA:
  194. return this.getDNS6ReverseAddressRecord(unique, ttl);
  195. default:
  196. }
  197. return null;
  198. }
  199. private DNSRecord.Pointer getDNS4ReverseAddressRecord(boolean unique, int ttl) {
  200. if (this.getInetAddress() instanceof Inet4Address) {
  201. return new DNSRecord.Pointer(this.getInetAddress().getHostAddress() + ".in-addr.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName());
  202. }
  203. if ((this.getInetAddress() instanceof Inet6Address) && (((Inet6Address) this.getInetAddress()).isIPv4CompatibleAddress())) {
  204. byte[] rawAddress = this.getInetAddress().getAddress();
  205. String address = (rawAddress[12] & 0xff) + "." + (rawAddress[13] & 0xff) + "." + (rawAddress[14] & 0xff) + "." + (rawAddress[15] & 0xff);
  206. return new DNSRecord.Pointer(address + ".in-addr.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName());
  207. }
  208. return null;
  209. }
  210. private DNSRecord.Pointer getDNS6ReverseAddressRecord(boolean unique, int ttl) {
  211. if (this.getInetAddress() instanceof Inet6Address) {
  212. return new DNSRecord.Pointer(this.getInetAddress().getHostAddress() + ".ip6.arpa.", DNSRecordClass.CLASS_IN, unique, ttl, this.getName());
  213. }
  214. return null;
  215. }
  216. @Override
  217. public String toString() {
  218. StringBuilder buf = new StringBuilder(1024);
  219. buf.append("local host info[");
  220. buf.append(getName() != null ? getName() : "no name");
  221. buf.append(", ");
  222. buf.append(getInterface() != null ? getInterface().getDisplayName() : "???");
  223. buf.append(":");
  224. buf.append(getInetAddress() != null ? getInetAddress().getHostAddress() : "no address");
  225. buf.append(", ");
  226. buf.append(_state);
  227. buf.append("]");
  228. return buf.toString();
  229. }
  230. public Collection<DNSRecord> answers(boolean unique, int ttl) {
  231. List<DNSRecord> list = new ArrayList<DNSRecord>();
  232. DNSRecord answer = this.getDNS4AddressRecord(unique, ttl);
  233. if (answer != null) {
  234. list.add(answer);
  235. }
  236. answer = this.getDNS6AddressRecord(unique, ttl);
  237. if (answer != null) {
  238. list.add(answer);
  239. }
  240. return list;
  241. }
  242. /**
  243. * {@inheritDoc}
  244. */
  245. @Override
  246. public JmDNSImpl getDns() {
  247. return this._state.getDns();
  248. }
  249. /**
  250. * {@inheritDoc}
  251. */
  252. @Override
  253. public boolean advanceState(DNSTask task) {
  254. return this._state.advanceState(task);
  255. }
  256. /**
  257. * {@inheritDoc}
  258. */
  259. @Override
  260. public void removeAssociationWithTask(DNSTask task) {
  261. this._state.removeAssociationWithTask(task);
  262. }
  263. /**
  264. * {@inheritDoc}
  265. */
  266. @Override
  267. public boolean revertState() {
  268. return this._state.revertState();
  269. }
  270. /**
  271. * {@inheritDoc}
  272. */
  273. @Override
  274. public void associateWithTask(DNSTask task, DNSState state) {
  275. this._state.associateWithTask(task, state);
  276. }
  277. /**
  278. * {@inheritDoc}
  279. */
  280. @Override
  281. public boolean isAssociatedWithTask(DNSTask task, DNSState state) {
  282. return this._state.isAssociatedWithTask(task, state);
  283. }
  284. /**
  285. * {@inheritDoc}
  286. */
  287. @Override
  288. public boolean cancelState() {
  289. return this._state.cancelState();
  290. }
  291. /**
  292. * {@inheritDoc}
  293. */
  294. @Override
  295. public boolean closeState() {
  296. return this._state.closeState();
  297. }
  298. /**
  299. * {@inheritDoc}
  300. */
  301. @Override
  302. public boolean recoverState() {
  303. return this._state.recoverState();
  304. }
  305. /**
  306. * {@inheritDoc}
  307. */
  308. @Override
  309. public boolean isProbing() {
  310. return this._state.isProbing();
  311. }
  312. /**
  313. * {@inheritDoc}
  314. */
  315. @Override
  316. public boolean isAnnouncing() {
  317. return this._state.isAnnouncing();
  318. }
  319. /**
  320. * {@inheritDoc}
  321. */
  322. @Override
  323. public boolean isAnnounced() {
  324. return this._state.isAnnounced();
  325. }
  326. /**
  327. * {@inheritDoc}
  328. */
  329. @Override
  330. public boolean isCanceling() {
  331. return this._state.isCanceling();
  332. }
  333. /**
  334. * {@inheritDoc}
  335. */
  336. @Override
  337. public boolean isCanceled() {
  338. return this._state.isCanceled();
  339. }
  340. /**
  341. * {@inheritDoc}
  342. */
  343. @Override
  344. public boolean isClosing() {
  345. return this._state.isClosing();
  346. }
  347. /**
  348. * {@inheritDoc}
  349. */
  350. @Override
  351. public boolean isClosed() {
  352. return this._state.isClosed();
  353. }
  354. /**
  355. * {@inheritDoc}
  356. */
  357. @Override
  358. public boolean waitForAnnounced(long timeout) {
  359. return _state.waitForAnnounced(timeout);
  360. }
  361. /**
  362. * {@inheritDoc}
  363. */
  364. @Override
  365. public boolean waitForCanceled(long timeout) {
  366. if (_address == null) {
  367. // No need to wait this was never announced.
  368. return true;
  369. }
  370. return _state.waitForCanceled(timeout);
  371. }
  372. }