日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

iOS端獲取DNS解析時間和LocalDNS的解析結果指南

本文檔介紹了在 iOS 上進行網絡請求時,獲取 DNS 解析時間和LocalDNS的解析結果的方法。

1.概述

在iOS端正常進行網絡請求時,可以通過NSURLSessionDelegate中的代理方法獲得LocalDns的解析時間,如果您接入了阿里云公共DNS SDK,那么SDK會繞過LocalDns進行域名解析,此時獲取DNS解析時間,只需在SDK的解析API前后分別獲取時間然后取差值即可。

在iOS上可以使用getaddrinfo 方法獲取本地DNS的解析結果,用戶可以和期望的解析結果進行比對來判斷是否有劫持情況。

2.獲取DNS解析時間方案

  • 如果您的網絡請求接口使用https://domain/path方式,可以參考下面代碼獲取DNS解析時間:

  • 說明

    如果您沒有使用iOS14原生加密方案進行自定義DNS設置,那么參考下面代碼獲取到的DNS解析時間為LocalDNS解析時間;如果您使用了iOS14原生加密方案進行自定義DNS設置,那么參考下面代碼獲取到的DNS解析時間為自定義DNS的解析時間。

#pragma mark URLSession Delegate
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics {
    if ([metrics.transactionMetrics count] <= 0) return;
    [metrics.transactionMetrics enumerateObjectsUsingBlock:^(NSURLSessionTaskTransactionMetrics *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
        if (obj.resourceFetchType == NSURLSessionTaskMetricsResourceFetchTypeNetworkLoad) {
            NSLog(@"%@",[NSString stringWithFormat:@"請求URL:%@",[obj.request.URL absoluteString]]);
            NSLog(@"%@",[NSString stringWithFormat:@"服務器IP:%@",obj.remoteAddress]);

            NSURLSessionTaskMetricsDomainResolutionProtocol dnsProtocol = obj.domainResolutionProtocol;
            NSLog(@"%@",[NSString stringWithFormat:@"DNS類型為 %ld", (long)dnsProtocol]);
            NSLog(@"%@",[NSString stringWithFormat:@"0:未知,1:UDP,2:TCP,3:TLS,4:HTTPS"]);
            if (obj.domainLookupStartDate && obj.domainLookupEndDate) {
                int dnsLookupTime = ceil([obj.domainLookupEndDate timeIntervalSinceDate:obj.domainLookupStartDate] * 1000);
                NSLog(@"%@",[NSString stringWithFormat:@"DNS開始時間:%@,DNS結束時間:%@", obj.domainLookupStartDate, obj.domainLookupEndDate]);
                NSLog(@"%@",[NSString stringWithFormat:@"DNS解析時長單位ms:%d",dnsLookupTime]);
            }
        }
    }];
}
  • 如果您集成了公共DNS SDK,那么您可以參考以下代碼獲取阿里云公共DNS SDK的域名解析時間:

CFTimeInterval startTimer = CACurrentMediaTime();
//替換為您使用的SDK解析方法
[[DNSResolver share] getIpv4DataWithDomain:@"main.m.taobao.com" complete:^(NSArray<NSString *> *dataArray) {
    CFTimeInterval endTimer = CACurrentMediaTime();
    UInt32 rtt = (endTimer - startTimer) * 1000;
    NSLog(@"%@",[NSString stringWithFormat:@"DNS解析時長單位ms:%d",rtt]);                   
}];

3.獲取LocalDNS的解析結果并進行劫持檢測對比

您可以通過以下代碼獲取LocalDNS解析結果用來和您期望的解析結果進行比對,以判斷是否有劫持情況。

#import <Foundation/Foundation.h>
#import <netdb.h>
#import <arpa/inet.h>

- (void)resolveDomain:(NSString *)domain expectedIPs:(NSArray<NSString *> *)expectedIPs {
    struct addrinfo hints, *result, *p;
    memset(&hints, 0, sizeof(hints));

    // 初始化 hints 結構
    hints.ai_family = AF_UNSPEC; // IPv4 or IPv6
    hints.ai_socktype = SOCK_STREAM; // TCP
    
    // 執行 DNS 查詢
    int s = getaddrinfo([domain UTF8String], NULL, &hints, &result);
    if (s != 0) {
        NSLog(@"getaddrinfo error: %s", gai_strerror(s));
        return;
    }

    BOOL isHijacked = NO;

    // 遍歷結果以獲取 IPv4 和 IPv6 地址
    for (p = result; p != NULL; p = p->ai_next) {
        char ipBuffer[INET6_ADDRSTRLEN]; // 緩沖區用于格式化 IP 地址
        if (p->ai_family == AF_INET) {
            struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
            inet_ntop(AF_INET, &ipv4->sin_addr, ipBuffer, sizeof(ipBuffer));
            NSLog(@"IPv4 地址: %s", ipBuffer);
        } else if (p->ai_family == AF_INET6) {
            struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
            inet_ntop(AF_INET6, &ipv6->sin6_addr, ipBuffer, sizeof(ipBuffer));
            NSLog(@"IPv6 地址: %s", ipBuffer);
        }

        // 比對解析結果與期望的 IP 地址
        if (![expectedIPs containsObject:[NSString stringWithUTF8String:ipBuffer]]) {
            isHijacked = YES;
        }
    }

    // 判斷是否存在劫持
    if (isHijacked) {
        NSLog(@"警告: 可能存在 DNS 劫持!");
    } else {
        NSLog(@"未檢測到 DNS 劫持.");
    }

    // 釋放內存
    freeaddrinfo(result);
}