-
-
Save valenting/dd1125978313320ee0ab7e52768ea48f to your computer and use it in GitHub Desktop.
DNSServiceQueryRecord MacOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <thread> | |
| #include <vector> | |
| #include <dns_sd.h> | |
| #include <unistd.h> | |
| #include <cstring> | |
| using std::string; | |
| void queryRecordCallback( | |
| 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 | |
| ) { | |
| if (errorCode == kDNSServiceErr_NoError) { | |
| printf("Received record for: %s\n", fullname); | |
| } else { | |
| printf("Error querying record: %d\n", errorCode); | |
| } | |
| } | |
| void performDNSQuery(const std::string& hostname) { | |
| std::string host = hostname; | |
| printf("starting query :%s\n", host.c_str()); | |
| DNSServiceRef sdRef; | |
| DNSServiceErrorType error = DNSServiceQueryRecord( | |
| &sdRef, | |
| 0, | |
| 0, | |
| host.c_str(), | |
| 1, | |
| kDNSServiceClass_IN, | |
| queryRecordCallback, | |
| nullptr | |
| ); | |
| if (error != kDNSServiceErr_NoError) { | |
| printf("Error starting query: %d\n", error); | |
| return; | |
| } | |
| int fd = DNSServiceRefSockFD(sdRef); | |
| fd_set readfds; | |
| FD_ZERO(&readfds); | |
| FD_SET(fd, &readfds); | |
| struct timeval timeout; | |
| timeout.tv_sec = 5; // 5-second timeout | |
| timeout.tv_usec = 0; | |
| printf("selecting\n"); | |
| struct timeval* select_timeout = NULL; | |
| // select_timeout = &timeout; | |
| // If the target domain doesn't have an HTTPS record | |
| // the callback never gets called and select hangs forever. | |
| // If this isn't a bug in the implementation this is the worst | |
| // API design ever! | |
| int result = select(fd + 1, &readfds, NULL, NULL, select_timeout); | |
| if (result > 0 && FD_ISSET(fd, &readfds)) { | |
| // Process the result | |
| DNSServiceProcessResult(sdRef); | |
| } else if (result == 0) { | |
| printf("select() timed out\n"); | |
| } else if (result < 0) { | |
| printf("select() failed\n"); | |
| } | |
| DNSServiceRefDeallocate(sdRef); | |
| printf("done query :%s\n", host.c_str()); | |
| } | |
| int main(int argc, char* argv[]) { | |
| // If an argument is passed, resolve only that domain | |
| std::string hostname = argv[1]; | |
| printf("Resolving single domain: %s\n", hostname.c_str()); | |
| performDNSQuery(hostname); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment