2

iOSでNAPTRを見つけるためにDNSを照会する方法を見つけるのに多くの問題を抱えています。IPに解決するための比較的簡単な方法はたくさんあるようですが、DNSルックアップですべてのNAPTRレコードを見つける必要があります。可能であれば、外部ライブラリを持ち込むことなく、そうすることを望んでいます。誰かがこれ(または私が推定できる類似のもの)を行うことができたなら、私はどんなポインタでもありがたいです。

すべてのコードはiOS5.0以降で機能する必要があります

4

1 に答える 1

4

最終的に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);
}

これは私にとってはうまくいくようです。もちろん、コールバックで解析されたすべてのデータを使用して他の必要な作業を行うか、後で使用するためにデータをどこかに保存します。

于 2013-03-19T18:16:48.673 に答える