src/jdk.dns.client/share/classes/jdk/dns/client/internal/DnsClient.java
author aefimov
Thu, 14 Nov 2019 23:16:40 +0000
branchaefimov-dns-client-branch
changeset 59101 258033faefc9
parent 58971 465a15dd6bed
permissions -rw-r--r--
aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
     1
/*
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
     2
 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
     4
 *
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    10
 *
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    15
 * accompanied this code).
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    16
 *
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    20
 *
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    23
 * questions.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    24
 */
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    25
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    26
package jdk.dns.client.internal;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    27
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    28
import jdk.dns.client.ex.DnsCommunicationException;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    29
import jdk.dns.client.ex.DnsNameNotFoundException;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    30
import jdk.dns.client.ex.DnsResolverException;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    31
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
    32
import java.io.BufferedInputStream;
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
    33
import java.io.BufferedOutputStream;
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    34
import java.io.IOException;
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
    35
import java.io.InputStream;
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
    36
import java.io.OutputStream;
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    37
import java.net.DatagramPacket;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    38
import java.net.InetAddress;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    39
import java.net.InetSocketAddress;
59101
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
    40
import java.net.PortUnreachableException;
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    41
import java.net.Socket;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    42
import java.net.SocketTimeoutException;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    43
import java.net.UnknownHostException;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    44
import java.nio.channels.DatagramChannel;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    45
import java.security.AccessController;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    46
import java.security.PrivilegedAction;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    47
import java.security.SecureRandom;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    48
import java.util.ArrayList;
59101
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
    49
import java.util.Arrays;
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    50
import java.util.Collections;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    51
import java.util.HashMap;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    52
import java.util.List;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    53
import java.util.Map;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    54
import java.util.concurrent.locks.ReentrantLock;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    55
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    56
import sun.net.util.IPAddressUtil;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    57
import sun.security.jca.JCAUtil;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    58
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    59
// Some of this code began life as part of sun.javaos.net.DnsClient
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    60
// originally by sritchie@eng 1/96.  It was first hacked up for JNDI
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    61
// use by caveh@eng 6/97.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    62
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    63
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    64
/**
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    65
 * The DnsClient class performs DNS client operations in support of DnsContext.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    66
 */
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    67
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    68
public class DnsClient {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    69
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    70
    // DNS packet header field offsets
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    71
    private static final int IDENT_OFFSET = 0;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    72
    private static final int FLAGS_OFFSET = 2;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    73
    private static final int NUMQ_OFFSET = 4;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    74
    private static final int NUMANS_OFFSET = 6;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    75
    private static final int NUMAUTH_OFFSET = 8;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    76
    private static final int NUMADD_OFFSET = 10;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    77
    private static final int DNS_HDR_SIZE = 12;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    78
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    79
    // DNS response codes
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    80
    private static final int NO_ERROR = 0;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    81
    private static final int FORMAT_ERROR = 1;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    82
    private static final int SERVER_FAILURE = 2;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    83
    private static final int NAME_ERROR = 3;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    84
    private static final int NOT_IMPL = 4;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    85
    private static final int REFUSED = 5;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    86
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    87
    private static final String[] rcodeDescription = {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    88
            "No error",
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    89
            "DNS format error",
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    90
            "DNS server failure",
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    91
            "DNS name not found",
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    92
            "DNS operation not supported",
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    93
            "DNS service refused"
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    94
    };
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    95
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    96
    private static final int DEFAULT_PORT = 53;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    97
    private static final int TRANSACTION_ID_BOUND = 0x10000;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    98
    private List<InetAddress> servers;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
    99
    private List<Integer> serverPorts;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   100
    private int timeout;                // initial timeout on UDP and TCP queries in ms
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   101
    private int retries;                // number of UDP retries
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   102
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   103
    private static final SecureRandom random;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   104
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   105
    static {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   106
        var pa = (PrivilegedAction<SecureRandom>) () -> JCAUtil.getSecureRandom();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   107
        random = System.getSecurityManager() == null ? pa.run()
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   108
                : AccessController.doPrivileged(pa);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   109
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   110
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   111
    private static final DnsDatagramChannelFactory factory =
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   112
            new DnsDatagramChannelFactory(random);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   113
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   114
    // Requests sent
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   115
    private Map<Integer, ResourceRecord> reqs;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   116
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   117
    // Responses received
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   118
    private Map<Integer, byte[]> resps;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   119
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   120
    //-------------------------------------------------------------------------
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   121
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   122
    /*
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   123
     * Each server is of the form "server[:port]".  IPv6 literal host names
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   124
     * include delimiting brackets.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   125
     * "timeout" is the initial timeout interval (in ms) for queries,
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   126
     * and "retries" gives the number of retries per server.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   127
     */
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   128
    public DnsClient(List<String> servers, int timeout, int retries) {
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   129
        this.timeout = timeout;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   130
        this.retries = retries;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   131
        var serversList = new ArrayList<InetAddress>();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   132
        var serverPortsList = new ArrayList<Integer>();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   133
59101
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   134
        if (DEBUG) {
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   135
            System.err.println("DNS Client: servers list:" + servers);
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   136
        }
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   137
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   138
        for (String serverString : servers) {
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   139
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   140
            // Is optional port given?
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   141
            int colon = serverString.indexOf(':',
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   142
                    serverString.indexOf(']') + 1);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   143
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   144
            int serverPort = (colon < 0) ? DEFAULT_PORT
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   145
                    : Integer.parseInt(serverString.substring(colon + 1));
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   146
            String server = (colon < 0)
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   147
                    ? serverString
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   148
                    : serverString.substring(0, colon);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   149
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   150
            var pa = (PrivilegedAction<byte[]>) () -> {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   151
                if (IPAddressUtil.isIPv4LiteralAddress(server)) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   152
                    return IPAddressUtil.textToNumericFormatV4(server);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   153
                } else if (IPAddressUtil.isIPv6LiteralAddress(server)) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   154
                    return IPAddressUtil.textToNumericFormatV6(server);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   155
                }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   156
                return null;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   157
            };
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   158
            byte[] addr = System.getSecurityManager() == null ?
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   159
                    pa.run() : AccessController.doPrivileged(pa);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   160
            if (addr != null) {
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   161
                try {
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   162
                    serversList.add(InetAddress.getByAddress(server, addr));
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   163
                    serverPortsList.add(serverPort);
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   164
                } catch (UnknownHostException e) {
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   165
                    // Malformed IP address is specified - will ignore it
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   166
                }
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   167
            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   168
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   169
        this.servers = Collections.unmodifiableList(serversList);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   170
        this.serverPorts = Collections.unmodifiableList(serverPortsList);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   171
        reqs = Collections.synchronizedMap(
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   172
                new HashMap<>());
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   173
        resps = Collections.synchronizedMap(new HashMap<>());
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   174
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   175
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   176
    DatagramChannel getDatagramChannel() throws DnsResolverException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   177
        try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   178
            return factory.open();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   179
        } catch (java.net.SocketException e) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   180
            throw new DnsResolverException("Can't create datagram channel", e);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   181
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   182
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   183
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   184
    @SuppressWarnings("deprecation")
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   185
    protected void finalize() {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   186
        close();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   187
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   188
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   189
    // A lock to access the request and response queues in tandem.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   190
    private ReentrantLock queuesLock = new ReentrantLock();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   191
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   192
    public void close() {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   193
        queuesLock.lock();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   194
        try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   195
            reqs.clear();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   196
            resps.clear();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   197
        } finally {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   198
            queuesLock.unlock();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   199
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   200
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   201
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   202
    /*
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   203
     * If recursion is true, recursion is requested on the query.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   204
     * If auth is true, only authoritative responses are accepted; other
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   205
     * responses throw NameNotFoundException.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   206
     */
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   207
    ResourceRecords query(DnsName fqdn, int qclass, int qtype,
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   208
                          boolean recursion, boolean auth)
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   209
            throws DnsResolverException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   210
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   211
        int xid;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   212
        Packet pkt;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   213
        ResourceRecord collision;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   214
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   215
        do {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   216
            // Generate a random transaction ID
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   217
            xid = random.nextInt(TRANSACTION_ID_BOUND);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   218
            pkt = makeQueryPacket(fqdn, xid, qclass, qtype, recursion);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   219
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   220
            // enqueue the outstanding request
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   221
            collision = reqs.putIfAbsent(xid, new ResourceRecord(pkt.getData(),
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   222
                    pkt.length(), Header.HEADER_SIZE, true, false));
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   223
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   224
        } while (collision != null);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   225
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   226
        Exception caughtException = null;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   227
        boolean[] doNotRetry = new boolean[servers.size()];
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   228
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   229
        try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   230
            //
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   231
            // The UDP retry strategy is to try the 1st server, and then
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   232
            // each server in order. If no answer, double the timeout
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   233
            // and try each server again.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   234
            //
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   235
            for (int retry = 0; retry < retries; retry++) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   236
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   237
                // Try each name server.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   238
                for (int i = 0; i < servers.size(); i++) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   239
                    if (doNotRetry[i]) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   240
                        continue;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   241
                    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   242
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   243
                    // send the request packet and wait for a response.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   244
                    try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   245
                        if (DEBUG) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   246
                            dprint("SEND ID (" + (retry + 1) + "): " + xid);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   247
                        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   248
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   249
                        byte[] msg = doUdpQuery(pkt, servers.get(i), serverPorts.get(i), retry, xid);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   250
                        //
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   251
                        // If the matching response is not got within the
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   252
                        // given timeout, check if the response was enqueued
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   253
                        // by some other thread, if not proceed with the next
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   254
                        // server or retry.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   255
                        //
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   256
                        if (msg == null) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   257
                            if (resps.size() > 0) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   258
                                msg = lookupResponse(xid);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   259
                            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   260
                            if (msg == null) { // try next server or retry
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   261
                                continue;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   262
                            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   263
                        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   264
                        Header hdr = new Header(msg, msg.length);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   265
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   266
                        if (auth && !hdr.authoritative) {
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   267
                            caughtException = new DnsResolverException("DNS response not authoritative");
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   268
                            doNotRetry[i] = true;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   269
                            continue;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   270
                        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   271
                        if (hdr.truncated) {  // message is truncated -- try TCP
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   272
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   273
                            // Try each server, starting with the one that just
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   274
                            // provided the truncated message.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   275
                            int retryTimeout = (timeout * (1 << retry));
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   276
                            for (int j = 0; j < servers.size(); j++) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   277
                                int ij = (i + j) % servers.size();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   278
                                if (doNotRetry[ij]) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   279
                                    continue;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   280
                                }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   281
                                try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   282
                                    Tcp tcp =
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   283
                                            new Tcp(servers.get(ij), serverPorts.get(ij), retryTimeout);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   284
                                    byte[] msg2;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   285
                                    try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   286
                                        msg2 = doTcpQuery(tcp, pkt);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   287
                                    } finally {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   288
                                        tcp.close();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   289
                                    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   290
                                    Header hdr2 = new Header(msg2, msg2.length);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   291
                                    if (hdr2.query) {
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   292
                                        throw new DnsResolverException(
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   293
                                                "DNS error: expecting response");
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   294
                                    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   295
                                    checkResponseCode(hdr2);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   296
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   297
                                    if (!auth || hdr2.authoritative) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   298
                                        // Got a valid response
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   299
                                        hdr = hdr2;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   300
                                        msg = msg2;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   301
                                        break;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   302
                                    } else {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   303
                                        doNotRetry[ij] = true;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   304
                                    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   305
                                } catch (Exception e) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   306
                                    // Try next server, or use UDP response
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   307
                                }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   308
                            } // servers
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   309
                        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   310
                        return new ResourceRecords(msg, msg.length, hdr, false);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   311
59101
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   312
                    } catch (PortUnreachableException e) {
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   313
                        if (caughtException == null) {
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   314
                            caughtException = e;
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   315
                        }
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   316
                        doNotRetry[i] = true;
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   317
                    } catch (IOException e) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   318
                        if (DEBUG) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   319
                            dprint("Caught IOException:" + e);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   320
                        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   321
                        if (caughtException == null) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   322
                            caughtException = e;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   323
                        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   324
                    } catch (DnsNameNotFoundException e) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   325
                        // This is authoritative, so return immediately
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   326
                        throw e;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   327
                    } catch (DnsCommunicationException e) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   328
                        if (caughtException == null) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   329
                            caughtException = e;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   330
                        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   331
                    } catch (DnsResolverException e) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   332
                        if (caughtException == null) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   333
                            caughtException = e;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   334
                        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   335
                        doNotRetry[i] = true;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   336
                    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   337
                } // servers
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   338
            } // retries
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   339
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   340
        } finally {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   341
            reqs.remove(xid); // cleanup
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   342
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   343
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   344
        if (caughtException instanceof DnsResolverException) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   345
            throw (DnsResolverException) caughtException;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   346
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   347
        // A network timeout or other error occurred.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   348
        throw new DnsResolverException("DNS error", caughtException);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   349
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   350
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   351
    /**
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   352
     * Tries to retrieve a UDP packet matching the given xid
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   353
     * received within the timeout.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   354
     * If a packet with different xid is received, the received packet
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   355
     * is enqueued with the corresponding xid in 'resps'.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   356
     */
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   357
    private byte[] doUdpQuery(Packet pkt, InetAddress server,
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   358
                              int port, int retry, int xid)
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   359
            throws IOException, DnsResolverException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   360
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   361
        int minTimeout = 50; // msec after which there are no retries.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   362
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   363
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   364
        try (DatagramChannel dc = getDatagramChannel()) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   365
            DatagramPacket opkt = new DatagramPacket(pkt.getData(), pkt.length(), server, port);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   366
            DatagramPacket ipkt = new DatagramPacket(new byte[8000], 8000);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   367
            // Packets may only be sent to or received from this server address
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   368
            // TODO: Revisit
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   369
            var pa = (PrivilegedAction<Void>) () -> {
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   370
                dc.socket().connect(server, port);
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   371
                return null;
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   372
            };
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   373
            if (System.getSecurityManager() == null) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   374
                pa.run();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   375
            } else {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   376
                AccessController.doPrivileged(pa);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   377
            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   378
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   379
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   380
            int pktTimeout = (timeout * (1 << retry));
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   381
            try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   382
                dc.socket().send(opkt);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   383
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   384
                // timeout remaining after successive 'receive()'
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   385
                int timeoutLeft = pktTimeout;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   386
                int cnt = 0;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   387
                do {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   388
                    if (DEBUG) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   389
                        cnt++;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   390
                        dprint("Trying RECEIVE(" +
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   391
                                cnt + ") retry(" + (retry + 1) +
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   392
                                ") for:" + xid + "    sock-timeout:" +
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   393
                                timeoutLeft + " ms.");
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   394
                    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   395
                    dc.socket().setSoTimeout(timeoutLeft);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   396
                    long start = System.currentTimeMillis();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   397
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   398
59101
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   399
                    dc.socket().receive(ipkt);
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   400
                    byte[] data = ipkt.getData();
59101
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   401
                    int length = ipkt.getLength();
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   402
                    long end = System.currentTimeMillis();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   403
59101
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   404
                    if (isMatchResponse(data, length, xid)) {
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   405
                        return data;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   406
                    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   407
                    timeoutLeft = pktTimeout - ((int) (end - start));
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   408
                } while (timeoutLeft > minTimeout);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   409
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   410
            } finally {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   411
                dc.disconnect();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   412
            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   413
            return null; // no matching packet received within the timeout
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   414
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   415
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   416
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   417
    /*
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   418
     * Sends a TCP query, and returns the first DNS message in the response.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   419
     */
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   420
    private byte[] doTcpQuery(Tcp tcp, Packet pkt) throws IOException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   421
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   422
        int len = pkt.length();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   423
        // Send 2-byte message length, then send message.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   424
        tcp.out.write(len >> 8);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   425
        tcp.out.write(len);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   426
        tcp.out.write(pkt.getData(), 0, len);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   427
        tcp.out.flush();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   428
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   429
        byte[] msg = continueTcpQuery(tcp);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   430
        if (msg == null) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   431
            throw new IOException("DNS error: no response");
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   432
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   433
        return msg;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   434
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   435
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   436
    /*
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   437
     * Returns the next DNS message from the TCP socket, or null on EOF.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   438
     */
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   439
    private byte[] continueTcpQuery(Tcp tcp) throws IOException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   440
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   441
        int lenHi = tcp.read();      // high-order byte of response length
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   442
        if (lenHi == -1) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   443
            return null;        // EOF
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   444
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   445
        int lenLo = tcp.read();      // low-order byte of response length
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   446
        if (lenLo == -1) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   447
            throw new IOException("Corrupted DNS response: bad length");
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   448
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   449
        int len = (lenHi << 8) | lenLo;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   450
        byte[] msg = new byte[len];
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   451
        int pos = 0;                    // next unfilled position in msg
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   452
        while (len > 0) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   453
            int n = tcp.read(msg, pos, len);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   454
            if (n == -1) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   455
                throw new IOException(
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   456
                        "Corrupted DNS response: too little data");
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   457
            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   458
            len -= n;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   459
            pos += n;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   460
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   461
        return msg;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   462
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   463
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   464
    private Packet makeQueryPacket(DnsName fqdn, int xid,
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   465
                                   int qclass, int qtype, boolean recursion) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   466
        int qnameLen = fqdn.getOctets();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   467
        int pktLen = DNS_HDR_SIZE + qnameLen + 4;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   468
        Packet pkt = new Packet(pktLen);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   469
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   470
        short flags = recursion ? Header.RD_BIT : 0;
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   471
        // flags = (short) (flags | Header.CD_BIT | Header.AD_BIT);
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   472
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   473
        pkt.putShort(xid, IDENT_OFFSET);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   474
        pkt.putShort(flags, FLAGS_OFFSET);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   475
        pkt.putShort(1, NUMQ_OFFSET);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   476
        pkt.putShort(0, NUMANS_OFFSET);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   477
        pkt.putInt(0, NUMAUTH_OFFSET);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   478
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   479
        makeQueryName(fqdn, pkt, DNS_HDR_SIZE);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   480
        pkt.putShort(qtype, DNS_HDR_SIZE + qnameLen);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   481
        pkt.putShort(qclass, DNS_HDR_SIZE + qnameLen + 2);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   482
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   483
        return pkt;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   484
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   485
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   486
    // Builds a query name in pkt according to the RFC spec.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   487
    private void makeQueryName(DnsName fqdn, Packet pkt, int off) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   488
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   489
        // Loop through labels, least-significant first.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   490
        for (int i = fqdn.size() - 1; i >= 0; i--) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   491
            String label = fqdn.get(i);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   492
            int len = label.length();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   493
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   494
            pkt.putByte(len, off++);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   495
            for (int j = 0; j < len; j++) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   496
                pkt.putByte(label.charAt(j), off++);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   497
            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   498
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   499
        if (!fqdn.hasRootLabel()) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   500
            pkt.putByte(0, off);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   501
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   502
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   503
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   504
    //-------------------------------------------------------------------------
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   505
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   506
    private byte[] lookupResponse(Integer xid) throws DnsResolverException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   507
        //
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   508
        // Check the queued responses: some other thread in between
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   509
        // received the response for this request.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   510
        //
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   511
        if (DEBUG) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   512
            dprint("LOOKUP for: " + xid +
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   513
                    "\tResponse Q:" + resps);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   514
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   515
        byte[] pkt;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   516
        if ((pkt = resps.get(xid)) != null) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   517
            checkResponseCode(new Header(pkt, pkt.length));
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   518
            queuesLock.lock();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   519
            try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   520
                resps.remove(xid);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   521
                reqs.remove(xid);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   522
            } finally {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   523
                queuesLock.unlock();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   524
            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   525
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   526
            if (DEBUG) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   527
                dprint("FOUND (" + Thread.currentThread() +
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   528
                        ") for:" + xid);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   529
            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   530
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   531
        return pkt;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   532
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   533
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   534
    /*
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   535
     * Checks the header of an incoming DNS response.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   536
     * Returns true if it matches the given xid and throws a naming
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   537
     * exception, if appropriate, based on the response code.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   538
     *
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   539
     * Also checks that the domain name, type and class in the response
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   540
     * match those in the original query.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   541
     */
59101
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   542
    private boolean isMatchResponse(byte[] pkt, int length, int xid)
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   543
            throws DnsResolverException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   544
59101
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   545
        Header hdr = new Header(pkt, length);
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   546
        if (hdr.query) {
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   547
            throw new DnsResolverException("DNS error: expecting response");
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   548
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   549
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   550
        if (!reqs.containsKey(xid)) { // already received, ignore the response
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   551
            return false;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   552
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   553
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   554
        // common case- the request sent matches the subsequent response read
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   555
        if (hdr.xid == xid) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   556
            if (DEBUG) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   557
                dprint("XID MATCH:" + xid);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   558
            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   559
            checkResponseCode(hdr);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   560
            if (!hdr.query && hdr.numQuestions == 1) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   561
59101
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   562
                ResourceRecord rr = new ResourceRecord(pkt, length,
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   563
                        Header.HEADER_SIZE, true, false);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   564
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   565
                // Retrieve the original query
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   566
                ResourceRecord query = reqs.get(xid);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   567
                int qtype = query.getType();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   568
                int qclass = query.getRrclass();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   569
                DnsName qname = query.getName();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   570
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   571
                // Check that the type/class/name in the query section of the
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   572
                // response match those in the original query
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   573
                if ((qtype == ResourceRecord.TYPE_ANY ||
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   574
                        qtype == rr.getType()) &&
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   575
                        (qclass == ResourceRecord.QCLASS_STAR ||
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   576
                                qclass == rr.getRrclass()) &&
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   577
                        qname.equals(rr.getName())) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   578
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   579
                    if (DEBUG) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   580
                        dprint("MATCH NAME:" + qname + " QTYPE:" + qtype +
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   581
                                " QCLASS:" + qclass);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   582
                    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   583
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   584
                    // Remove the response for the xid if received by some other
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   585
                    // thread.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   586
                    queuesLock.lock();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   587
                    try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   588
                        resps.remove(xid);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   589
                        reqs.remove(xid);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   590
                    } finally {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   591
                        queuesLock.unlock();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   592
                    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   593
                    return true;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   594
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   595
                } else {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   596
                    if (DEBUG) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   597
                        dprint("NO-MATCH NAME:" + qname + " QTYPE:" + qtype +
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   598
                                " QCLASS:" + qclass);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   599
                    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   600
                }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   601
            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   602
            return false;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   603
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   604
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   605
        //
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   606
        // xid mis-match: enqueue the response, it may belong to some other
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   607
        // thread that has not yet had a chance to read its response.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   608
        // enqueue only the first response, responses for retries are ignored.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   609
        //
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   610
        queuesLock.lock();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   611
        try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   612
            if (reqs.containsKey(hdr.xid)) { // enqueue only the first response
59101
258033faefc9 aefimov-dns-client-branch: Fix timeouts, add platform specific file locations
aefimov
parents: 58971
diff changeset
   613
                resps.put(hdr.xid, Arrays.copyOf(pkt, length));
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   614
            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   615
        } finally {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   616
            queuesLock.unlock();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   617
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   618
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   619
        if (DEBUG) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   620
            dprint("NO-MATCH SEND ID:" +
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   621
                    xid + " RECVD ID:" + hdr.xid +
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   622
                    "    Response Q:" + resps +
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   623
                    "    Reqs size:" + reqs.size());
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   624
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   625
        return false;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   626
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   627
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   628
    /*
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   629
     * Throws an exception if appropriate for the response code of a
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   630
     * given header.
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   631
     */
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   632
    private void checkResponseCode(Header hdr) throws DnsResolverException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   633
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   634
        int rcode = hdr.rcode;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   635
        if (rcode == NO_ERROR) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   636
            return;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   637
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   638
        String msg = (rcode < rcodeDescription.length)
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   639
                ? rcodeDescription[rcode]
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   640
                : "DNS error";
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   641
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   642
        msg += " [response code " + rcode + "]";
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   643
        throw new DnsResolverException(msg);
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   644
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   645
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   646
    //-------------------------------------------------------------------------
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   647
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   648
    private static final boolean DEBUG = java.security.AccessController.doPrivileged(
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   649
            (PrivilegedAction<Boolean>) () -> Boolean.getBoolean("jdk.dns.client.debug"));
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   650
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   651
    private static void dprint(String mess) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   652
        if (DEBUG) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   653
            System.err.println("DNS: " + mess);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   654
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   655
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   656
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   657
}
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   658
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   659
class Tcp {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   660
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   661
    private final Socket sock;
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   662
    private final InputStream in;
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   663
    final OutputStream out;
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   664
    private int timeoutLeft;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   665
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   666
    Tcp(InetAddress server, int port, int timeout) throws IOException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   667
        sock = new Socket();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   668
        try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   669
            long start = System.currentTimeMillis();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   670
            sock.connect(new InetSocketAddress(server, port), timeout);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   671
            timeoutLeft = (int) (timeout - (System.currentTimeMillis() - start));
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   672
            if (timeoutLeft <= 0)
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   673
                throw new SocketTimeoutException();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   674
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   675
            sock.setTcpNoDelay(true);
58971
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   676
            out = new BufferedOutputStream(sock.getOutputStream());
465a15dd6bed aefimov-dns-client-branch: Cleanup and address ANY type failures
aefimov
parents: 58870
diff changeset
   677
            in = new BufferedInputStream(sock.getInputStream());
58870
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   678
        } catch (Exception e) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   679
            try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   680
                sock.close();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   681
            } catch (IOException ex) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   682
                e.addSuppressed(ex);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   683
            }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   684
            throw e;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   685
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   686
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   687
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   688
    void close() throws IOException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   689
        sock.close();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   690
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   691
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   692
    private interface SocketReadOp {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   693
        int read() throws IOException;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   694
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   695
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   696
    private int readWithTimeout(SocketReadOp reader) throws IOException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   697
        if (timeoutLeft <= 0)
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   698
            throw new SocketTimeoutException();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   699
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   700
        sock.setSoTimeout(timeoutLeft);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   701
        long start = System.currentTimeMillis();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   702
        try {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   703
            return reader.read();
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   704
        } finally {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   705
            timeoutLeft -= System.currentTimeMillis() - start;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   706
        }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   707
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   708
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   709
    int read() throws IOException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   710
        return readWithTimeout(in::read);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   711
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   712
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   713
    int read(byte b[], int off, int len) throws IOException {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   714
        return readWithTimeout(() -> in.read(b, off, len));
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   715
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   716
}
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   717
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   718
/*
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   719
 * javaos emulation -cj
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   720
 */
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   721
class Packet {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   722
    byte[] buf;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   723
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   724
    Packet(int len) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   725
        buf = new byte[len];
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   726
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   727
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   728
    Packet(byte data[], int len) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   729
        buf = new byte[len];
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   730
        System.arraycopy(data, 0, buf, 0, len);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   731
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   732
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   733
    void putInt(int x, int off) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   734
        buf[off] = (byte) (x >> 24);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   735
        buf[off + 1] = (byte) (x >> 16);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   736
        buf[off + 2] = (byte) (x >> 8);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   737
        buf[off + 3] = (byte) x;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   738
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   739
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   740
    void putShort(int x, int off) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   741
        buf[off] = (byte) (x >> 8);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   742
        buf[off + 1] = (byte) x;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   743
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   744
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   745
    void putByte(int x, int off) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   746
        buf[off] = (byte) x;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   747
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   748
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   749
    void putBytes(byte src[], int src_offset, int dst_offset, int len) {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   750
        System.arraycopy(src, src_offset, buf, dst_offset, len);
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   751
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   752
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   753
    int length() {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   754
        return buf.length;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   755
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   756
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   757
    byte[] getData() {
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   758
        return buf;
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   759
    }
35c438a6d45c aefimov-dns-client-branch: Add jdk.dns.client source
aefimov
parents:
diff changeset
   760
}