1 #include "tinysvcmdns.h"
2
3 extern "C" {
4 #include "mdnsd.h"
5 }
6
7 #include <QHostInfo>
8 #include <QNetworkInterface>
9 #include <QtEndian>
10
11 #include "core/logging.h"
12
CreateMdnsd(uint32_t ipv4,QString ipv6)13 void TinySVCMDNS::CreateMdnsd(uint32_t ipv4, QString ipv6) {
14 // Get our hostname
15 QString host = QHostInfo::localHostName();
16
17 // Start the service
18 mdnsd* mdnsd = mdnsd_start_bind(ipv4);
19
20 // Set our hostname
21 mdnsd_set_hostname(mdnsd, QString(host + ".local").toUtf8().constData(),
22 ipv4);
23
24 // Add to the list
25 mdnsd_.append(mdnsd);
26 }
27
TinySVCMDNS()28 TinySVCMDNS::TinySVCMDNS() {
29 // Get all network interfaces
30 QList<QNetworkInterface> network_interfaces =
31 QNetworkInterface::allInterfaces();
32 for (QNetworkInterface network_interface : network_interfaces) {
33 // Only use up and non loopback interfaces
34 if (network_interface.flags().testFlag(network_interface.IsUp) &&
35 !network_interface.flags().testFlag(network_interface.IsLoopBack)) {
36 uint32_t ipv4 = 0;
37 QString ipv6;
38
39 qLog(Debug) << "Interface" << network_interface.humanReadableName();
40
41 // Now check all network addresses for this device
42 QList<QNetworkAddressEntry> network_address_entries =
43 network_interface.addressEntries();
44
45 for (QNetworkAddressEntry network_address_entry :
46 network_address_entries) {
47 QHostAddress host_address = network_address_entry.ip();
48 if (host_address.protocol() == QAbstractSocket::IPv4Protocol) {
49 ipv4 = qToBigEndian(host_address.toIPv4Address());
50 qLog(Debug) << " ipv4:" << host_address.toString();
51 } else if (host_address.protocol() == QAbstractSocket::IPv6Protocol) {
52 ipv6 = host_address.toString();
53 qLog(Debug) << " ipv6:" << host_address.toString();
54 }
55 }
56
57 // Now start the service
58 CreateMdnsd(ipv4, ipv6);
59 }
60 }
61 }
62
~TinySVCMDNS()63 TinySVCMDNS::~TinySVCMDNS() {
64 for (mdnsd* mdnsd : mdnsd_) {
65 mdnsd_stop(mdnsd);
66 }
67 }
68
PublishInternal(const QString & domain,const QString & type,const QByteArray & name,quint16 port)69 void TinySVCMDNS::PublishInternal(const QString& domain, const QString& type,
70 const QByteArray& name, quint16 port) {
71
72 // Some pointless text, so tinymDNS publishes the service correctly.
73 const char* txt[] = {"cat=nyan", nullptr};
74
75 for (mdnsd* mdnsd : mdnsd_) {
76 mdnsd_register_svc(mdnsd, name.constData(),
77 QString(type + ".local").toUtf8().constData(), port,
78 nullptr, txt);
79 }
80 }
81