This library provides a cross-platform mDNS and DNS-DS library in C++.
Currently this library is only a C++ wrapper around Mattias Jansson (@maniccoder) mdns.h file -> all feature credits go to him. His work is licensed with the The Unlicense license.
why does this exist:
- better integration in C++ projects
- better usage of modern C++ features
- higher level API
- pass logger function to library to use users logger
The library does DNS-SD discovery and service as well as one-shot single record mDNS query and response.
mkdir build
cd build
cmake ..
make -j
make install
you can either install the library, include the library as subdirectory or use conan: mdns_cpp/0.1.0@gocarlos/testing
# add subdirectory
add_subdirectory(vendor/mdns_cpp)
# or install / use conan
find_package(mdns_cpp)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE mdns_cpp::mdns_cpp)
See the example folder for the different examples:
#include <thread>
#include "mdns_cpp/mdns.hpp"
int main() {
mdns_cpp::mDNS mdns;
mdns.setServiceHostname("AirForce1");
mdns.startService();
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
To listen for incoming DNS-SD requests and mDNS queries the socket can be opened/setup on the default interface by passing 0 as socket address in the call to the socket open/setup functions (the socket will receive data from all network interfaces). Then call mdns_socket_listen
either on notification of incoming data, or by setting blocking mode and calling mdns_socket_listen
to block until data is available and parsed.
The entry type passed to the callback will be MDNS_ENTRYTYPE_QUESTION
and record type MDNS_RECORDTYPE_PTR
. Use the mdns_record_parse_ptr
function to get the name string of the service record that was asked for.
If service record name is _services._dns-sd._udp.local.
you should use mdns_discovery_answer
to send the records of the services you provide (DNS-SD).
If the service record name is a service you provide, use mdns_query_answer
to send the service details back in response to the query.
See the test executable implementation for more details on how to handle the parameters to the given functions.
#include <thread>
#include "mdns_cpp/mdns.hpp"
int main() {
mdns_cpp::mDNS mdns;
mdns.executeDiscovery();
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
To send a DNS-SD service discovery request use mdns_discovery_send
. This will send a single multicast packet (single PTR question record for _services._dns-sd._udp.local.
) requesting a unicast response.
To read discovery responses use mdns_discovery_recv
. All records received since last call will be piped to the callback supplied in the function call. The entry type will be one of MDNS_ENTRYTYPE_ANSWER
, MDNS_ENTRYTYPE_AUTHORITY
and MDNS_ENTRYTYPE_ADDITIONAL
.
#include <thread>
#include "mdns_cpp/mdns.hpp"
int main() {
mdns_cpp::mDNS mdns;
const std::string service = "_http._tcp.local.";
mdns.executeQuery(service);
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
To send a one-shot mDNS query for a single record use mdns_query_send
. This will send a single multicast packet for the given record (single PTR question record, for example _http._tcp.local.
). You can optionally pass in a query ID for the query for later filtering of responses (even though this is discouraged by the RFC), or pass 0 to be fully compliant. The function returns the query ID associated with this query, which if non-zero can be used to filter responses in mdns_query_recv
. If the socket is bound to port 5353 a multicast response is requested, otherwise a unicast response.
To read query responses use mdns_query_recv
. All records received since last call will be piped to the callback supplied in the function call. If query_id
parameter is non-zero the function will filter out any response with a query ID that does not match the given query ID. The entry type will be one of MDNS_ENTRYTYPE_ANSWER
, MDNS_ENTRYTYPE_AUTHORITY
and MDNS_ENTRYTYPE_ADDITIONAL
.