DNSRecord.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.DataOutputStream;
00008 import java.io.IOException;
00009 import java.io.UnsupportedEncodingException;
00010 import java.net.Inet4Address;
00011 import java.net.Inet6Address;
00012 import java.net.InetAddress;
00013 import java.net.UnknownHostException;
00014 import java.util.HashMap;
00015 import java.util.Map;
00016 import java.util.logging.Level;
00017 import java.util.logging.Logger;
00018 
00019 import javax.jmdns.ServiceEvent;
00020 import javax.jmdns.ServiceInfo;
00021 import javax.jmdns.ServiceInfo.Fields;
00022 import javax.jmdns.impl.DNSOutgoing.MessageOutputStream;
00023 import javax.jmdns.impl.constants.DNSConstants;
00024 import javax.jmdns.impl.constants.DNSRecordClass;
00025 import javax.jmdns.impl.constants.DNSRecordType;
00026 
00032 public abstract class DNSRecord extends DNSEntry {
00033     private static Logger logger = Logger.getLogger(DNSRecord.class.getName());
00034     private int           _ttl;
00035     private long          _created;
00036 
00040     private InetAddress   _source;
00041 
00045     DNSRecord(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique, int ttl) {
00046         super(name, type, recordClass, unique);
00047         this._ttl = ttl;
00048         this._created = System.currentTimeMillis();
00049     }
00050 
00051     /*
00052      * (non-Javadoc)
00053      * @see javax.jmdns.impl.DNSEntry#equals(java.lang.Object)
00054      */
00055     @Override
00056     public boolean equals(Object other) {
00057         return (other instanceof DNSRecord) && super.equals(other) && sameValue((DNSRecord) other);
00058     }
00059 
00063     abstract boolean sameValue(DNSRecord other);
00064 
00068     boolean sameType(DNSRecord other) {
00069         return this.getRecordType() == other.getRecordType();
00070     }
00071 
00077     abstract boolean handleQuery(JmDNSImpl dns, long expirationTime);
00078 
00084     abstract boolean handleResponse(JmDNSImpl dns);
00085 
00089     abstract DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException;
00090 
00094     boolean suppressedBy(DNSIncoming msg) {
00095         try {
00096             for (DNSRecord answer : msg.getAllAnswers()) {
00097                 if (suppressedBy(answer)) {
00098                     return true;
00099                 }
00100             }
00101             return false;
00102         } catch (ArrayIndexOutOfBoundsException e) {
00103             logger.log(Level.WARNING, "suppressedBy() message " + msg + " exception ", e);
00104             // msg.print(true);
00105             return false;
00106         }
00107     }
00108 
00112     boolean suppressedBy(DNSRecord other) {
00113         if (this.equals(other) && (other._ttl > _ttl / 2)) {
00114             return true;
00115         }
00116         return false;
00117     }
00118 
00122     long getExpirationTime(int percent) {
00123         // ttl is in seconds the constant 10 is 1000 ms / 100 %
00124         return _created + (percent * _ttl * 10L);
00125     }
00126 
00130     int getRemainingTTL(long now) {
00131         return (int) Math.max(0, (getExpirationTime(100) - now) / 1000);
00132     }
00133 
00134     /*
00135      * (non-Javadoc)
00136      * @see javax.jmdns.impl.DNSEntry#isExpired(long)
00137      */
00138     @Override
00139     public boolean isExpired(long now) {
00140         return getExpirationTime(100) <= now;
00141     }
00142 
00143     /*
00144      * (non-Javadoc)
00145      * @see javax.jmdns.impl.DNSEntry#isStale(long)
00146      */
00147     @Override
00148     public boolean isStale(long now) {
00149         return getExpirationTime(50) <= now;
00150     }
00151 
00155     void resetTTL(DNSRecord other) {
00156         _created = other._created;
00157         _ttl = other._ttl;
00158     }
00159 
00163     void setWillExpireSoon(long now) {
00164         _created = now;
00165         _ttl = DNSConstants.RECORD_EXPIRY_DELAY;
00166     }
00167 
00171     abstract void write(MessageOutputStream out);
00172 
00173     public static class IPv4Address extends Address {
00174 
00175         IPv4Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, InetAddress addr) {
00176             super(name, DNSRecordType.TYPE_A, recordClass, unique, ttl, addr);
00177         }
00178 
00179         IPv4Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, byte[] rawAddress) {
00180             super(name, DNSRecordType.TYPE_A, recordClass, unique, ttl, rawAddress);
00181         }
00182 
00183         @Override
00184         void write(MessageOutputStream out) {
00185             if (_addr != null) {
00186                 byte[] buffer = _addr.getAddress();
00187                 // If we have a type A records we should answer with a IPv4 address
00188                 if (_addr instanceof Inet4Address) {
00189                     // All is good
00190                 } else {
00191                     // Get the last four bytes
00192                     byte[] tempbuffer = buffer;
00193                     buffer = new byte[4];
00194                     System.arraycopy(tempbuffer, 12, buffer, 0, 4);
00195                 }
00196                 int length = buffer.length;
00197                 out.writeBytes(buffer, 0, length);
00198             }
00199         }
00200 
00201         /*
00202          * (non-Javadoc)
00203          * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
00204          */
00205         @Override
00206         public ServiceInfo getServiceInfo(boolean persistent) {
00207 
00208             ServiceInfoImpl info = (ServiceInfoImpl) super.getServiceInfo(persistent);
00209             info.addAddress((Inet4Address) _addr);
00210             return info;
00211         }
00212 
00213     }
00214 
00215     public static class IPv6Address extends Address {
00216 
00217         IPv6Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, InetAddress addr) {
00218             super(name, DNSRecordType.TYPE_AAAA, recordClass, unique, ttl, addr);
00219         }
00220 
00221         IPv6Address(String name, DNSRecordClass recordClass, boolean unique, int ttl, byte[] rawAddress) {
00222             super(name, DNSRecordType.TYPE_AAAA, recordClass, unique, ttl, rawAddress);
00223         }
00224 
00225         @Override
00226         void write(MessageOutputStream out) {
00227             if (_addr != null) {
00228                 byte[] buffer = _addr.getAddress();
00229                 // If we have a type AAAA records we should answer with a IPv6 address
00230                 if (_addr instanceof Inet4Address) {
00231                     byte[] tempbuffer = buffer;
00232                     buffer = new byte[16];
00233                     for (int i = 0; i < 16; i++) {
00234                         if (i < 11) {
00235                             buffer[i] = tempbuffer[i - 12];
00236                         } else {
00237                             buffer[i] = 0;
00238                         }
00239                     }
00240                 }
00241                 int length = buffer.length;
00242                 out.writeBytes(buffer, 0, length);
00243             }
00244         }
00245 
00246         /*
00247          * (non-Javadoc)
00248          * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
00249          */
00250         @Override
00251         public ServiceInfo getServiceInfo(boolean persistent) {
00252 
00253             ServiceInfoImpl info = (ServiceInfoImpl) super.getServiceInfo(persistent);
00254             info.addAddress((Inet6Address) _addr);
00255             return info;
00256         }
00257 
00258     }
00259 
00263     public static abstract class Address extends DNSRecord {
00264         private static Logger logger1 = Logger.getLogger(Address.class.getName());
00265 
00266         InetAddress           _addr;
00267 
00268         protected Address(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique, int ttl, InetAddress addr) {
00269             super(name, type, recordClass, unique, ttl);
00270             this._addr = addr;
00271         }
00272 
00273         protected Address(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique, int ttl, byte[] rawAddress) {
00274             super(name, type, recordClass, unique, ttl);
00275             try {
00276                 this._addr = InetAddress.getByAddress(rawAddress);
00277             } catch (UnknownHostException exception) {
00278                 logger1.log(Level.WARNING, "Address() exception ", exception);
00279             }
00280         }
00281 
00282         boolean same(DNSRecord other) {
00283             if (! (other instanceof Address) ) {
00284                 return false;
00285             }
00286             return ((sameName(other)) && ((sameValue(other))));
00287         }
00288 
00289         boolean sameName(DNSRecord other) {
00290             return this.getName().equalsIgnoreCase(other.getName());
00291         }
00292 
00293         @Override
00294         boolean sameValue(DNSRecord other) {
00295             if (! (other instanceof Address) ) {
00296                 return false;
00297             }
00298             Address address = (Address) other;
00299             if ((this.getAddress() == null) && (address.getAddress() != null)) {
00300                 return false;
00301             }
00302             return this.getAddress().equals(address.getAddress());
00303         }
00304 
00305         @Override
00306         public boolean isSingleValued() {
00307             return false;
00308         }
00309 
00310         InetAddress getAddress() {
00311             return _addr;
00312         }
00313 
00317         @Override
00318         protected void toByteArray(DataOutputStream dout) throws IOException {
00319             super.toByteArray(dout);
00320             byte[] buffer = this.getAddress().getAddress();
00321             for (int i = 0; i < buffer.length; i++) {
00322                 dout.writeByte(buffer[i]);
00323             }
00324         }
00325 
00329         @Override
00330         boolean handleQuery(JmDNSImpl dns, long expirationTime) {
00331             if (dns.getLocalHost().conflictWithRecord(this)) {
00332                 DNSRecord.Address localAddress = dns.getLocalHost().getDNSAddressRecord(this.getRecordType(), this.isUnique(), DNSConstants.DNS_TTL);
00333                 int comparison = this.compareTo(localAddress);
00334 
00335                 if (comparison == 0) {
00336                     // the 2 records are identical this probably means we are seeing our own record.
00337                     // With multiple interfaces on a single computer it is possible to see our
00338                     // own records come in on different interfaces than the ones they were sent on.
00339                     // see section "10. Conflict Resolution" of mdns draft spec.
00340                     logger1.finer("handleQuery() Ignoring an identical address query");
00341                     return false;
00342                 }
00343 
00344                 logger1.finer("handleQuery() Conflicting query detected.");
00345                 // Tie breaker test
00346                 if (dns.isProbing() && comparison > 0) {
00347                     // We lost the tie-break. We have to choose a different name.
00348                     dns.getLocalHost().incrementHostName();
00349                     dns.getCache().clear();
00350                     for (ServiceInfo serviceInfo : dns.getServices().values()) {
00351                         ServiceInfoImpl info = (ServiceInfoImpl) serviceInfo;
00352                         info.revertState();
00353                     }
00354                 }
00355                 dns.revertState();
00356                 return true;
00357             }
00358             return false;
00359         }
00360 
00364         @Override
00365         boolean handleResponse(JmDNSImpl dns) {
00366             if (dns.getLocalHost().conflictWithRecord(this)) {
00367                 logger1.finer("handleResponse() Denial detected");
00368 
00369                 if (dns.isProbing()) {
00370                     dns.getLocalHost().incrementHostName();
00371                     dns.getCache().clear();
00372                     for (ServiceInfo serviceInfo : dns.getServices().values()) {
00373                         ServiceInfoImpl info = (ServiceInfoImpl) serviceInfo;
00374                         info.revertState();
00375                     }
00376                 }
00377                 dns.revertState();
00378                 return true;
00379             }
00380             return false;
00381         }
00382 
00383         @Override
00384         DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException {
00385             return out;
00386         }
00387 
00388         /*
00389          * (non-Javadoc)
00390          * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
00391          */
00392         @Override
00393         public ServiceInfo getServiceInfo(boolean persistent) {
00394             ServiceInfoImpl info = new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, (byte[]) null);
00395             // info.setAddress(_addr); This is done in the sub class so we don't have to test for class type
00396             return info;
00397         }
00398 
00399         /*
00400          * (non-Javadoc)
00401          * @see javax.jmdns.impl.DNSRecord#getServiceEvent(javax.jmdns.impl.JmDNSImpl)
00402          */
00403         @Override
00404         public ServiceEvent getServiceEvent(JmDNSImpl dns) {
00405             ServiceInfo info = this.getServiceInfo(false);
00406             ((ServiceInfoImpl) info).setDns(dns);
00407             return new ServiceEventImpl(dns, info.getType(), info.getName(), info);
00408         }
00409 
00410         /*
00411          * (non-Javadoc)
00412          * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
00413          */
00414         @Override
00415         protected void toString(StringBuilder aLog) {
00416             super.toString(aLog);
00417             aLog.append(" address: '" + (this.getAddress() != null ? this.getAddress().getHostAddress() : "null") + "'");
00418         }
00419 
00420     }
00421 
00425     public static class Pointer extends DNSRecord {
00426         // private static Logger logger = Logger.getLogger(Pointer.class.getName());
00427         private final String _alias;
00428 
00429         public Pointer(String name, DNSRecordClass recordClass, boolean unique, int ttl, String alias) {
00430             super(name, DNSRecordType.TYPE_PTR, recordClass, unique, ttl);
00431             this._alias = alias;
00432         }
00433 
00434         /*
00435          * (non-Javadoc)
00436          * @see javax.jmdns.impl.DNSEntry#isSameEntry(javax.jmdns.impl.DNSEntry)
00437          */
00438         @Override
00439         public boolean isSameEntry(DNSEntry entry) {
00440             return super.isSameEntry(entry) && (entry instanceof Pointer) && this.sameValue((Pointer) entry);
00441         }
00442 
00443         @Override
00444         void write(MessageOutputStream out) {
00445             out.writeName(_alias);
00446         }
00447 
00448         @Override
00449         boolean sameValue(DNSRecord other) {
00450             if (! (other instanceof Pointer) ) {
00451                 return false;
00452             }
00453             Pointer pointer = (Pointer) other;
00454             if ((_alias == null) && (pointer._alias != null)) {
00455                 return false;
00456             }
00457             return _alias.equals(pointer._alias);
00458         }
00459 
00460         @Override
00461         public boolean isSingleValued() {
00462             return false;
00463         }
00464 
00465         @Override
00466         boolean handleQuery(JmDNSImpl dns, long expirationTime) {
00467             // Nothing to do (?)
00468             // I think there is no possibility for conflicts for this record type?
00469             return false;
00470         }
00471 
00472         @Override
00473         boolean handleResponse(JmDNSImpl dns) {
00474             // Nothing to do (?)
00475             // I think there is no possibility for conflicts for this record type?
00476             return false;
00477         }
00478 
00479         String getAlias() {
00480             return _alias;
00481         }
00482 
00483         @Override
00484         DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException {
00485             return out;
00486         }
00487 
00488         /*
00489          * (non-Javadoc)
00490          * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
00491          */
00492         @Override
00493         public ServiceInfo getServiceInfo(boolean persistent) {
00494             if (this.isServicesDiscoveryMetaQuery()) {
00495                 // The service name is in the alias
00496                 Map<Fields, String> map = ServiceInfoImpl.decodeQualifiedNameMapForType(this.getAlias());
00497                 return new ServiceInfoImpl(map, 0, 0, 0, persistent, (byte[]) null);
00498             } else if (this.isReverseLookup()) {
00499                 return new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, (byte[]) null);
00500             } else if (this.isDomainDiscoveryQuery()) {
00501                 // FIXME [PJYF Nov 16 2010] We do not currently support domain discovery
00502                 return new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, (byte[]) null);
00503             }
00504             Map<Fields, String> map = ServiceInfoImpl.decodeQualifiedNameMapForType(this.getAlias());
00505             map.put(Fields.Subtype, this.getQualifiedNameMap().get(Fields.Subtype));
00506             return new ServiceInfoImpl(map, 0, 0, 0, persistent, this.getAlias());
00507         }
00508 
00509         /*
00510          * (non-Javadoc)
00511          * @see javax.jmdns.impl.DNSRecord#getServiceEvent(javax.jmdns.impl.JmDNSImpl)
00512          */
00513         @Override
00514         public ServiceEvent getServiceEvent(JmDNSImpl dns) {
00515             ServiceInfo info = this.getServiceInfo(false);
00516             ((ServiceInfoImpl) info).setDns(dns);
00517             String domainName = info.getType();
00518             String serviceName = JmDNSImpl.toUnqualifiedName(domainName, this.getAlias());
00519             return new ServiceEventImpl(dns, domainName, serviceName, info);
00520         }
00521 
00522         /*
00523          * (non-Javadoc)
00524          * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
00525          */
00526         @Override
00527         protected void toString(StringBuilder aLog) {
00528             super.toString(aLog);
00529             aLog.append(" alias: '" + (_alias != null ? _alias.toString() : "null") + "'");
00530         }
00531 
00532     }
00533 
00534     public final static byte[] EMPTY_TXT = new byte[] { 0 };
00535 
00536     public static class Text extends DNSRecord {
00537         // private static Logger logger = Logger.getLogger(Text.class.getName());
00538         private final byte[] _text;
00539 
00540         public Text(String name, DNSRecordClass recordClass, boolean unique, int ttl, byte text[]) {
00541             super(name, DNSRecordType.TYPE_TXT, recordClass, unique, ttl);
00542             this._text = (text != null && text.length > 0 ? text : EMPTY_TXT);
00543         }
00544 
00548         byte[] getText() {
00549             return this._text;
00550         }
00551 
00552         @Override
00553         void write(MessageOutputStream out) {
00554             out.writeBytes(_text, 0, _text.length);
00555         }
00556 
00557         @Override
00558         boolean sameValue(DNSRecord other) {
00559             if (! (other instanceof Text) ) {
00560                 return false;
00561             }
00562             Text txt = (Text) other;
00563             if ((_text == null) && (txt._text != null)) {
00564                 return false;
00565             }
00566             if (txt._text.length != _text.length) {
00567                 return false;
00568             }
00569             for (int i = _text.length; i-- > 0;) {
00570                 if (txt._text[i] != _text[i]) {
00571                     return false;
00572                 }
00573             }
00574             return true;
00575         }
00576 
00577         @Override
00578         public boolean isSingleValued() {
00579             return true;
00580         }
00581 
00582         @Override
00583         boolean handleQuery(JmDNSImpl dns, long expirationTime) {
00584             // Nothing to do (?)
00585             // I think there is no possibility for conflicts for this record type?
00586             return false;
00587         }
00588 
00589         @Override
00590         boolean handleResponse(JmDNSImpl dns) {
00591             // Nothing to do (?)
00592             // Shouldn't we care if we get a conflict at this level?
00593             /*
00594              * ServiceInfo info = (ServiceInfo) dns.services.get(name.toLowerCase()); if (info != null) { if (! Arrays.equals(text,info.text)) { info.revertState(); return true; } }
00595              */
00596             return false;
00597         }
00598 
00599         @Override
00600         DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException {
00601             return out;
00602         }
00603 
00604         /*
00605          * (non-Javadoc)
00606          * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
00607          */
00608         @Override
00609         public ServiceInfo getServiceInfo(boolean persistent) {
00610             return new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, _text);
00611         }
00612 
00613         /*
00614          * (non-Javadoc)
00615          * @see javax.jmdns.impl.DNSRecord#getServiceEvent(javax.jmdns.impl.JmDNSImpl)
00616          */
00617         @Override
00618         public ServiceEvent getServiceEvent(JmDNSImpl dns) {
00619             ServiceInfo info = this.getServiceInfo(false);
00620             ((ServiceInfoImpl) info).setDns(dns);
00621             return new ServiceEventImpl(dns, info.getType(), info.getName(), info);
00622         }
00623 
00624         /*
00625          * (non-Javadoc)
00626          * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
00627          */
00628         @Override
00629         protected void toString(StringBuilder aLog) {
00630             super.toString(aLog);
00631             aLog.append(" text: '" + ((_text.length > 20) ? new String(_text, 0, 17) + "..." : new String(_text)) + "'");
00632         }
00633 
00634     }
00635 
00639     public static class Service extends DNSRecord {
00640         private static Logger logger1 = Logger.getLogger(Service.class.getName());
00641         private final int     _priority;
00642         private final int     _weight;
00643         private final int     _port;
00644         private final String  _server;
00645 
00646         public Service(String name, DNSRecordClass recordClass, boolean unique, int ttl, int priority, int weight, int port, String server) {
00647             super(name, DNSRecordType.TYPE_SRV, recordClass, unique, ttl);
00648             this._priority = priority;
00649             this._weight = weight;
00650             this._port = port;
00651             this._server = server;
00652         }
00653 
00654         @Override
00655         void write(MessageOutputStream out) {
00656             out.writeShort(_priority);
00657             out.writeShort(_weight);
00658             out.writeShort(_port);
00659             if (DNSIncoming.USE_DOMAIN_NAME_FORMAT_FOR_SRV_TARGET) {
00660                 out.writeName(_server);
00661             } else {
00662                 // [PJYF Nov 13 2010] Do we still need this? This looks really bad. All label are supposed to start by a length.
00663                 out.writeUTF(_server, 0, _server.length());
00664 
00665                 // add a zero byte to the end just to be safe, this is the strange form
00666                 // used by the BonjourConformanceTest
00667                 out.writeByte(0);
00668             }
00669         }
00670 
00671         @Override
00672         protected void toByteArray(DataOutputStream dout) throws IOException {
00673             super.toByteArray(dout);
00674             dout.writeShort(_priority);
00675             dout.writeShort(_weight);
00676             dout.writeShort(_port);
00677             try {
00678                 dout.write(_server.getBytes("UTF-8"));
00679             } catch (UnsupportedEncodingException exception) {
00680                 /* UTF-8 is always present */
00681             }
00682         }
00683 
00684         String getServer() {
00685             return _server;
00686         }
00687 
00691         public int getPriority() {
00692             return this._priority;
00693         }
00694 
00698         public int getWeight() {
00699             return this._weight;
00700         }
00701 
00705         public int getPort() {
00706             return this._port;
00707         }
00708 
00709         @Override
00710         boolean sameValue(DNSRecord other) {
00711             if (! (other instanceof Service) ) {
00712                 return false;
00713             }
00714             Service s = (Service) other;
00715             return (_priority == s._priority) && (_weight == s._weight) && (_port == s._port) && _server.equals(s._server);
00716         }
00717 
00718         @Override
00719         public boolean isSingleValued() {
00720             return true;
00721         }
00722 
00723         @Override
00724         boolean handleQuery(JmDNSImpl dns, long expirationTime) {
00725             ServiceInfoImpl info = (ServiceInfoImpl) dns.getServices().get(this.getKey());
00726             if (info != null && (info.isAnnouncing() || info.isAnnounced()) && (_port != info.getPort() || !_server.equalsIgnoreCase(dns.getLocalHost().getName()))) {
00727                 logger1.finer("handleQuery() Conflicting probe detected from: " + getRecordSource());
00728                 DNSRecord.Service localService = new DNSRecord.Service(info.getQualifiedName(), DNSRecordClass.CLASS_IN, DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL, info.getPriority(), info.getWeight(), info.getPort(), dns.getLocalHost().getName());
00729 
00730                 // This block is useful for debugging race conditions when jmdns is responding to itself.
00731                 try {
00732                     if (dns.getInetAddress().equals(getRecordSource())) {
00733                         logger1.warning("Got conflicting probe from ourselves\n" + "incoming: " + this.toString() + "\n" + "local   : " + localService.toString());
00734                     }
00735                 } catch (IOException e) {
00736                     logger1.log(Level.WARNING, "IOException", e);
00737                 }
00738 
00739                 int comparison = this.compareTo(localService);
00740 
00741                 if (comparison == 0) {
00742                     // the 2 records are identical this probably means we are seeing our own record.
00743                     // With multiple interfaces on a single computer it is possible to see our
00744                     // own records come in on different interfaces than the ones they were sent on.
00745                     // see section "10. Conflict Resolution" of mdns draft spec.
00746                     logger1.finer("handleQuery() Ignoring a identical service query");
00747                     return false;
00748                 }
00749 
00750                 // Tie breaker test
00751                 if (info.isProbing() && comparison > 0) {
00752                     // We lost the tie break
00753                     String oldName = info.getQualifiedName().toLowerCase();
00754                     info.setName(dns.incrementName(info.getName()));
00755                     dns.getServices().remove(oldName);
00756                     dns.getServices().put(info.getQualifiedName().toLowerCase(), info);
00757                     logger1.finer("handleQuery() Lost tie break: new unique name chosen:" + info.getName());
00758 
00759                     // We revert the state to start probing again with the new name
00760                     info.revertState();
00761                 } else {
00762                     // We won the tie break, so this conflicting probe should be ignored
00763                     // See paragraph 3 of section 9.2 in mdns draft spec
00764                     return false;
00765                 }
00766 
00767                 return true;
00768 
00769             }
00770             return false;
00771         }
00772 
00773         @Override
00774         boolean handleResponse(JmDNSImpl dns) {
00775             ServiceInfoImpl info = (ServiceInfoImpl) dns.getServices().get(this.getKey());
00776             if (info != null && (_port != info.getPort() || !_server.equalsIgnoreCase(dns.getLocalHost().getName()))) {
00777                 logger1.finer("handleResponse() Denial detected");
00778 
00779                 if (info.isProbing()) {
00780                     String oldName = info.getQualifiedName().toLowerCase();
00781                     info.setName(dns.incrementName(info.getName()));
00782                     dns.getServices().remove(oldName);
00783                     dns.getServices().put(info.getQualifiedName().toLowerCase(), info);
00784                     logger1.finer("handleResponse() New unique name chose:" + info.getName());
00785 
00786                 }
00787                 info.revertState();
00788                 return true;
00789             }
00790             return false;
00791         }
00792 
00793         @Override
00794         DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException {
00795             ServiceInfoImpl info = (ServiceInfoImpl) dns.getServices().get(this.getKey());
00796             if (info != null) {
00797                 if (this._port == info.getPort() != _server.equals(dns.getLocalHost().getName())) {
00798                     return dns.addAnswer(in, addr, port, out, new DNSRecord.Service(info.getQualifiedName(), DNSRecordClass.CLASS_IN, DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL, info.getPriority(), info.getWeight(), info.getPort(), dns
00799                             .getLocalHost().getName()));
00800                 }
00801             }
00802             return out;
00803         }
00804 
00805         /*
00806          * (non-Javadoc)
00807          * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
00808          */
00809         @Override
00810         public ServiceInfo getServiceInfo(boolean persistent) {
00811             return new ServiceInfoImpl(this.getQualifiedNameMap(), _port, _weight, _priority, persistent, _server);
00812         }
00813 
00814         /*
00815          * (non-Javadoc)
00816          * @see javax.jmdns.impl.DNSRecord#getServiceEvent(javax.jmdns.impl.JmDNSImpl)
00817          */
00818         @Override
00819         public ServiceEvent getServiceEvent(JmDNSImpl dns) {
00820             ServiceInfo info = this.getServiceInfo(false);
00821             ((ServiceInfoImpl) info).setDns(dns);
00822             // String domainName = "";
00823             // String serviceName = this.getServer();
00824             // int index = serviceName.indexOf('.');
00825             // if (index > 0)
00826             // {
00827             // serviceName = this.getServer().substring(0, index);
00828             // if (index + 1 < this.getServer().length())
00829             // domainName = this.getServer().substring(index + 1);
00830             // }
00831             // return new ServiceEventImpl(dns, domainName, serviceName, info);
00832             return new ServiceEventImpl(dns, info.getType(), info.getName(), info);
00833 
00834         }
00835 
00836         /*
00837          * (non-Javadoc)
00838          * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
00839          */
00840         @Override
00841         protected void toString(StringBuilder aLog) {
00842             super.toString(aLog);
00843             aLog.append(" server: '" + _server + ":" + _port + "'");
00844         }
00845 
00846     }
00847 
00848     public static class HostInformation extends DNSRecord {
00849         String _os;
00850         String _cpu;
00851 
00860         public HostInformation(String name, DNSRecordClass recordClass, boolean unique, int ttl, String cpu, String os) {
00861             super(name, DNSRecordType.TYPE_HINFO, recordClass, unique, ttl);
00862             _cpu = cpu;
00863             _os = os;
00864         }
00865 
00866         /*
00867          * (non-Javadoc)
00868          * @see javax.jmdns.impl.DNSRecord#addAnswer(javax.jmdns.impl.JmDNSImpl, javax.jmdns.impl.DNSIncoming, java.net.InetAddress, int, javax.jmdns.impl.DNSOutgoing)
00869          */
00870         @Override
00871         DNSOutgoing addAnswer(JmDNSImpl dns, DNSIncoming in, InetAddress addr, int port, DNSOutgoing out) throws IOException {
00872             return out;
00873         }
00874 
00875         /*
00876          * (non-Javadoc)
00877          * @see javax.jmdns.impl.DNSRecord#handleQuery(javax.jmdns.impl.JmDNSImpl, long)
00878          */
00879         @Override
00880         boolean handleQuery(JmDNSImpl dns, long expirationTime) {
00881             return false;
00882         }
00883 
00884         /*
00885          * (non-Javadoc)
00886          * @see javax.jmdns.impl.DNSRecord#handleResponse(javax.jmdns.impl.JmDNSImpl)
00887          */
00888         @Override
00889         boolean handleResponse(JmDNSImpl dns) {
00890             return false;
00891         }
00892 
00893         /*
00894          * (non-Javadoc)
00895          * @see javax.jmdns.impl.DNSRecord#sameValue(javax.jmdns.impl.DNSRecord)
00896          */
00897         @Override
00898         boolean sameValue(DNSRecord other) {
00899             if (! (other instanceof HostInformation) ) {
00900                 return false;
00901             }
00902             HostInformation hinfo = (HostInformation) other;
00903             if ((_cpu == null) && (hinfo._cpu != null)) {
00904                 return false;
00905             }
00906             if ((_os == null) && (hinfo._os != null)) {
00907                 return false;
00908             }
00909             return _cpu.equals(hinfo._cpu) && _os.equals(hinfo._os);
00910         }
00911 
00912         /*
00913          * (non-Javadoc)
00914          * @see javax.jmdns.impl.DNSRecord#isSingleValued()
00915          */
00916         @Override
00917         public boolean isSingleValued() {
00918             return true;
00919         }
00920 
00921         /*
00922          * (non-Javadoc)
00923          * @see javax.jmdns.impl.DNSRecord#write(javax.jmdns.impl.DNSOutgoing)
00924          */
00925         @Override
00926         void write(MessageOutputStream out) {
00927             String hostInfo = _cpu + " " + _os;
00928             out.writeUTF(hostInfo, 0, hostInfo.length());
00929         }
00930 
00931         /*
00932          * (non-Javadoc)
00933          * @see javax.jmdns.impl.DNSRecord#getServiceInfo(boolean)
00934          */
00935         @Override
00936         public ServiceInfo getServiceInfo(boolean persistent) {
00937             Map<String, String> hinfo = new HashMap<String, String>(2);
00938             hinfo.put("cpu", _cpu);
00939             hinfo.put("os", _os);
00940             return new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, hinfo);
00941         }
00942 
00943         /*
00944          * (non-Javadoc)
00945          * @see javax.jmdns.impl.DNSRecord#getServiceEvent(javax.jmdns.impl.JmDNSImpl)
00946          */
00947         @Override
00948         public ServiceEvent getServiceEvent(JmDNSImpl dns) {
00949             ServiceInfo info = this.getServiceInfo(false);
00950             ((ServiceInfoImpl) info).setDns(dns);
00951             return new ServiceEventImpl(dns, info.getType(), info.getName(), info);
00952         }
00953 
00954         /*
00955          * (non-Javadoc)
00956          * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
00957          */
00958         @Override
00959         protected void toString(StringBuilder aLog) {
00960             super.toString(aLog);
00961             aLog.append(" cpu: '" + _cpu + "' os: '" + _os + "'");
00962         }
00963 
00964     }
00965 
00971     public abstract boolean isSingleValued();
00972 
00978     public ServiceInfo getServiceInfo() {
00979         return this.getServiceInfo(false);
00980     }
00981 
00989     public abstract ServiceInfo getServiceInfo(boolean persistent);
00990 
00998     public abstract ServiceEvent getServiceEvent(JmDNSImpl dns);
00999 
01000     public void setRecordSource(InetAddress source) {
01001         this._source = source;
01002     }
01003 
01004     public InetAddress getRecordSource() {
01005         return _source;
01006     }
01007 
01008     /*
01009      * (non-Javadoc)
01010      * @see com.webobjects.discoveryservices.DNSRecord#toString(java.lang.StringBuilder)
01011      */
01012     @Override
01013     protected void toString(StringBuilder aLog) {
01014         super.toString(aLog);
01015         aLog.append(" ttl: '" + getRemainingTTL(System.currentTimeMillis()) + "/" + _ttl + "'");
01016     }
01017 
01018     public void setTTL(int ttl) {
01019         this._ttl = ttl;
01020     }
01021 
01022     public int getTTL() {
01023         return _ttl;
01024     }
01025 }


zeroconf_jmdns_suite
Author(s): Daniel Stonier
autogenerated on Thu Aug 27 2015 15:50:27