Skip to content

Commit 69dfdd2

Browse files
Merge PR #4494: FEAT(client, server): use native mDNS/DNS-SD API on Windows, if available
2 parents 66c4838 + ee731f8 commit 69dfdd2

21 files changed

+730
-240
lines changed

.ci/travis-ci/script.bash

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
3939
PATH=$PATH:/usr/lib/mxe/usr/bin
4040

4141
${MUMBLE_HOST}.static-cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -Dtests=ON -Dversion=$VER -Dstatic=ON -Dsymbols=ON -Dasio=ON \
42-
-Dbonjour=OFF -Dice=OFF -Doverlay=OFF -Donline-tests=ON ..
42+
-Dzeroconf=OFF -Dice=OFF -Doverlay=OFF -Donline-tests=ON ..
4343
cmake --build .
4444
# TODO: investigate why tests fail.
4545
#ctest

src/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ option(server "Build the server (Murmur)" ON)
1010

1111
option(qssldiffiehellmanparameters "Build support for custom Diffie-Hellman parameters." ON)
1212

13-
option(bonjour "Build support for Bonjour." ON)
13+
option(zeroconf "Build support for zeroconf (mDNS/DNS-SD)." ON)
1414

1515
option(dbus "Build support for DBus." ON)
1616

src/mumble/BonjourClient.cpp

-21
This file was deleted.

src/mumble/BonjourClient.h

-23
This file was deleted.

src/mumble/CMakeLists.txt

+6-5
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ if(g15)
814814
endif()
815815
endif()
816816

817-
if(bonjour)
817+
if(zeroconf)
818818
if(NOT APPLE)
819819
find_pkg(avahi-compat-libdns_sd QUIET)
820820
if(avahi-compat-libdns_sd_FOUND)
@@ -831,17 +831,18 @@ if(bonjour)
831831

832832
target_sources(mumble
833833
PRIVATE
834-
"BonjourClient.cpp"
835-
"BonjourClient.h"
836-
834+
"Zeroconf.cpp"
835+
"Zeroconf.h"
836+
# Unlike what the name implies, this 3rdparty helper is not actually related to Bonjour.
837+
# It just uses the API provided by mDNSResponder, making it compatible with Avahi too.
837838
"${3RDPARTY_DIR}/qqbonjour/BonjourRecord.h"
838839
"${3RDPARTY_DIR}/qqbonjour/BonjourServiceBrowser.cpp"
839840
"${3RDPARTY_DIR}/qqbonjour/BonjourServiceBrowser.h"
840841
"${3RDPARTY_DIR}/qqbonjour/BonjourServiceResolver.cpp"
841842
"${3RDPARTY_DIR}/qqbonjour/BonjourServiceResolver.h"
842843
)
843844

844-
target_compile_definitions(mumble PRIVATE "USE_BONJOUR")
845+
target_compile_definitions(mumble PRIVATE "USE_ZEROCONF")
845846
target_include_directories(mumble PRIVATE "${3RDPARTY_DIR}/qqbonjour")
846847
endif()
847848

src/mumble/ConnectDialog.cpp

+64-73
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55

66
#include "ConnectDialog.h"
77

8-
#ifdef USE_BONJOUR
9-
# include "BonjourClient.h"
10-
# include "BonjourServiceBrowser.h"
11-
# include "BonjourServiceResolver.h"
8+
#ifdef USE_ZEROCONF
9+
# include "Zeroconf.h"
1210
#endif
1311

1412
#include "Channel.h"
@@ -102,7 +100,7 @@ ServerView::ServerView(QWidget *p) : QTreeWidget(p) {
102100
siFavorite->setExpanded(true);
103101
siFavorite->setHidden(true);
104102

105-
#ifdef USE_BONJOUR
103+
#ifdef USE_ZEROCONF
106104
siLAN = new ServerItem(tr("LAN"), ServerItem::LANType);
107105
addTopLevelItem(siLAN);
108106
siLAN->setExpanded(true);
@@ -220,10 +218,10 @@ ServerItem::ServerItem(const FavoriteServer &fs) : QTreeWidgetItem(QTreeWidgetIt
220218
qsUrl = fs.qsUrl;
221219

222220
bCA = false;
223-
#ifdef USE_BONJOUR
221+
#ifdef USE_ZEROCONF
224222
if (fs.qsHostname.startsWith(QLatin1Char('@'))) {
225-
qsBonjourHost = fs.qsHostname.mid(1);
226-
brRecord = BonjourRecord(qsBonjourHost, QLatin1String("_mumble._tcp."), QLatin1String("local."));
223+
zeroconfHost = fs.qsHostname.mid(1);
224+
zeroconfRecord = BonjourRecord(zeroconfHost, QLatin1String("_mumble._tcp."), QLatin1String("local."));
227225
} else {
228226
qsHostname = fs.qsHostname;
229227
}
@@ -261,10 +259,10 @@ ServerItem::ServerItem(const QString &name, const QString &host, unsigned short
261259
qsPassword = password;
262260

263261
bCA = false;
264-
#ifdef USE_BONJOUR
262+
#ifdef USE_ZEROCONF
265263
if (host.startsWith(QLatin1Char('@'))) {
266-
qsBonjourHost = host.mid(1);
267-
brRecord = BonjourRecord(qsBonjourHost, QLatin1String("_mumble._tcp."), QLatin1String("local."));
264+
zeroconfHost = host.mid(1);
265+
zeroconfRecord = BonjourRecord(zeroconfHost, QLatin1String("_mumble._tcp."), QLatin1String("local."));
268266
} else {
269267
qsHostname = host;
270268
}
@@ -274,16 +272,16 @@ ServerItem::ServerItem(const QString &name, const QString &host, unsigned short
274272
init();
275273
}
276274

277-
#ifdef USE_BONJOUR
275+
#ifdef USE_ZEROCONF
278276
ServerItem::ServerItem(const BonjourRecord &br) : QTreeWidgetItem(QTreeWidgetItem::UserType) {
279-
siParent = nullptr;
280-
bParent = false;
281-
itType = LANType;
282-
qsName = br.serviceName;
283-
qsBonjourHost = qsName;
284-
brRecord = br;
285-
usPort = 0;
286-
bCA = false;
277+
siParent = nullptr;
278+
bParent = false;
279+
itType = LANType;
280+
qsName = br.serviceName;
281+
zeroconfHost = qsName;
282+
zeroconfRecord = br;
283+
usPort = 0;
284+
bCA = false;
287285

288286
init();
289287
}
@@ -314,9 +312,9 @@ ServerItem::ServerItem(const ServerItem *si) {
314312
qsCountryCode = si->qsCountryCode;
315313
qsContinentCode = si->qsContinentCode;
316314
qsUrl = si->qsUrl;
317-
#ifdef USE_BONJOUR
318-
qsBonjourHost = si->qsBonjourHost;
319-
brRecord = si->brRecord;
315+
#ifdef USE_ZEROCONF
316+
zeroconfHost = si->zeroconfHost;
317+
zeroconfRecord = si->zeroconfRecord;
320318
#endif
321319
qlAddresses = si->qlAddresses;
322320
bCA = si->bCA;
@@ -490,10 +488,10 @@ QVariant ServerItem::data(int column, int role) const {
490488
.arg(ConnectDialog::tr("Servername"), qsName.toHtmlEscaped())
491489
+ QString::fromLatin1("<tr><th align=left>%1</th><td>%2</td></tr>")
492490
.arg(ConnectDialog::tr("Hostname"), qsHostname.toHtmlEscaped());
493-
#ifdef USE_BONJOUR
494-
if (!qsBonjourHost.isEmpty())
491+
#ifdef USE_ZEROCONF
492+
if (!zeroconfHost.isEmpty())
495493
qs += QString::fromLatin1("<tr><th align=left>%1</th><td>%2</td></tr>")
496-
.arg(ConnectDialog::tr("Bonjour name"), qsBonjourHost.toHtmlEscaped());
494+
.arg(ConnectDialog::tr("Bonjour name"), zeroconfHost.toHtmlEscaped());
497495
#endif
498496
qs += QString::fromLatin1("<tr><th align=left>%1</th><td>%2</td></tr>")
499497
.arg(ConnectDialog::tr("Port"))
@@ -592,9 +590,9 @@ void ServerItem::setDatas(double elapsed, quint32 users, quint32 maxusers) {
592590
FavoriteServer ServerItem::toFavoriteServer() const {
593591
FavoriteServer fs;
594592
fs.qsName = qsName;
595-
#ifdef USE_BONJOUR
596-
if (!qsBonjourHost.isEmpty())
597-
fs.qsHostname = QLatin1Char('@') + qsBonjourHost;
593+
#ifdef USE_ZEROCONF
594+
if (!zeroconfHost.isEmpty())
595+
fs.qsHostname = QLatin1Char('@') + zeroconfHost;
598596
else
599597
fs.qsHostname = qsHostname;
600598
#else
@@ -944,7 +942,7 @@ ConnectDialog::ConnectDialog(QWidget *p, bool autoconnect) : QDialog(p), bAutoCo
944942

945943
bAllowPing = g.s.ptProxyType == Settings::NoProxy;
946944
bAllowHostLookup = g.s.ptProxyType == Settings::NoProxy;
947-
bAllowBonjour = g.s.ptProxyType == Settings::NoProxy;
945+
bAllowZeroconf = g.s.ptProxyType == Settings::NoProxy;
948946
bAllowFilters = g.s.ptProxyType == Settings::NoProxy;
949947

950948
if (tPublicServers.elapsed() >= 60 * 24 * 1000000ULL) {
@@ -1033,22 +1031,16 @@ ConnectDialog::ConnectDialog(QWidget *p, bool autoconnect) : QDialog(p), bAutoCo
10331031
startDns(si);
10341032
qtwServers->siFavorite->addServerItem(si);
10351033
}
1034+
#ifdef USE_ZEROCONF
1035+
if (bAllowZeroconf && g.zeroconf && g.zeroconf->isOk()) {
1036+
connect(g.zeroconf, &Zeroconf::recordsChanged, this, &ConnectDialog::onUpdateLanList);
1037+
connect(g.zeroconf, &Zeroconf::recordResolved, this, &ConnectDialog::onResolved);
1038+
connect(g.zeroconf, &Zeroconf::resolveError, this, &ConnectDialog::onLanResolveError);
1039+
onUpdateLanList(g.zeroconf->currentRecords());
10361040

1037-
#ifdef USE_BONJOUR
1038-
// Make sure the we got the objects we need, then wire them up
1039-
if (bAllowBonjour && g.bc->bsbBrowser && g.bc->bsrResolver) {
1040-
connect(g.bc->bsbBrowser.data(), SIGNAL(error(DNSServiceErrorType)), this,
1041-
SLOT(onLanBrowseError(DNSServiceErrorType)));
1042-
connect(g.bc->bsbBrowser.data(), SIGNAL(currentBonjourRecordsChanged(const QList< BonjourRecord > &)), this,
1043-
SLOT(onUpdateLanList(const QList< BonjourRecord > &)));
1044-
connect(g.bc->bsrResolver.data(), SIGNAL(error(BonjourRecord, DNSServiceErrorType)), this,
1045-
SLOT(onLanResolveError(BonjourRecord, DNSServiceErrorType)));
1046-
connect(g.bc->bsrResolver.data(), SIGNAL(bonjourRecordResolved(BonjourRecord, QString, int)), this,
1047-
SLOT(onResolved(BonjourRecord, QString, int)));
1048-
onUpdateLanList(g.bc->bsbBrowser->currentRecords());
1041+
g.zeroconf->startBrowser(QLatin1String("_mumble._tcp"));
10491042
}
10501043
#endif
1051-
10521044
qtPingTick = new QTimer(this);
10531045
connect(qtPingTick, SIGNAL(timeout()), this, SLOT(timeTick()));
10541046

@@ -1082,6 +1074,12 @@ ConnectDialog::ConnectDialog(QWidget *p, bool autoconnect) : QDialog(p), bAutoCo
10821074
}
10831075

10841076
ConnectDialog::~ConnectDialog() {
1077+
#ifdef USE_ZEROCONF
1078+
if (bAllowZeroconf && g.zeroconf && g.zeroconf->isOk()) {
1079+
g.zeroconf->stopBrowser();
1080+
g.zeroconf->cleanupResolvers();
1081+
}
1082+
#endif
10851083
ServerItem::qmIcons.clear();
10861084

10871085
QList< FavoriteServer > ql;
@@ -1175,9 +1173,9 @@ void ConnectDialog::on_qaFavoriteEdit_triggered() {
11751173
return;
11761174

11771175
QString host;
1178-
#ifdef USE_BONJOUR
1179-
if (!si->qsBonjourHost.isEmpty())
1180-
host = QLatin1Char('@') + si->qsBonjourHost;
1176+
#ifdef USE_ZEROCONF
1177+
if (!si->zeroconfHost.isEmpty())
1178+
host = QLatin1Char('@') + si->zeroconfHost;
11811179
else
11821180
host = si->qsHostname;
11831181
#else
@@ -1196,16 +1194,16 @@ void ConnectDialog::on_qaFavoriteEdit_triggered() {
11961194
si->reset();
11971195

11981196
si->usPort = cde->usPort;
1199-
#ifdef USE_BONJOUR
1197+
#ifdef USE_ZEROCONF
12001198
if (cde->qsHostname.startsWith(QLatin1Char('@'))) {
1201-
si->qsHostname = QString();
1202-
si->qsBonjourHost = cde->qsHostname.mid(1);
1203-
si->brRecord =
1204-
BonjourRecord(si->qsBonjourHost, QLatin1String("_mumble._tcp."), QLatin1String("local."));
1199+
si->qsHostname = QString();
1200+
si->zeroconfHost = cde->qsHostname.mid(1);
1201+
si->zeroconfRecord =
1202+
BonjourRecord(si->zeroconfHost, QLatin1String("_mumble._tcp."), QLatin1String("local."));
12051203
} else {
1206-
si->qsHostname = cde->qsHostname;
1207-
si->qsBonjourHost = QString();
1208-
si->brRecord = BonjourRecord();
1204+
si->qsHostname = cde->qsHostname;
1205+
si->zeroconfHost = QString();
1206+
si->zeroconfRecord = BonjourRecord();
12091207
}
12101208
#else
12111209
si->qsHostname = cde->qsHostname;
@@ -1355,11 +1353,11 @@ void ConnectDialog::initList() {
13551353
WebFetch::fetch(QLatin1String("publist"), url, this, SLOT(fetched(QByteArray, QUrl, QMap< QString, QString >)));
13561354
}
13571355

1358-
#ifdef USE_BONJOUR
1359-
void ConnectDialog::onResolved(BonjourRecord record, QString host, int port) {
1356+
#ifdef USE_ZEROCONF
1357+
void ConnectDialog::onResolved(const BonjourRecord record, const QString host, const uint16_t port) {
13601358
qlBonjourActive.removeAll(record);
13611359
foreach (ServerItem *si, qlItems) {
1362-
if (si->brRecord == record) {
1360+
if (si->zeroconfRecord == record) {
13631361
unsigned short usport = static_cast< unsigned short >(port);
13641362
if ((host != si->qsHostname) || (usport != si->usPort)) {
13651363
stopDns(si);
@@ -1384,7 +1382,7 @@ void ConnectDialog::onUpdateLanList(const QList< BonjourRecord > &list) {
13841382
foreach (const BonjourRecord &record, list) {
13851383
bool found = false;
13861384
foreach (ServerItem *si, old) {
1387-
if (si->brRecord == record) {
1385+
if (si->zeroconfRecord == record) {
13881386
items.insert(si);
13891387
found = true;
13901388
break;
@@ -1393,7 +1391,7 @@ void ConnectDialog::onUpdateLanList(const QList< BonjourRecord > &list) {
13931391
if (!found) {
13941392
ServerItem *si = new ServerItem(record);
13951393
qlItems << si;
1396-
g.bc->bsrResolver->resolveBonjourRecord(record);
1394+
g.zeroconf->startResolver(record);
13971395
startDns(si);
13981396
qtwServers->siLAN->addServerItem(si);
13991397
}
@@ -1406,13 +1404,8 @@ void ConnectDialog::onUpdateLanList(const QList< BonjourRecord > &list) {
14061404
}
14071405
}
14081406

1409-
void ConnectDialog::onLanBrowseError(DNSServiceErrorType err) {
1410-
qWarning() << "Bonjour reported browser error " << err;
1411-
}
1412-
1413-
void ConnectDialog::onLanResolveError(BonjourRecord br, DNSServiceErrorType err) {
1414-
qlBonjourActive.removeAll(br);
1415-
qWarning() << "Bonjour reported resolver error " << err;
1407+
void ConnectDialog::onLanResolveError(const BonjourRecord record) {
1408+
qlBonjourActive.removeAll(record);
14161409
}
14171410
#endif
14181411

@@ -1627,17 +1620,15 @@ void ConnectDialog::startDns(ServerItem *si) {
16271620
foreach (const ServerAddress &addr, si->qlAddresses) { qhPings[addr].insert(si); }
16281621
return;
16291622
}
1630-
1631-
#ifdef USE_BONJOUR
1632-
if (bAllowBonjour && si->qsHostname.isEmpty() && !si->brRecord.serviceName.isEmpty()) {
1633-
if (!qlBonjourActive.contains(si->brRecord)) {
1634-
g.bc->bsrResolver->resolveBonjourRecord(si->brRecord);
1635-
qlBonjourActive.append(si->brRecord);
1623+
#ifdef USE_ZEROCONF
1624+
if (bAllowZeroconf && si->qsHostname.isEmpty() && !si->zeroconfRecord.serviceName.isEmpty()) {
1625+
if (!qlBonjourActive.contains(si->zeroconfRecord)) {
1626+
g.zeroconf->startResolver(si->zeroconfRecord);
1627+
qlBonjourActive.append(si->zeroconfRecord);
16361628
}
16371629
return;
16381630
}
16391631
#endif
1640-
16411632
if (!qhDNSWait.contains(unresolved)) {
16421633
if (si->itType == ServerItem::PublicType)
16431634
qlDNSLookup.append(unresolved);

0 commit comments

Comments
 (0)