GithubHelp home page GithubHelp logo

happy-dns-objc's Introduction

Happy DNS for Objective-C

@qiniu on weibo LICENSE Build Status GitHub release codecov Platform

用途

调用系统底层Dns解析库,可以使用114 等第三方dns解析,可以使用 Doh 协议的 Dns 解析方案,也可以集成dnspod等httpdns。另外也有丰富的hosts 域名配置。

安装

通过CocoaPods

pod "HappyDNS"

通过 Swift Package Manager (Xcode 11+)

App 对接:
File -> Swift Packages -> Add Package Dependency,输入 HappyDNS 库链接,选择相应版本即可
库链接: https://github.com/qiniu/happy-dns-objc

库对接:
let package = Package(
    dependencies: [
        .package(url: "https://github.com/qiniu/happy-dns-objc", from: "1.0.3")
    ],
    // ...
)

运行环境

使用方法

* 返回IP列表

 NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:[QNResolver systemResolver]];
[array addObject:[[QNResolver alloc] initWithAddress:@"119.29.29.29"]];
[array addObject:[QNDohResolver resolverWithServer:@"https://dns.alidns.com/dns-query"]];
QNDnsManager *dns = [[QNDnsManager alloc] init:array networkInfo:[QNNetworkInfo normal]];
NSArray <QNRecord *> *records = [dns queryRecords:@"www.qiniu.com"];

* url 请求,返回一个IP 替换URL 里的domain

NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:[QNResolver systemResolver]];
[array addObject:[[QNResolver alloc] initWithAddress:@"119.29.29.29"]];
QNDnsManager *dns = [[QNDnsManager alloc] init:array networkInfo:[QNNetworkInfo normal]];
NSURL *u = [[NSURL alloc] initWithString:@"rtmp://www.qiniu.com/abc?q=1"];
NSURL *u2 = [dns queryAndReplaceWithIP:u];
  • 兼容 getaddrinfo, 方便底层C代码接入
static QNDnsManager *dns = nil;
dns = [[QNDnsManager alloc] init:@[ [QNResolver systemResolver] ] networkInfo:nil];
[QNDnsManager setGetAddrInfoBlock:^NSArray *(NSString *host) {
        return [dns query:host];
    }];
struct addrinfo hints = {0};
struct addrinfo *ai = NULL;
int x = qn_getaddrinfo(host, "http", &hints, &ai);
qn_freeaddrinfo(ai); // 也可以用系统的freeaddrinfo, 代码一致,不过最好用这个

运行测试

$ xctool -workspace HappyDNS.xcworkspace -scheme "HappyDNS_Mac" -sdk macosx -configuration Release test -test-sdk macosx

指定测试

可以在单元测试上修改,熟悉使用

常见问题

  • 如果碰到其他编译错误,请参考 CocoaPods 的 troubleshooting
  • httpdns 在ios8 时不支持 nat64 模式下 IP 直接访问url,原因是 NSUrlConnection 不支持。无论是用http://119.29.29.29/d 还是http://[64:ff9b::771d:1d1d]/d 都不行,此时可以使用localdns方式。
  • 如果软件有国外的使用情况时,建议初始化程序采取这样的方式
QNDnsManager *dns;
if([QNDnsManager needHttpDns]){
    NSMutableArray *array = [[NSMutableArray alloc] init];
    [array addObject:[[QNResolver alloc] initWithAddress:@"119.29.29.29"]];
    [array addObject:[QNResolver systemResolver]];
    dns = [[QNDnsManager alloc] init:array networkInfo:[QNNetworkInfo normal]];
}else{
    NSMutableArray *array = [[NSMutableArray alloc] init];
    [array addObject:[QNResolver systemResolver]];
    [array addObject:[[QNResolver alloc] initWithAddress:@"114.114.114.114"]];
    dns = [[QNDnsManager alloc] init:array networkInfo:[QNNetworkInfo normal]];
}

代码贡献

详情参考代码提交指南

贡献记录

联系我们

  • 如果有什么问题,可以到问答社区提问,问答社区
  • 如果发现了bug, 欢迎提交 issue
  • 如果有功能需求,欢迎提交 issue
  • 如果要提交代码,欢迎提交 pull request
  • 欢迎关注我们的微信 微博,及时获取动态信息。

代码许可

The MIT License (MIT).详情见 License文件.

happy-dns-objc's People

Contributors

bachue avatar carlji avatar kivenhaoyu avatar lawder avatar longbai avatar mei-zhao avatar readmecritic avatar shiyingxixi avatar wangliangliang2 avatar xiaopingsun avatar xwen-winnie avatar yangsen-qn avatar zju-xjh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

happy-dns-objc's Issues

怎么手动集成?

因为我需要修改源代码,所以想手动集成,结果报错了。
Undefined symbols for architecture arm64:
"_res_9_setservers", referenced from:
_setup_dns_server in QNResolvUtil.o
"_res_9_ninit", referenced from:
+[QNResolver systemDnsServer] in QNResolver.o
_setup_dns_server in QNResolvUtil.o
"_res_9_getservers", referenced from:
+[QNResolver systemDnsServer] in QNResolver.o
"_res_9_ns_name_uncompress", referenced from:
_query_ip_v4 in QNResolver.o
"_res_9_ns_parserr", referenced from:
_query_ip in QNTxtResolver.o
_query_ip_v4 in QNResolver.o
"_res_9_nquery", referenced from:
_query_ip in QNTxtResolver.o
_query_ip_v4 in QNResolver.o
"_res_9_ns_initparse", referenced from:
_query_ip in QNTxtResolver.o
_query_ip_v4 in QNResolver.o
"_res_9_ndestroy", referenced from:
_query_ip in QNTxtResolver.o
_query_ip_v4 in QNResolver.o
+[QNResolver systemDnsServer] in QNResolver.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

happy-dns可以和afnetworking配合使用吗

happy-dns可以和afnetworking配合使用吗?目前我们在联通3/4g网发现无法查找主机的问题,已经确定是dns的问题所以我们想在afnetworking使用httpdns,不知道是不是能够兼容?

DNS解析后Response的Set-Cookie

在 QNGetAddrInfo.m 中导入系统库时的写法有点问题

导入系统库时"#include "string.h" " 这种写法是不规范的,应该修改为 "#include <string.h>",后面的两个也一样。
使用了第一种写法,如果有第三方库中定义了string.h 文件的话,两个库在一起很可能就会报错。

当然,我在这里提这个问题正式因为我们在使用 grpc的时候遇到这个尴尬的问题。所以,为了以后同学能够更好的使用,希望你们能够采纳我的建议,修改掉代码里的这种用法。

期待你们的回复

NSURLErrorDomain Code=-999,如何集成http请求?

Hi,

network failure: Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=https://54.255.32.12/v1.0/report, NSErrorFailingURLKey=https://54.255.32.12/v1.0/report, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <6B1DA05D-25CB-4DA8-9368-A7CF0FC40CCD>.<7>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <6B1DA05D-25CB-4DA8-9368-A7CF0FC40CCD>.<7>, NSLocalizedDescription=cancelled}

我就是简单的替换了NSUurl,需要该如何才能在接下来的https请求生效呢,有没有集成http请求的demo呢?

我看网上说需要将http请求中的header中的字段host改成原始的域名,但是尝试后也没有效果。

app进入后台再进入前台,由_cache中得到的result始终是nil

@synchronized(_cache) {
        if ([_curNetwork isEqualToInfo:[QNNetworkInfo normal]] && [QNNetworkInfo isNetworkChanged]) {
            [_cache removeAllObjects];
            _resolverStatus = 0;
        } else {
            result = [_cache objectForKey:domain.domain];
        }
    }

如题所述情况下,确认是走的else,得到的result是nil。并没有发现代码中有其他地方清cache

请问支持自定义dns解析的ip么?

Hi,

NSURL *u2 = [dns queryAndReplaceWithIP:u];

这里能外部指定ip么?我的服务端会下发不同的ip,希望直接在客户端请求的时候直接使用下发的ip(而不是通过dns解析出来的ip),不知道该怎么实现呢?

短时间多次调用query方法会触发多次dns查询请求吗?

比如说在SDWebImage里配置了happydns,然后加载图片时触发了dns查询, 当然图片很多请求次数也很频繁,会不会出现一种情况:第一次dns查询还未完成,后边又多次调用了query方法,导致发出了N个指向同一个Host的dns查询请求?

was mutated while being enumerated. 崩溃

Bugly 统计,HappytDNS 导致 崩溃很频繁。

NSGenericException
*** Collection <__NSArrayM: 0x1513962d0> was mutated while being enumerated.
解析原始
0 CoreFoundation ___exceptionPreprocess + 124
1 libobjc.A.dylib objc_exception_throw + 56
2 CoreFoundation -[NSException name]
3 HappyDNS records2Ips + 208
4 HappyDNS -[QNDnsManager queryInternalWithDomain:] + 1472
5 HappyDNS -[QNDnsManager queryWithDomain:] + 228
6 Qiniu -[QNSessionManager sendRequest:withCompleteBlock:withProgressBlock:withCancelBlock:] + 944
7 libdispatch.dylib __dispatch_call_block_and_release + 24
8 libdispatch.dylib __dispatch_client_callout + 16
9 libdispatch.dylib __dispatch_root_queue_drain + 2140
10 libdispatch.dylib __dispatch_worker_thread3 + 112
11 libsystem_pthread.dylib _pthread_wqthread + 1092
12 libsystem_pthread.dylib start_wqthread + 4

具体问题在 QNDnsManager.m 文件中, 对 queryInternalWithDomain 方法进行了异步调用,并且在@synchronized 块 中对 result 数组进行了更改,所以会导致崩溃, 建议在 records2Ips 方法中 的 for (QNRecord *r in records) 改为 for (QNRecord *r in [records copy]) 或者不要使用 for in 来进行循环。

static NSArray *records2Ips(NSArray *records) {
    NSMutableArray *array = [[NSMutableArray alloc] init];
    for (QNRecord *r in records) {    // 此处使用 for in  遍历会有问题
        [array addObject:r.value];
    }
    return array;
}
- (NSArray *)queryInternalWithDomain:(QNDomain *)domain {
    if (domain.hostsFirst) {
        NSArray *ret = [_hosts query:domain networkInfo:_curNetwork];
        if (ret != nil && ret.count != 0) {
            return ret;
        }
    }
    NSMutableArray *result;
    @synchronized(_cache) {
        if ([_curNetwork isEqualToInfo:[QNNetworkInfo normal]] && [QNNetworkInfo isNetworkChanged]) {
            [_cache removeAllObjects];
            _resolverStatus = 0;
        } else {
            result = [_cache objectForKey:domain.domain];
            if (result != nil && result.count > 1) {
                QNRecord *first = [result firstObject];
                [result removeObjectAtIndex:0];    // 此处对 result 进行了修改
                [result addObject:first];
            }
        }
    }

    if (result != nil && result.count > 0) {
        QNRecord *record = [result objectAtIndex:0];
        if (![record expired:[[NSDate date] timeIntervalSince1970]]) {
            return records2Ips(result);
        }
    }
...

注释错误

QNDnsManager.h :135:14:

/**
 *    设置底层 业务统计 如connect 回调使用的Callback
 *
 *    @param dns 回调用的dnsmanager
 */
+ (void)setIpStatusCallback:(QNIpStatusCallback)block;

分享happy-dns 配合 SDWebImage 的使用

1.先pod 'HappyDNS', '~> 0.1.1'到项目中;

2.项目中使用QNDnsManager 返回ips;
NSMutableArray *array = [[NSMutableArray alloc]init];
[array addObject:[QNResolver systemResolver]];
[array addObject:[[QNResolver alloc] initWithAddres:@"114.114.115.115"]];
QNDnsManager *dnsManager = [[QNDnsManager alloc] init:array networkInfo:[QNNetworkInfo normal]];
NSArray *ips = [dnsManager query:@"http://xxxx.com2.z0.glb.qiniucdn.com"];

3.请求七牛图片时使用ip替换域名http://xxxx.com2.z0.glb.qiniucdn.com,并设置HTTPHeadField;
[SDWebImageManager.sharedManager.imageDownloader setValue:@"http://xxxx.com2.z0.glb.qiniucdn.com" forHTTPHeaderField:@"Host"];
注:自己封装请求图片时使用[request setValue: @"http://xxxx.com2.z0.glb.qiniucdn.com" forHTTPHeaderField:@"Host"];

4.项目中因为图片还有其他来源,这里区分使用设置HTTPHeadField中Host;
SDWebImageManager.sharedManager.imageDownloader.headersFilter = ^NSDictionary *(NSURL *url, NSDictionary *headers)
{
NSMutableDictionary *mutableHeaders = [headers mutableCopy];
[mutableHeaders removeObjectForKey:@"Host"];
//是否为ip格式
if ([url.host rh_isIp])
{
[mutableHeaders setValue:@"xxxx.com2.z0.glb.qiniucdn.com" forKey:@"Host"];
}
return mutableHeaders;
};

最后,谢谢longbai在此过程中提供的帮助,由于缺少相关文档,冒昧抛砖引玉,希望可以帮助到小伙伴们,欢迎一起交流!

如何访问已经禁止ip访问的网站?

使用NSURLProtocol代理了UiWebView的请求,用HappyDNS将url的host转换成了ip,但是有些服务器设置了禁止ip访问,所以直接返回了404,问下有没有什么解决办法???

IPV6网络和Https都不支持么

[QNDnsManager needHttpDns] 、[QNDnsManager setGetAddrInfoBlock:^NSArray *(NSString *host) {
return [dns query:host];
}]; 没有这2个函数呢

导入SDK编译出错

自己的工程,不想使用cocoapods,所以将sdk导入工程,结构如下:
struct
编译出错,提示如下:
error_1
error_2
是否因为没有导入某些第三方框架?
能够加入单独使用七牛sdk的方法,不依赖于cocoapods。
谢谢!

关于是否兼容 ipv6 的问题

release 里写了全面兼容 ipv6,不过我对照这片文章过了一下几个兼容点时,其中有一点

IPV4时只需要通过res_ninit进行初始化就可以获取,但是在IPV6环境下需要通过res_getservers()接口才能获取。

在0.3.3.1版本的 setup_dns_server 里只有使用 res_ninit ,这样也可以兼容 ipv6 吗?

多谢

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.