From 79c2aaacd928b74b8ba32af0353a5f3ee412f1a9 Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 8 Mar 2013 15:20:31 +0100 Subject: [PATCH] Windows: Publish service on all interfaces. --- 3rdparty/tinysvcmdns/mdnsd.c | 10 ++-- 3rdparty/tinysvcmdns/mdnsd.h | 1 + src/networkremote/tinysvcmdns.cpp | 77 +++++++++++++++++-------------- src/networkremote/tinysvcmdns.h | 2 +- 4 files changed, 51 insertions(+), 39 deletions(-) diff --git a/3rdparty/tinysvcmdns/mdnsd.c b/3rdparty/tinysvcmdns/mdnsd.c index aef6c3a5e..2a9919648 100644 --- a/3rdparty/tinysvcmdns/mdnsd.c +++ b/3rdparty/tinysvcmdns/mdnsd.c @@ -102,7 +102,7 @@ static void log_message(int loglevel, char *fmt_str, ...) { fprintf(stderr, "%s\n", buf); } -static int create_recv_sock() { +static int create_recv_sock(uint32_t bind_ip) { int sd = socket(AF_INET, SOCK_DGRAM, 0); if (sd < 0) { log_message(LOG_ERR, "recv socket(): %m"); @@ -122,7 +122,7 @@ static int create_recv_sock() { memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(MDNS_PORT); - serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); /* receive multicast */ + serveraddr.sin_addr.s_addr = bind_ip; /* receive multicast */ if ((r = bind(sd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0) { log_message(LOG_ERR, "recv bind(): %m"); } @@ -609,6 +609,10 @@ void mdns_service_destroy(struct mdns_service *srv) { } struct mdnsd *mdnsd_start() { + return mdnsd_start_bind(htonl(INADDR_ANY)); +} + +struct mdnsd *mdnsd_start_bind(uint32_t bind_ip) { pthread_t tid; pthread_attr_t attr; @@ -621,7 +625,7 @@ struct mdnsd *mdnsd_start() { return NULL; } - server->sockfd = create_recv_sock(); + server->sockfd = create_recv_sock(bind_ip); if (server->sockfd < 0) { log_message(LOG_ERR, "unable to create recv socket"); free(server); diff --git a/3rdparty/tinysvcmdns/mdnsd.h b/3rdparty/tinysvcmdns/mdnsd.h index 99f1b865e..e4c3573e3 100644 --- a/3rdparty/tinysvcmdns/mdnsd.h +++ b/3rdparty/tinysvcmdns/mdnsd.h @@ -37,6 +37,7 @@ struct mdns_service; // starts a MDNS responder instance // returns NULL if unsuccessful struct mdnsd *mdnsd_start(); +struct mdnsd *mdnsd_start_bind(uint32_t bind_ip); // stops the given MDNS responder instance void mdnsd_stop(struct mdnsd *s); diff --git a/src/networkremote/tinysvcmdns.cpp b/src/networkremote/tinysvcmdns.cpp index 4399f5f96..03d75f605 100644 --- a/src/networkremote/tinysvcmdns.cpp +++ b/src/networkremote/tinysvcmdns.cpp @@ -10,36 +10,41 @@ extern "C" { #include "core/logging.h" -namespace { - -uint32_t GetLocalIPAddress() { - QList addresses = QNetworkInterface::allAddresses(); - foreach (const QHostAddress& address, addresses) { - // TODO: Add ipv6 support to tinysvcmdns. - if (address.protocol() == QAbstractSocket::IPv4Protocol && - !address.isInSubnet(QHostAddress::parseSubnet("127.0.0.1/8"))) { - return qToBigEndian(address.toIPv4Address()); - } - } - return 0; -} - -} // namespace - TinySVCMDNS::TinySVCMDNS() : mdnsd_(NULL) { - uint32_t ip_address = GetLocalIPAddress(); - if (ip_address == 0) { - qLog(Warning) << "Could not publish service over mDNS as there is no" - << "non-local IPv4 interface"; - return; - } - mdnsd_ = mdnsd_start(); + // Get our hostname QString host = QHostInfo::localHostName(); - mdnsd_set_hostname( - mdnsd_, - QString(host + ".local").toUtf8().constData(), - ip_address); + + // Get all network interfaces + QList network_interfaces = QNetworkInterface::allInterfaces(); + foreach (QNetworkInterface network_interface, network_interfaces) { + // Only use up and non loopback interfaces + if (network_interface..flags().testFlag(a.IsUp) + && !network_interface..flags().testFlag(a.IsLoopBack)) + { + uint32_t ipv4 = 0; + + // Now check all network addresses for this device + QList network_address_entries = a.addressEntries(); + foreach (QNetworkAddressEntry network_address_entry, network_address_entries) { + QHostAddress host_address = network_address_entry.ip(); + if (host_address.protocol() == QAbstractSocket::IPv4Protocol) { + ipv4 = qToBigEndian(host_address.toIPv4Address()); + } + } + + // Now start the service + mdnsd* mdnsd = mdnsd_start_bind(ipv4); + + mdnsd_set_hostname( + mdnsd, + QString(host + ".local").toUtf8().constData(), + ip_address); + + // Add to the list + mdnsd_.append(mdnsd); + } + } } TinySVCMDNS::~TinySVCMDNS() { @@ -62,12 +67,14 @@ void TinySVCMDNS::PublishInternal( "cat=nyan", NULL }; - - mdnsd_register_svc( - mdnsd_, - name.constData(), - QString(type + ".local").toUtf8().constData(), - port, - NULL, - txt); + + foreach(mdnsd* mdnsd, mdnsd_) { + mdnsd_register_svc( + mdnsd, + name.constData(), + QString(type + ".local").toUtf8().constData(), + port, + NULL, + txt); + } } diff --git a/src/networkremote/tinysvcmdns.h b/src/networkremote/tinysvcmdns.h index 7d40c8ab5..a1d6fda27 100644 --- a/src/networkremote/tinysvcmdns.h +++ b/src/networkremote/tinysvcmdns.h @@ -18,7 +18,7 @@ class TinySVCMDNS : public Zeroconf { quint16 port); private: - mdnsd* mdnsd_; + QList mdnsd_; }; #endif // TINYSVCMDNS_H