View Javadoc
1   /*
2    * Copyright 2019 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.dns;
17  
18  import io.netty.buffer.ByteBuf;
19  
20  import static io.netty.util.internal.ObjectUtil.checkNotNull;
21  
22  final class DnsQueryEncoder {
23  
24      private final DnsRecordEncoder recordEncoder;
25  
26      /**
27       * Creates a new encoder with the specified {@code recordEncoder}.
28       */
29      DnsQueryEncoder(DnsRecordEncoder recordEncoder) {
30          this.recordEncoder = checkNotNull(recordEncoder, "recordEncoder");
31      }
32  
33      /**
34       * Encodes the given {@link DnsQuery} into a {@link ByteBuf}.
35       */
36      void encode(DnsQuery query, ByteBuf out) throws Exception {
37          encodeHeader(query, out);
38          encodeQuestions(query, out);
39          encodeRecords(query, DnsSection.ADDITIONAL, out);
40      }
41  
42      /**
43       * Encodes the header that is always 12 bytes long.
44       *
45       * @param query the query header being encoded
46       * @param buf   the buffer the encoded data should be written to
47       */
48      private static void encodeHeader(DnsQuery query, ByteBuf buf) {
49          buf.writeShort(query.id());
50          int flags = 0;
51          flags |= (query.opCode().byteValue() & 0xFF) << 14;
52          if (query.isRecursionDesired()) {
53              flags |= 1 << 8;
54          }
55          buf.writeShort(flags);
56          buf.writeShort(query.count(DnsSection.QUESTION));
57          buf.writeShort(0); // answerCount
58          buf.writeShort(0); // authorityResourceCount
59          buf.writeShort(query.count(DnsSection.ADDITIONAL));
60      }
61  
62      private void encodeQuestions(DnsQuery query, ByteBuf buf) throws Exception {
63          final int count = query.count(DnsSection.QUESTION);
64          for (int i = 0; i < count; i++) {
65              recordEncoder.encodeQuestion((DnsQuestion) query.recordAt(DnsSection.QUESTION, i), buf);
66          }
67      }
68  
69      private void encodeRecords(DnsQuery query, DnsSection section, ByteBuf buf) throws Exception {
70          final int count = query.count(section);
71          for (int i = 0; i < count; i++) {
72              recordEncoder.encodeRecord(query.recordAt(section, i), buf);
73          }
74      }
75  }