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.netty5.handler.codec.dns;
17  
18  import io.netty5.buffer.api.Buffer;
19  
20  import java.util.Objects;
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 = Objects.requireNonNull(recordEncoder, "recordEncoder");
31      }
32  
33      /**
34       * Encodes the given {@link DnsQuery} into a {@link Buffer}.
35       */
36      void encode(DnsQuery query, Buffer 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, Buffer buf) {
49          buf.ensureWritable(12);
50          buf.writeShort((short) query.id());
51          short flags = 0;
52          flags |= (query.opCode().byteValue() & 0xFF) << 14;
53          if (query.isRecursionDesired()) {
54              flags |= 1 << 8;
55          }
56          buf.writeShort(flags);
57          buf.writeShort((short) query.count(DnsSection.QUESTION));
58          buf.writeShort((short) 0); // answerCount
59          buf.writeShort((short) 0); // authorityResourceCount
60          buf.writeShort((short) query.count(DnsSection.ADDITIONAL));
61      }
62  
63      private void encodeQuestions(DnsQuery query, Buffer buf) throws Exception {
64          final int count = query.count(DnsSection.QUESTION);
65          for (int i = 0; i < count; i++) {
66              recordEncoder.encodeQuestion(query.recordAt(DnsSection.QUESTION, i), buf);
67          }
68      }
69  
70      private void encodeRecords(DnsQuery query, DnsSection section, Buffer buf) throws Exception {
71          final int count = query.count(section);
72          for (int i = 0; i < count; i++) {
73              recordEncoder.encodeRecord(query.recordAt(section, i), buf);
74          }
75      }
76  }