Skip to content

Commit

Permalink
check ip change
Browse files Browse the repository at this point in the history
  • Loading branch information
longbai committed Jul 15, 2015
1 parent af2659e commit c79f369
Show file tree
Hide file tree
Showing 17 changed files with 1,833 additions and 20 deletions.
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.0.1'
s.version = '0.1.0'
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
6 changes: 6 additions & 0 deletions HappyDNS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
DF1A94E31B429996006517C0 /* DnsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DF1A94E11B429996006517C0 /* DnsTest.m */; };
DF1DA8941B3BDF1800A88CB6 /* HappyDNS.h in Headers */ = {isa = PBXBuildFile; fileRef = DF1DA8931B3BDF1800A88CB6 /* HappyDNS.h */; };
DF22C0CB1B37B9B90010FEBF /* libHappyDNS.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DF22C0BF1B37B9B90010FEBF /* libHappyDNS.dylib */; };
DF44A1021B563CFB00A0EEB9 /* QNNetworkTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DF44A1011B563CFB00A0EEB9 /* QNNetworkTest.m */; };
DF44A1031B563CFB00A0EEB9 /* QNNetworkTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DF44A1011B563CFB00A0EEB9 /* QNNetworkTest.m */; };
DF801F641B396D5100866FDE /* QNRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = DF801F621B396D5100866FDE /* QNRecord.h */; };
DF801F651B396D5100866FDE /* QNRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = DF801F631B396D5100866FDE /* QNRecord.m */; };
DF801F691B396DA000866FDE /* QNDnsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DF801F671B396DA000866FDE /* QNDnsManager.h */; };
Expand Down Expand Up @@ -98,6 +100,7 @@
DF22C0BF1B37B9B90010FEBF /* libHappyDNS.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libHappyDNS.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
DF22C0CA1B37B9B90010FEBF /* HappyDNS_MacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HappyDNS_MacTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
DF22C0D01B37B9B90010FEBF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DF44A1011B563CFB00A0EEB9 /* QNNetworkTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QNNetworkTest.m; sourceTree = "<group>"; };
DF801F621B396D5100866FDE /* QNRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QNRecord.h; path = Common/QNRecord.h; sourceTree = "<group>"; };
DF801F631B396D5100866FDE /* QNRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = QNRecord.m; path = Common/QNRecord.m; sourceTree = "<group>"; };
DF801F671B396DA000866FDE /* QNDnsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QNDnsManager.h; path = Common/QNDnsManager.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -221,6 +224,7 @@
DF1552501B3B915D008D3E7C /* DnspodFreeTest.m */,
DF1A94DE1B429983006517C0 /* HostsTest.m */,
DF1A94E11B429996006517C0 /* DnsTest.m */,
DF44A1011B563CFB00A0EEB9 /* QNNetworkTest.m */,
);
path = HappyDNSTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -517,6 +521,7 @@
DF1A94DF1B429983006517C0 /* HostsTest.m in Sources */,
DF1A94E21B429996006517C0 /* DnsTest.m in Sources */,
DF1552441B3A9536008D3E7C /* ResolverTest.m in Sources */,
DF44A1021B563CFB00A0EEB9 /* QNNetworkTest.m in Sources */,
DF1552511B3B915D008D3E7C /* DnspodFreeTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -542,6 +547,7 @@
DF1A94E01B429983006517C0 /* HostsTest.m in Sources */,
DF1A94E31B429996006517C0 /* DnsTest.m in Sources */,
DF1552451B3A9536008D3E7C /* ResolverTest.m in Sources */,
DF44A1031B563CFB00A0EEB9 /* QNNetworkTest.m in Sources */,
DF1552521B3B915D008D3E7C /* DnspodFreeTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
7 changes: 6 additions & 1 deletion HappyDNS/Common/QNDnsManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
#import "QNDomain.h"
#import "QNHosts.h"

const int kQNDomainHijackingCode = -7001;
const int kQNDomainNotOwnCode = -7002;
const int kQNDomainSeverError = -7003;

@interface QNDnsManager ()

@property (nonatomic) NSCache *cache;
Expand Down Expand Up @@ -98,12 +102,13 @@ - (NSArray *)queryWithDomain:(QNDomain *)domain {
}
}
NSArray *records = nil;
NSError *error = nil;
int firstOk = 32 - bits_leadingZeros(_resolverStatus);
for (int i = 0; i < _resolvers.count; i++) {
int pos = (firstOk + i) % _resolvers.count;
id <QNResolverDelegate> resolver = [_resolvers objectAtIndex:pos];
QNNetworkInfo *before = _curNetwork;
records = [resolver query:domain networkInfo:before];
records = [resolver query:domain networkInfo:before error:&error];
if (records == nil || records.count == 0) {
if (_curNetwork == before) {
_resolverStatus = bits_set(_resolverStatus, pos);
Expand Down
3 changes: 3 additions & 0 deletions HappyDNS/Common/QNNetworkInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@ extern const int kQNISP_OTHER;
+ (instancetype)noNet;

+ (instancetype)normal;

+ (BOOL) isNetworkChanged;

@end
64 changes: 64 additions & 0 deletions HappyDNS/Common/QNNetworkInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
// Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
//

#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#import <arpa/inet.h>

#import "QNNetworkInfo.h"

const int kQNNO_NETWORK = -1;
Expand All @@ -21,6 +27,49 @@
const int kQNISP_YIDONG = kQNISP_CMCC;
const int kQNISP_OTHER = 999;

static char previousIp[32] = {0};
static NSString* lock = @"";
static int localIp(char *buf){
int err;
int sock;

// Create the UDP socket itself.

err = 0;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
err = errno;
return err;
}


struct sockaddr_in addr;

memset(&addr, 0, sizeof(addr));

inet_pton(AF_INET, "8.8.8.8", &addr.sin_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(53);
err = connect(sock, (const struct sockaddr *) &addr, sizeof(addr));

if (err < 0) {
err = errno;
}

struct sockaddr_in localAddress;
socklen_t addressLength = sizeof(struct sockaddr_in);
err = getsockname(sock, (struct sockaddr*)&localAddress, &addressLength);
close(sock);
if (err != 0) {
return err;
}
const char* ip = inet_ntop(AF_INET, &(localAddress.sin_addr), buf, 32);
if (ip == nil) {
return -1;
}
return 0;
}

@implementation QNNetworkInfo

- (instancetype)init:(int)connecton provider:(int)provider {
Expand All @@ -39,4 +88,19 @@ + (instancetype)normal {
return [[QNNetworkInfo alloc] init:kQNISP_GENERAL provider:kQNISP_GENERAL];
}

+ (BOOL) isNetworkChanged {
@synchronized(lock){
char local[32] = {0};
int err = localIp(local);
if (err != 0) {
return YES;
}
if (memcmp(previousIp, local, 32)!=0) {
memcpy(previousIp, local, 32);
return YES;
}
return NO;
}
}

@end
4 changes: 2 additions & 2 deletions HappyDNS/Common/QNRecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ extern const int kQNTypeCname;
@property (readonly) long long timeStamp;

- (instancetype)init:(NSString *)value
ttl:(int)ttl
type:(int)type;
ttl:(int)ttl
type:(int)type;

- (BOOL)expired:(long long)time;
@end
4 changes: 2 additions & 2 deletions HappyDNS/Common/QNRecord.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

@implementation QNRecord
- (instancetype)init:(NSString *)value
ttl:(int)ttl
type:(int)type {
ttl:(int)ttl
type:(int)type {
if (self = [super init]) {
_value = value;
_type = type;
Expand Down
6 changes: 5 additions & 1 deletion HappyDNS/Common/QNResolverDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@

#import <Foundation/Foundation.h>

extern const int kQNDomainHijackingCode;
extern const int kQNDomainNotOwnCode;
extern const int kQNDomainSeverError;

@class QNDomain;
@class QNNetworkInfo;
@protocol QNResolverDelegate <NSObject>
- (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo;
- (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError **)error;
@end
2 changes: 1 addition & 1 deletion HappyDNS/Http/QNDnspodFree.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
#import "QNResolverDelegate.h"

@interface QNDnspodFree : NSObject <QNResolverDelegate>
- (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo;
- (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error;
@end
13 changes: 8 additions & 5 deletions HappyDNS/Http/QNDnspodFree.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@
#import "QNRecord.h"

@implementation QNDnspodFree
- (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo {
- (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error {
NSString *url = [@"http://119.29.29.29/d?ttl=1&dn=" stringByAppendingString:domain.domain];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSError *httpError = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
returningResponse:&response
error:&httpError];

if (error != nil) {
if (httpError != nil) {
if (error != nil) {
*error = httpError;
}
return nil;
}
if (response.statusCode != 200) {
Expand Down
2 changes: 1 addition & 1 deletion HappyDNS/Local/QNResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#import "QNResolverDelegate.h"

@interface QNResolver : NSObject <QNResolverDelegate>
- (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo;
- (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error;
- (instancetype)initWithAddres:(NSString *)address;
+ (instancetype)systemResolver;
@end
2 changes: 1 addition & 1 deletion HappyDNS/Local/QNResolver.m
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ - (instancetype)initWithAddres:(NSString *)address {
return self;
}

- (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo {
- (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error {
struct __res_state res;

int r;
Expand Down
4 changes: 2 additions & 2 deletions HappyDNSTests/DnspodFreeTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ - (void)tearDown {

- (void)testDnspodFree {
id <QNResolverDelegate> resolver = [[QNDnspodFree alloc] init];
NSArray *records = [resolver query:[[QNDomain alloc]init:@"baidu.com"] networkInfo:nil];
NSArray *records = [resolver query:[[QNDomain alloc]init:@"baidu.com"] networkInfo:nil error:nil];
XCTAssert(records != nil, @"Pass");
XCTAssert(records.count > 0, @"Pass");
XCTAssert(records.count >= 1, @"Pass");
QNRecord *record = [records objectAtIndex:0];
XCTAssert(record.ttl >= 0, @"Pass");

records = [resolver query:[[QNDomain alloc]init:@"www.qiniu.com"] networkInfo:nil];
records = [resolver query:[[QNDomain alloc]init:@"www.qiniu.com"] networkInfo:nil error:nil];
XCTAssert(records != nil, @"Pass");
XCTAssert(records.count >= 1, @"Pass");
record = [records objectAtIndex:0];
Expand Down
2 changes: 1 addition & 1 deletion HappyDNSTests/HostsTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ - (void)testQuery {
NSArray *r1 = [hosts query:[[QNDomain alloc] init:@"hello.qiniu.com"] networkInfo:info];
NSArray *r2 = [hosts query:[[QNDomain alloc] init:@"hello.qiniu.com"] networkInfo:info];
NSArray *r3 = [hosts query:[[QNDomain alloc] init:@"hello.qiniu.com"] networkInfo:info];
NSArray *r4 = [hosts query:[[QNDomain alloc] init:@"hello.qiniu.com"] networkInfo:info];
NSArray *r4 = [hosts query:[[QNDomain alloc] init:@"hello.qiniu.com"] networkInfo:info];
XCTAssertTrue(!([r1 isEqualToArray:r2] && [r1 isEqualToArray:r3] && [r1 isEqualToArray:r4]), @"PASS");
}

Expand Down
35 changes: 35 additions & 0 deletions HappyDNSTests/QNNetworkTest.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// QNNetworkTest.m
// HappyDNS
//
// Created by bailong on 15/7/15.
// Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
//

#import <XCTest/XCTest.h>
#import "QNNetworkInfo.h"

@interface QNNetworkTest : XCTestCase

@end

@implementation QNNetworkTest

- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}

- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}

- (void)testNetworkChange {
BOOL changed = [QNNetworkInfo isNetworkChanged];
XCTAssertTrue(changed, @"PASS");
changed =[QNNetworkInfo isNetworkChanged];
XCTAssertTrue(!changed, @"PASS");
}

@end
4 changes: 2 additions & 2 deletions HappyDNSTests/ResolverTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ - (void)tearDown {

- (void)template:(NSString *)server {
id <QNResolverDelegate> resolver = [[QNResolver alloc] initWithAddres:server];
NSArray *records = [resolver query:[[QNDomain alloc]init:@"baidu.com"] networkInfo:nil];
NSArray *records = [resolver query:[[QNDomain alloc]init:@"baidu.com"] networkInfo:nil error:nil];
XCTAssert(records != nil, @"Pass");
XCTAssert(records.count > 0, @"Pass");
XCTAssert(records.count >= 1, @"Pass");
QNRecord *record = [records objectAtIndex:0];
XCTAssert(record.ttl >= 0, @"Pass");

records = [resolver query:[[QNDomain alloc]init:@"www.qiniu.com"] networkInfo:nil];
records = [resolver query:[[QNDomain alloc]init:@"www.qiniu.com"] networkInfo:nil error:nil];
XCTAssert(records != nil, @"Pass");
XCTAssert(records.count >= 3, @"Pass");
record = [records objectAtIndex:0];
Expand Down
Loading

0 comments on commit c79f369

Please sign in to comment.