解决了语音上传到问题,接下来要解决下载播放问题
This commit is contained in:
36
Pods/HappyDNS/HappyDNS/Common/QNDnsError.h
generated
Normal file
36
Pods/HappyDNS/HappyDNS/Common/QNDnsError.h
generated
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// QNDnsError.h
|
||||
// Doh
|
||||
//
|
||||
// Created by yangsen on 2021/7/20.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern const int kQNDomainHijackingCode;
|
||||
extern const int kQNDomainNotOwnCode;
|
||||
extern const int kQNDomainSeverError;
|
||||
|
||||
extern const int kQNDnsMethodErrorCode;
|
||||
extern const int kQNDnsInvalidParamCode;
|
||||
extern const int kQNDnsResponseBadTypeCode;
|
||||
extern const int kQNDnsResponseBadClassCode;
|
||||
extern const int kQNDnsResponseFormatCode;
|
||||
|
||||
#define kQNDnsErrorDomain @"qiniu.dns"
|
||||
|
||||
@interface QNDnsError : NSObject
|
||||
|
||||
+ (NSError *)error:(int)code desc:(NSString *)desc;
|
||||
|
||||
@end
|
||||
|
||||
#define kQNDnsMethodError(description) [QNDnsError error:kQNDnsMethodErrorCode desc:description]
|
||||
#define kQNDnsInvalidParamError(description) [QNDnsError error:kQNDnsInvalidParamCode desc:description]
|
||||
#define kQNDnsResponseBadTypeError(description) [QNDnsError error:kQNDnsResponseBadTypeCode desc:description]
|
||||
#define kQNDnsResponseBadClassError(description) [QNDnsError error:kQNDnsResponseBadClassCode desc:description]
|
||||
#define kQNDnsResponseFormatError(description) [QNDnsError error:kQNDnsResponseFormatCode desc:description]
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
27
Pods/HappyDNS/HappyDNS/Common/QNDnsError.m
generated
Normal file
27
Pods/HappyDNS/HappyDNS/Common/QNDnsError.m
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// QNDnsError.m
|
||||
// Doh
|
||||
//
|
||||
// Created by yangsen on 2021/7/20.
|
||||
//
|
||||
|
||||
#import "QNDnsError.h"
|
||||
|
||||
const int kQNDomainHijackingCode = -7001;
|
||||
const int kQNDomainNotOwnCode = -7002;
|
||||
const int kQNDomainSeverError = -7003;
|
||||
|
||||
const int kQNDnsMethodErrorCode = -7010;
|
||||
|
||||
const int kQNDnsInvalidParamCode = -7021;
|
||||
const int kQNDnsResponseBadTypeCode = -7022;
|
||||
const int kQNDnsResponseBadClassCode = -7023;
|
||||
const int kQNDnsResponseFormatCode = -7024;
|
||||
|
||||
@implementation QNDnsError
|
||||
|
||||
+ (NSError *)error:(int)code desc:(NSString *)desc {
|
||||
return [NSError errorWithDomain:kQNDnsErrorDomain code:code userInfo:@{@"user_info" : desc ?: @"nil"}];
|
||||
}
|
||||
|
||||
@end
|
||||
174
Pods/HappyDNS/HappyDNS/Common/QNDnsManager.h
generated
Normal file
174
Pods/HappyDNS/HappyDNS/Common/QNDnsManager.h
generated
Normal file
@@ -0,0 +1,174 @@
|
||||
//
|
||||
// QNDnsManager.h
|
||||
// HappyDNS
|
||||
//
|
||||
// Created by bailong on 15/6/23.
|
||||
// Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QNRecord.h"
|
||||
|
||||
@class QNNetworkInfo;
|
||||
@class QNDomain;
|
||||
|
||||
/**
|
||||
* getaddrinfo 回调上层的函数
|
||||
*
|
||||
* @param host 请求的域名
|
||||
* @return ip 列表
|
||||
*/
|
||||
typedef NSArray<NSString *> * (^QNGetAddrInfoCallback)(NSString *host);
|
||||
|
||||
/**
|
||||
* ip status 回调上层的函数
|
||||
*
|
||||
* @param ip 请求的IP
|
||||
* @param code 错误码
|
||||
* @param ms 消耗时间
|
||||
*/
|
||||
typedef void (^QNIpStatusCallback)(NSString *ip, int code, int ms);
|
||||
|
||||
/**
|
||||
* 外部 Record 排序接口
|
||||
*/
|
||||
@protocol QNRecordSorter <NSObject>
|
||||
|
||||
/**
|
||||
* 排序方法
|
||||
*
|
||||
* @param ips 传入的IP列表
|
||||
*
|
||||
* @return 返回排序好的IP 列表
|
||||
*/
|
||||
- (NSArray<QNRecord *> *)sort:(NSArray<QNRecord *> *)ips;
|
||||
@end
|
||||
|
||||
/**
|
||||
* DNS请求客户端,集成了cache管理
|
||||
*/
|
||||
@interface QNDnsManager : NSObject
|
||||
|
||||
/// 查询失败时抛出错误信息回调
|
||||
@property(nonatomic, copy)void(^queryErrorHandler)(NSError *error, NSString *host);
|
||||
|
||||
/**
|
||||
* 解析域名
|
||||
*
|
||||
* @param domain 域名
|
||||
*
|
||||
* @return QNRecord列表 QNRecord.value即为host
|
||||
*/
|
||||
- (NSArray <QNRecord *> *)queryRecords:(NSString *)domain;
|
||||
|
||||
/**
|
||||
* 解析域名,使用Domain对象进行详细约定
|
||||
*
|
||||
* @param domain 配置了一些domain 参数的 domain 对象
|
||||
*
|
||||
* @return IP 列表
|
||||
*/
|
||||
- (NSArray <QNRecord *> *)queryRecordsWithDomain:(QNDomain *)domain;
|
||||
|
||||
/**
|
||||
* 通知网络发生变化
|
||||
*
|
||||
* @param netInfo 网络信息
|
||||
*/
|
||||
- (void)onNetworkChange:(QNNetworkInfo *)netInfo;
|
||||
|
||||
/**
|
||||
* Dns client 初始化
|
||||
*
|
||||
* @param resolvers 解析服务器列表
|
||||
* @param netInfo 当前网络信息
|
||||
*
|
||||
* @return DnsManager
|
||||
*/
|
||||
- (instancetype)init:(NSArray *)resolvers networkInfo:(QNNetworkInfo *)netInfo;
|
||||
|
||||
/**
|
||||
* Dns client 初始化
|
||||
*
|
||||
* @param resolvers 解析服务器列表
|
||||
* @param netInfo 当前网络信息
|
||||
* @param sorter 外部排序函数
|
||||
*
|
||||
* @return DnsManager
|
||||
*/
|
||||
- (instancetype)init:(NSArray *)resolvers networkInfo:(QNNetworkInfo *)netInfo sorter:(id<QNRecordSorter>)sorter;
|
||||
|
||||
/**
|
||||
* 内置 Hosts 解析
|
||||
*
|
||||
* @param domain 域名
|
||||
* @param ipv4 对应IPv4 ip
|
||||
*
|
||||
* @return 当前Dnsmanager, 为了链式调用
|
||||
*/
|
||||
- (instancetype)putHosts:(NSString *)domain ipv4:(NSString *)ipv4;
|
||||
|
||||
/**
|
||||
* 内置 Hosts 解析
|
||||
*
|
||||
* @param domain 域名
|
||||
* @param ip 对应IP
|
||||
* @param type ip 类别,kQNTypeA / kQNTypeAAAA
|
||||
* @param provider 网络运营商
|
||||
*
|
||||
* @return 当前Dnsmanager, 为了链式调用
|
||||
*/
|
||||
- (instancetype)putHosts:(NSString *)domain ip:(NSString *)ip type:(int)type provider:(int)provider;
|
||||
|
||||
/**
|
||||
* 内置 Hosts 解析
|
||||
*
|
||||
* @param domain 域名
|
||||
* @param record 对应 record 记录
|
||||
* @param provider 网络运营商
|
||||
*
|
||||
* @return 当前Dnsmanager, 为了链式调用
|
||||
*/
|
||||
- (instancetype)putHosts:(NSString *)domain record:(QNRecord *)record provider:(int)provider;
|
||||
|
||||
/**
|
||||
* 设置底层 getaddrinfo 使用的回调
|
||||
*
|
||||
* @param block 回调的代码块
|
||||
*/
|
||||
+ (void)setGetAddrInfoBlock:(QNGetAddrInfoCallback)block;
|
||||
|
||||
/**
|
||||
* 设置底层 getaddrinfo 回调使用的dnsmanager
|
||||
*
|
||||
* @param dns 回调用的dnsmanager
|
||||
*/
|
||||
+ (void)setDnsManagerForGetAddrInfo:(QNDnsManager *)dns;
|
||||
|
||||
/**
|
||||
* 设置底层 业务统计 如connect 回调使用的Callback
|
||||
*
|
||||
* @param block 回调返回该IP状态
|
||||
*/
|
||||
+ (void)setIpStatusCallback:(QNIpStatusCallback)block;
|
||||
|
||||
/**
|
||||
* 根据时区判断是否要设置httpDns
|
||||
*/
|
||||
+ (BOOL)needHttpDns;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* DnsManager 的 URL 辅助类
|
||||
*/
|
||||
@interface QNDnsManager (NSURL)
|
||||
|
||||
/**
|
||||
* 使用URL 进行请求
|
||||
*
|
||||
* @param url 请求的Url
|
||||
*
|
||||
* @return 返回IP 替换过的url
|
||||
*/
|
||||
- (NSURL *)queryAndReplaceWithIP:(NSURL *)url;
|
||||
@end
|
||||
322
Pods/HappyDNS/HappyDNS/Common/QNDnsManager.m
generated
Normal file
322
Pods/HappyDNS/HappyDNS/Common/QNDnsManager.m
generated
Normal file
@@ -0,0 +1,322 @@
|
||||
//
|
||||
// QNDnsManager.m
|
||||
// HappyDNS
|
||||
//
|
||||
// Created by bailong on 15/6/23.
|
||||
// Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QNDnsManager.h"
|
||||
#import "QNDomain.h"
|
||||
#import "QNHosts.h"
|
||||
#import "QNIP.h"
|
||||
#import "QNLruCache.h"
|
||||
#import "QNNetworkInfo.h"
|
||||
#import "QNRecord.h"
|
||||
#import "QNResolverDelegate.h"
|
||||
|
||||
#include "QNGetAddrInfo.h"
|
||||
|
||||
@interface QNDnsManager ()
|
||||
|
||||
@property (nonatomic, strong) QNLruCache *cache;
|
||||
@property (atomic) QNNetworkInfo *curNetwork;
|
||||
@property (nonatomic) NSArray *resolvers;
|
||||
@property (atomic) UInt32 resolverStatus;
|
||||
@property (nonatomic, strong) QNHosts *hosts;
|
||||
@property (nonatomic, strong) id<QNRecordSorter> sorter;
|
||||
@end
|
||||
|
||||
//static inline BOOL bits_isSet(UInt32 v, int index) {
|
||||
// return (v & (1 << index)) != 0;
|
||||
//}
|
||||
|
||||
static inline UInt32 bits_set(UInt32 v, int bitIndex) {
|
||||
return v |= (1 << bitIndex);
|
||||
}
|
||||
|
||||
static inline UInt32 bits_leadingZeros(UInt32 x) {
|
||||
UInt32 y;
|
||||
int n = 32;
|
||||
y = x >> 16;
|
||||
if (y != 0) {
|
||||
n = n - 16;
|
||||
x = y;
|
||||
}
|
||||
y = x >> 8;
|
||||
if (y != 0) {
|
||||
n = n - 8;
|
||||
x = y;
|
||||
}
|
||||
y = x >> 4;
|
||||
if (y != 0) {
|
||||
n = n - 4;
|
||||
x = y;
|
||||
}
|
||||
y = x >> 2;
|
||||
if (y != 0) {
|
||||
n = n - 2;
|
||||
x = y;
|
||||
}
|
||||
y = x >> 1;
|
||||
if (y != 0) {
|
||||
return n - 2;
|
||||
}
|
||||
return n - x;
|
||||
}
|
||||
|
||||
static NSMutableArray *trimCname(NSArray *records) {
|
||||
NSMutableArray *array = [[NSMutableArray alloc] init];
|
||||
for (QNRecord *r in records) {
|
||||
if (r.type == kQNTypeA || r.type == kQNTypeAAAA) {
|
||||
[array addObject:r];
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
static NSArray<NSString *> *records2Ips(NSArray<QNRecord *> *records) {
|
||||
NSMutableArray *array = [[NSMutableArray alloc] init];
|
||||
for (QNRecord *r in records) {
|
||||
if (r.value && r.value.length > 0) {
|
||||
[array addObject:r.value];
|
||||
}
|
||||
}
|
||||
return [array copy];
|
||||
}
|
||||
|
||||
static NSArray<QNRecord *> * filterInvalidRecords(NSArray *records) {
|
||||
NSMutableArray *array = [[NSMutableArray alloc] init];
|
||||
long long timestamp = [[NSDate date] timeIntervalSince1970];
|
||||
for (QNRecord *r in records) {
|
||||
if (r.value && r.value.length > 0 && ![r expired:timestamp]) {
|
||||
[array addObject:r];
|
||||
}
|
||||
}
|
||||
return [array copy];
|
||||
}
|
||||
|
||||
@interface DummySorter : NSObject <QNRecordSorter>
|
||||
|
||||
@end
|
||||
|
||||
@implementation DummySorter
|
||||
|
||||
//sorted already
|
||||
- (NSArray *)sort:(NSArray *)ips {
|
||||
return ips;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation QNDnsManager
|
||||
|
||||
- (NSArray <QNRecord *> *)queryRecords:(NSString *)domain {
|
||||
return [self queryRecordsWithDomain:[[QNDomain alloc] init:domain]];
|
||||
}
|
||||
|
||||
- (NSArray <QNRecord *> *)queryRecordsWithDomain:(QNDomain *)domain{
|
||||
if (domain == nil) {
|
||||
return nil;
|
||||
}
|
||||
if ([QNIP mayBeIpV4:domain.domain]) {
|
||||
QNRecord *record = [[QNRecord alloc] init:domain.domain ttl:kQNRecordForeverTTL type:kQNTypeA source:QNRecordSourceUnknown];
|
||||
return [NSArray arrayWithObject:record];
|
||||
}
|
||||
NSArray<QNRecord *> *records = [self queryInternalWithDomain:domain];
|
||||
return [_sorter sort:records];
|
||||
}
|
||||
|
||||
- (NSArray <QNRecord *> *)queryInternalWithDomain:(QNDomain *)domain {
|
||||
if (domain.hostsFirst) {
|
||||
NSArray <QNRecord *> *result = [_hosts query:domain networkInfo:_curNetwork];
|
||||
result = filterInvalidRecords(result);
|
||||
if (result.count > 0) {
|
||||
return [result copy];
|
||||
}
|
||||
}
|
||||
|
||||
if ([_curNetwork isEqualToInfo:[QNNetworkInfo normal]] && [QNNetworkInfo isNetworkChanged]) {
|
||||
@synchronized(_cache) {
|
||||
[_cache removeAllObjects];
|
||||
}
|
||||
_resolverStatus = 0;
|
||||
} else {
|
||||
@synchronized(_cache) {
|
||||
NSArray *result = [_cache objectForKey:domain.domain];
|
||||
result = filterInvalidRecords(result);
|
||||
if (result.count > 0) {
|
||||
return [result copy];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 *previousNetwork = _curNetwork;
|
||||
NSString *previousIp = [QNNetworkInfo getIp];
|
||||
records = [resolver query:domain networkInfo:previousNetwork error:&error];
|
||||
if (error != nil) {
|
||||
NSError *tmp = error;
|
||||
error = nil;
|
||||
if (tmp.code == kQNDomainNotOwnCode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self.queryErrorHandler) {
|
||||
self.queryErrorHandler(error, domain.domain);
|
||||
}
|
||||
}
|
||||
|
||||
if (records == nil || records.count == 0) {
|
||||
if (_curNetwork == previousNetwork && [previousIp isEqualToString:[QNNetworkInfo getIp]]) {
|
||||
_resolverStatus = bits_set(_resolverStatus, pos);
|
||||
}
|
||||
} else {
|
||||
NSMutableArray *result = trimCname(records);
|
||||
if (_curNetwork == previousNetwork && [previousIp isEqualToString:[QNNetworkInfo getIp]]) {
|
||||
@synchronized(_cache) {
|
||||
[_cache setObject:[result copy] forKey:domain.domain];
|
||||
}
|
||||
}
|
||||
return [result copy];
|
||||
}
|
||||
}
|
||||
|
||||
if (!domain.hostsFirst) {
|
||||
return [_hosts query:domain networkInfo:_curNetwork];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (instancetype)init:(NSArray *)resolvers networkInfo:(QNNetworkInfo *)netInfo {
|
||||
return [self init:resolvers networkInfo:netInfo sorter:nil];
|
||||
}
|
||||
|
||||
- (instancetype)init:(NSArray *)resolvers networkInfo:(QNNetworkInfo *)netInfo sorter:(id<QNRecordSorter>)sorter {
|
||||
if (self = [super init]) {
|
||||
_cache = [[QNLruCache alloc] init:1024];
|
||||
_curNetwork = netInfo;
|
||||
_resolvers = [[NSArray alloc] initWithArray:resolvers];
|
||||
_hosts = [[QNHosts alloc] init];
|
||||
if (sorter == nil) {
|
||||
_sorter = [[DummySorter alloc] init];
|
||||
} else {
|
||||
_sorter = sorter;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)onNetworkChange:(QNNetworkInfo *)netInfo {
|
||||
@synchronized(_cache) {
|
||||
[_cache removeAllObjects];
|
||||
}
|
||||
_curNetwork = netInfo;
|
||||
}
|
||||
|
||||
- (instancetype)putHosts:(NSString *)domain ipv4:(NSString *)ipv4 {
|
||||
return [self putHosts:domain ip:ipv4 type:kQNTypeA provider:kQNISP_GENERAL];
|
||||
}
|
||||
|
||||
- (instancetype)putHosts:(NSString *)domain ip:(NSString *)ip type:(int)type provider:(int)provider {
|
||||
return [self putHosts:domain record:[[QNRecord alloc] init:ip ttl:kQNRecordForeverTTL type:type source:QNRecordSourceCustom] provider:provider];
|
||||
}
|
||||
|
||||
- (instancetype)putHosts:(NSString *)domain record:(QNRecord *)record provider:(int)provider {
|
||||
QNRecord *recordNew = [[QNRecord alloc] init:record.value ttl:record.ttl type:record.type timeStamp:record.timeStamp server:record.server source:QNRecordSourceCustom];
|
||||
[_hosts put:domain record:recordNew provider:provider];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSURL *)queryAndReplaceWithIP:(NSURL *)url {
|
||||
NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:YES];
|
||||
if (!urlComponents) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString *host = urlComponents.host;
|
||||
NSArray<QNRecord *> *records = [self queryRecords:host];
|
||||
|
||||
NSURL *URL = nil;
|
||||
if (records && records.firstObject) {
|
||||
urlComponents.host = [QNIP ipHost:records.firstObject.value];
|
||||
}
|
||||
|
||||
URL = urlComponents.URL;
|
||||
return URL;
|
||||
}
|
||||
|
||||
static QNGetAddrInfoCallback getAddrInfoCallback = nil;
|
||||
static qn_ips_ret *dns_callback_internal(const char *host) {
|
||||
if (getAddrInfoCallback == nil) {
|
||||
return NULL;
|
||||
}
|
||||
NSString *s = [[NSString alloc] initWithUTF8String:host];
|
||||
if (s == nil) {
|
||||
return NULL;
|
||||
}
|
||||
NSArray *ips = getAddrInfoCallback(s);
|
||||
if (ips == nil) {
|
||||
return NULL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
static qn_ips_ret *dns_callback(const char *host) {
|
||||
qn_ips_ret *ret = dns_callback_internal(host);
|
||||
if (ret == NULL) {
|
||||
//only for compatible
|
||||
qn_ips_ret *ret = calloc(sizeof(char *), 2);
|
||||
ret->ips[0] = strdup(host);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static QNIpStatusCallback ipStatusCallback = nil;
|
||||
static void ip_status_callback(const char *ip, int code, int time_ms) {
|
||||
if (ipStatusCallback == nil) {
|
||||
return;
|
||||
}
|
||||
NSString *s = [[NSString alloc] initWithUTF8String:ip];
|
||||
if (s == nil) {
|
||||
return;
|
||||
}
|
||||
ipStatusCallback(s, code, time_ms);
|
||||
}
|
||||
|
||||
+ (void)setGetAddrInfoBlock:(QNGetAddrInfoCallback)block {
|
||||
if ([QNIP isIpV6FullySupported] || ![QNIP isV6]) {
|
||||
getAddrInfoCallback = block;
|
||||
qn_set_dns_callback(dns_callback);
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)setDnsManagerForGetAddrInfo:(QNDnsManager *)dns {
|
||||
[QNDnsManager setGetAddrInfoBlock:^NSArray<NSString *> *(NSString *host) {
|
||||
NSArray *records = [dns queryRecords:host];
|
||||
return records2Ips(records);
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)setIpStatusCallback:(QNIpStatusCallback)block {
|
||||
ipStatusCallback = block;
|
||||
qn_set_ip_report_callback(ip_status_callback);
|
||||
}
|
||||
|
||||
+ (BOOL)needHttpDns {
|
||||
NSTimeZone *timeZone = [NSTimeZone localTimeZone];
|
||||
NSString *tzName = [timeZone name];
|
||||
return [tzName isEqual:@"Asia/Shanghai"] || [tzName isEqual:@"Asia/Chongqing"] || [tzName isEqual:@"Asia/Harbin"] || [tzName isEqual:@"Asia/Urumqi"];
|
||||
}
|
||||
@end
|
||||
27
Pods/HappyDNS/HappyDNS/Common/QNDomain.h
generated
Normal file
27
Pods/HappyDNS/HappyDNS/Common/QNDomain.h
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// QNDomain.h
|
||||
// HappyDNS
|
||||
//
|
||||
// Created by bailong on 15/6/23.
|
||||
// Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface QNDomain : NSObject
|
||||
@property (nonatomic, strong, readonly) NSString *domain;
|
||||
|
||||
// 用来判断劫持
|
||||
@property (nonatomic, readonly) BOOL hasCname;
|
||||
// 用来判断劫持
|
||||
@property (nonatomic, readonly) int maxTtl;
|
||||
|
||||
@property (nonatomic, readonly) BOOL hostsFirst;
|
||||
|
||||
- (instancetype)init:(NSString *)domain;
|
||||
|
||||
- (instancetype)init:(NSString *)domain hostsFirst:(BOOL)hostsFirst hasCname:(BOOL)hasCname;
|
||||
|
||||
- (instancetype)init:(NSString *)domain hostsFirst:(BOOL)hostsFirst hasCname:(BOOL)hasCname maxTtl:(int)maxTtl;
|
||||
|
||||
@end
|
||||
30
Pods/HappyDNS/HappyDNS/Common/QNDomain.m
generated
Normal file
30
Pods/HappyDNS/HappyDNS/Common/QNDomain.m
generated
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// QNDomain.m
|
||||
// HappyDNS
|
||||
//
|
||||
// Created by bailong on 15/6/23.
|
||||
// Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QNDomain.h"
|
||||
|
||||
@implementation QNDomain
|
||||
- (instancetype)init:(NSString *)domain {
|
||||
return [self init:domain hostsFirst:NO hasCname:NO maxTtl:0];
|
||||
}
|
||||
|
||||
- (instancetype)init:(NSString *)domain hostsFirst:(BOOL)hostsFirst hasCname:(BOOL)hasCname {
|
||||
return [self init:domain hostsFirst:hostsFirst hasCname:hasCname maxTtl:0];
|
||||
}
|
||||
|
||||
- (instancetype)init:(NSString *)domain hostsFirst:(BOOL)hostsFirst hasCname:(BOOL)hasCname maxTtl:(int)maxTtl {
|
||||
if (self = [super init]) {
|
||||
_domain = domain;
|
||||
_hasCname = hasCname;
|
||||
_maxTtl = maxTtl;
|
||||
_hostsFirst = hostsFirst;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
23
Pods/HappyDNS/HappyDNS/Common/QNLruCache.h
generated
Normal file
23
Pods/HappyDNS/HappyDNS/Common/QNLruCache.h
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// QNLruCache.h
|
||||
// HappyDNS
|
||||
//
|
||||
// Created by bailong on 16/7/5.
|
||||
// Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface QNLruCache : NSObject
|
||||
|
||||
- (instancetype)init:(NSUInteger)limit;
|
||||
|
||||
- (void)removeAllObjects;
|
||||
|
||||
- (void)removeObjectForKey:(NSString *)key;
|
||||
|
||||
- (id)objectForKey:(NSString *)key;
|
||||
|
||||
- (void)setObject:(id)obj forKey:(NSString *)key;
|
||||
|
||||
@end
|
||||
90
Pods/HappyDNS/HappyDNS/Common/QNLruCache.m
generated
Normal file
90
Pods/HappyDNS/HappyDNS/Common/QNLruCache.m
generated
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// QNLruCache.m
|
||||
// HappyDNS
|
||||
//
|
||||
// Created by bailong on 16/7/5.
|
||||
// Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QNLruCache.h"
|
||||
|
||||
@interface QNLruCache ()
|
||||
|
||||
@property (nonatomic, readonly) NSUInteger limit;
|
||||
|
||||
@property (nonatomic, readonly) NSMutableDictionary* cache;
|
||||
|
||||
@property (nonatomic, readonly) NSMutableArray* list;
|
||||
|
||||
@end
|
||||
|
||||
@interface _QNElement : NSObject
|
||||
@property (nonatomic, readonly, strong) NSString* key;
|
||||
@property (nonatomic, strong) id obj;
|
||||
- (instancetype)initObject:(id)obj forKey:(NSString*)key;
|
||||
@end
|
||||
|
||||
@implementation _QNElement
|
||||
|
||||
- (instancetype)initObject:(id)obj forKey:(NSString*)key {
|
||||
if (self = [super init]) {
|
||||
_key = key;
|
||||
_obj = obj;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation QNLruCache
|
||||
|
||||
- (instancetype)init:(NSUInteger)limit {
|
||||
if (self = [super init]) {
|
||||
_limit = limit;
|
||||
_cache = [NSMutableDictionary new];
|
||||
_list = [NSMutableArray new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)removeAllObjects {
|
||||
[_cache removeAllObjects];
|
||||
[_list removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)removeObjectForKey:(NSString*)key {
|
||||
_QNElement* obj = [_cache objectForKey:key];
|
||||
if (obj == nil) {
|
||||
return;
|
||||
}
|
||||
[_cache removeObjectForKey:key];
|
||||
[_list removeObjectIdenticalTo:obj];
|
||||
}
|
||||
|
||||
- (id)objectForKey:(NSString*)key {
|
||||
_QNElement* obj = [_cache objectForKey:key];
|
||||
if (obj != nil) {
|
||||
[_list removeObjectIdenticalTo:obj];
|
||||
[_list insertObject:obj atIndex:0];
|
||||
}
|
||||
return obj.obj;
|
||||
}
|
||||
|
||||
- (void)setObject:(id)obj forKey:(NSString*)key {
|
||||
_QNElement* old = [_cache objectForKey:key];
|
||||
if (old) {
|
||||
old.obj = obj;
|
||||
[_list removeObjectIdenticalTo:old];
|
||||
[_list insertObject:old atIndex:0];
|
||||
return;
|
||||
} else if (_list.count == _limit) {
|
||||
old = [_list lastObject];
|
||||
[_list removeLastObject];
|
||||
[_cache removeObjectForKey:old.key];
|
||||
}
|
||||
_QNElement* newElement = [[_QNElement alloc] initObject:obj forKey:key];
|
||||
[_cache setObject:newElement forKey:key];
|
||||
[_list insertObject:newElement atIndex:0];
|
||||
}
|
||||
|
||||
@end
|
||||
42
Pods/HappyDNS/HappyDNS/Common/QNNetworkInfo.h
generated
Normal file
42
Pods/HappyDNS/HappyDNS/Common/QNNetworkInfo.h
generated
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// QNNetworkInfo.h
|
||||
// HappyDNS
|
||||
//
|
||||
// Created by bailong on 15/6/25.
|
||||
// Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
extern const int kQNNO_NETWORK;
|
||||
extern const int kQNWIFI;
|
||||
extern const int kQNMOBILE;
|
||||
|
||||
extern const int kQNISP_GENERAL;
|
||||
extern const int kQNISP_CTC;
|
||||
extern const int kQNISP_DIANXIN;
|
||||
extern const int kQNISP_CNC;
|
||||
extern const int kQNISP_LIANTONG;
|
||||
extern const int kQNISP_CMCC;
|
||||
extern const int kQNISP_YIDONG;
|
||||
extern const int kQNISP_OTHER;
|
||||
|
||||
@interface QNNetworkInfo : NSObject
|
||||
|
||||
@property (nonatomic, readonly) int networkConnection;
|
||||
@property (nonatomic, readonly) int provider;
|
||||
|
||||
- (instancetype)init:(int)connecton provider:(int)provider;
|
||||
|
||||
- (BOOL)isEqual:(id)other;
|
||||
- (BOOL)isEqualToInfo:(QNNetworkInfo *)info;
|
||||
|
||||
+ (instancetype)noNet;
|
||||
|
||||
+ (instancetype)normal;
|
||||
|
||||
+ (BOOL)isNetworkChanged;
|
||||
|
||||
+ (NSString *)getIp;
|
||||
|
||||
@end
|
||||
86
Pods/HappyDNS/HappyDNS/Common/QNNetworkInfo.m
generated
Normal file
86
Pods/HappyDNS/HappyDNS/Common/QNNetworkInfo.m
generated
Normal file
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// QNNetworkInfo.m
|
||||
// HappyDNS
|
||||
//
|
||||
// Created by bailong on 15/6/25.
|
||||
// Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
|
||||
//
|
||||
|
||||
#import <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#import "QNIP.h"
|
||||
#import "QNNetworkInfo.h"
|
||||
|
||||
const int kQNNO_NETWORK = -1;
|
||||
const int kQNWIFI = 1;
|
||||
const int kQNMOBILE = 2;
|
||||
|
||||
const int kQNISP_GENERAL = 0;
|
||||
const int kQNISP_CTC = 1;
|
||||
const int kQNISP_DIANXIN = kQNISP_CTC;
|
||||
const int kQNISP_CNC = 2;
|
||||
const int kQNISP_LIANTONG = kQNISP_CNC;
|
||||
const int kQNISP_CMCC = 3;
|
||||
const int kQNISP_YIDONG = kQNISP_CMCC;
|
||||
const int kQNISP_OTHER = 999;
|
||||
|
||||
#define IPLength 64
|
||||
|
||||
static char previousIp[IPLength] = {0};
|
||||
static NSString *lock = @"";
|
||||
|
||||
@implementation QNNetworkInfo
|
||||
|
||||
- (instancetype)init:(int)connecton provider:(int)provider {
|
||||
if (self = [super init]) {
|
||||
_networkConnection = connecton;
|
||||
_provider = provider;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)noNet {
|
||||
return [[QNNetworkInfo alloc] init:kQNNO_NETWORK provider:kQNISP_GENERAL];
|
||||
}
|
||||
|
||||
+ (instancetype)normal {
|
||||
return [[QNNetworkInfo alloc] init:kQNISP_GENERAL provider:kQNISP_GENERAL];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToInfo:(QNNetworkInfo *)info {
|
||||
if (self == info)
|
||||
return YES;
|
||||
return self.provider == info.provider && self.networkConnection == info.networkConnection;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)other {
|
||||
if (other == self)
|
||||
return YES;
|
||||
if (!other || ![other isKindOfClass:[self class]])
|
||||
return NO;
|
||||
return [self isEqualToInfo:other];
|
||||
}
|
||||
|
||||
+ (BOOL)isNetworkChanged {
|
||||
@synchronized(lock) {
|
||||
char local[IPLength] = {0};
|
||||
int err = qn_localIp(local, sizeof(local));
|
||||
if (err != 0) {
|
||||
return YES;
|
||||
}
|
||||
if (memcmp(previousIp, local, sizeof(local)) != 0) {
|
||||
memcpy(previousIp, local, sizeof(local));
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSString *)getIp {
|
||||
return [QNIP local];
|
||||
}
|
||||
@end
|
||||
69
Pods/HappyDNS/HappyDNS/Common/QNRecord.h
generated
Normal file
69
Pods/HappyDNS/HappyDNS/Common/QNRecord.h
generated
Normal file
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// QNRecord.h
|
||||
// HappyDNS
|
||||
//
|
||||
// Created by bailong on 15/6/23.
|
||||
// Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* A 记录
|
||||
*/
|
||||
extern const int kQNTypeA;
|
||||
|
||||
/**
|
||||
* AAAA 记录
|
||||
*/
|
||||
extern const int kQNTypeAAAA;
|
||||
|
||||
/**
|
||||
* Cname 记录
|
||||
*/
|
||||
extern const int kQNTypeCname;
|
||||
|
||||
/**
|
||||
* Txt 记录
|
||||
*/
|
||||
extern const int kQNTypeTXT;
|
||||
|
||||
/**
|
||||
* 永久有效的 ttl
|
||||
*/
|
||||
extern const int kQNRecordForeverTTL;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, QNRecordSource) {
|
||||
QNRecordSourceUnknown,
|
||||
QNRecordSourceCustom,
|
||||
QNRecordSourceDnspodEnterprise,
|
||||
QNRecordSourceSystem,
|
||||
QNRecordSourceUdp,
|
||||
QNRecordSourceDoh,
|
||||
};
|
||||
|
||||
|
||||
@interface QNRecord : NSObject
|
||||
|
||||
@property (nonatomic, copy, readonly) NSString *value;
|
||||
@property (nonatomic, copy, readonly) NSString *server;
|
||||
@property (nonatomic, readonly) int ttl;
|
||||
@property (nonatomic, readonly) int type;
|
||||
@property (nonatomic, readonly) long long timeStamp;
|
||||
@property (nonatomic, readonly) QNRecordSource source;
|
||||
|
||||
- (instancetype)init:(NSString *)value
|
||||
ttl:(int)ttl
|
||||
type:(int)type
|
||||
source:(QNRecordSource)source;
|
||||
|
||||
- (instancetype)init:(NSString *)value
|
||||
ttl:(int)ttl
|
||||
type:(int)type
|
||||
timeStamp:(long long)timeStamp
|
||||
server:(NSString *)server
|
||||
source:(QNRecordSource)source;
|
||||
|
||||
- (BOOL)expired:(long long)time;
|
||||
|
||||
@end
|
||||
60
Pods/HappyDNS/HappyDNS/Common/QNRecord.m
generated
Normal file
60
Pods/HappyDNS/HappyDNS/Common/QNRecord.m
generated
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// QNRecord.m
|
||||
// HappyDNS
|
||||
//
|
||||
// Created by bailong on 15/6/23.
|
||||
// Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QNRecord.h"
|
||||
|
||||
const int kQNTypeA = 1;
|
||||
const int kQNTypeAAAA = 28;
|
||||
const int kQNTypeCname = 5;
|
||||
const int kQNTypeTXT = 16;
|
||||
const int kQNRecordForeverTTL = -1;
|
||||
|
||||
@implementation QNRecord
|
||||
- (instancetype)init:(NSString *)value
|
||||
ttl:(int)ttl
|
||||
type:(int)type
|
||||
source:(QNRecordSource)source {
|
||||
if (self = [super init]) {
|
||||
_value = value;
|
||||
_type = type;
|
||||
_ttl = ttl;
|
||||
_source = source;
|
||||
_timeStamp = [[NSDate date] timeIntervalSince1970];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init:(NSString *)value
|
||||
ttl:(int)ttl
|
||||
type:(int)type
|
||||
timeStamp:(long long)timeStamp
|
||||
server:(NSString *)server
|
||||
source:(QNRecordSource)source {
|
||||
if (self = [super init]) {
|
||||
_value = value;
|
||||
_type = type;
|
||||
_ttl = ttl;
|
||||
_server = server;
|
||||
_source = source;
|
||||
_timeStamp = timeStamp;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)expired:(long long)time {
|
||||
if (_ttl == kQNRecordForeverTTL) {
|
||||
return false;
|
||||
}
|
||||
return time > _timeStamp + _ttl;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"value:%@, ttl:%d, timestamp:%lld, type:%d server:%@ source:%lu", _value, _ttl, _timeStamp, _type, _server, (unsigned long)_source];
|
||||
}
|
||||
|
||||
@end
|
||||
19
Pods/HappyDNS/HappyDNS/Common/QNResolverDelegate.h
generated
Normal file
19
Pods/HappyDNS/HappyDNS/Common/QNResolverDelegate.h
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// QNResolverDelegate.h
|
||||
// HappyDNS
|
||||
//
|
||||
// Created by bailong on 15/6/23.
|
||||
// Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QNDnsError.h"
|
||||
|
||||
#define QN_DNS_DEFAULT_TIMEOUT 20 //seconds
|
||||
|
||||
@class QNDomain;
|
||||
@class QNNetworkInfo;
|
||||
@protocol QNResolverDelegate <NSObject>
|
||||
|
||||
- (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError **)error;
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user