IPv6 support (#1369)

* hyperion-remote - Support IPv6

* LEDDevices - Remove IPv6 limitations

* Separate JsonEditorHostValidation

* Standalone grabbers & JSON/Flatbuffer forwarder: IPv6 support

* remote: Fix setting multiple colors via Hex, add standard logging

* IPv6 Updates -Add db migration activities

* Addressing non-Windows compile issues

* Code cleanup, address clang feedback

* Update address (hostname, IPv4/IPv6) help text

* Apply migration steps to "old" configurations imported

* Show user the UI-Url, if hyperion is already running, address clang findings

* Windows Cmake OpenSLL output

* Minor Text update
This commit is contained in:
LordGrey
2021-11-17 20:30:43 +00:00
committed by GitHub
parent b33466d392
commit ad293b2fb6
61 changed files with 1714 additions and 926 deletions

View File

@@ -233,6 +233,12 @@ protected:
///
bool saveSettings(const QJsonObject &data);
///
/// @brief Restore settings object. Requires ADMIN ACCESS
/// @param data The data object
///
bool restoreSettings(const QJsonObject &data);
///
/// @brief Test if we are authorized to use the interface
/// @return The result

View File

@@ -229,6 +229,12 @@ private:
///
void handleConfigSetCommand(const QJsonObject &message, const QString &command, int tan);
/// Handle an incoming JSON RestoreConfig message from handleConfigCommand()
///
/// @param message the incoming message
///
void handleConfigRestoreCommand(const QJsonObject &message, const QString &command, int tan);
///
/// Handle an incoming JSON Component State message
///

View File

@@ -7,6 +7,7 @@
#include <QTcpSocket>
#include <QTimer>
#include <QMap>
#include <QHostAddress>
// hyperion util
#include <utils/Image.h>
@@ -16,6 +17,8 @@
#include <flatbuffers/flatbuffers.h>
const int FLATBUFFER_DEFAULT_PORT = 19400;
namespace hyperionnet
{
struct Reply;
@@ -32,10 +35,11 @@ class FlatBufferConnection : public QObject
public:
///
/// @brief Constructor
/// @param address The address of the Hyperion server (for example "192.168.0.32:19444)
/// @param host The hostname or IP-address of the Hyperion Flatbuffer server (for example "192.168.0.32")
/// @param port The port of the Hyperion Flatpuffer server (default is 19400)
/// @param skipReply If true skip reply
///
FlatBufferConnection(const QString& origin, const QString & address, int priority, bool skipReply);
FlatBufferConnection(const QString& origin, const QString& host, int priority, bool skipReply, quint16 port = FLATBUFFER_DEFAULT_PORT);
///
/// @brief Destructor

View File

@@ -324,6 +324,14 @@ public slots:
///
bool saveSettings(const QJsonObject& config, bool correct = false);
///
/// @brief Restore a complete json config
/// @param config The entire config object
/// @param correct If true will correct json against schema before save
/// @return True on success else false
///
bool restoreSettings(const QJsonObject& config, bool correct = false);
/// ############
/// COMPONENTREGISTER
///

View File

@@ -36,8 +36,8 @@ public:
MessageForwarder(Hyperion* hyperion);
~MessageForwarder() override;
void addJsonSlave(const QString& slave);
void addFlatbufferSlave(const QString& slave);
void addJsonTarget(const QJsonObject& targetConfig);
void addFlatbufferTarget(const QJsonObject& targetConfig);
private slots:
///
@@ -61,25 +61,36 @@ private slots:
void handlePriorityChanges(quint8 priority);
///
/// @brief Forward message to all json slaves
/// @brief Forward message to all json target hosts
/// @param message The JSON message to send
///
void forwardJsonMessage(const QJsonObject &message);
///
/// @brief Forward image to all flatbuffer slaves
/// @brief Forward image to all flatbuffer target hosts
/// @param image The flatbuffer image to send
///
void forwardFlatbufferMessage(const QString& name, const Image<ColorRgb> &image);
///
/// @brief Forward message to a single json slave
/// @brief Forward message to a single json target host
/// @param message The JSON message to send
/// @param socket The TCP-Socket with the connection to the slave
/// @param socket The TCP-Socket with the connection to the target host
///
void sendJsonMessage(const QJsonObject &message, QTcpSocket *socket);
private:
struct TargetHost {
QHostAddress host;
quint16 port;
bool operator == (TargetHost const& a) const
{
return ((host == a.host) && (port == a.port));
}
};
/// Hyperion instance
Hyperion *_hyperion;
@@ -89,11 +100,11 @@ private:
/// Muxer instance
PriorityMuxer *_muxer;
// JSON connection for forwarding
QStringList _jsonSlaves;
// JSON connections for forwarding
QList<TargetHost> _jsonTargets;
/// Proto connection for forwarding
QStringList _flatSlaves;
/// Flatbuffer connection for forwarding
QList<TargetHost> _flatbufferTargets;
QList<FlatBufferConnection*> _forwardClients;
/// Flag if forwarder is enabled

View File

@@ -36,6 +36,14 @@ public:
///
bool saveSettings(QJsonObject config, bool correct = false);
///
/// @brief Restore a complete json configuration
/// @param config The entire config object
/// @param correct If true will correct json against schema before save
/// @return True on success else false
///
bool restoreSettings(QJsonObject config, bool correct = false);
///
/// @brief get a single setting json from configuration
/// @param type The settings::type from enum

View File

@@ -3,15 +3,21 @@
#include <utils/Logger.h>
#include <QTcpServer>
#include <QUrl>
#include <QHostAddress>
#include <QHostInfo>
namespace NetUtils {
const int MAX_PORT = 65535;
///
/// @brief Check if the port is available for listening
/// @param[in/out] port The port to test, will be incremented if port is in use
/// @param log The logger of the caller to print
/// @return True on success else false
///
static bool portAvailable(quint16& port, Logger* log)
inline bool portAvailable(quint16& port, Logger* log)
{
const quint16 prevPort = port;
QTcpServer server;
@@ -29,4 +35,89 @@ namespace NetUtils {
return true;
}
///
/// @brief Check if the port is in the valid range
/// @param log The logger of the caller to print///
/// @param[in] port The port to be tested
/// @param[in] host A hostname/IP-address to make reference to during logging
/// @return True on success else false
///
inline bool isValidPort(Logger* log, int port, const QString& host)
{
if (port <= 0 || port > MAX_PORT)
{
Error(log, "Invalid port [%d] for host: %s!", port, QSTRING_CSTR(host));
return false;
}
return true;
}
///
/// @brief Get host and port from an host address
/// @param[in] address Hostname or IP-address with or without port (e.g. 192.168.1.100:4711, 2003:e4:c73a:8e00:d5bb:dc3c:50cb:c76e, hyperion.fritz.box)
/// @param[in/out] host The resolved hostname or IP-address
/// @param[in/out] port The resolved port, if available.
/// @return True on success else false
///
inline bool resolveHostPort(const QString& address, QString& host, quint16& port)
{
QString testUrl;
if (address.at(0) != '[' && address.count(':') > 1)
{
testUrl = QString("http://[%1]").arg(address);
}
else
{
testUrl = QString("http://%1").arg(address);
}
QUrl url(testUrl);
if (!url.isValid())
{
return false;
}
host = url.host();
if (url.port() != -1)
{
port = url.port();
}
return true;
}
///
/// @brief Check if the port is in the valid range
/// @param log The logger of the caller to print
/// @param[in] address The port to be tested
/// @param[out] hostAddress A hostname to make reference to during logging
/// @return True on success else false
///
inline bool resolveHostAddress(Logger* log, const QString& address, QHostAddress& hostAddress)
{
bool isHostAddressOK{ false };
if (hostAddress.setAddress(address))
{
Debug(log, "Successfully parsed %s as an IP-address.", QSTRING_CSTR(hostAddress.toString()));
isHostAddressOK = true;
}
else
{
QHostInfo hostInfo = QHostInfo::fromName(address);
if (hostInfo.error() == QHostInfo::NoError)
{
hostAddress = hostInfo.addresses().first();
Debug(log, "Successfully resolved IP-address (%s) for hostname (%s).", QSTRING_CSTR(hostAddress.toString()), QSTRING_CSTR(address));
isHostAddressOK = true;
}
else
{
QString errortext = QString("Failed resolving IP-address for [%1], (%2) %3").arg(address).arg(hostInfo.error()).arg(hostInfo.errorString());
Error(log, "%s", QSTRING_CSTR(errortext));
isHostAddressOK = false;
}
}
return isHostAddressOK;
}
}