diff --git a/CMakeLists.txt b/CMakeLists.txt index db6220d..d693531 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,13 +59,13 @@ if(BUILD_DOC) add_subdirectory(doc) endif() -option(BUILD_EXAMPLES "Build example applications" OFF) +option(BUILD_EXAMPLES "Build example applications" ON) if(BUILD_EXAMPLES) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED) add_subdirectory(examples) endif() -option(BUILD_TESTS "Build test suite" OFF) +option(BUILD_TESTS "Build test suite" ON) if(BUILD_TESTS) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Test REQUIRED) enable_testing() diff --git a/examples/browser/CMakeLists.txt b/examples/browser/CMakeLists.txt index f472ae7..75d3329 100644 --- a/examples/browser/CMakeLists.txt +++ b/examples/browser/CMakeLists.txt @@ -4,15 +4,20 @@ set(SRC servicemodel.cpp ) -add_executable(browser WIN32 ${SRC}) +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_executable(browser ${SRC}) +else() + add_executable(browser WIN32 ${SRC}) +endif() set_target_properties(browser PROPERTIES CXX_STANDARD 11 ) -target_link_libraries(browser qmdnsengine Qt${QT_VERSION_MAJOR}::Widgets) +target_link_libraries(browser PRIVATE qmdnsengine Qt${QT_VERSION_MAJOR}::Widgets) install(TARGETS browser RUNTIME DESTINATION "${EXAMPLE_DIR}" + LIBRARY DESTINATION "${EXAMPLE_DIR}" COMPONENT examples ) diff --git a/examples/provider/CMakeLists.txt b/examples/provider/CMakeLists.txt index bea09e7..8be7598 100644 --- a/examples/provider/CMakeLists.txt +++ b/examples/provider/CMakeLists.txt @@ -3,11 +3,16 @@ set(SRC provider.cpp ) -add_executable(provider WIN32 ${SRC}) +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_executable(provider ${SRC}) +else() + add_executable(provider WIN32 ${SRC}) +endif() -target_link_libraries(provider qmdnsengine Qt${QT_VERSION_MAJOR}::Widgets) +target_link_libraries(provider PRIVATE qmdnsengine Qt${QT_VERSION_MAJOR}::Widgets) install(TARGETS provider RUNTIME DESTINATION "${EXAMPLE_DIR}" + LIBRARY DESTINATION "${EXAMPLE_DIR}" COMPONENT examples ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e2368d2..2957e7b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,7 +71,7 @@ target_include_directories(qmdnsengine PUBLIC "$" ) -target_link_libraries(qmdnsengine Qt${QT_VERSION_MAJOR}::Network) +target_link_libraries(qmdnsengine PUBLIC Qt${QT_VERSION_MAJOR}::Network) install(TARGETS qmdnsengine EXPORT qmdnsengine-export diff --git a/src/src/server.cpp b/src/src/server.cpp index e91566e..af00b3f 100644 --- a/src/src/server.cpp +++ b/src/src/server.cpp @@ -44,7 +44,7 @@ using namespace QMdnsEngine; ServerPrivate::ServerPrivate(Server *server) : QObject(server), - q(server) + q(server) { connect(&timer, &QTimer::timeout, this, &ServerPrivate::onTimeout); connect(&ipv4Socket, &QUdpSocket::readyRead, this, &ServerPrivate::onReadyRead); @@ -62,26 +62,10 @@ bool ServerPrivate::bindSocket(QUdpSocket &socket, const QHostAddress &address) return true; } - // I cannot find the correct combination of flags that allows the socket - // to bind properly on Linux, so on that platform, we must manually create - // the socket and initialize the QUdpSocket with it - -#ifdef Q_OS_UNIX - if (!socket.bind(address, MdnsPort, QAbstractSocket::ShareAddress)) { - int arg = 1; - if (setsockopt(socket.socketDescriptor(), SOL_SOCKET, SO_REUSEADDR, - reinterpret_cast(&arg), sizeof(int))) { - emit q->error(strerror(errno)); - return false; - } -#endif - if (!socket.bind(address, MdnsPort, QAbstractSocket::ReuseAddressHint)) { - emit q->error(socket.errorString()); - return false; - } -#ifdef Q_OS_UNIX + if (!socket.bind(address, MdnsPort, QAbstractSocket::ShareAddress | QAbstractSocket::ReuseAddressHint)) { + emit q->error(socket.errorString()); + return false; } -#endif return true; } @@ -135,7 +119,7 @@ void ServerPrivate::onReadyRead() Server::Server(QObject *parent) : AbstractServer(parent), - d(new ServerPrivate(this)) + d(new ServerPrivate(this)) { } @@ -143,10 +127,23 @@ void Server::sendMessage(const Message &message) { QByteArray packet; toPacket(message, packet); - if (message.address().protocol() == QAbstractSocket::IPv4Protocol) { - d->ipv4Socket.writeDatagram(packet, message.address(), message.port()); + + QUdpSocket *socket = (message.address().protocol() == QAbstractSocket::IPv4Protocol) + ? &d->ipv4Socket + : &d->ipv6Socket; + + if (message.address().isMulticast()) { + const auto interfaces = QNetworkInterface::allInterfaces(); + for (const QNetworkInterface &iface : interfaces) { + if ((iface.flags() & QNetworkInterface::IsUp) && + (iface.flags() & QNetworkInterface::CanMulticast)) { + + socket->setMulticastInterface(iface); + socket->writeDatagram(packet, message.address(), message.port()); + } + } } else { - d->ipv6Socket.writeDatagram(packet, message.address(), message.port()); + socket->writeDatagram(packet, message.address(), message.port()); } } @@ -154,6 +151,18 @@ void Server::sendMessageToAll(const Message &message) { QByteArray packet; toPacket(message, packet); - d->ipv4Socket.writeDatagram(packet, MdnsIpv4Address, MdnsPort); - d->ipv6Socket.writeDatagram(packet, MdnsIpv6Address, MdnsPort); + + const auto interfaces = QNetworkInterface::allInterfaces(); + for (const QNetworkInterface &iface : interfaces) { + + if ((iface.flags() & QNetworkInterface::IsUp) && + (iface.flags() & QNetworkInterface::CanMulticast)) { + + d->ipv4Socket.setMulticastInterface(iface); + d->ipv4Socket.writeDatagram(packet, MdnsIpv4Address, MdnsPort); + + d->ipv6Socket.setMulticastInterface(iface); + d->ipv6Socket.writeDatagram(packet, MdnsIpv6Address, MdnsPort); + } + } }