diff --git a/src/Config.cpp b/src/Config.cpp
index 2243183b..91ee476f 100644
--- a/src/Config.cpp
+++ b/src/Config.cpp
@@ -28,6 +28,7 @@ with this program. If not, see
#define PARAM_FIRSTLOAD "FirstLoad"
#define PARAM_ENABLED "ServerEnabled"
#define PARAM_PORT "ServerPort"
+#define PARAM_BINDLOOPBACK "BindLoopback"
#define PARAM_ALERTS "AlertsEnabled"
#define PARAM_AUTHREQUIRED "AuthRequired"
#define PARAM_PASSWORD "ServerPassword"
@@ -43,6 +44,7 @@ Config::Config() :
FirstLoad(true),
ServerEnabled(true),
ServerPort(4455),
+ BindLoopback(true),
Ipv4Only(false),
DebugEnabled(false),
AlertsEnabled(false),
@@ -64,6 +66,7 @@ void Config::Load()
ServerEnabled = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ENABLED);
AlertsEnabled = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ALERTS);
ServerPort = config_get_uint(obsConfig, CONFIG_SECTION_NAME, PARAM_PORT);
+ BindLoopback = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_BINDLOOPBACK);
AuthRequired = config_get_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_AUTHREQUIRED);
ServerPassword = config_get_string(obsConfig, CONFIG_SECTION_NAME, PARAM_PASSWORD);
@@ -131,6 +134,7 @@ void Config::Save()
if (!PortOverridden) {
config_set_uint(obsConfig, CONFIG_SECTION_NAME, PARAM_PORT, ServerPort);
}
+ config_set_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_BINDLOOPBACK, BindLoopback);
config_set_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ALERTS, AlertsEnabled);
if (!PasswordOverridden) {
config_set_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_AUTHREQUIRED, AuthRequired);
@@ -151,6 +155,7 @@ void Config::SetDefaultsToGlobalStore()
config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_FIRSTLOAD, FirstLoad);
config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ENABLED, ServerEnabled);
config_set_default_uint(obsConfig, CONFIG_SECTION_NAME, PARAM_PORT, ServerPort);
+ config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_BINDLOOPBACK, BindLoopback);
config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_ALERTS, AlertsEnabled);
config_set_default_bool(obsConfig, CONFIG_SECTION_NAME, PARAM_AUTHREQUIRED, AuthRequired);
config_set_default_string(obsConfig, CONFIG_SECTION_NAME, PARAM_PASSWORD, QT_TO_UTF8(ServerPassword));
diff --git a/src/Config.h b/src/Config.h
index 17533223..3b3f4a54 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -38,6 +38,7 @@ struct Config {
std::atomic FirstLoad;
std::atomic ServerEnabled;
std::atomic ServerPort;
+ std::atomic BindLoopback;
std::atomic Ipv4Only;
std::atomic DebugEnabled;
std::atomic AlertsEnabled;
diff --git a/src/utils/Platform.cpp b/src/utils/Platform.cpp
index 9079d88b..83b5f897 100644
--- a/src/utils/Platform.cpp
+++ b/src/utils/Platform.cpp
@@ -76,6 +76,21 @@ std::string Utils::Platform::GetLocalAddress()
return preferredAddresses[0].first.toStdString();
}
+std::string Utils::Platform::GetLoopbackAddress(bool allowIpv6)
+{
+ std::vector validAddresses;
+ for (auto address : QNetworkInterface::allAddresses()) {
+ if (address == QHostAddress::LocalHost)
+ return address.toString().toStdString();
+ else if (address == QHostAddress::LocalHostIPv6 && allowIpv6)
+ return address.toString().toStdString();
+ else if (address.isLoopback())
+ return address.toString().toStdString();
+ }
+
+ return "";
+}
+
QString Utils::Platform::GetCommandLineArgument(QString arg)
{
QCommandLineParser parser;
diff --git a/src/utils/Platform.h b/src/utils/Platform.h
index aee2213d..a2692e15 100644
--- a/src/utils/Platform.h
+++ b/src/utils/Platform.h
@@ -26,6 +26,7 @@ with this program. If not, see
namespace Utils {
namespace Platform {
std::string GetLocalAddress();
+ std::string GetLoopbackAddress(bool allowIpv6 = true);
QString GetCommandLineArgument(QString arg);
bool GetCommandLineFlagSet(QString arg);
void SendTrayNotification(QSystemTrayIcon::MessageIcon icon, QString title, QString body);
diff --git a/src/websocketserver/WebSocketServer.cpp b/src/websocketserver/WebSocketServer.cpp
index 2fa1c40f..ad7b1539 100644
--- a/src/websocketserver/WebSocketServer.cpp
+++ b/src/websocketserver/WebSocketServer.cpp
@@ -129,17 +129,25 @@ void WebSocketServer::Start()
_server.reset();
websocketpp::lib::error_code errorCode;
- if (conf->Ipv4Only) {
- blog(LOG_INFO, "[WebSocketServer::Start] Locked to IPv4 bindings");
+ if (conf->BindLoopback) {
+ std::string addr = Utils::Platform::GetLoopbackAddress(!conf->Ipv4Only);
+ if (addr.empty()) {
+ blog(LOG_ERROR, "[WebSocketServer::Start] Failed to find loopback interface. Server not started.");
+ return;
+ }
+ _server.listen(addr, std::to_string(conf->ServerPort), errorCode);
+ blog(LOG_INFO, "[WebSocketServer::Start] Locked to loopback interface.");
+ } else if (conf->Ipv4Only) {
_server.listen(websocketpp::lib::asio::ip::tcp::v4(), conf->ServerPort, errorCode);
+ blog(LOG_INFO, "[WebSocketServer::Start] Locked to IPv4 bindings.");
} else {
- blog(LOG_INFO, "[WebSocketServer::Start] Not locked to IPv4 bindings");
_server.listen(conf->ServerPort, errorCode);
+ blog(LOG_INFO, "[WebSocketServer::Start] Not locked to IPv4 bindings.");
}
if (errorCode) {
std::string errorCodeMessage = errorCode.message();
- blog(LOG_INFO, "[WebSocketServer::Start] Listen failed: %s", errorCodeMessage.c_str());
+ blog(LOG_ERROR, "[WebSocketServer::Start] Listen failed: %s", errorCodeMessage.c_str());
return;
}