Skip to content
Permalink
Browse files

Add IPv6 UPNP support

This adds some UPNP support for IPV6 only setups. The frontend
auto-discovery now works through IPv6. I cannot get Windows media
center to see MythTV through IPV6, perhaps IPv6 is not supported
by Windows Media Center in this way.

There are now some extra settings available. Setting IPv4Support to 0
disables IPv4 listening and setting IPv6Support to 0 disables IPv6
listening.

Fixes #12316
  • Loading branch information...
bennettpeter committed Apr 15, 2017
1 parent ae81146 commit 79844ba0d7c834f6760f745a84f2ce3b4a93e1ac
@@ -332,7 +332,10 @@ QList<QHostAddress> ServerPool::DefaultBroadcast(void)
{
QList<QHostAddress> blist;
if (!gCoreContext->GetNumSetting("ListenOnAllIps",1))
{
blist << DefaultBroadcastIPv4();
blist << DefaultBroadcastIPv6();
}
return blist;
}

@@ -351,10 +354,12 @@ QList<QHostAddress> ServerPool::DefaultBroadcastIPv4(void)
return blist;
}

//QList<QHostAddress> ServerPool::DefaultBroadcastIPv6(void)
//{
//
//}
QList<QHostAddress> ServerPool::DefaultBroadcastIPv6(void)
{
QList<QHostAddress> blist;
blist << QHostAddress("FF02::1");
return blist;
}


void ServerPool::close(void)
@@ -388,6 +393,11 @@ bool ServerPool::listen(QList<QHostAddress> addrs, quint16 port,

for (it = addrs.begin(); it != addrs.end(); ++it)
{
// If IPV4 support is disabled and this is an IPV4 address,
// bypass this address
if (it->protocol() == QAbstractSocket::IPv4Protocol
&& ! gCoreContext->GetNumSetting("IPv4Support",1))
continue;
// If IPV6 support is disabled and this is an IPV6 address,
// bypass this address
if (it->protocol() == QAbstractSocket::IPv6Protocol
@@ -437,6 +447,15 @@ bool ServerPool::listen(QList<QHostAddress> addrs, quint16 port,
continue;
}

if (server->serverError() == QAbstractSocket::UnsupportedSocketOperationError
&& it->protocol() == QAbstractSocket::IPv4Protocol)
{
LOG(VB_GENERAL, LOG_INFO,
QString("No IPv4 support on this system. Disabling MythTV IPv4."));
gCoreContext->OverrideSettingForSession("IPv4Support", "0");
continue;
}

if (server->serverError() == QAbstractSocket::UnsupportedSocketOperationError
&& it->protocol() == QAbstractSocket::IPv6Protocol)
{
@@ -485,6 +504,17 @@ bool ServerPool::bind(QList<QHostAddress> addrs, quint16 port,

for (it = addrs.begin(); it != addrs.end(); ++it)
{
// If IPV4 support is disabled and this is an IPV4 address,
// bypass this address
if (it->protocol() == QAbstractSocket::IPv4Protocol
&& ! gCoreContext->GetNumSetting("IPv4Support",1))
continue;
// If IPV6 support is disabled and this is an IPV6 address,
// bypass this address
if (it->protocol() == QAbstractSocket::IPv6Protocol
&& ! gCoreContext->GetNumSetting("IPv6Support",1))
continue;

QNetworkAddressEntry host;

if (it->protocol() == QAbstractSocket::IPv6Protocol)
@@ -70,7 +70,7 @@ class MBASE_PUBLIC ServerPool : public QObject
static QList<QHostAddress> DefaultListenIPv6(void);
static QList<QHostAddress> DefaultBroadcast(void);
static QList<QHostAddress> DefaultBroadcastIPv4(void);
// static QList<QHostAddress> DefaultBroadcastIPv6(void);
static QList<QHostAddress> DefaultBroadcastIPv6(void);

bool listen(QList<QHostAddress> addrs, quint16 port, bool requireall=true,
PoolServerType type = kTCPServer);
@@ -12,6 +12,7 @@

#include <QNetworkInterface>

#include "mythcorecontext.h"
#include "upnptaskcache.h"
#include "mythlogging.h"
#include "serverpool.h"
@@ -127,6 +128,23 @@ bool UPnp::Initialize( QList<QHostAddress> &sIPAddrList, int nServicePort, HttpS
}

g_IPAddrList = sIPAddrList;
int it;
bool ipv4 = gCoreContext->GetNumSetting("IPv4Support",1);
bool ipv6 = gCoreContext->GetNumSetting("IPv6Support",1);

for (it = 0; it < g_IPAddrList.size(); ++it)
{
// If IPV4 support is disabled and this is an IPV4 address,
// remove this address
// If IPV6 support is disabled and this is an IPV6 address,
// remove this address
if ((g_IPAddrList[it].protocol() == QAbstractSocket::IPv4Protocol
&& ! ipv4)
||(g_IPAddrList[it].protocol() == QAbstractSocket::IPv6Protocol
&& ! ipv6))
g_IPAddrList.removeAt(it--);
}

m_nServicePort = nServicePort;

// ----------------------------------------------------------------------
@@ -108,7 +108,13 @@ void UPnpNotifyTask::SendNotifyMsg( MSocketDevice *pSocket,
continue;
}

QString ipaddress = (*it).toString();
QHostAddress ip = *it;
// Descope the Link Local address. The scope is only valid
// on the server sending the announcement, not the clients
// that receive it
ip.setScopeId(QString());

QString ipaddress = ip.toString();

// If this looks like an IPv6 address, then enclose it in []'s
if (ipaddress.contains(":"))
@@ -108,29 +108,24 @@ void UPnpSearchTask::SendMsg( MSocketDevice *pSocket,
{
QString ipaddress;


// Avoid announcing the localhost address
if (*it == QHostAddress::LocalHost ||
*it == QHostAddress::LocalHostIPv6 ||
*it == QHostAddress::AnyIPv4 ||
*it == QHostAddress::AnyIPv6)
continue;

QHostAddress ip = *it;
// Descope the Link Local address. The scope is only valid
// on the server sending the announcement, not the clients
// that receive it
// FIXME what happens for scopeId "4"? Do we remove all 4s from the address?
// http://doc.qt.io/qt-5/qhostaddress.html#scopeId
if ((*it).isInSubnet(kLinkLocal6))
{
ipaddress = "[" + (*it).toString()
.remove('%').remove((*it).scopeId()) + "]";
}
ip.setScopeId(QString());

// If this looks like an IPv6 address, then enclose it in []'s
else if ((*it).protocol() == QAbstractSocket::IPv6Protocol)
ipaddress = "[" + (*it).toString() + "]";
if (ip.protocol() == QAbstractSocket::IPv6Protocol)
ipaddress = "[" + ip.toString() + "]";
else
ipaddress = (*it).toString();
ipaddress = ip.toString();

QString sHeader = QString ( "HTTP/1.1 200 OK\r\n"
"LOCATION: http://%1:%2/getDeviceDesc\r\n" )

0 comments on commit 79844ba

Please sign in to comment.
You can’t perform that action at this time.