001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020
021package org.apache.directory.server.dns.messages;
022
023
024import java.util.List;
025
026import org.apache.commons.lang3.builder.EqualsBuilder;
027import org.apache.commons.lang3.builder.HashCodeBuilder;
028import org.apache.commons.lang3.builder.ToStringBuilder;
029
030
031/**
032 * All communications inside of the domain protocol are carried in a single
033 * format called a message.  The top level format of message is divided
034 * into 5 sections (some of which are empty in certain cases) shown below:
035 *
036 *     +---------------------+
037 *     |        Header       |
038 *     +---------------------+
039 *     |       Question      | the question for the name server
040 *     +---------------------+
041 *     |        Answer       | ResourceRecords answering the question
042 *     +---------------------+
043 *     |      Authority      | ResourceRecords pointing toward an authority
044 *     +---------------------+
045 *     |      Additional     | ResourceRecords holding additional information
046 *     +---------------------+
047 *
048 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
049 */
050public class DnsMessage
051{
052    /**
053     * The header section is always present.  The header includes fields that
054     * specify which of the remaining sections are present, and also specify
055     * whether the message is a query or a response, a standard query or some
056     * other opcode, etc.
057     */
058    private int transactionId;
059    private MessageType messageType;
060    private OpCode opCode;
061    private boolean authoritativeAnswer;
062    private boolean truncated;
063    private boolean recursionDesired;
064    private boolean recursionAvailable;
065    private boolean reserved;
066    private boolean acceptNonAuthenticatedData;
067
068    private ResponseCode responseCode;
069
070    private List<QuestionRecord> questionRecords;
071    private List<ResourceRecord> answerRecords;
072    private List<ResourceRecord> authorityRecords;
073    private List<ResourceRecord> additionalRecords;
074
075
076    /**
077     * Creates a new instance of DnsMessage.
078     *
079     * @param transactionId
080     * @param messageType
081     * @param opCode
082     * @param authoritativeAnswer
083     * @param truncated
084     * @param recursionDesired
085     * @param recursionAvailable
086     * @param reserved
087     * @param acceptNonAuthenticatedData
088     * @param responseCode
089     * @param question
090     * @param answer
091     * @param authority
092     * @param additional
093     */
094    public DnsMessage( int transactionId, MessageType messageType, OpCode opCode, boolean authoritativeAnswer,
095        boolean truncated, boolean recursionDesired, boolean recursionAvailable, boolean reserved,
096        boolean acceptNonAuthenticatedData, ResponseCode responseCode, List<QuestionRecord> question,
097        List<ResourceRecord> answer, List<ResourceRecord> authority, List<ResourceRecord> additional )
098    {
099        this.transactionId = transactionId;
100        this.messageType = messageType;
101        this.opCode = opCode;
102        this.authoritativeAnswer = authoritativeAnswer;
103        this.truncated = truncated;
104        this.recursionDesired = recursionDesired;
105        this.recursionAvailable = recursionAvailable;
106        this.reserved = reserved;
107        this.acceptNonAuthenticatedData = acceptNonAuthenticatedData;
108        this.responseCode = responseCode;
109        this.questionRecords = question;
110        this.answerRecords = answer;
111        this.authorityRecords = authority;
112        this.additionalRecords = additional;
113    }
114
115
116    /**
117     * @return Returns the acceptNonAuthenticatedData.
118     */
119    public boolean isAcceptNonAuthenticatedData()
120    {
121        return acceptNonAuthenticatedData;
122    }
123
124
125    /**
126     * @return Returns the additional.
127     */
128    public List<ResourceRecord> getAdditionalRecords()
129    {
130        return additionalRecords;
131    }
132
133
134    /**
135     * @return Returns the answers.
136     */
137    public List<ResourceRecord> getAnswerRecords()
138    {
139        return answerRecords;
140    }
141
142
143    /**
144     * @return Returns the authoritativeAnswer.
145     */
146    public boolean isAuthoritativeAnswer()
147    {
148        return authoritativeAnswer;
149    }
150
151
152    /**
153     * @return Returns the authority.
154     */
155    public List<ResourceRecord> getAuthorityRecords()
156    {
157        return authorityRecords;
158    }
159
160
161    /**
162     * @return Returns the messageType.
163     */
164    public MessageType getMessageType()
165    {
166        return messageType;
167    }
168
169
170    /**
171     * @return Returns the opCode.
172     */
173    public OpCode getOpCode()
174    {
175        return opCode;
176    }
177
178
179    /**
180     * @return Returns the question.
181     */
182    public List<QuestionRecord> getQuestionRecords()
183    {
184        return questionRecords;
185    }
186
187
188    /**
189     * @return Returns the recursionAvailable.
190     */
191    public boolean isRecursionAvailable()
192    {
193        return recursionAvailable;
194    }
195
196
197    /**
198     * @return Returns the recursionDesired.
199     */
200    public boolean isRecursionDesired()
201    {
202        return recursionDesired;
203    }
204
205
206    /**
207     * @return Returns the reserved.
208     */
209    public boolean isReserved()
210    {
211        return reserved;
212    }
213
214
215    /**
216     * @return Returns the responseCode.
217     */
218    public ResponseCode getResponseCode()
219    {
220        return responseCode;
221    }
222
223
224    /**
225     * @return Returns the transactionId.
226     */
227    public int getTransactionId()
228    {
229        return transactionId;
230    }
231
232
233    /**
234     * @return Returns the truncated.
235     */
236    public boolean isTruncated()
237    {
238        return truncated;
239    }
240
241
242    /**
243     * @see java.lang.Object#equals(Object)
244     */
245    @Override
246    public boolean equals( Object object )
247    {
248        if ( object == this )
249        {
250            return true;
251        }
252        if ( !( object instanceof DnsMessage ) )
253        {
254            return false;
255        }
256        DnsMessage rhs = ( DnsMessage ) object;
257        return new EqualsBuilder().append( this.transactionId, rhs.transactionId ).append( this.answerRecords,
258            rhs.answerRecords ).append( this.opCode, rhs.opCode ).append( this.recursionAvailable,
259            rhs.recursionAvailable ).append( this.messageType, rhs.messageType ).append( this.additionalRecords,
260            rhs.additionalRecords ).append( this.truncated, rhs.truncated ).append( this.recursionDesired,
261            rhs.recursionDesired ).append( this.responseCode, rhs.responseCode ).append( this.authorityRecords,
262            rhs.authorityRecords ).append( this.authoritativeAnswer, rhs.authoritativeAnswer ).append( this.reserved,
263            rhs.reserved ).append( this.acceptNonAuthenticatedData, rhs.acceptNonAuthenticatedData ).append(
264            this.questionRecords, rhs.questionRecords ).isEquals();
265    }
266
267
268    /**
269     * @see java.lang.Object#hashCode()
270     * @return the instance's hash code
271     */
272    @Override
273    public int hashCode()
274    {
275        return new HashCodeBuilder( -1805208585, -276770303 ).append( this.transactionId ).append( this.answerRecords )
276            .append( this.opCode ).append( this.recursionAvailable ).append( this.messageType ).append(
277                this.additionalRecords ).append( this.truncated ).append( this.recursionDesired ).append(
278                this.responseCode ).append( this.authorityRecords ).append( this.authoritativeAnswer ).append(
279                this.reserved ).append( this.acceptNonAuthenticatedData ).append( this.questionRecords ).toHashCode();
280    }
281
282
283    /**
284     * @see java.lang.Object#toString()
285     */
286    @Override
287    public String toString()
288    {
289        return new ToStringBuilder( this ).appendSuper( super.toString() ).append( "transactionId", this.transactionId )
290            .append( "opCode", this.opCode ).append( "truncated", this.truncated ).append( "messageType",
291                this.messageType ).append( "recursionDesired", this.recursionDesired ).append( "additionalRecords",
292                this.additionalRecords ).append( "responseCode", this.responseCode ).append( "authorityRecords",
293                this.authorityRecords ).append( "acceptNonAuthenticatedData", this.acceptNonAuthenticatedData ).append(
294                "recursionAvailable", this.recursionAvailable ).append( "answerRecords", this.answerRecords ).append(
295                "questionRecords", this.questionRecords ).append( "authoritativeAnswer", this.authoritativeAnswer )
296            .append( "reserved", this.reserved ).toString();
297    }
298}