View Javadoc
1   /*
2    * Copyright 2018 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.resolver.dns;
17  
18  import io.netty5.buffer.api.Buffer;
19  import io.netty5.handler.codec.dns.DnsRawRecord;
20  import io.netty5.handler.codec.dns.DnsRecord;
21  
22  import java.net.IDN;
23  import java.net.InetAddress;
24  import java.net.UnknownHostException;
25  
26  /**
27   * Decodes an {@link InetAddress} from an A or AAAA {@link DnsRawRecord}.
28   */
29  final class DnsAddressDecoder {
30  
31      private static final int INADDRSZ4 = 4;
32      private static final int INADDRSZ6 = 16;
33  
34      /**
35       * Decodes an {@link InetAddress} from an A or AAAA {@link DnsRawRecord}.
36       *
37       * @param record the {@link DnsRecord}, most likely a {@link DnsRawRecord}
38       * @param name the host name of the decoded address
39       * @param decodeIdn whether to convert {@code name} to a unicode host name
40       *
41       * @return the {@link InetAddress}, or {@code null} if {@code record} is not a {@link DnsRawRecord} or
42       *         its content is malformed
43       */
44      static InetAddress decodeAddress(DnsRecord record, String name, boolean decodeIdn) {
45          if (!(record instanceof DnsRawRecord)) {
46              return null;
47          }
48          final Buffer content = ((DnsRawRecord) record).content();
49          final int contentLen = content.readableBytes();
50          if (contentLen != INADDRSZ4 && contentLen != INADDRSZ6) {
51              return null;
52          }
53  
54          final byte[] addrBytes = new byte[contentLen];
55          content.copyInto(content.readerOffset(), addrBytes, 0, addrBytes.length);
56  
57          try {
58              return InetAddress.getByAddress(decodeIdn ? IDN.toUnicode(name) : name, addrBytes);
59          } catch (UnknownHostException e) {
60              // Should never reach here.
61              throw new Error(e);
62          }
63      }
64  
65      private DnsAddressDecoder() { }
66  }