すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud DNS:AndroidアプリでOkHttpライブラリを使用して、ローカルDNSサーバーのDNS解決期間と解決結果を取得する

最終更新日:Nov 12, 2024

このトピックでは、AndroidアプリでOkHttpライブラリを使用してネットワークリクエストを実行するときに、ドメインネームシステム (DNS) 解決期間を取得する方法について説明します。

1. 概要

AndroidアプリでOkHttpライブラリを使用してネットワークリクエストを実行するときに、EventListenerを使用してDNS解決期間を取得できます。 EventListenerは、DNS解決、接続確立、データ送信など、さまざまなフェーズでネットワーク要求を追跡するための複数のコールバックメソッドを提供します。

InetAddress.getAllByName(String host) を使用して、ローカルDNSサーバーのDNS解決解決を取得できます。 これにより、取得した解像度と予想される解像度を比較して、ドメインハイジャックが発生したかどうかを判断できます。

2. 手順

OkHttpEventListenerを使用してDNS解決期間を取得するには、次の手順を実行します。

手順1: OkHttpライブラリのインポート

build.gradleファイルにOkHttp依存関係を追加します。

implementation 'com.squareup.okhttp3:okhttp:4.9.3'

手順2: カスタムEventListenerクラスを作成する

DNS解決期間をリッスンして記録するカスタムEventListenerクラスを作成します。

import okhttp3.EventListener;
import okhttp3.Call;
import okhttp3.HttpUrl;

public class DnsTimingEventListener extends EventListener {
    private long dnsStartTime;
    private long dnsEndTime;

    @Override
    public void dnsStart(Call call, String domainName) {
        super.dnsStart(call, domainName);
        dnsStartTime = System.currentTimeMillis();
    }

    @Override
    public void dnsEnd(Call call, String domainName, List<InetAddress> inetAddressList) {
        super.dnsEnd(call, domainName, inetAddressList);
        dnsEndTime = System.currentTimeMillis();
        long dnsDuration = dnsEndTime - dnsStartTime;
        System.out.println("DNS resolution duration: " + dnsDuration + "Milliseconds");
    }
}

手順3: OkHttpClientインスタンスを作成し、EventListener.Factoryパラメーターを設定します。

OkHttpClientインスタンスのカスタムEventListener.Factoryパラメーターを設定します。

import okhttp3.OkHttpClient;

// Create an OkHttpClient instance.
OkHttpClient client = new OkHttpClient.Builder()
        .eventListenerFactory(new EventListener.Factory() {
            @Override
            public EventListener create(Call call) {
                return new DnsTimingEventListener();
            }
        })
        .build();

ステップ4: ネットワーク要求を実行する

設定されたOkHttpClientインスタンスを使用してネットワークリクエストを実行します。

import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;

public void executeNetworkRequest() {
    // Create a Request object.
    Request request = new Request.Builder()
    // Enter an actual URL in .url() 
            .url("https://www.example.com")
            .build();

    try {
        // Execute the request.
        Response response = client.newCall(request).execute();
        // Process the response.
        if (response.isSuccessful()) {
            System.out.println("The request is successful");
            // You can process the response here.
        } else {
            System.out.println("The request failed, Status code:" + response.code());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

上記の手順を実行して、DNS解決期間を取得し、応答を処理できます。 これは、ネットワークリクエストによって消費される期間を理解するのに役立つだけでなく、パフォーマンスの向上と監視にも使用できます。

Alibaba Cloud Public DNS SDKをOkHttpライブラリを使用するAndroidアプリと統合している場合、上記の手順を実行することで、Alibaba Cloud Public DNSのDNS解決期間を取得できます。 Alibaba CloudパブリックDNS SDKをOkHttpライブラリを使用するAndroidアプリと統合していない場合、上記の手順を実行することで、ローカルDNSサーバーInetAddressのDNS解決期間のみを取得できます。

次のサンプルコードは、OkHttpを使用するAndroidアプリでAlibaba Cloud Public DNS SDKにアクセスする方法の例を示しています。

   public class OkHttpDns implements Dns {

    private static OkHttpDns instance;
    private static Object lock = new Object();
    private DNSResolver mDNSResolver = DNSResolver.getInstance();

    private OkHttpDns() {
    }

    public static OkHttpDns getInstance() {
        if (null == instance) {
            synchronized (lock) {
                if (instance == null) {
                    instance = new OkHttpDns();
                }
            }
        }
        return instance;
    }

    @Override
    public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
        //Call the API operation in Alibaba Cloud Public DNS SDK for Android to resolve a domain name.
        String ip = null;
        String[] ipv4Array = mDNSResolver.getIpv4ByHostFromCache(hostname,true);
        if (ipv4Array != null && ipv4Array.length > 0) {
            ip = ipv4Array[0];
        }else {
            ip = mDNSResolver.getIPV4ByHost(hostname);
        }

        if (ip != null) {
            //If the returned ip value is not null, directly use the IP address to send network requests.
            Log.d(TAG, "mDnsCache IP: " + ip);
            return Arrays.asList(InetAddress.getAllByName(ip));
        }
        //If null is returned, use the system DNS service to resolve the domain name.
        return Dns.SYSTEM.lookup(hostname);
    }
}

3. ローカルDNSサーバーのDNS解決結果を取得し、ドメインハイジャックが発生するかどうかを判断する

次のサンプルコードは、ローカルDNSサーバーのDNS解決期間を取得する方法の例を示しています。

public List<String> getIPAddresses(String domain) {
    List<String> ipAddresses = new ArrayList<>();
    try {
        InetAddress[] addresses = InetAddress.getAllByName(domain);
        for (InetAddress address : addresses) {
            ipAddresses.add(address.getHostAddress());
        }
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
    return ipAddresses;
}

次のサンプルコードでは、取得したローカルDNSサーバーのDNS解決期間を予想期間と比較して、ドメインハイジャックが発生したかどうかを判断する方法の例を示します。

public boolean isDnsHijacked(String domain, List<String> expectedIps) {
      List<String> localIps = getIPAddresses(domain);
      if (localIps.isEmpty()) {
          return false; //  Domain name cannot be resolved.
      }
      for (String localIp : localIps) {
          if (!expectedIps.contains(localIp)) {
              return true; // The unexptected IP address indicates that DNS may be hijacked.
          }
      }
      return false; // All DNS resolutions match the expected duration.
  }