1
0
mirror of https://github.com/clementine-player/Clementine synced 2024-12-18 04:19:55 +01:00

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);
}
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);

View File

@ -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);

View File

@ -10,36 +10,41 @@ extern "C" {
#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()
: 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<QNetworkInterface> 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<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() {
@ -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);
}
}

View File

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