00001
00002
00003
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
00053
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
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
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
00136
00137
00138 @Override
00139 public boolean isExpired(long now) {
00140 return getExpirationTime(100) <= now;
00141 }
00142
00143
00144
00145
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
00188 if (_addr instanceof Inet4Address) {
00189
00190 } else {
00191
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
00203
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
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
00248
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
00337
00338
00339
00340 logger1.finer("handleQuery() Ignoring an identical address query");
00341 return false;
00342 }
00343
00344 logger1.finer("handleQuery() Conflicting query detected.");
00345
00346 if (dns.isProbing() && comparison > 0) {
00347
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
00390
00391
00392 @Override
00393 public ServiceInfo getServiceInfo(boolean persistent) {
00394 ServiceInfoImpl info = new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, (byte[]) null);
00395
00396 return info;
00397 }
00398
00399
00400
00401
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
00412
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
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
00436
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
00468
00469 return false;
00470 }
00471
00472 @Override
00473 boolean handleResponse(JmDNSImpl dns) {
00474
00475
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
00490
00491
00492 @Override
00493 public ServiceInfo getServiceInfo(boolean persistent) {
00494 if (this.isServicesDiscoveryMetaQuery()) {
00495
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
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
00511
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
00524
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
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
00585
00586 return false;
00587 }
00588
00589 @Override
00590 boolean handleResponse(JmDNSImpl dns) {
00591
00592
00593
00594
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
00606
00607
00608 @Override
00609 public ServiceInfo getServiceInfo(boolean persistent) {
00610 return new ServiceInfoImpl(this.getQualifiedNameMap(), 0, 0, 0, persistent, _text);
00611 }
00612
00613
00614
00615
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
00626
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
00663 out.writeUTF(_server, 0, _server.length());
00664
00665
00666
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
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
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
00743
00744
00745
00746 logger1.finer("handleQuery() Ignoring a identical service query");
00747 return false;
00748 }
00749
00750
00751 if (info.isProbing() && comparison > 0) {
00752
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
00760 info.revertState();
00761 } else {
00762
00763
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
00807
00808
00809 @Override
00810 public ServiceInfo getServiceInfo(boolean persistent) {
00811 return new ServiceInfoImpl(this.getQualifiedNameMap(), _port, _weight, _priority, persistent, _server);
00812 }
00813
00814
00815
00816
00817
00818 @Override
00819 public ServiceEvent getServiceEvent(JmDNSImpl dns) {
00820 ServiceInfo info = this.getServiceInfo(false);
00821 ((ServiceInfoImpl) info).setDns(dns);
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 return new ServiceEventImpl(dns, info.getType(), info.getName(), info);
00833
00834 }
00835
00836
00837
00838
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
00868
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
00877
00878
00879 @Override
00880 boolean handleQuery(JmDNSImpl dns, long expirationTime) {
00881 return false;
00882 }
00883
00884
00885
00886
00887
00888 @Override
00889 boolean handleResponse(JmDNSImpl dns) {
00890 return false;
00891 }
00892
00893
00894
00895
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
00914
00915
00916 @Override
00917 public boolean isSingleValued() {
00918 return true;
00919 }
00920
00921
00922
00923
00924
00925 @Override
00926 void write(MessageOutputStream out) {
00927 String hostInfo = _cpu + " " + _os;
00928 out.writeUTF(hostInfo, 0, hostInfo.length());
00929 }
00930
00931
00932
00933
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
00945
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
00956
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
01010
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 }