From 8664daeb9a2ed7bc9016c29c38cac7a061c6177c Mon Sep 17 00:00:00 2001 From: Thulinma Date: Fri, 17 May 2024 14:53:55 +0200 Subject: [PATCH] Improve and robustify local UDP port handling --- lib/defines.h | 9 --------- src/controller/controller_api.cpp | 25 +++++++++++++++++++++---- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/lib/defines.h b/lib/defines.h index 905d1a19..28b2b070 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -260,15 +260,6 @@ static inline void show_stackframe(){} #define SIMUL_TRACKS 40 -#ifndef UDP_API_HOST -#define UDP_API_HOST "localhost" -#endif - -#ifndef UDP_API_PORT -#define UDP_API_PORT 4242 -#endif - - // The amount of milliseconds a simulated live stream is allowed to be "behind". // Setting this value to lower than 2 seconds **WILL** cause stuttering in playback due to buffer negotiation. #define SIMULATED_LIVE_BUFFER 7000 diff --git a/src/controller/controller_api.cpp b/src/controller/controller_api.cpp index 0d40c284..f46e1083 100644 --- a/src/controller/controller_api.cpp +++ b/src/controller/controller_api.cpp @@ -452,10 +452,27 @@ int Controller::handleAPIConnection(Socket::Connection &conn){ void Controller::handleUDPAPI(void *np){ Socket::UDPConnection uSock(true); - uint16_t boundPort = uSock.bind(UDP_API_PORT, UDP_API_HOST); - if (!boundPort){ - FAIL_MSG("Could not open local API UDP socket - not all functionality will be available"); - return; + uint16_t boundPort; + { + HTTP::URL udpApiAddr("udp://localhost:4242"); + if (getenv("UDP_API")){udpApiAddr = HTTP::URL(getenv("UDP_API"));} + boundPort = uSock.bind(udpApiAddr.getPort(), udpApiAddr.host); + if (!boundPort){ + FAIL_MSG("Could not open local UDP API socket on %s:%" PRIu16 " - retrying with an ephemeral port", udpApiAddr.host.c_str(), udpApiAddr.getPort()); + boundPort = uSock.bind(0, udpApiAddr.host); + if (!boundPort){ + std::stringstream newHost; + char ranNums[3]; + Util::getRandomBytes(ranNums, 3); + newHost << "127." << (int)ranNums[0] << "." << (int)ranNums[1] << "." << (int)ranNums[2]; + FAIL_MSG("Could not open local ephemeral UDP API socket either - retrying with host %s", newHost.str().c_str()); + boundPort = uSock.bind(0, newHost.str()); + if (!boundPort){ + FAIL_MSG("Could not open local UDP API socket even after all that... disabling local UDP API, some functionality may not be available"); + return; + } + } + } } HTTP::URL boundAddr; boundAddr.protocol = "udp";