diff --git a/.travis.yml b/.travis.yml index c126192e..465f4451 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,8 +11,9 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:mhier/libboost-latest' 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: - MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9" @@ -21,8 +22,9 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:mhier/libboost-latest' 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: - MATRIX_EVAL="CC=gcc-5 && CXX=g++-5" @@ -31,8 +33,9 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:mhier/libboost-latest' 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: - MATRIX_EVAL="CC=gcc-6 && CXX=g++-6" @@ -41,8 +44,9 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:mhier/libboost-latest' 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: - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7" @@ -52,8 +56,9 @@ matrix: apt: sources: - llvm-toolchain-trusty-3.9 + - sourceline: 'ppa:mhier/libboost-latest' 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: - MATRIX_EVAL="CC=clang-3.9 && CXX=clang++-3.9" @@ -63,8 +68,9 @@ matrix: apt: sources: - llvm-toolchain-trusty-4.0 + - sourceline: 'ppa:mhier/libboost-latest' 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: - MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0" @@ -74,8 +80,9 @@ matrix: apt: sources: - llvm-toolchain-trusty-5.0 + - sourceline: 'ppa:mhier/libboost-latest' 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: - MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0" @@ -83,17 +90,17 @@ matrix: - os: osx osx_image: xcode9.4 env: - - MATRIX_EVAL="brew update && brew install flac libvorbis" + - MATRIX_EVAL="brew update && brew install flac libvorbis boost" - os: osx osx_image: xcode10.3 env: - - MATRIX_EVAL="brew update && brew install flac libvorbis" + - MATRIX_EVAL="brew update && brew install flac libvorbis boost" - os: osx osx_image: xcode11 env: - - MATRIX_EVAL="brew update && brew install flac libvorbis" + - MATRIX_EVAL="brew update && brew install flac libvorbis boost" # - os: osx # osx_image: xcode8 @@ -106,8 +113,4 @@ before_install: script: - mkdir 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 6652aa03..ff5f47f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,7 +177,6 @@ if(BUILD_WITH_VORBIS) endif(VORBISENC_FOUND) endif() -# TODO: if (BUILD_WITH_WEBSOCKETS) find_package(Boost 1.66 REQUIRED) add_subdirectory(common) diff --git a/client/decoder/flacDecoder.cpp b/client/decoder/flacDecoder.cpp index f92bdef3..c4691112 100644 --- a/client/decoder/flacDecoder.cpp +++ b/client/decoder/flacDecoder.cpp @@ -212,14 +212,4 @@ void error_callback(const FLAC__StreamDecoder* decoder, FLAC__StreamDecoderError (void)decoder, (void)client_data; SLOG(ERROR) << "Got error callback: " << FLAC__StreamDecoderErrorStatusString[status] << "\n"; static_cast(client_data)->lastError_ = std::unique_ptr(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 } diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 14181500..b34d6e4d 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -59,7 +59,6 @@ if (FLAC_FOUND) list(APPEND SERVER_INCLUDE ${FLAC_INCLUDE_DIRS}) endif (FLAC_FOUND) -# TODO: if (BUILD_WITH_WEBSOCKETS) list(APPEND SERVER_LIBRARIES Boost::boost) include_directories(${SERVER_INCLUDE}) diff --git a/server/control_server.cpp b/server/control_server.cpp index 4a76fd32..4dc2f5de 100644 --- a/server/control_server.cpp +++ b/server/control_server.cpp @@ -98,17 +98,11 @@ void ControlServer::startAccept() LOG(ERROR) << "Error while accepting socket connection: " << ec.message() << "\n"; }; - if (acceptor_tcp_.first) - acceptor_tcp_.first->async_accept(accept_handler_tcp); + for (auto& acceptor : acceptor_tcp_) + acceptor->async_accept(accept_handler_tcp); - if (acceptor_tcp_.second) - acceptor_tcp_.second->async_accept(accept_handler_tcp); - - if (acceptor_http_.first) - acceptor_http_.first->async_accept(accept_handler_http); - - if (acceptor_http_.second) - acceptor_http_.second->async_accept(accept_handler_http); + for (auto& acceptor : acceptor_http_) + acceptor->async_accept(accept_handler_http); } @@ -139,66 +133,35 @@ void ControlServer::handleAccept(tcp::socket socket, Args&&... args) startAccept(); } -std::pair 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(*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(*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(std::move(acceptor_v4), std::move(acceptor_v6)); -} void ControlServer::start() { 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(*io_context_, tcp::endpoint(boost::asio::ip::address::from_string(address), tcp_settings_.port))); + } 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(*io_context_, tcp::endpoint(boost::asio::ip::address::from_string(address), http_settings_.port))); + } + startAccept(); } void ControlServer::stop() { - auto cancel_accept = [](tcp::acceptor* acceptor) { - if (acceptor) - { - acceptor->cancel(); - acceptor = nullptr; - } - }; + for (auto& acceptor : acceptor_tcp_) + acceptor->cancel(); + + for (auto& acceptor : acceptor_http_) + 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 mlock(session_mutex_); cleanup(); for (auto s : sessions_) diff --git a/server/control_server.hpp b/server/control_server.hpp index 949b3fe5..5112623a 100644 --- a/server/control_server.hpp +++ b/server/control_server.hpp @@ -60,7 +60,6 @@ public: private: void startAccept(); - std::pair createAcceptors(size_t port); template void handleAccept(tcp::socket socket, Args&&... args); @@ -69,8 +68,8 @@ private: mutable std::recursive_mutex session_mutex_; std::vector> sessions_; - std::pair acceptor_tcp_; - std::pair acceptor_http_; + std::vector acceptor_tcp_; + std::vector acceptor_http_; boost::asio::io_context* io_context_; ServerSettings::TcpSettings tcp_settings_; diff --git a/server/server_settings.hpp b/server/server_settings.hpp index 49ec54da..a960d156 100644 --- a/server/server_settings.hpp +++ b/server/server_settings.hpp @@ -28,6 +28,7 @@ struct ServerSettings { bool enabled{true}; size_t port{1780}; + std::vector bind_to_address{{"0.0.0.0"}}; std::string doc_root{""}; }; @@ -35,6 +36,7 @@ struct ServerSettings { bool enabled{true}; size_t port{1705}; + std::vector bind_to_address{{"0.0.0.0"}}; }; struct StreamSettings diff --git a/server/snapserver.conf b/server/snapserver.conf index 06aea0c1..a50e6568 100644 --- a/server/snapserver.conf +++ b/server/snapserver.conf @@ -22,8 +22,7 @@ #enabled = true # address to listen on -# TODO: not implemented yet -#bind_to_address = 127.0.0.1 +#bind_to_address = 0.0.0.0 # which port the server should listen to #port = 1780 @@ -41,8 +40,7 @@ doc_root = /home/johannes/Develop/snapcast/control #enabled = true # address to listen on -# TODO: not implemented yet -#bind_to_address = 127.0.0.1 +#bind_to_address = 0.0.0.0 # which port the server should listen to #port = 1705 diff --git a/server/snapserver.cpp b/server/snapserver.cpp index fddbe860..1e11481e 100644 --- a/server/snapserver.cpp +++ b/server/snapserver.cpp @@ -95,11 +95,15 @@ int main(int argc, char* argv[]) // HTTP RPC settings conf.add>("", "http.enabled", "enable HTTP Json RPC (HTTP POST and websockets)", settings.http.enabled, &settings.http.enabled); conf.add>("", "http.port", "which port the server should listen to", settings.http.port, &settings.http.port); + auto http_bind_to_address = conf.add>("", "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>("", "http.doc_root", "serve a website from the doc_root location", settings.http.doc_root, &settings.http.doc_root); // TCP RPC settings conf.add>("", "tcp.enabled", "enable TCP Json RPC)", settings.tcp.enabled, &settings.tcp.enabled); conf.add>("", "tcp.port", "which port the server should listen to", settings.tcp.port, &settings.tcp.port); + auto tcp_bind_to_address = conf.add>("", "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 @@ -107,6 +111,18 @@ int main(int argc, char* argv[]) { op.parse(argc, argv); 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) {