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:
parent
7c5d2a4b29
commit
7f2bd7f4f0
2
daemon/json.cpp
Normal file → Executable file
2
daemon/json.cpp
Normal file → Executable 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
2
daemon/mdns_server.hpp
Normal file → Executable 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 =
|
||||||
|
72
daemon/rtsp_client.cpp
Normal file → Executable file
72
daemon/rtsp_client.cpp
Normal file → Executable file
@ -166,13 +166,13 @@ std::pair<bool, RtspSource> RtspClient::process(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!res.content_type.empty() &&
|
if (!res.content_type.empty() &&
|
||||||
res.content_type.rfind("application/sdp", 0) == std::string::npos) {
|
res.content_type.rfind("application/sdp", 0) == std::string::npos) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "rtsp_client:: unsupported content-type "
|
BOOST_LOG_TRIVIAL(error) << "rtsp_client:: unsupported content-type "
|
||||||
<< res.content_type << " from "
|
<< res.content_type << " from "
|
||||||
<< "rtsp://" << address << ":" << port << path;
|
<< "rtsp://" << address << ":" << port << path;
|
||||||
if (is_describe) {
|
if (is_describe) {
|
||||||
return {false, rtsp_source};
|
return {false, rtsp_source};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "rtsp:" << std::hex
|
ss << "rtsp:" << std::hex
|
||||||
@ -183,65 +183,65 @@ std::pair<bool, RtspSource> RtspClient::process(
|
|||||||
rtsp_source.source = "mDNS";
|
rtsp_source.source = "mDNS";
|
||||||
rtsp_source.address = address;
|
rtsp_source.address = address;
|
||||||
rtsp_source.sdp = std::move(res.body);
|
rtsp_source.sdp = std::move(res.body);
|
||||||
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: completed "
|
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: completed "
|
||||||
<< "rtsp://" << address << ":" << port << path;
|
<< "rtsp://" << address << ":" << port << path;
|
||||||
|
|
||||||
if (is_announce || is_describe) {
|
if (is_announce || is_describe) {
|
||||||
if (is_announce && announced_name.empty()) {
|
if (is_announce && announced_name.empty()) {
|
||||||
/* if no name from URL we try from SDP file */
|
/* if no name from URL we try from SDP file */
|
||||||
announced_name = sdp_get_subject(rtsp_source.sdp);
|
announced_name = sdp_get_subject(rtsp_source.sdp);
|
||||||
}
|
}
|
||||||
callback(announced_name.empty() ? name : announced_name, domain,
|
callback(announced_name.empty() ? name : announced_name, domain,
|
||||||
rtsp_source);
|
rtsp_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_announce) {
|
if (is_announce) {
|
||||||
s << "RTSP/1.0 200 OK\r\n";
|
s << "RTSP/1.0 200 OK\r\n";
|
||||||
s << "CSeq: " << res.cseq << "\r\n";
|
s << "CSeq: " << res.cseq << "\r\n";
|
||||||
s << "\r\n";
|
s << "\r\n";
|
||||||
} else if (!is_describe) {
|
} else if (!is_describe) {
|
||||||
s << "RTSP/1.0 405 Method Not Allowed\r\n";
|
s << "RTSP/1.0 405 Method Not Allowed\r\n";
|
||||||
s << "CSeq: " << res.cseq << "\r\n";
|
s << "CSeq: " << res.cseq << "\r\n";
|
||||||
s << "\r\n";
|
s << "\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait_for_updates) {
|
if (wait_for_updates) {
|
||||||
g_mutex.lock();
|
g_mutex.lock();
|
||||||
g_active_clients[{name, domain}] = &s;
|
g_active_clients[{name, domain}] = &s;
|
||||||
g_mutex.unlock();
|
g_mutex.unlock();
|
||||||
|
|
||||||
/* we start waiting for updates */
|
/* we start waiting for updates */
|
||||||
do {
|
do {
|
||||||
std::getline(s, request);
|
std::getline(s, request);
|
||||||
} while (request.empty() && !s.error());
|
} while (request.empty() && !s.error());
|
||||||
if (s.error()) {
|
if (s.error()) {
|
||||||
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: end: "
|
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: end: "
|
||||||
<< s.error().message();
|
<< s.error().message();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: received " << request;
|
|
||||||
boost::trim(request);
|
|
||||||
is_describe = is_announce = false;
|
|
||||||
announced_name = "";
|
|
||||||
std::vector<std::string> fields;
|
|
||||||
split(fields, request, boost::is_any_of(" "));
|
|
||||||
if (fields.size() >= 2 && fields[0] == "ANNOUNCE") {
|
|
||||||
auto const [ok, protocol, host, port, path] = parse_url(fields[1]);
|
|
||||||
if (ok) {
|
|
||||||
/* if we find a valid announced source name we use it
|
|
||||||
* otherwise we try from SDP file or we use the mDNS name */
|
|
||||||
if (path.rfind("/by-name/") != std::string::npos) {
|
|
||||||
announced_name = path.substr(9);
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "rtsp_client:: found announced name "
|
|
||||||
<< announced_name;
|
|
||||||
}
|
}
|
||||||
}
|
BOOST_LOG_TRIVIAL(info) << "rtsp_client:: received " << request;
|
||||||
is_announce = true;
|
boost::trim(request);
|
||||||
}
|
is_describe = is_announce = false;
|
||||||
|
announced_name = "";
|
||||||
|
std::vector<std::string> fields;
|
||||||
|
split(fields, request, boost::is_any_of(" "));
|
||||||
|
if (fields.size() >= 2 && fields[0] == "ANNOUNCE") {
|
||||||
|
auto const res = parse_url(fields[1]);
|
||||||
|
if (std::get<0>(res)) {
|
||||||
|
/* if we find a valid announced source name we use it
|
||||||
|
* 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) {
|
||||||
|
announced_name = path.substr(9);
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "rtsp_client:: found announced name "
|
||||||
|
<< announced_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is_announce = true;
|
||||||
}
|
}
|
||||||
} 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
17
daemon/rtsp_server.cpp
Normal file → Executable 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
7
daemon/rtsp_server.hpp
Normal file → Executable 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
3
daemon/session_manager.cpp
Normal file → Executable 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"
|
||||||
|
16
daemon/utils.cpp
Normal file → Executable file
16
daemon/utils.cpp
Normal file → Executable 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;
|
||||||
ss << "AES67 daemon " << std::hex << (uint32_t)gethostid();
|
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();
|
||||||
|
}
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
2
daemon/utils.hpp
Normal file → Executable file
2
daemon/utils.hpp
Normal file → Executable 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user