1// Licensed under Apache License version 2.0
2package javax.jmdns.impl.tasks;
3
4import java.io.IOException;
5import java.util.Timer;
6import java.util.TimerTask;
7
8import javax.jmdns.impl.DNSIncoming;
9import javax.jmdns.impl.DNSOutgoing;
10import javax.jmdns.impl.DNSQuestion;
11import javax.jmdns.impl.DNSRecord;
12import javax.jmdns.impl.JmDNSImpl;
13import javax.jmdns.impl.constants.DNSConstants;
14
15/**
16 * This is the root class for all task scheduled by the timer in JmDNS.
17 *
18 * @author Pierre Frisch
19 */
20public abstract class DNSTask extends TimerTask {
21
22    /**
23     *
24     */
25    private final JmDNSImpl _jmDNSImpl;
26
27    /**
28     * @param jmDNSImpl
29     */
30    protected DNSTask(JmDNSImpl jmDNSImpl) {
31        super();
32        this._jmDNSImpl = jmDNSImpl;
33    }
34
35    /**
36     * Return the DNS associated with this task.
37     *
38     * @return associated DNS
39     */
40    public JmDNSImpl getDns() {
41        return _jmDNSImpl;
42    }
43
44    /**
45     * Start this task.
46     *
47     * @param timer
48     *            task timer.
49     */
50    public abstract void start(Timer timer);
51
52    /**
53     * Return this task name.
54     *
55     * @return task name
56     */
57    public abstract String getName();
58
59    /*
60     * (non-Javadoc)
61     * @see java.lang.Object#toString()
62     */
63    @Override
64    public String toString() {
65        return this.getName();
66    }
67
68    /**
69     * Add a question to the message.
70     *
71     * @param out
72     *            outgoing message
73     * @param rec
74     *            DNS question
75     * @return outgoing message for the next question
76     * @exception IOException
77     */
78    public DNSOutgoing addQuestion(DNSOutgoing out, DNSQuestion rec) throws IOException {
79        DNSOutgoing newOut = out;
80        try {
81            newOut.addQuestion(rec);
82        } catch (final IOException e) {
83            int flags = newOut.getFlags();
84            boolean multicast = newOut.isMulticast();
85            int maxUDPPayload = newOut.getMaxUDPPayload();
86            int id = newOut.getId();
87
88            newOut.setFlags(flags | DNSConstants.FLAGS_TC);
89            newOut.setId(id);
90            this._jmDNSImpl.send(newOut);
91
92            newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
93            newOut.addQuestion(rec);
94        }
95        return newOut;
96    }
97
98    /**
99     * Add an answer if it is not suppressed.
100     *
101     * @param out
102     *            outgoing message
103     * @param in
104     *            incoming request
105     * @param rec
106     *            DNS record answer
107     * @return outgoing message for the next answer
108     * @exception IOException
109     */
110    public DNSOutgoing addAnswer(DNSOutgoing out, DNSIncoming in, DNSRecord rec) throws IOException {
111        DNSOutgoing newOut = out;
112        try {
113            newOut.addAnswer(in, rec);
114        } catch (final IOException e) {
115            int flags = newOut.getFlags();
116            boolean multicast = newOut.isMulticast();
117            int maxUDPPayload = newOut.getMaxUDPPayload();
118            int id = newOut.getId();
119
120            newOut.setFlags(flags | DNSConstants.FLAGS_TC);
121            newOut.setId(id);
122            this._jmDNSImpl.send(newOut);
123
124            newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
125            newOut.addAnswer(in, rec);
126        }
127        return newOut;
128    }
129
130    /**
131     * Add an answer to the message.
132     *
133     * @param out
134     *            outgoing message
135     * @param rec
136     *            DNS record answer
137     * @param now
138     * @return outgoing message for the next answer
139     * @exception IOException
140     */
141    public DNSOutgoing addAnswer(DNSOutgoing out, DNSRecord rec, long now) throws IOException {
142        DNSOutgoing newOut = out;
143        try {
144            newOut.addAnswer(rec, now);
145        } catch (final IOException e) {
146            int flags = newOut.getFlags();
147            boolean multicast = newOut.isMulticast();
148            int maxUDPPayload = newOut.getMaxUDPPayload();
149            int id = newOut.getId();
150
151            newOut.setFlags(flags | DNSConstants.FLAGS_TC);
152            newOut.setId(id);
153            this._jmDNSImpl.send(newOut);
154
155            newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
156            newOut.addAnswer(rec, now);
157        }
158        return newOut;
159    }
160
161    /**
162     * Add an authoritative answer to the message.
163     *
164     * @param out
165     *            outgoing message
166     * @param rec
167     *            DNS record answer
168     * @return outgoing message for the next answer
169     * @exception IOException
170     */
171    public DNSOutgoing addAuthoritativeAnswer(DNSOutgoing out, DNSRecord rec) throws IOException {
172        DNSOutgoing newOut = out;
173        try {
174            newOut.addAuthorativeAnswer(rec);
175        } catch (final IOException e) {
176            int flags = newOut.getFlags();
177            boolean multicast = newOut.isMulticast();
178            int maxUDPPayload = newOut.getMaxUDPPayload();
179            int id = newOut.getId();
180
181            newOut.setFlags(flags | DNSConstants.FLAGS_TC);
182            newOut.setId(id);
183            this._jmDNSImpl.send(newOut);
184
185            newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
186            newOut.addAuthorativeAnswer(rec);
187        }
188        return newOut;
189    }
190
191    /**
192     * Add an additional answer to the record. Omit if there is no room.
193     *
194     * @param out
195     *            outgoing message
196     * @param in
197     *            incoming request
198     * @param rec
199     *            DNS record answer
200     * @return outgoing message for the next answer
201     * @exception IOException
202     */
203    public DNSOutgoing addAdditionalAnswer(DNSOutgoing out, DNSIncoming in, DNSRecord rec) throws IOException {
204        DNSOutgoing newOut = out;
205        try {
206            newOut.addAdditionalAnswer(in, rec);
207        } catch (final IOException e) {
208            int flags = newOut.getFlags();
209            boolean multicast = newOut.isMulticast();
210            int maxUDPPayload = newOut.getMaxUDPPayload();
211            int id = newOut.getId();
212
213            newOut.setFlags(flags | DNSConstants.FLAGS_TC);
214            newOut.setId(id);
215            this._jmDNSImpl.send(newOut);
216
217            newOut = new DNSOutgoing(flags, multicast, maxUDPPayload);
218            newOut.addAdditionalAnswer(in, rec);
219        }
220        return newOut;
221    }
222
223}
224