Im my iOS application, I want to resolve the DNS service records (SRV) of a domain.
I found some libraries that allows to do this, but the response is empty. One of the library that I tried is DNS. The code looks sometihng like this:
import UIKit
import DNS
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let url = "_registration._tcp.gateway.zeeotp.com"
print("Starting discovery")
do {
let request = Message(
type: .query,
authoritativeAnswer: false,
questions: [Question(name: url, type: .service)]
)
let requestData = try request.serialize()
// Decoding a message
let responseData = requestData
let response = try Message.init(deserialize: responseData)
print(response)
} catch {
print("Unexpected error: \(error).")
}
}
}
And the output I get is:
DNS Request(id: 0, authoritativeAnswer: false, truncation: false, recursionDesired: false, recursionAvailable: false, questions: [DNS.Question(name: "_registration._tcp.gateway.zeeotp.com.", type: SRV, unique: false, internetClass: A)], answers: [], authorities: [], additional: [])
During my research I came accross SRVResolver but it is in Objective-C and I have no clue how to make it work with Swift.
Is there something that I am missing in the ablove code to make it work correctly?
After trying various things, I finally was able to make this work. As mentioned in comments by @Paulw11, the library DNS did not send the actual DNS request and hence I was not getting the desired result.
Option 1:
I finally decided to integrate the Objective-C example provided by Apple into my Swift application. To do so,
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#include "SRVResolver.h"
libresolv.tbd
in Link Binary With Libraries section under target's Build PhasesNow in my ViewController.swift
I was able to use it as follows to get the priority
, weight
and hostname
values:
let url = "_registration._tcp.gateway.zeeotp.com"
print("Starting discovery")
let resolver = SRVResolver.init(srvName: url)
assert(resolver != nil)
resolver?.delegate = self
resolver?.start()
while !(resolver!.isFinished) {
RunLoop.current.run(mode: .default, before: Date.distantFuture)
}
if(resolver?.error == nil) {
for result in resolver?.results ?? [] {
let dataArray = result as! NSDictionary;
for (key, value) in dataArray { // loop through data items
print("\(key) -> \(value)")
}
}
} else {
print("Error: \(String(describing: resolver?.error))")
}
Option: 2
I also found an external library NioDNS that allows us to do some DNS operations. Using this library also I was able to retrieve the SRV records. In my ViewController.swift
I added the following code:
import NIO
import DNSClient
let loop: MultiThreadedEventLoopGroup!
do {
loop = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let client = try DNSClient.connect(on: loop).wait()
let records = try client.getSRVRecords(from: url).wait()
for record in records {
print(record.resource.weight)
print(record.resource.priority)
print(record.resource.domainName.string)
}
} catch {
print("Error: \(error)")
}