Skip to content

Commit

Permalink
Merge pull request #36 from longbai/getaddrinfo
Browse files Browse the repository at this point in the history
add dns callback
  • Loading branch information
longbai authored Jul 19, 2016
2 parents 099ab76 + aa18c28 commit 2b769b1
Show file tree
Hide file tree
Showing 11 changed files with 346 additions and 10 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#Changelog

## 0.3.8 (2016-07-19)

### 增加
* getaddrinfo 支持

## 0.3.7 (2016-07-11)

### 增加
Expand Down
2 changes: 1 addition & 1 deletion HappyDNS.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'HappyDNS'
s.version = '0.3.7'
s.version = '0.3.8'
s.summary = 'DNS library for iOS and Mac'
s.homepage = 'https://github.com/qiniu/happy-dns-objc'
s.social_media_url = 'http://weibo.com/qiniutek'
Expand Down
16 changes: 16 additions & 0 deletions HappyDNS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@
DF801F871B396F5500866FDE /* QNResolverDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF801F851B396F5500866FDE /* QNResolverDelegate.h */; };
DF801F8C1B39743200866FDE /* QNDomain.h in Headers */ = {isa = PBXBuildFile; fileRef = DF801F8A1B39743200866FDE /* QNDomain.h */; };
DF801F8D1B39743200866FDE /* QNDomain.m in Sources */ = {isa = PBXBuildFile; fileRef = DF801F8B1B39743200866FDE /* QNDomain.m */; };
DF8152671D3D4097007C44DA /* QNGetAddrInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = DF8152651D3D4097007C44DA /* QNGetAddrInfo.c */; };
DF8152681D3D4097007C44DA /* QNGetAddrInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = DF8152651D3D4097007C44DA /* QNGetAddrInfo.c */; };
DF8152691D3D4097007C44DA /* QNGetAddrInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DF8152661D3D4097007C44DA /* QNGetAddrInfo.h */; };
DF81526D1D3DA932007C44DA /* GetAddrInfoTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DF81526C1D3DA932007C44DA /* GetAddrInfoTest.m */; };
DF81526E1D3DA932007C44DA /* GetAddrInfoTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DF81526C1D3DA932007C44DA /* GetAddrInfoTest.m */; };
DF90509A1CFD888F008B98C2 /* QNResolvUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = DF9050981CFD888F008B98C2 /* QNResolvUtil.m */; };
DF90509B1CFD888F008B98C2 /* QNResolvUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = DF9050991CFD888F008B98C2 /* QNResolvUtil.h */; };
DF90509C1CFD88AA008B98C2 /* QNResolvUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = DF9050981CFD888F008B98C2 /* QNResolvUtil.m */; };
Expand Down Expand Up @@ -160,6 +165,9 @@
DF801F8B1B39743200866FDE /* QNDomain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QNDomain.m; path = Common/QNDomain.m; sourceTree = "<group>"; };
DF801F951B3A4F4D00866FDE /* libHappyDNS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libHappyDNS.a; sourceTree = BUILT_PRODUCTS_DIR; };
DF801F9F1B3A4F4D00866FDE /* HappyDNS_iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HappyDNS_iOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
DF8152651D3D4097007C44DA /* QNGetAddrInfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = QNGetAddrInfo.c; path = Util/QNGetAddrInfo.c; sourceTree = "<group>"; };
DF8152661D3D4097007C44DA /* QNGetAddrInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QNGetAddrInfo.h; path = Util/QNGetAddrInfo.h; sourceTree = "<group>"; };
DF81526C1D3DA932007C44DA /* GetAddrInfoTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GetAddrInfoTest.m; sourceTree = "<group>"; };
DF9050981CFD888F008B98C2 /* QNResolvUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QNResolvUtil.m; path = Local/QNResolvUtil.m; sourceTree = "<group>"; };
DF9050991CFD888F008B98C2 /* QNResolvUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QNResolvUtil.h; path = Local/QNResolvUtil.h; sourceTree = "<group>"; };
DFDD2A731CF58887006ECFCE /* QNIP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QNIP.h; path = Util/QNIP.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -289,6 +297,7 @@
DF2B76F81C3C1E5A00643678 /* TxtResolverTest.m */,
DFDD2A7A1CF65906006ECFCE /* IPTest.m */,
DF5B33831D2BC78900CD608F /* LruCacheTest.m */,
DF81526C1D3DA932007C44DA /* GetAddrInfoTest.m */,
);
path = HappyDNSTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -356,6 +365,8 @@
DFFC8AAA1B6BD73900EC938D /* QNDes.m */,
DFDD2A731CF58887006ECFCE /* QNIP.h */,
DFDD2A741CF58887006ECFCE /* QNIP.m */,
DF8152651D3D4097007C44DA /* QNGetAddrInfo.c */,
DF8152661D3D4097007C44DA /* QNGetAddrInfo.h */,
);
name = Util;
sourceTree = "<group>";
Expand All @@ -370,6 +381,7 @@
DF0A03201B3BABBD00E3778C /* QNNetworkInfo.h in Headers */,
DF801F691B396DA000866FDE /* QNDnsManager.h in Headers */,
DF801F641B396D5100866FDE /* QNRecord.h in Headers */,
DF8152691D3D4097007C44DA /* QNGetAddrInfo.h in Headers */,
DF5AC8E11B575E2800728D30 /* QNHijackingDetectWrapper.h in Headers */,
DF2B76F51C3C1D5300643678 /* QNTxtResolver.h in Headers */,
DF801F731B396E3C00866FDE /* QNResolver.h in Headers */,
Expand Down Expand Up @@ -598,6 +610,7 @@
DF801F6A1B396DA000866FDE /* QNDnsManager.m in Sources */,
DF2B76F61C3C1D5300643678 /* QNTxtResolver.m in Sources */,
DF5B33811D2BB28500CD608F /* QNLruCache.m in Sources */,
DF8152671D3D4097007C44DA /* QNGetAddrInfo.c in Sources */,
DF801F7E1B396E7600866FDE /* QNDnspodFree.m in Sources */,
DFFC8AAC1B6BD73900EC938D /* QNDes.m in Sources */,
DF801F651B396D5100866FDE /* QNRecord.m in Sources */,
Expand Down Expand Up @@ -625,6 +638,7 @@
DF1552441B3A9536008D3E7C /* ResolverTest.m in Sources */,
DF44A1021B563CFB00A0EEB9 /* NetworkTest.m in Sources */,
DF1552511B3B915D008D3E7C /* DnspodFreeTest.m in Sources */,
DF81526D1D3DA932007C44DA /* GetAddrInfoTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -638,6 +652,7 @@
DFFC8AB21B6BD77000EC938D /* QNDnspodEnterprise.m in Sources */,
DF1552561B3B9316008D3E7C /* QNRecord.m in Sources */,
DF5B33821D2BB28500CD608F /* QNLruCache.m in Sources */,
DF8152681D3D4097007C44DA /* QNGetAddrInfo.c in Sources */,
DF2B76F71C3C1D5300643678 /* QNTxtResolver.m in Sources */,
DF1552591B3B9316008D3E7C /* QNDomain.m in Sources */,
DFFC8AAD1B6BD73900EC938D /* QNDes.m in Sources */,
Expand Down Expand Up @@ -665,6 +680,7 @@
DF1552451B3A9536008D3E7C /* ResolverTest.m in Sources */,
DF44A1031B563CFB00A0EEB9 /* NetworkTest.m in Sources */,
DF1552521B3B915D008D3E7C /* DnspodFreeTest.m in Sources */,
DF81526E1D3DA932007C44DA /* GetAddrInfoTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
9 changes: 9 additions & 0 deletions HappyDNS/Common/QNDnsManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
@class QNNetworkInfo;
@class QNDomain;

/**
* 上传进度回调函数
*
* @param key 上传时指定的存储key
* @param percent 进度百分比
*/
typedef NSArray * (^QNGetAddrInfoCallback)(NSString *host);

@protocol QNIpSorter <NSObject>
- (NSArray *)sort:(NSArray *)ips;
@end
Expand All @@ -23,6 +31,7 @@
- (instancetype)init:(NSArray *)resolvers networkInfo:(QNNetworkInfo *)netInfo sorter:(id<QNIpSorter>)sorter;
- (instancetype)putHosts:(NSString *)domain ip:(NSString *)ip;
- (instancetype)putHosts:(NSString *)domain ip:(NSString *)ip provider:(int)provider;
+ (void)setGetAddrInfoBlock:(QNGetAddrInfoCallback)block;
@end

@interface QNDnsManager (NSURL)
Expand Down
28 changes: 28 additions & 0 deletions HappyDNS/Common/QNDnsManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#import "QNRecord.h"
#import "QNResolverDelegate.h"

#import "QNGetAddrInfo.h"

const int kQNDomainHijackingCode = -7001;
const int kQNDomainNotOwnCode = -7002;
const int kQNDomainSeverError = -7003;
Expand Down Expand Up @@ -234,4 +236,30 @@ - (NSURL *)queryAndReplaceWithIP:(NSURL *)url {
return URL;
}

static QNGetAddrInfoCallback getAddrInfoCallback = nil;
static qn_ips_ret *dns_callback(const char *host) {
if (getAddrInfoCallback == nil) {
//only for compatible
qn_ips_ret *ret = calloc(sizeof(char *), 2);
ret->ips[0] = strdup(host);
return ret;
}
NSString *s = [[NSString alloc] initWithUTF8String:host];
NSArray *ips = getAddrInfoCallback(s);
qn_ips_ret *ret = calloc(sizeof(char *), ips.count + 1);
for (int i = 0; i < ips.count; i++) {
NSString *ip = ips[i];
char *ip2 = strdup([ip cStringUsingEncoding:NSUTF8StringEncoding]);
ret->ips[i] = ip2;
}
return ret;
}

+ (void)setGetAddrInfoBlock:(QNGetAddrInfoCallback)block {
if ([QNIP isIpV6FullySupported] || ![QNIP isV6]) {
getAddrInfoCallback = block;
qn_set_dns_callback(dns_callback);
}
}

@end
2 changes: 2 additions & 0 deletions HappyDNS/HappyDNS.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@
#import "QNRecord.h"
#import "QNResolver.h"
#import "QNResolverDelegate.h"

#import "QNGetAddrInfo.h"
125 changes: 125 additions & 0 deletions HappyDNS/Util/QNGetAddrInfo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//
// QNGetAddrInfo.c
// HappyDNS
//
// Created by bailong on 16/7/19.
// Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
//

#include "string.h"
#include "stdlib.h"
#include "netdb.h"

#include "QNGetAddrInfo.h"


//fast judge domain or ip, not verify ip right.
static int isIp(const char* domain){
size_t l = strlen(domain);
if (l >15 || l < 7) {
return 0;
}

for (const char* p = domain; p < domain+l; p++) {
if ((*p < '0' || *p > '9') && *p != '.') {
return 0;
}
}
return 1;
}

static struct addrinfo* addrinfo_clone(struct addrinfo* addr){
struct addrinfo *ai;
ai = calloc(sizeof(struct addrinfo) + addr->ai_addrlen, 1);
if (ai) {
memcpy(ai, addr, sizeof(struct addrinfo));
ai->ai_addr = (void *)(ai+1);
memcpy(ai->ai_addr, addr->ai_addr, addr->ai_addrlen);
if (addr->ai_canonname) {
ai->ai_canonname = strdup(addr->ai_canonname);
}
ai->ai_next = NULL;
}
return ai;
}

static void append_addrinfo(struct addrinfo** head, struct addrinfo* addr){
if (*head == NULL) {
*head = addr;
return;
}
struct addrinfo* ai = *head;
while (ai->ai_next != NULL) {
ai = ai->ai_next;
}
ai->ai_next = addr;
}

void qn_free_ips_ret(qn_ips_ret *ip_list){
if (ip_list == NULL) {
return;
}
char** p = ip_list->ips;
while (*p != NULL) {
free(*p);
p++;
}
free(ip_list);
}

static qn_dns_callback dns_callback = NULL;
int qn_getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res){
if (dns_callback == NULL || hostname == NULL || isIp(hostname)) {
return getaddrinfo(hostname, servname, hints, res);
}

qn_ips_ret* ret = dns_callback(hostname);
if (ret == NULL) {
return EAI_NODATA;
}
if (ret->ips[0] == NULL) {
qn_free_ips_ret(ret);
return EAI_NODATA;
}
int i;
struct addrinfo* ai = NULL;
struct addrinfo* store = NULL;
int r = 0;
for (i = 0; ret->ips[i] != NULL; i++) {
r = getaddrinfo(ret->ips[i], servname, hints, &ai);
if (r != 0) {
break;
}
struct addrinfo* temp = ai;
ai = addrinfo_clone(ai);
append_addrinfo(&store, ai);
freeaddrinfo(temp);
ai = NULL;
}
qn_free_ips_ret(ret);
if (r != 0) {
qn_freeaddrinfo(store);
return r;
}
*res = store;
return 0;
}

void qn_freeaddrinfo(struct addrinfo *ai){
if (ai == NULL) {
return;
}
struct addrinfo *next;
do {
next = ai->ai_next;
if (ai->ai_canonname)
free(ai->ai_canonname);
/* no need to free(ai->ai_addr) */
free(ai);
ai = next;
} while (ai);
}

void qn_set_dns_callback(qn_dns_callback cb){
dns_callback = cb;
}
26 changes: 26 additions & 0 deletions HappyDNS/Util/QNGetAddrInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// QNGetAddrInfo.h
// HappyDNS
//
// Created by bailong on 16/7/19.
// Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
//

#ifndef QNGetAddrInfo_h
#define QNGetAddrInfo_h

typedef struct qn_ips_ret {
char *ips[1];
} qn_ips_ret;

typedef qn_ips_ret *(*qn_dns_callback)(const char *host);

void qn_free_ips_ret(qn_ips_ret *ip_list);

int qn_getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res);

void qn_freeaddrinfo(struct addrinfo *ai);

void qn_set_dns_callback(qn_dns_callback cb);

#endif /* QNGetAddrInfo_h */
Loading

0 comments on commit 2b769b1

Please sign in to comment.