Fix to generation of Node ID based on get_node_id() utils function: if gethostid() uses the loopback address interface IPv4 we create a new ID based on the current interface IPv4

This fixes a problem on old Ubuntu distro causing the Node ID to be the same for multiple hosts.
Additional minor changes:
 - removed compilation warnings
 - some fixes to code indentation
This commit is contained in:
Andrea Bondavalli 2020-06-14 14:05:21 +02:00
parent 7c5d2a4b29
commit 7f2bd7f4f0
8 changed files with 69 additions and 52 deletions

2
daemon/json.cpp Normal file → Executable file
View File

@ -96,7 +96,7 @@ std::string config_to_json(const Config& config) {
<< ",\n \"mdns_enabled\": " << std::boolalpha << config.get_mdns_enabled() << ",\n \"mdns_enabled\": " << std::boolalpha << config.get_mdns_enabled()
<< ",\n \"mac_addr\": \"" << escape_json(config.get_mac_addr_str()) << "\"" << ",\n \"mac_addr\": \"" << escape_json(config.get_mac_addr_str()) << "\""
<< ",\n \"ip_addr\": \"" << escape_json(config.get_ip_addr_str()) << "\"" << ",\n \"ip_addr\": \"" << escape_json(config.get_ip_addr_str()) << "\""
<< ",\n \"node_id\": \"" << escape_json(get_node_id()) << "\"" << ",\n \"node_id\": \"" << escape_json(get_node_id(config.get_ip_addr())) << "\""
<< "\n}\n"; << "\n}\n";
return ss.str(); return ss.str();
} }

2
daemon/mdns_server.hpp Normal file → Executable file
View File

@ -59,7 +59,7 @@ class MDNSServer {
std::atomic_bool running_{false}; std::atomic_bool running_{false};
std::shared_ptr<SessionManager> session_manager_; std::shared_ptr<SessionManager> session_manager_;
std::shared_ptr<Config> config_; std::shared_ptr<Config> config_;
std::string node_id_{get_node_id()}; std::string node_id_{get_node_id(config_->get_ip_addr())};
#ifdef _USE_AVAHI_ #ifdef _USE_AVAHI_
using entry_group_bimap_t = using entry_group_bimap_t =

6
daemon/rtsp_client.cpp Normal file → Executable file
View File

@ -227,10 +227,11 @@ std::pair<bool, RtspSource> RtspClient::process(
std::vector<std::string> fields; std::vector<std::string> fields;
split(fields, request, boost::is_any_of(" ")); split(fields, request, boost::is_any_of(" "));
if (fields.size() >= 2 && fields[0] == "ANNOUNCE") { if (fields.size() >= 2 && fields[0] == "ANNOUNCE") {
auto const [ok, protocol, host, port, path] = parse_url(fields[1]); auto const res = parse_url(fields[1]);
if (ok) { if (std::get<0>(res)) {
/* if we find a valid announced source name we use it /* if we find a valid announced source name we use it
* otherwise we try from SDP file or we use the mDNS name */ * otherwise we try from SDP file or we use the mDNS name */
auto path = std::get<4>(res);
if (path.rfind("/by-name/") != std::string::npos) { if (path.rfind("/by-name/") != std::string::npos) {
announced_name = path.substr(9); announced_name = path.substr(9);
BOOST_LOG_TRIVIAL(debug) << "rtsp_client:: found announced name " BOOST_LOG_TRIVIAL(debug) << "rtsp_client:: found announced name "
@ -241,7 +242,6 @@ std::pair<bool, RtspSource> RtspClient::process(
} }
} }
} while (wait_for_updates); } while (wait_for_updates);
} catch (std::exception& e) { } catch (std::exception& e) {
BOOST_LOG_TRIVIAL(warning) BOOST_LOG_TRIVIAL(warning)
<< "rtsp_client:: error with " << "rtsp_client:: error with "

17
daemon/rtsp_server.cpp Normal file → Executable file
View File

@ -46,9 +46,8 @@ void RtspServer::accept() {
unsigned int i = 0; unsigned int i = 0;
for (; i < sessions_.size(); i++) { for (; i < sessions_.size(); i++) {
if (sessions_[i].use_count() == 0) { if (sessions_[i].use_count() == 0) {
auto session = std::make_shared<RtspSession>(session_manager_, auto session = std::make_shared<RtspSession>(config_,
std::move(socket_)); session_manager_, std::move(socket_));
sessions_[i] = session; sessions_[i] = session;
sessions_start_point_[i] = steady_clock::now(); sessions_start_point_[i] = steady_clock::now();
session->start(); session->start();
@ -75,7 +74,8 @@ bool RtspSession::announce(uint8_t id,
/* if a describe request is currently not beeing process /* if a describe request is currently not beeing process
* and the specified source id has been described on this session send update */ * and the specified source id has been described on this session send update */
if (cseq_ < 0 && source_ids_.find(id) != source_ids_.end()) { if (cseq_ < 0 && source_ids_.find(id) != source_ids_.end()) {
std::string path(std::string("/by-name/") + get_node_id() + " " + name); std::string path(std::string("/by-name/") +
get_node_id(config_->get_ip_addr()) + " " + name);
std::stringstream ss; std::stringstream ss;
ss << "ANNOUNCE rtsp://" << address << ":" << std::to_string(port) ss << "ANNOUNCE rtsp://" << address << ":" << std::to_string(port)
<< httplib::detail::encode_url(path) << " RTSP/1.0\r\n" << httplib::detail::encode_url(path) << " RTSP/1.0\r\n"
@ -164,15 +164,16 @@ bool RtspSession::process_request() {
} }
void RtspSession::build_response(const std::string& url) { void RtspSession::build_response(const std::string& url) {
auto const [ok, protocol, host, port, path] = parse_url(url); auto const res = parse_url(url);
if (!ok) { if (!std::get<0>(res)) {
BOOST_LOG_TRIVIAL(error) << "rtsp_server:: cannot parse URL " << url BOOST_LOG_TRIVIAL(error) << "rtsp_server:: cannot parse URL " << url
<< " from " << socket_.remote_endpoint(); << " from " << socket_.remote_endpoint();
send_error(400, "Bad Request"); send_error(400, "Bad Request");
return; return;
} }
auto path = std::get<4>(res);
auto base_path = std::string("/by-name/") + get_node_id() + " "; auto base_path = std::string("/by-name/") +
get_node_id(config_->get_ip_addr()) + " ";
uint8_t id = SessionManager::stream_id_max + 1; uint8_t id = SessionManager::stream_id_max + 1;
if (path.rfind(base_path) != std::string::npos) { if (path.rfind(base_path) != std::string::npos) {
/* extract the source name from path and retrive the id */ /* extract the source name from path and retrive the id */

7
daemon/rtsp_server.hpp Normal file → Executable file
View File

@ -39,9 +39,11 @@ class RtspSession : public std::enable_shared_from_this<RtspSession> {
constexpr static uint16_t max_length = 4096; // byte constexpr static uint16_t max_length = 4096; // byte
constexpr static uint16_t session_tout_secs = 10; // sec constexpr static uint16_t session_tout_secs = 10; // sec
RtspSession(std::shared_ptr<SessionManager> session_manager, RtspSession(std::shared_ptr<Config> config,
std::shared_ptr<SessionManager> session_manager,
tcp::socket socket) tcp::socket socket)
: session_manager_(session_manager), : config_(config),
session_manager_(session_manager),
socket_(std::move(socket)), socket_(std::move(socket)),
length_{0}, length_{0},
cseq_{-1}, cseq_{-1},
@ -66,6 +68,7 @@ class RtspSession : public std::enable_shared_from_this<RtspSession> {
void read_request(); void read_request();
void send_error(int status_code, const std::string& description); void send_error(int status_code, const std::string& description);
void send_response(const std::string& response); void send_response(const std::string& response);
std::shared_ptr<Config> config_;
std::shared_ptr<SessionManager> session_manager_; std::shared_ptr<SessionManager> session_manager_;
tcp::socket socket_; tcp::socket socket_;
char data_[max_length + 1]; char data_[max_length + 1];

3
daemon/session_manager.cpp Normal file → Executable file
View File

@ -557,7 +557,8 @@ std::string SessionManager::get_source_sdp_(uint32_t id,
ss << "v=0\n" ss << "v=0\n"
<< "o=- " << static_cast<unsigned>(id) << " 0 IN IP4 " << "o=- " << static_cast<unsigned>(id) << " 0 IN IP4 "
<< ip::address_v4(info.stream.m_ui32SrcIP).to_string() << "\n" << ip::address_v4(info.stream.m_ui32SrcIP).to_string() << "\n"
<< "s=" << get_node_id() << " " << info.stream.m_cName << "\n" << "s=" << get_node_id(config_->get_ip_addr()) << " "
<< info.stream.m_cName << "\n"
<< "c=IN IP4 " << ip::address_v4(info.stream.m_ui32DestIP).to_string() << "c=IN IP4 " << ip::address_v4(info.stream.m_ui32DestIP).to_string()
<< "/" << static_cast<unsigned>(info.stream.m_byTTL) << "\n" << "/" << static_cast<unsigned>(info.stream.m_byTTL) << "\n"
<< "t=0 0\n" << "t=0 0\n"

14
daemon/utils.cpp Normal file → Executable file
View File

@ -18,6 +18,7 @@
// //
// //
#include <boost/format.hpp>
#include "utils.hpp" #include "utils.hpp"
uint16_t crc16(const uint8_t* p, size_t len) { uint16_t crc16(const uint8_t* p, size_t len) {
@ -73,8 +74,19 @@ parse_url(const std::string& _url) {
return {host.length() > 0, protocol, host, port, path}; return {host.length() > 0, protocol, host, port, path};
} }
std::string get_node_id() { std::string get_node_id(uint32_t ip_addr) {
std::stringstream ss; std::stringstream ss;
if (gethostid() == 0x7f0101) {
/* hostid is using lo interface ip
we create an host ID based on the current IP */
ss << "AES67 daemon "
<< boost::format("%02x%02x%02x%02x")
% ((ip_addr >> 8) & 0xff)
% ((ip_addr >> 24) & 0xff)
% (ip_addr & 0xff)
% ((ip_addr >> 16) & 0xff);
} else {
ss << "AES67 daemon " << std::hex << (uint32_t)gethostid(); ss << "AES67 daemon " << std::hex << (uint32_t)gethostid();
}
return ss.str(); return ss.str();
} }

2
daemon/utils.hpp Normal file → Executable file
View File

@ -34,6 +34,6 @@ std::tuple<bool /* res */,
std::string /* path */> std::string /* path */>
parse_url(const std::string& _url); parse_url(const std::string& _url);
std::string get_node_id(); std::string get_node_id(uint32_t ip_addr);
#endif #endif