Clover Coverage Report - JmDNS 3.4.1
Coverage timestamp: Thu Aug 25 2011 13:06:33 CEST
../../../../img/srcFileCovDistChart7.png 18% of files have more coverage
51   157   25   10.2
34   101   0.49   5
5     5  
1    
 
  Responder       Line # 23 51 0% 25 32 64.4% 0.64444447
 
  (19)
 
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;
6   
7    import java.util.HashSet;
8    import java.util.Set;
9    import java.util.Timer;
10    import java.util.logging.Level;
11    import java.util.logging.Logger;
12   
13    import javax.jmdns.impl.DNSIncoming;
14    import javax.jmdns.impl.DNSOutgoing;
15    import javax.jmdns.impl.DNSQuestion;
16    import javax.jmdns.impl.DNSRecord;
17    import javax.jmdns.impl.JmDNSImpl;
18    import javax.jmdns.impl.constants.DNSConstants;
19   
20    /**
21    * The Responder sends a single answer for the specified service infos and for the host name.
22    */
 
23    public class Responder extends DNSTask {
24    static Logger logger = Logger.getLogger(Responder.class.getName());
25   
26    /**
27    *
28    */
29    private final DNSIncoming _in;
30   
31    /**
32    *
33    */
34    private final boolean _unicast;
35   
 
36  340 toggle public Responder(JmDNSImpl jmDNSImpl, DNSIncoming in, int port) {
37  323 super(jmDNSImpl);
38  341 this._in = in;
39  324 this._unicast = (port != DNSConstants.MDNS_PORT);
40    }
41   
42    /*
43    * (non-Javadoc)
44    * @see javax.jmdns.impl.tasks.DNSTask#getName()
45    */
 
46  0 toggle @Override
47    public String getName() {
48  0 return "Responder(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
49    }
50   
51    /*
52    * (non-Javadoc)
53    * @see java.lang.Object#toString()
54    */
 
55  0 toggle @Override
56    public String toString() {
57  0 return super.toString() + " incomming: " + _in;
58    }
59   
60    /*
61    * (non-Javadoc)
62    * @see javax.jmdns.impl.tasks.DNSTask#start(java.util.Timer)
63    */
 
64  330 toggle @Override
65    public void start(Timer timer) {
66    // According to draft-cheshire-dnsext-multicastdns.txt chapter "7 Responding":
67    // We respond immediately if we know for sure, that we are the only one who can respond to the query.
68    // In all other cases, we respond within 20-120 ms.
69    //
70    // According to draft-cheshire-dnsext-multicastdns.txt chapter "6.2 Multi-Packet Known Answer Suppression":
71    // We respond after 20-120 ms if the query is truncated.
72   
73  339 boolean iAmTheOnlyOne = true;
74  333 for (DNSQuestion question : _in.getQuestions()) {
75  339 if (logger.isLoggable(Level.FINEST)) {
76  0 logger.finest(this.getName() + "start() question=" + question);
77    }
78  335 iAmTheOnlyOne = question.iAmTheOnlyOne(this.getDns());
79  341 if (!iAmTheOnlyOne) {
80  155 break;
81    }
82    }
83  341 int delay = (iAmTheOnlyOne && !_in.isTruncated()) ? 0 : DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + JmDNSImpl.getRandom().nextInt(DNSConstants.RESPONSE_MAX_WAIT_INTERVAL - DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + 1) - _in.elapseSinceArrival();
84  340 if (delay < 0) {
85  0 delay = 0;
86    }
87  346 if (logger.isLoggable(Level.FINEST)) {
88  0 logger.finest(this.getName() + "start() Responder chosen delay=" + delay);
89    }
90  345 if (!this.getDns().isCanceling() && !this.getDns().isCanceled()) {
91  344 timer.schedule(this, delay);
92    }
93    }
94   
 
95  348 toggle @Override
96    public void run() {
97  349 this.getDns().respondToQuery(_in);
98   
99    // We use these sets to prevent duplicate records
100  348 Set<DNSQuestion> questions = new HashSet<DNSQuestion>();
101  349 Set<DNSRecord> answers = new HashSet<DNSRecord>();
102   
103  350 if (this.getDns().isAnnounced()) {
104  139 try {
105    // Answer questions
106  139 for (DNSQuestion question : _in.getQuestions()) {
107  143 if (logger.isLoggable(Level.FINER)) {
108  0 logger.finer(this.getName() + "run() JmDNS responding to: " + question);
109    }
110    // for unicast responses the question must be included
111  143 if (_unicast) {
112    // out.addQuestion(q);
113  0 questions.add(question);
114    }
115   
116  143 question.addAnswers(this.getDns(), answers);
117    }
118   
119    // remove known answers, if the ttl is at least half of the correct value. (See Draft Cheshire chapter 7.1.).
120  139 long now = System.currentTimeMillis();
121  139 for (DNSRecord knownAnswer : _in.getAnswers()) {
122  18 if (knownAnswer.isStale(now)) {
123  0 answers.remove(knownAnswer);
124  0 if (logger.isLoggable(Level.FINER)) {
125  0 logger.finer(this.getName() + "JmDNS Responder Known Answer Removed");
126    }
127    }
128    }
129   
130    // respond if we have answers
131  139 if (!answers.isEmpty()) {
132  33 if (logger.isLoggable(Level.FINER)) {
133  0 logger.finer(this.getName() + "run() JmDNS responding");
134    }
135  33 DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, !_unicast, _in.getSenderUDPPayload());
136  33 out.setId(_in.getId());
137  33 for (DNSQuestion question : questions) {
138  0 if (question != null) {
139  0 out = this.addQuestion(out, question);
140    }
141    }
142  33 for (DNSRecord answer : answers) {
143  123 if (answer != null) {
144  123 out = this.addAnswer(out, _in, answer);
145   
146    }
147    }
148  30 if (!out.isEmpty()) this.getDns().send(out);
149    }
150    // this.cancel();
151    } catch (Throwable e) {
152  0 logger.log(Level.WARNING, this.getName() + "run() exception ", e);
153  0 this.getDns().close();
154    }
155    }
156    }
157    }