bind to configurable interface

This commit is contained in:
badaix 2019-10-11 22:44:26 +02:00
parent 12a11e12a9
commit 9ced0aa438
9 changed files with 59 additions and 90 deletions

View file

@ -11,8 +11,9 @@ matrix:
apt: apt:
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
- sourceline: 'ppa:mhier/libboost-latest'
packages: packages:
- g++-4.9 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon - g++-4.9 boost1.70 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon
env: env:
- MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9" - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
@ -21,8 +22,9 @@ matrix:
apt: apt:
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
- sourceline: 'ppa:mhier/libboost-latest'
packages: packages:
- g++-5 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon - g++-5 boost1.70 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon
env: env:
- MATRIX_EVAL="CC=gcc-5 && CXX=g++-5" - MATRIX_EVAL="CC=gcc-5 && CXX=g++-5"
@ -31,8 +33,9 @@ matrix:
apt: apt:
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
- sourceline: 'ppa:mhier/libboost-latest'
packages: packages:
- g++-6 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon - g++-6 boost1.70 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon
env: env:
- MATRIX_EVAL="CC=gcc-6 && CXX=g++-6" - MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
@ -41,8 +44,9 @@ matrix:
apt: apt:
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
- sourceline: 'ppa:mhier/libboost-latest'
packages: packages:
- g++-7 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon - g++-7 boost1.70 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon
env: env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7" - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
@ -52,8 +56,9 @@ matrix:
apt: apt:
sources: sources:
- llvm-toolchain-trusty-3.9 - llvm-toolchain-trusty-3.9
- sourceline: 'ppa:mhier/libboost-latest'
packages: packages:
- clang-3.9 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon - clang-3.9 boost1.70 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon
env: env:
- MATRIX_EVAL="CC=clang-3.9 && CXX=clang++-3.9" - MATRIX_EVAL="CC=clang-3.9 && CXX=clang++-3.9"
@ -63,8 +68,9 @@ matrix:
apt: apt:
sources: sources:
- llvm-toolchain-trusty-4.0 - llvm-toolchain-trusty-4.0
- sourceline: 'ppa:mhier/libboost-latest'
packages: packages:
- clang-4.0 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon - clang-4.0 boost1.70 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon
env: env:
- MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0" - MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0"
@ -74,8 +80,9 @@ matrix:
apt: apt:
sources: sources:
- llvm-toolchain-trusty-5.0 - llvm-toolchain-trusty-5.0
- sourceline: 'ppa:mhier/libboost-latest'
packages: packages:
- clang-5.0 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon - clang-5.0 boost1.70 libasound2-dev libvorbisidec-dev libvorbis-dev libflac-dev alsa-utils libavahi-client-dev avahi-daemon
env: env:
- MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0" - MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0"
@ -83,17 +90,17 @@ matrix:
- os: osx - os: osx
osx_image: xcode9.4 osx_image: xcode9.4
env: env:
- MATRIX_EVAL="brew update && brew install flac libvorbis" - MATRIX_EVAL="brew update && brew install flac libvorbis boost"
- os: osx - os: osx
osx_image: xcode10.3 osx_image: xcode10.3
env: env:
- MATRIX_EVAL="brew update && brew install flac libvorbis" - MATRIX_EVAL="brew update && brew install flac libvorbis boost"
- os: osx - os: osx
osx_image: xcode11 osx_image: xcode11
env: env:
- MATRIX_EVAL="brew update && brew install flac libvorbis" - MATRIX_EVAL="brew update && brew install flac libvorbis boost"
# - os: osx # - os: osx
# osx_image: xcode8 # osx_image: xcode8
@ -106,8 +113,4 @@ before_install:
script: script:
- mkdir build - mkdir build
- cd build - cd build
- cmake ../externals/aixlog && make && sudo make install
- rm -rf *
- cmake ../externals/popl && make && sudo make install
- rm -rf *
- cmake .. && make && sudo make install - cmake .. && make && sudo make install

View file

@ -177,7 +177,6 @@ if(BUILD_WITH_VORBIS)
endif(VORBISENC_FOUND) endif(VORBISENC_FOUND)
endif() endif()
# TODO: if (BUILD_WITH_WEBSOCKETS)
find_package(Boost 1.66 REQUIRED) find_package(Boost 1.66 REQUIRED)
add_subdirectory(common) add_subdirectory(common)

View file

@ -212,14 +212,4 @@ void error_callback(const FLAC__StreamDecoder* decoder, FLAC__StreamDecoderError
(void)decoder, (void)client_data; (void)decoder, (void)client_data;
SLOG(ERROR) << "Got error callback: " << FLAC__StreamDecoderErrorStatusString[status] << "\n"; SLOG(ERROR) << "Got error callback: " << FLAC__StreamDecoderErrorStatusString[status] << "\n";
static_cast<FlacDecoder*>(client_data)->lastError_ = std::unique_ptr<FLAC__StreamDecoderErrorStatus>(new FLAC__StreamDecoderErrorStatus(status)); static_cast<FlacDecoder*>(client_data)->lastError_ = std::unique_ptr<FLAC__StreamDecoderErrorStatus>(new FLAC__StreamDecoderErrorStatus(status));
/// TODO, see issue #120:
// Thu Nov 10 07:26:44 2016 daemon.warn dnsmasq-dhcp[1194]: no address range available for DHCP request via wlan0
// Thu Nov 10 07:54:39 2016 daemon.err snapclient[1158]: Got error callback: FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC
// Thu Nov 10 07:54:39 2016 daemon.err snapclient[1158]: Got error callback: FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC
//
// and:
// Oct 27 17:37:38 kitchen snapclient[869]: Connected to 192.168.222.10
// Oct 27 17:47:13 kitchen snapclient[869]: Got error callback: FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM
// Oct 27 17:47:13 kitchen snapclient[869]: Got error callback: FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC
} }

View file

@ -59,7 +59,6 @@ if (FLAC_FOUND)
list(APPEND SERVER_INCLUDE ${FLAC_INCLUDE_DIRS}) list(APPEND SERVER_INCLUDE ${FLAC_INCLUDE_DIRS})
endif (FLAC_FOUND) endif (FLAC_FOUND)
# TODO: if (BUILD_WITH_WEBSOCKETS)
list(APPEND SERVER_LIBRARIES Boost::boost) list(APPEND SERVER_LIBRARIES Boost::boost)
include_directories(${SERVER_INCLUDE}) include_directories(${SERVER_INCLUDE})

View file

@ -98,17 +98,11 @@ void ControlServer::startAccept()
LOG(ERROR) << "Error while accepting socket connection: " << ec.message() << "\n"; LOG(ERROR) << "Error while accepting socket connection: " << ec.message() << "\n";
}; };
if (acceptor_tcp_.first) for (auto& acceptor : acceptor_tcp_)
acceptor_tcp_.first->async_accept(accept_handler_tcp); acceptor->async_accept(accept_handler_tcp);
if (acceptor_tcp_.second) for (auto& acceptor : acceptor_http_)
acceptor_tcp_.second->async_accept(accept_handler_tcp); acceptor->async_accept(accept_handler_http);
if (acceptor_http_.first)
acceptor_http_.first->async_accept(accept_handler_http);
if (acceptor_http_.second)
acceptor_http_.second->async_accept(accept_handler_http);
} }
@ -139,66 +133,35 @@ void ControlServer::handleAccept(tcp::socket socket, Args&&... args)
startAccept(); startAccept();
} }
std::pair<acceptor_ptr, acceptor_ptr> ControlServer::createAcceptors(size_t port)
{
bool is_v6_only(true);
tcp::endpoint endpoint_tcp_v6(tcp::v6(), port);
acceptor_ptr acceptor_v4;
acceptor_ptr acceptor_v6;
try
{
acceptor_v6 = make_unique<tcp::acceptor>(*io_context_, endpoint_tcp_v6);
boost::system::error_code ec;
acceptor_v6->set_option(boost::asio::ip::v6_only(true), ec);
boost::asio::ip::v6_only option;
acceptor_v6->get_option(option);
is_v6_only = option.value();
LOG(DEBUG) << "IPv6 only: " << is_v6_only << "\n";
}
catch (const boost::system::system_error& e)
{
LOG(ERROR) << "error creating TCP acceptor: " << e.what() << ", code: " << e.code() << "\n";
}
if (!acceptor_v6 || is_v6_only)
{
tcp::endpoint endpoint_v4(tcp::v4(), port);
try
{
acceptor_v4 = make_unique<tcp::acceptor>(*io_context_, endpoint_v4);
}
catch (const boost::system::system_error& e)
{
LOG(ERROR) << "error creating TCP acceptor: " << e.what() << ", code: " << e.code() << "\n";
}
}
return make_pair<acceptor_ptr, acceptor_ptr>(std::move(acceptor_v4), std::move(acceptor_v6));
}
void ControlServer::start() void ControlServer::start()
{ {
if (tcp_settings_.enabled) if (tcp_settings_.enabled)
acceptor_tcp_ = createAcceptors(tcp_settings_.port); {
for (const auto& address : tcp_settings_.bind_to_address)
acceptor_tcp_.emplace_back(
make_unique<tcp::acceptor>(*io_context_, tcp::endpoint(boost::asio::ip::address::from_string(address), tcp_settings_.port)));
}
if (http_settings_.enabled) if (http_settings_.enabled)
acceptor_http_ = createAcceptors(http_settings_.port); {
for (const auto& address : http_settings_.bind_to_address)
acceptor_http_.emplace_back(
make_unique<tcp::acceptor>(*io_context_, tcp::endpoint(boost::asio::ip::address::from_string(address), http_settings_.port)));
}
startAccept(); startAccept();
} }
void ControlServer::stop() void ControlServer::stop()
{ {
auto cancel_accept = [](tcp::acceptor* acceptor) { for (auto& acceptor : acceptor_tcp_)
if (acceptor) acceptor->cancel();
{
acceptor->cancel(); for (auto& acceptor : acceptor_http_)
acceptor = nullptr; acceptor->cancel();
}
};
cancel_accept(acceptor_tcp_.first.get());
cancel_accept(acceptor_tcp_.second.get());
cancel_accept(acceptor_http_.first.get());
cancel_accept(acceptor_http_.second.get());
std::lock_guard<std::recursive_mutex> mlock(session_mutex_); std::lock_guard<std::recursive_mutex> mlock(session_mutex_);
cleanup(); cleanup();
for (auto s : sessions_) for (auto s : sessions_)

View file

@ -60,7 +60,6 @@ public:
private: private:
void startAccept(); void startAccept();
std::pair<acceptor_ptr, acceptor_ptr> createAcceptors(size_t port);
template <typename SessionType, typename... Args> template <typename SessionType, typename... Args>
void handleAccept(tcp::socket socket, Args&&... args); void handleAccept(tcp::socket socket, Args&&... args);
@ -69,8 +68,8 @@ private:
mutable std::recursive_mutex session_mutex_; mutable std::recursive_mutex session_mutex_;
std::vector<std::weak_ptr<ControlSession>> sessions_; std::vector<std::weak_ptr<ControlSession>> sessions_;
std::pair<acceptor_ptr, acceptor_ptr> acceptor_tcp_; std::vector<acceptor_ptr> acceptor_tcp_;
std::pair<acceptor_ptr, acceptor_ptr> acceptor_http_; std::vector<acceptor_ptr> acceptor_http_;
boost::asio::io_context* io_context_; boost::asio::io_context* io_context_;
ServerSettings::TcpSettings tcp_settings_; ServerSettings::TcpSettings tcp_settings_;

View file

@ -28,6 +28,7 @@ struct ServerSettings
{ {
bool enabled{true}; bool enabled{true};
size_t port{1780}; size_t port{1780};
std::vector<std::string> bind_to_address{{"0.0.0.0"}};
std::string doc_root{""}; std::string doc_root{""};
}; };
@ -35,6 +36,7 @@ struct ServerSettings
{ {
bool enabled{true}; bool enabled{true};
size_t port{1705}; size_t port{1705};
std::vector<std::string> bind_to_address{{"0.0.0.0"}};
}; };
struct StreamSettings struct StreamSettings

View file

@ -22,8 +22,7 @@
#enabled = true #enabled = true
# address to listen on # address to listen on
# TODO: not implemented yet #bind_to_address = 0.0.0.0
#bind_to_address = 127.0.0.1
# which port the server should listen to # which port the server should listen to
#port = 1780 #port = 1780
@ -41,8 +40,7 @@ doc_root = /home/johannes/Develop/snapcast/control
#enabled = true #enabled = true
# address to listen on # address to listen on
# TODO: not implemented yet #bind_to_address = 0.0.0.0
#bind_to_address = 127.0.0.1
# which port the server should listen to # which port the server should listen to
#port = 1705 #port = 1705

View file

@ -95,11 +95,15 @@ int main(int argc, char* argv[])
// HTTP RPC settings // HTTP RPC settings
conf.add<Value<bool>>("", "http.enabled", "enable HTTP Json RPC (HTTP POST and websockets)", settings.http.enabled, &settings.http.enabled); conf.add<Value<bool>>("", "http.enabled", "enable HTTP Json RPC (HTTP POST and websockets)", settings.http.enabled, &settings.http.enabled);
conf.add<Value<size_t>>("", "http.port", "which port the server should listen to", settings.http.port, &settings.http.port); conf.add<Value<size_t>>("", "http.port", "which port the server should listen to", settings.http.port, &settings.http.port);
auto http_bind_to_address = conf.add<Value<string>>("", "http.bind_to_address", "address for the server to listen on",
settings.http.bind_to_address.front(), &settings.http.bind_to_address[0]);
conf.add<Value<string>>("", "http.doc_root", "serve a website from the doc_root location", settings.http.doc_root, &settings.http.doc_root); conf.add<Value<string>>("", "http.doc_root", "serve a website from the doc_root location", settings.http.doc_root, &settings.http.doc_root);
// TCP RPC settings // TCP RPC settings
conf.add<Value<bool>>("", "tcp.enabled", "enable TCP Json RPC)", settings.tcp.enabled, &settings.tcp.enabled); conf.add<Value<bool>>("", "tcp.enabled", "enable TCP Json RPC)", settings.tcp.enabled, &settings.tcp.enabled);
conf.add<Value<size_t>>("", "tcp.port", "which port the server should listen to", settings.tcp.port, &settings.tcp.port); conf.add<Value<size_t>>("", "tcp.port", "which port the server should listen to", settings.tcp.port, &settings.tcp.port);
auto tcp_bind_to_address = conf.add<Value<string>>("", "tcp.bind_to_address", "address for the server to listen on",
settings.tcp.bind_to_address.front(), &settings.tcp.bind_to_address[0]);
// TODO: Should be possible to override settings on command line // TODO: Should be possible to override settings on command line
@ -107,6 +111,18 @@ int main(int argc, char* argv[])
{ {
op.parse(argc, argv); op.parse(argc, argv);
conf.parse(config_file); conf.parse(config_file);
if (tcp_bind_to_address->is_set())
{
settings.tcp.bind_to_address.clear();
for (size_t n = 0; n < tcp_bind_to_address->count(); ++n)
settings.tcp.bind_to_address.push_back(tcp_bind_to_address->value(n));
}
if (http_bind_to_address->is_set())
{
settings.http.bind_to_address.clear();
for (size_t n = 0; n < http_bind_to_address->count(); ++n)
settings.http.bind_to_address.push_back(http_bind_to_address->value(n));
}
} }
catch (const std::invalid_argument& e) catch (const std::invalid_argument& e)
{ {