diff --git a/libnymea-core/hardware/network/avahi/qtavahiservice.cpp b/libnymea-core/hardware/network/avahi/qtavahiservice.cpp index 35cf95d9..a5fac526 100644 --- a/libnymea-core/hardware/network/avahi/qtavahiservice.cpp +++ b/libnymea-core/hardware/network/avahi/qtavahiservice.cpp @@ -52,6 +52,8 @@ #include "qtavahiservice_p.h" #include "loggingcategories.h" +#include + namespace nymeaserver { /*! Constructs a new \l{QtAvahiService} with the given \a parent. */ @@ -79,6 +81,12 @@ QtAvahiService::~QtAvahiService() delete d_ptr; } +/*! Returns the hostAddress of this \l{QtAvahiService}. */ +QHostAddress QtAvahiService::hostAddress() const +{ + return d_ptr->hostAddress; +} + /*! Returns the port of this \l{QtAvahiService}. */ quint16 QtAvahiService::port() const { @@ -108,7 +116,7 @@ QtAvahiService::QtAvahiServiceState QtAvahiService::state() const } /*! Register a new \l{QtAvahiService} with the given \a name and \a port. The service type can be specified with the \a serviceType string. The \a txtRecords records inform about additional information. Returns true if the service could be registered. */ -bool QtAvahiService::registerService(const QString &name, const quint16 &port, const QString &serviceType, const QHash &txtRecords) +bool QtAvahiService::registerService(const QString &name, const QHostAddress &hostAddress, const quint16 &port, const QString &serviceType, const QHash &txtRecords) { // Check if the client is running if (!d_ptr->client->m_client || AVAHI_CLIENT_S_RUNNING != avahi_client_get_state(d_ptr->client->m_client)) { @@ -117,6 +125,7 @@ bool QtAvahiService::registerService(const QString &name, const quint16 &port, c } d_ptr->name = name; + d_ptr->hostAddress = hostAddress; d_ptr->port = port; d_ptr->type = serviceType; d_ptr->txtRecords = txtRecords; @@ -128,9 +137,23 @@ bool QtAvahiService::registerService(const QString &name, const quint16 &port, c // If the group is empty if (avahi_entry_group_is_empty(d_ptr->group)) { // Add the service + AvahiIfIndex ifIndex = AVAHI_IF_UNSPEC; + if (hostAddress != QHostAddress("0.0.0.0")) { + foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) { + foreach (const QNetworkAddressEntry &addressEntry, interface.addressEntries()) { + QPair subnet = QHostAddress::parseSubnet(addressEntry.ip().toString() + "/" + addressEntry.netmask().toString()); + if (hostAddress.isInSubnet(subnet.first, subnet.second)) { + ifIndex = interface.index(); + break; + } + } + } + } + qCDebug(dcAvahi()) << "Registering avahi service" << name << hostAddress.toString() << port << serviceType << "on interface" << ifIndex; + d_ptr->serviceList = QtAvahiServicePrivate::createTxtList(txtRecords); d_ptr->error = avahi_entry_group_add_service_strlst(d_ptr->group, - AVAHI_IF_UNSPEC, + ifIndex, AVAHI_PROTO_INET, (AvahiPublishFlags) 0, d_ptr->name.toLatin1().data(), @@ -234,7 +257,7 @@ bool QtAvahiService::handlCollision() qCDebug(dcAvahi()) << "Service name colision. Picking alternative service name" << alternativeServiceName; resetService(); - return registerService(alternativeServiceName, port(), serviceType(), txtRecords()); + return registerService(alternativeServiceName, hostAddress(), port(), serviceType(), txtRecords()); } void QtAvahiService::onStateChanged(const QtAvahiServiceState &state) diff --git a/libnymea-core/hardware/network/avahi/qtavahiservice.h b/libnymea-core/hardware/network/avahi/qtavahiservice.h index 1e388688..fb574f20 100644 --- a/libnymea-core/hardware/network/avahi/qtavahiservice.h +++ b/libnymea-core/hardware/network/avahi/qtavahiservice.h @@ -26,7 +26,7 @@ #include #include #include - +#include namespace nymeaserver { @@ -49,13 +49,14 @@ public: explicit QtAvahiService(QObject *parent = nullptr); ~QtAvahiService(); + QHostAddress hostAddress() const; quint16 port() const; QString name() const; QString serviceType() const; QHash txtRecords() const; QtAvahiServiceState state() const; - bool registerService(const QString &name, const quint16 &port, const QString &serviceType = "_http._tcp", const QHash &txtRecords = QHash()); + bool registerService(const QString &name, const QHostAddress &hostAddress, const quint16 &port, const QString &serviceType = "_http._tcp", const QHash &txtRecords = QHash()); void resetService(); bool updateTxtRecord(const QHash &txtRecords); diff --git a/libnymea-core/hardware/network/avahi/qtavahiservice_p.h b/libnymea-core/hardware/network/avahi/qtavahiservice_p.h index 9e97cc3a..7f51f468 100644 --- a/libnymea-core/hardware/network/avahi/qtavahiservice_p.h +++ b/libnymea-core/hardware/network/avahi/qtavahiservice_p.h @@ -46,6 +46,7 @@ public: AvahiEntryGroup *group; AvahiStringList *serviceList = nullptr; QString name; + QHostAddress hostAddress; quint16 port; QString type; QHash txtRecords; diff --git a/libnymea-core/tcpserver.cpp b/libnymea-core/tcpserver.cpp index f07fcc79..c9742d2c 100644 --- a/libnymea-core/tcpserver.cpp +++ b/libnymea-core/tcpserver.cpp @@ -138,7 +138,7 @@ void TcpServer::resetAvahiService() txt.insert("uuid", NymeaCore::instance()->configuration()->serverUuid().toString()); txt.insert("name", NymeaCore::instance()->configuration()->serverName()); txt.insert("sslEnabled", configuration().sslEnabled ? "true" : "false"); - if (!m_avahiService->registerService(QString("nymea-tcp-%1").arg(configuration().id), configuration().port, "_jsonrpc._tcp", txt)) { + if (!m_avahiService->registerService(QString("nymea-tcp-%1").arg(configuration().id), configuration().address, configuration().port, "_jsonrpc._tcp", txt)) { qCWarning(dcTcpServer()) << "Could not register avahi service for" << configuration(); } } diff --git a/libnymea-core/webserver.cpp b/libnymea-core/webserver.cpp index 16894264..c6be1f7a 100644 --- a/libnymea-core/webserver.cpp +++ b/libnymea-core/webserver.cpp @@ -544,7 +544,7 @@ void WebServer::resetAvahiService() txt.insert("name", NymeaCore::instance()->configuration()->serverName()); txt.insert("sslEnabled", m_configuration.sslEnabled ? "true" : "false"); - if (!m_avahiService->registerService(QString("nymea-http-%1").arg(m_configuration.id), m_configuration.port, "_http._tcp", txt)) { + if (!m_avahiService->registerService(QString("nymea-http-%1").arg(m_configuration.id), m_configuration.address, m_configuration.port, "_http._tcp", txt)) { qCWarning(dcTcpServer()) << "Could not register avahi service for" << m_configuration; } } diff --git a/libnymea-core/websocketserver.cpp b/libnymea-core/websocketserver.cpp index 0bdb86ff..73b83cbb 100644 --- a/libnymea-core/websocketserver.cpp +++ b/libnymea-core/websocketserver.cpp @@ -201,7 +201,7 @@ void WebSocketServer::resetAvahiService() return; m_avahiService->resetService(); - if (!m_avahiService->registerService(QString("nymea-ws-%1").arg(configuration().id), configuration().port, "_ws._tcp", createTxtRecord())) { + if (!m_avahiService->registerService(QString("nymea-ws-%1").arg(configuration().id), configuration().address, configuration().port, "_ws._tcp", createTxtRecord())) { qCWarning(dcWebServer()) << "Could not register avahi service for" << configuration(); } }