Dns&HttpDns

目錄

1、Dns
2、HttpDns

1、Dns

  1. 終端向LocalDNS發起遞歸查詢。

  2. LocalDNS(未開啓轉發模式),則向根DNS服務器發起迭代查詢請求。(如開啓轉發模式,則轉發至上級localDns)

(任何LocalDNS都需知道根DNS服務器的IP地址(全球共13臺)。)

  1. 根DNS服務器返回一級域名服務器IP地址,(com DNS服務器的IP地址)。

(LocalDNS將com DNS服務器及其IP地址加入到緩存,下次DNS請求,在緩存未過期的情況下,授權給com 區的域名需向com DNS服務器請求查詢時,直接往com DNS服務器發查詢請求,不再向根DNS服務器請求。)

  1. LocalDNS服務器向一級域名服務器(com DNS服務器)發起迭代查詢請求。

  2. com DNS服務器返回二級域名服務器IP地址(wangsu.com DNS服務器的IP地址)。

(LocalDNS將wangsu.comDNS服務器及其IP地址加入到緩存,下次DNS請求,在緩存未過期的情況下,授權給wangsu.com區的域名需向wangsu.com DNS服務器請求查詢時,直接往對應 DNS服務器發查詢請求,不再向根DNS服務器及com DNS服務器請求。)

  1. LocalDNS服務器向wangsu.com DNS服務器發起迭代查詢請求。

7.wangsu.com DNS服務器給出域名的IP地址。

(LocalDNS將www.wangsu.com
IP地址加入到緩存,下次相同的DNS請求,在緩存未過期的情況下,LocalDNS直接給出該域名的IP地址,不再向權威DNS服務器查詢。)

  1. LocalDNS服務器將該域名對應的IP地址返回給終端用戶,

(DNS客戶端將域名對應的IP地址接入緩存。下次請求該域名時,若緩存未過期,DNS客戶端直接從緩存取出IP,不再向LocalDNS發起迭代查詢。)

遞歸查詢指如果終端用戶所請求的LocalDNS服務器不知道被查詢的域名的IP地址,則以DNS客戶端的身份,向其它域名服務器繼續發出查詢請求報文(即替主機繼續查詢),而不是讓主機自己進行下一步查詢。因此,遞歸查詢返回的查詢結果或者是所要查詢的IP地址,或者是報錯,表示無法查詢到所需的IP地址。

迭代查詢指域名服務器或者給出最終結果,或者告訴DNS客戶(此處指LocalDNS)應去哪些DNS服務器查詢。

2、httpdns

2.1、httpdns解決的問題

2.1.1、域名劫持

1、黑客侵入了寬帶路由器並對Local DNS進行篡改;
2、攻擊者還可以監聽終端用戶的域名解析請求,並在Local DNS返回正確結果之前將僞造的DNS解析響應傳遞給終端用戶
3、Local DNS針對部分域名的緩存進行更改

2.1.2、調度不精準

由於運營商策略的多樣性,其 Local DNS 的解析結果可能不是最近、最優的節點。

部分Local DNS A供應商爲了降低運營成本,會將請求到自己節點的域名解析請求轉發給其他供應商的Local DNS B節點,Local DNS B請求權威dns解析時,權威dns會根據Local DNS B的ip,分配離Local DNS B地理位置最近的ip地址。

Local DNS的布點受成本因素制約分佈並不均勻也會導致上述調度不準的問題。

2.2、HTTPDNS

1、使用HTTP協議進行域名解析,直接將域名解析請求直接發送到HTTPDNS服務端,繞過運營商 Local DNS ,避免域名劫持。
2、HTTPDNS服務端會將終端用戶的IP信息直接交付給權威DNS,從而解決調度不精準的問題。
3、另外通過域名預解析、緩存(DNS解析結果)、(解析結果)懶更新策略等方式實現無延遲解析。

2.2.1、預加載

app啓動時,可以對我們後續需要用到的域名,調用HTTPDNS SDK中的預解析方法發起異步的預解析請求。

2.2.2、懶更新

所謂懶加載策略,核心的實現思路如下:

1、如果緩存中沒有記錄,那麼異步網絡請求HTTPDNS解析,獲取解析結果。
(網絡請求需要異步,同步調用需要直接拿到結果,可採取線程池+Future)
2、如果緩存中存在記錄,不論過期與否,直接返回業務層緩存中的記錄;
3、如果緩存中的記錄已過期,後臺發起異步網絡請求進行HTTPDNS解析;

絕大多數場景下域名對應IP變更並不頻繁,特別是在單次APP的使用週期內,域名解析出的IP往往是相同的。
另一方面,即使域名對應的IP發生改變,後臺會異步發起的異步HTTPDNS解析解析會很快獲取最新解析結果 ,結合我們的網絡重試策略,保證了下一次網絡請求的正確性。

2.2.3、OKhttp+HttpDns
public class OkHttpDns implements Dns {
    private static final Dns SYSTEM = Dns.SYSTEM;
    HttpDnsService httpdns;//httpdns 解析服務
    private static OkHttpDns instance = null;
    private OkHttpDns(Context context) {
        this.httpdns = HttpDns.getService(context, "account id");
    }
    public static OkHttpDns getInstance(Context context) {
        if(instance == null) {
            instance = new OkHttpDns(context);
        }
        return instance;
    }
    @Override
    public List<InetAddress> lookup(String hostname) throws UnknownHostException {
        //通過異步解析接口獲取ip
        String ip = httpdnsManager.getIpByHost(hostname);
        if(ip != null) {
            //如果ip不爲null,直接使用該ip進行網絡請求
            List<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(ip));
            Log.e("OkHttpDns", "inetAddresses:" + inetAddresses);
            return inetAddresses;
        }
        //如果返回null,走系統DNS服務解析域名
        return Dns.SYSTEM.lookup(hostname);
    }
}

//給okhttpclient設置自定義的dns
private void okhttpDnsRequest() {
    OkHttpClient client = new OkHttpClient.Builder()
    .dns(OkHttpDns.getInstance(getApplicationContext()))
    .build();

自定義一個類實現Dns,並重寫Dns的lookup方法,
在這個方法中結合懶更新策略獲取域名對應的ip,包裝成InetAddress list進行返回。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章