Home | History | Annotate | Download | only in state
      1 // Copyright 2003-2005 Arthur van Hoff, Rick Blair
      2 // Licensed under Apache License version 2.0
      3 // Original license LGPL
      4 
      5 package javax.jmdns.impl.tasks.state;
      6 
      7 import java.io.IOException;
      8 import java.util.Timer;
      9 import java.util.logging.Logger;
     10 
     11 import javax.jmdns.impl.DNSOutgoing;
     12 import javax.jmdns.impl.DNSQuestion;
     13 import javax.jmdns.impl.DNSRecord;
     14 import javax.jmdns.impl.JmDNSImpl;
     15 import javax.jmdns.impl.ServiceInfoImpl;
     16 import javax.jmdns.impl.constants.DNSConstants;
     17 import javax.jmdns.impl.constants.DNSRecordClass;
     18 import javax.jmdns.impl.constants.DNSRecordType;
     19 import javax.jmdns.impl.constants.DNSState;
     20 
     21 /**
     22  * The Prober sends three consecutive probes for all service infos that needs probing as well as for the host name. The state of each service info of the host name is advanced, when a probe has been sent for it. When the prober has run three times,
     23  * it launches an Announcer.
     24  * <p/>
     25  * If a conflict during probes occurs, the affected service infos (and affected host name) are taken away from the prober. This eventually causes the prober to cancel itself.
     26  */
     27 public class Prober extends DNSStateTask {
     28     static Logger logger = Logger.getLogger(Prober.class.getName());
     29 
     30     public Prober(JmDNSImpl jmDNSImpl) {
     31         super(jmDNSImpl, defaultTTL());
     32 
     33         this.setTaskState(DNSState.PROBING_1);
     34         this.associate(DNSState.PROBING_1);
     35     }
     36 
     37     /*
     38      * (non-Javadoc)
     39      * @see javax.jmdns.impl.tasks.DNSTask#getName()
     40      */
     41     @Override
     42     public String getName() {
     43         return "Prober(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
     44     }
     45 
     46     /*
     47      * (non-Javadoc)
     48      * @see java.lang.Object#toString()
     49      */
     50     @Override
     51     public String toString() {
     52         return super.toString() + " state: " + this.getTaskState();
     53     }
     54 
     55     /*
     56      * (non-Javadoc)
     57      * @see javax.jmdns.impl.tasks.DNSTask#start(java.util.Timer)
     58      */
     59     @Override
     60     public void start(Timer timer) {
     61         long now = System.currentTimeMillis();
     62         if (now - this.getDns().getLastThrottleIncrement() < DNSConstants.PROBE_THROTTLE_COUNT_INTERVAL) {
     63             this.getDns().setThrottle(this.getDns().getThrottle() + 1);
     64         } else {
     65             this.getDns().setThrottle(1);
     66         }
     67         this.getDns().setLastThrottleIncrement(now);
     68 
     69         if (this.getDns().isAnnounced() && this.getDns().getThrottle() < DNSConstants.PROBE_THROTTLE_COUNT) {
     70             timer.schedule(this, JmDNSImpl.getRandom().nextInt(1 + DNSConstants.PROBE_WAIT_INTERVAL), DNSConstants.PROBE_WAIT_INTERVAL);
     71         } else if (!this.getDns().isCanceling() && !this.getDns().isCanceled()) {
     72             timer.schedule(this, DNSConstants.PROBE_CONFLICT_INTERVAL, DNSConstants.PROBE_CONFLICT_INTERVAL);
     73         }
     74     }
     75 
     76     @Override
     77     public boolean cancel() {
     78         this.removeAssociation();
     79 
     80         return super.cancel();
     81     }
     82 
     83     /*
     84      * (non-Javadoc)
     85      * @see javax.jmdns.impl.tasks.state.DNSStateTask#getTaskDescription()
     86      */
     87     @Override
     88     public String getTaskDescription() {
     89         return "probing";
     90     }
     91 
     92     /*
     93      * (non-Javadoc)
     94      * @see javax.jmdns.impl.tasks.state.DNSStateTask#checkRunCondition()
     95      */
     96     @Override
     97     protected boolean checkRunCondition() {
     98         return !this.getDns().isCanceling() && !this.getDns().isCanceled();
     99     }
    100 
    101     /*
    102      * (non-Javadoc)
    103      * @see javax.jmdns.impl.tasks.state.DNSStateTask#createOugoing()
    104      */
    105     @Override
    106     protected DNSOutgoing createOugoing() {
    107         return new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
    108     }
    109 
    110     /*
    111      * (non-Javadoc)
    112      * @see javax.jmdns.impl.tasks.state.DNSStateTask#buildOutgoingForDNS(javax.jmdns.impl.DNSOutgoing)
    113      */
    114     @Override
    115     protected DNSOutgoing buildOutgoingForDNS(DNSOutgoing out) throws IOException {
    116         DNSOutgoing newOut = out;
    117         newOut.addQuestion(DNSQuestion.newQuestion(this.getDns().getLocalHost().getName(), DNSRecordType.TYPE_ANY, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
    118         for (DNSRecord answer : this.getDns().getLocalHost().answers(DNSRecordClass.NOT_UNIQUE, this.getTTL())) {
    119             newOut = this.addAuthoritativeAnswer(newOut, answer);
    120         }
    121         return newOut;
    122     }
    123 
    124     /*
    125      * (non-Javadoc)
    126      * @see javax.jmdns.impl.tasks.state.DNSStateTask#buildOutgoingForInfo(javax.jmdns.impl.ServiceInfoImpl, javax.jmdns.impl.DNSOutgoing)
    127      */
    128     @Override
    129     protected DNSOutgoing buildOutgoingForInfo(ServiceInfoImpl info, DNSOutgoing out) throws IOException {
    130         DNSOutgoing newOut = out;
    131         newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(info.getQualifiedName(), DNSRecordType.TYPE_ANY, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
    132         // the "unique" flag should be not set here because these answers haven't been proven unique yet this means the record will not exactly match the announcement record
    133         newOut = this.addAuthoritativeAnswer(newOut, new DNSRecord.Service(info.getQualifiedName(), DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, this.getTTL(), info.getPriority(), info.getWeight(), info.getPort(), this.getDns().getLocalHost()
    134                 .getName()));
    135         return newOut;
    136     }
    137 
    138     /*
    139      * (non-Javadoc)
    140      * @see javax.jmdns.impl.tasks.state.DNSStateTask#recoverTask(java.lang.Throwable)
    141      */
    142     @Override
    143     protected void recoverTask(Throwable e) {
    144         this.getDns().recover();
    145     }
    146 
    147     /*
    148      * (non-Javadoc)
    149      * @see javax.jmdns.impl.tasks.state.DNSStateTask#advanceTask()
    150      */
    151     @Override
    152     protected void advanceTask() {
    153         this.setTaskState(this.getTaskState().advance());
    154         if (!this.getTaskState().isProbing()) {
    155             cancel();
    156 
    157             this.getDns().startAnnouncer();
    158         }
    159     }
    160 
    161 }