title: iOS Resolve DNS programmatically is returning invalid IPs sometimes
body: <p><strong>Hi,</strong></p>
  
  <p>I am working on an iOS app which requires to <strong>resolve DNS programmatically</strong>. </p>
  
  <p>Consider this as a proxy to resolve all dns queries on iPhone. I receive DNS queries from each app on iPhone and send back corresponding IPList</p>
  
  <p>I have tried a couple of methods but both have same kind of responses. The one I decided to move with is given below <strong>resolveHost</strong> function written in objective-c and c I am calling this method from swift code.</p>
  
  <p>This is how I am calling from swift, also sharing sample host/url, value of host can be any domain ("google.com, apple.com etc") or a domain/host as a result of trails when you open a site in mkwebview</p>
  
  <p>let host = "www.opera.com"</p>
  
  <p>let ipArray = ResolveUtil().resolveHost(host, usingDNSServer: "8.8.8.8") as! [String]</p>
  
  <p>More specifically <strong>Facebook app does not work well with IPs returned from function  resolveHost</strong></p>
  
  <p>By not working well I mean app <strong>does not connect to IPs</strong> returned from the functions</p>
  
  <p>Some times it returns <strong>192.16.192.16</strong> as part of other IPs for some hosts/domains. What is this IP?  </p>
  
  <pre><code>- (NSArray*)resolveHost:(NSString *)host usingDNSServer:(NSString *)dnsServer
  {
  
      NSMutableArray* result = [[NSMutableArray alloc] init];
      struct __res_state res;
      setup_dns_server(&amp;res, [dnsServer cStringUsingEncoding:NSASCIIStringEncoding]);
      int count;
      char** ips = query_ips(&amp;res, [host cStringUsingEncoding:NSUTF8StringEncoding], &amp;count);
      for (int i=0; i&lt;count; i++){
          [result addObject:[[NSString alloc] initWithCString:ips[i] encoding:NSASCIIStringEncoding]];
      }
  
      for (int i=0; i&lt;count; i++){
  
          free(ips[i]);
      }
      free(ips);
      ips = NULL;
  
      return result;
  
  }
  
  char ** query_ips(res_state res, const char *host, int* count)
  {
      u_char answer[NS_PACKETSZ];
      int len = res_nquery(res, host, ns_c_in, ns_t_a, answer, sizeof(answer));
  
      ns_msg handle;
      ns_initparse(answer, len, &amp;handle);
  
      int messageCount = ns_msg_count(handle, ns_s_an);
      *count = messageCount;
      char **ips = malloc(messageCount * sizeof(char *));
  
      for (int i=0; i &lt; messageCount; i++) {
          ips[i] = malloc(16 * sizeof(char));
          memset(ips[i], '\0', sizeof(16));
          ns_rr rr;
          if(ns_parserr(&amp;handle, ns_s_an, i, &amp;rr) == 0) {
              strcpy(ips[i], inet_ntoa(*(struct in_addr *)ns_rr_rdata(rr)));
          }
      }
      return ips;
  }
  </code></pre>
  
  <p><strong>Other Method</strong> </p>
  
  <pre><code>func resolveIp(_ hostUrl:String) -&gt; [String]{
          var ips:[String] = [String]()
          let host = CFHostCreateWithName(nil,hostUrl as CFString).takeRetainedValue()
          CFHostStartInfoResolution(host, .addresses, nil)
          var success: DarwinBoolean = false
          if let addresses = CFHostGetAddressing(host, &amp;success)?.takeUnretainedValue() as NSArray? {
              for case let theAddress as NSData in addresses {
                  var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                  if getnameinfo(theAddress.bytes.assumingMemoryBound(to: sockaddr.self), socklen_t(theAddress.length),
                                 &amp;hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 {
                      let numAddress = String(cString: hostname)
                      ips.append(numAddress)
                  }
              }
          }
          Logger.info("\(#function) validIPs:\(ips.joined(separator: "-")) url:\(hostUrl)")
          return ips
      }
  </code></pre>