Windows: Publish service on all interfaces.

This commit is contained in:
Andreas 2013-03-08 15:20:31 +01:00
parent fa5a16e057
commit 79c2aaacd9
4 changed files with 51 additions and 39 deletions

View File

@ -102,7 +102,7 @@ static void log_message(int loglevel, char *fmt_str, ...) {
fprintf(stderr, "%s\n", buf); 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); int sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd < 0) { if (sd < 0) {
log_message(LOG_ERR, "recv socket(): %m"); log_message(LOG_ERR, "recv socket(): %m");
@ -122,7 +122,7 @@ static int create_recv_sock() {
memset(&serveraddr, 0, sizeof(serveraddr)); memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET; serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(MDNS_PORT); 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) { if ((r = bind(sd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0) {
log_message(LOG_ERR, "recv bind(): %m"); log_message(LOG_ERR, "recv bind(): %m");
} }
@ -609,6 +609,10 @@ void mdns_service_destroy(struct mdns_service *srv) {
} }
struct mdnsd *mdnsd_start() { struct mdnsd *mdnsd_start() {
return mdnsd_start_bind(htonl(INADDR_ANY));
}
struct mdnsd *mdnsd_start_bind(uint32_t bind_ip) {
pthread_t tid; pthread_t tid;
pthread_attr_t attr; pthread_attr_t attr;
@ -621,7 +625,7 @@ struct mdnsd *mdnsd_start() {
return NULL; return NULL;
} }
server->sockfd = create_recv_sock(); server->sockfd = create_recv_sock(bind_ip);
if (server->sockfd < 0) { if (server->sockfd < 0) {
log_message(LOG_ERR, "unable to create recv socket"); log_message(LOG_ERR, "unable to create recv socket");
free(server); free(server);

View File

@ -37,6 +37,7 @@ struct mdns_service;
// starts a MDNS responder instance // starts a MDNS responder instance
// returns NULL if unsuccessful // returns NULL if unsuccessful
struct mdnsd *mdnsd_start(); struct mdnsd *mdnsd_start();
struct mdnsd *mdnsd_start_bind(uint32_t bind_ip);
// stops the given MDNS responder instance // stops the given MDNS responder instance
void mdnsd_stop(struct mdnsd *s); void mdnsd_stop(struct mdnsd *s);

View File

@ -10,36 +10,41 @@ extern "C" {
#include "core/logging.h" #include "core/logging.h"
namespace {
uint32_t GetLocalIPAddress() {
QList<QHostAddress> 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() TinySVCMDNS::TinySVCMDNS()
: mdnsd_(NULL) { : mdnsd_(NULL) {
uint32_t ip_address = GetLocalIPAddress(); // Get our hostname
if (ip_address == 0) {
qLog(Warning) << "Could not publish service over mDNS as there is no"
<< "non-local IPv4 interface";
return;
}
mdnsd_ = mdnsd_start();
QString host = QHostInfo::localHostName(); QString host = QHostInfo::localHostName();
mdnsd_set_hostname(
mdnsd_, // Get all network interfaces
QString(host + ".local").toUtf8().constData(), QList<QNetworkInterface> network_interfaces = QNetworkInterface::allInterfaces();
ip_address); 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<QNetworkAddressEntry> 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() { TinySVCMDNS::~TinySVCMDNS() {
@ -62,12 +67,14 @@ void TinySVCMDNS::PublishInternal(
"cat=nyan", "cat=nyan",
NULL NULL
}; };
mdnsd_register_svc( foreach(mdnsd* mdnsd, mdnsd_) {
mdnsd_, mdnsd_register_svc(
name.constData(), mdnsd,
QString(type + ".local").toUtf8().constData(), name.constData(),
port, QString(type + ".local").toUtf8().constData(),
NULL, port,
txt); NULL,
txt);
}
} }

View File

@ -18,7 +18,7 @@ class TinySVCMDNS : public Zeroconf {
quint16 port); quint16 port);
private: private:
mdnsd* mdnsd_; QList<mdnsd*> mdnsd_;
}; };
#endif // TINYSVCMDNS_H #endif // TINYSVCMDNS_H