Thursday, February 17, 2011

SRV record lookup with iPhone SDK

In either a Windows or Mac OS X terminal if you type...

nslookup -type=SRV _xmpp-server._tcp.gmail.com

... (for example) you will receive a bunch of SRV records relating to different google chat servers..

Does anyone have any experience in this area and possibly know how to service this information (hostname, port, weight, priority) using the iPhone SDK? I have experimented with the Bonjour classes, but as yet have had no luck..

Thanks!

From stackoverflow
  • The dig application may be a useful replacement for nslookup. If you run the following in OS X Terminal.app, you get the same information in a slightly different format:

    Host:~ username$ dig -t SRV _xmpp-server._tcp.gmail.com

    ; > DiG 9.4.2-P2 > -t SRV _xmpp-server._tcp.gmail.com ;; global options: printcmd ;; Got answer: ;; ->>HEADER ;; QUESTION SECTION: ;_xmpp-server._tcp.gmail.com. IN SRV

    ;; ANSWER SECTION: _xmpp-server._tcp.gmail.com. 78169 IN SRV 5 0 5269 xmpp-server.l.google.com. _xmpp-server._tcp.gmail.com. 78169 IN SRV 20 0 5269 xmpp-server1.l.google.com. _xmpp-server._tcp.gmail.com. 78169 IN SRV 20 0 5269 xmpp-server2.l.google.com. _xmpp-server._tcp.gmail.com. 78169 IN SRV 20 0 5269 xmpp-server3.l.google.com. _xmpp-server._tcp.gmail.com. 78169 IN SRV 20 0 5269 xmpp-server4.l.google.com.

    ;; Query time: 23 msec ;; SERVER: 10.0.1.1#53(10.0.1.1) ;; WHEN: Mon Nov 3 03:05:26 2008 ;; MSG SIZE rcvd: 269

    The iPhone is running OS X, so you might be able to run something like the following in your application:

    char digOutput;
    digOutput = system("dig -t SRV _xmpp-server._tcp.gmail.com > digOutput.txt");
    NSString *tempResult = [NSString stringWithContentsOfFile:@"/usr/share/digOutput.txt" encoding:4 error:nil];

    You might split tempResult by the \n newline separator, put the results into an NSArray and run an NSEnumerator over the array to get your answer section.

    I haven't tested this, so I don't know if dig is built into the iPhone OS X.

    Also, I'm not sure if you'll have access to /usr/share, although you should have access to your application's Documents subfolder to store temporary files.

    A better approach might be to pipe the results of the system() call into an awk statement to get the results more directly.

    Still a better approach, if dig is available, is to use an NSTask object to call dig and skip temporary file creation altogether.

    If you try this out, I'd be curious to know if it works.

    Louis Gerbarg : That will not work, you cannot fork applications on the phone.
  • Hmm, looks like I can't run system() on the Simulator or the device. I can run NSTask on the Simulator, but not the iPhone, and NSTask is not part of the Foundation framework.

    The ISC BIND package has a BSD license. If feasible, perhaps relevant parts of the dig code could be wrapped into the project directly.

  • I think your best bet is to implement a DNS query tool using CFNetwork.

    Try to read more about this here: http://developer.apple.com/documentation/Networking/Conceptual/CFNetwork/Introduction/chapter_1_section_1.html#//apple_ref/doc/uid/TP30001132-CH1-DontLinkElementID_24

  • I believe you need to use the DNSServiceDiscovery framework. I don't have the iPhone SDK, but a Google search suggests that it is available on the iPhone.

    See the Apple Developer Site for full API details.

    I've included some (incomplete) sample code too:

    #include <dns_sd.h>
    
    int main(int argc, char *argv[])
    {
       DNSServiceRef sdRef;
       DNSServiceErrorType res;
    
       DNSServiceQueryRecord(
         &sdRef, 0, 0,
         "_xmpp-server._tcp.gmail.com",
         kDNSServiceType_SRV,
         kDNSServiceClass_IN,
         callback,
         NULL
      );
    
      DNSServiceProcessResult(sdRef);
      DNSServiceRefDeallocate(sdRef);
    }
    

    You'll need to provide your own callback function, and note that the rdata field sent to the callback is in wire-format, so you'll have to decode the raw data from the SRV record fields yourself.

  • Thanks,

    I used the DNSServiceQueryRecord technique...

    good example here http://www.opensource.apple.com/darwinsource/10.3.1/mDNSResponder-58/mDNSMacOSX/SampleUDSClient.c

    Alnitak : please upvote useful answers...

0 comments:

Post a Comment