1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net; 18 19 import android.annotation.NonNull; 20 import android.util.Log; 21 22 import java.io.IOException; 23 import java.net.InetSocketAddress; 24 25 import javax.net.SocketFactory; 26 import javax.net.ssl.SSLSocket; 27 import javax.net.ssl.SSLSocketFactory; 28 29 /** 30 * Class for testing connectivity to DNS-over-TLS servers. 31 * {@hide} 32 */ 33 public class PrivateDnsConnectivityChecker { 34 private static final String TAG = "NetworkUtils"; 35 36 private static final int PRIVATE_DNS_PORT = 853; 37 private static final int CONNECTION_TIMEOUT_MS = 5000; 38 PrivateDnsConnectivityChecker()39 private PrivateDnsConnectivityChecker() { } 40 41 /** 42 * checks that a provided host can perform a TLS handshake on port 853. 43 * @param hostname host to connect to. 44 */ canConnectToPrivateDnsServer(@onNull String hostname)45 public static boolean canConnectToPrivateDnsServer(@NonNull String hostname) { 46 final SocketFactory factory = SSLSocketFactory.getDefault(); 47 TrafficStats.setThreadStatsTag(TrafficStats.TAG_SYSTEM_APP); 48 49 try (SSLSocket socket = (SSLSocket) factory.createSocket()) { 50 socket.setSoTimeout(CONNECTION_TIMEOUT_MS); 51 socket.connect(new InetSocketAddress(hostname, PRIVATE_DNS_PORT)); 52 if (!socket.isConnected()) { 53 Log.w(TAG, String.format("Connection to %s failed.", hostname)); 54 return false; 55 } 56 socket.startHandshake(); 57 Log.w(TAG, String.format("TLS handshake to %s succeeded.", hostname)); 58 return true; 59 } catch (IOException e) { 60 Log.w(TAG, String.format("TLS handshake to %s failed.", hostname), e); 61 return false; 62 } 63 } 64 } 65