iOSでNAPTRを見つけるためにDNSを照会する方法を見つけるのに多くの問題を抱えています。IPに解決するための比較的簡単な方法はたくさんあるようですが、DNSルックアップですべてのNAPTRレコードを見つける必要があります。可能であれば、外部ライブラリを持ち込むことなく、そうすることを望んでいます。誰かがこれ(または私が推定できる類似のもの)を行うことができたなら、私はどんなポインタでもありがたいです。
すべてのコードはiOS5.0以降で機能する必要があります
iOSでNAPTRを見つけるためにDNSを照会する方法を見つけるのに多くの問題を抱えています。IPに解決するための比較的簡単な方法はたくさんあるようですが、DNSルックアップですべてのNAPTRレコードを見つける必要があります。可能であれば、外部ライブラリを持ち込むことなく、そうすることを望んでいます。誰かがこれ(または私が推定できる類似のもの)を行うことができたなら、私はどんなポインタでもありがたいです。
すべてのコードはiOS5.0以降で機能する必要があります
最終的にDNSServiceQueryRecordを使用しました。
DNSServiceRef sdRef;
DNSServiceQueryRecord(&sdRef, 0, 0,
"google.com",
kDNSServiceType_NAPTR,
kDNSServiceClass_IN,
callback,
NULL);
DNSServiceProcessResult(sdRef);
DNSServiceRefDeallocate(sdRef);
実際の使用では、結果がない場合にアプリが無期限にハングするという問題があったため、結果にタイムアウトを追加するようにコードを調整する必要がありました。
/*
Attempt to fetch the NAPTR from the stored server address. Since iOS will continue waiting
until told directly to stop (even if there is no result) we must set our own timeout on the
request (set to 5 seconds).
On success, the callback function is called. On timeout, the kSRVLookupComplete notification
is sent.
*/
- (void)attemptNAPTRFetch {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
DNSServiceRef sdRef;
DNSServiceErrorType err;
err = DNSServiceQueryRecord(&sdRef, 0, 0,
[server cStringUsingEncoding:[NSString defaultCStringEncoding]],
kDNSServiceType_NAPTR,
kDNSServiceClass_IN,
callback,
NULL);
// This stuff is necessary so we don't hang forever if there are no results
int dns_sd_fd = DNSServiceRefSockFD(sdRef);
int nfds = dns_sd_fd + 1;
fd_set readfds;
struct timeval tv;
int result;
int stopNow = 0;
int timeOut = 5; // Timeout in seconds
while (!stopNow) {
FD_ZERO(&readfds);
FD_SET(dns_sd_fd, &readfds);
tv.tv_sec = timeOut;
tv.tv_usec = 0;
result = select(nfds, &readfds, (fd_set*)NULL, (fd_set*)NULL, &tv);
if (result > 0) {
if(FD_ISSET(dns_sd_fd, &readfds)) {
err = DNSServiceProcessResult(sdRef);
if (err != kDNSServiceErr_NoError){
NSLog(@"There was an error");
}
stopNow = 1;
}
}
else {
printf("select() returned %d errno %d %s\n", result, errno, strerror(errno));
if (errno != EINTR) {
stopNow = 1;
postNotification(kSRVLookupComplete, nil);
}
}
}
DNSServiceRefDeallocate(sdRef);
});
}
次に、コールバックの場合:
static void callback(DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
const char *fullname,
uint16_t rrtype,
uint16_t rrclass,
uint16_t rdlen,
const void *rdata,
uint32_t ttl,
void *context)
{
uint16_t order, pref;
char flag;
NSMutableString *service = [[NSMutableString alloc] init];
NSMutableString *replacement = [[NSMutableString alloc] init];
const char *data = (const char*)rdata;
order = data[1];
pref = data[3];
flag = data[5];
int i = 7;
while (data[i] != 0){
[service appendString:[NSString stringWithFormat:@"%c", data[i]]];
i++;
}
i += 2;
while(data[i] != 0){
if(data[i] >= 32 && data[i] <= 127)
[replacement appendString:[NSString stringWithFormat:@"%c", data[i]]];
else
[replacement appendString:@"."];
i++;
}
NSLog(@"\nOrder: %i\nPreference: %i\nFlag: %c\nService: %@\nReplacement: %@\n", order, pref, flag, service, replacement);
}
これは私にとってはうまくいくようです。もちろん、コールバックで解析されたすべてのデータを使用して他の必要な作業を行うか、後で使用するためにデータをどこかに保存します。