diff --git a/README.md b/README.md index 2a27804d7..105e483f3 100755 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ For previous versions, please read: ## V4 changes +* v4.0, 2021-02-05, RTC: Refine UDP packet peer fast id. 4.0.68 * v4.0, 2021-02-04, RTC: Reuse UDP socket to receive packet. 4.0.67 * v4.0, 2021-02-04, At least wait 1ms when <1ms, to avoid epoll_wait spin loop. 4.0.66 * v4.0, 2021-01-31, Enable -std=c++11 by default. 4.0.65 diff --git a/trunk/src/app/srs_app_conn.cpp b/trunk/src/app/srs_app_conn.cpp index c7a4d3a84..707aa4af8 100644 --- a/trunk/src/app/srs_app_conn.cpp +++ b/trunk/src/app/srs_app_conn.cpp @@ -127,6 +127,12 @@ void SrsResourceManager::add_with_id(const std::string& id, ISrsResource* conn) conns_id_[id] = conn; } +void SrsResourceManager::add_with_fast_id(uint64_t id, ISrsResource* conn) +{ + add(conn); + conns_fast_id_[id] = conn; +} + void SrsResourceManager::add_with_name(const std::string& name, ISrsResource* conn) { add(conn); @@ -144,6 +150,12 @@ ISrsResource* SrsResourceManager::find_by_id(std::string id) return (it != conns_id_.end())? it->second : NULL; } +ISrsResource* SrsResourceManager::find_by_fast_id(uint64_t id) +{ + map::iterator it = conns_fast_id_.find(id); + return (it != conns_fast_id_.end())? it->second : NULL; +} + ISrsResource* SrsResourceManager::find_by_name(std::string name) { map::iterator it = conns_name_.find(name); @@ -316,6 +328,15 @@ void SrsResourceManager::dispose(ISrsResource* c) } } + for (map::iterator it = conns_fast_id_.begin(); it != conns_fast_id_.end();) { + if (c != it->second) { + ++it; + } else { + // Use C++98 style: https://stackoverflow.com/a/4636230 + conns_fast_id_.erase(it++); + } + } + vector::iterator it = std::find(conns_.begin(), conns_.end(), c); if (it != conns_.end()) { conns_.erase(it); diff --git a/trunk/src/app/srs_app_conn.hpp b/trunk/src/app/srs_app_conn.hpp index c61bbefbe..8af94e956 100644 --- a/trunk/src/app/srs_app_conn.hpp +++ b/trunk/src/app/srs_app_conn.hpp @@ -76,6 +76,8 @@ private: std::vector conns_; // The connections with resource id. std::map conns_id_; + // The connections with resource fast(int) id. + std::map conns_fast_id_; // The connections with resource name. std::map conns_name_; public: @@ -91,9 +93,11 @@ public: public: void add(ISrsResource* conn); void add_with_id(const std::string& id, ISrsResource* conn); + void add_with_fast_id(uint64_t id, ISrsResource* conn); void add_with_name(const std::string& name, ISrsResource* conn); ISrsResource* at(int index); ISrsResource* find_by_id(std::string id); + ISrsResource* find_by_fast_id(uint64_t id); ISrsResource* find_by_name(std::string name); public: void subscribe(ISrsDisposingHandler* h); diff --git a/trunk/src/app/srs_app_listener.cpp b/trunk/src/app/srs_app_listener.cpp index b93769e9d..e2b1d4c13 100755 --- a/trunk/src/app/srs_app_listener.cpp +++ b/trunk/src/app/srs_app_listener.cpp @@ -293,6 +293,8 @@ SrsUdpMuxSocket::SrsUdpMuxSocket(srs_netfd_t fd) fromlen = 0; peer_port = 0; + + fast_id_ = 0; } SrsUdpMuxSocket::~SrsUdpMuxSocket() @@ -327,7 +329,9 @@ int SrsUdpMuxSocket::recvfrom(srs_utime_t timeout) peer_ip = it->second; } + peer_id_ = ""; peer_port = ntohs(addr->sin_port); + fast_id_ = uint64_t(peer_port)<<48 | uint64_t(addr->sin_addr.s_addr); parsed = true; } @@ -403,10 +407,17 @@ int SrsUdpMuxSocket::get_peer_port() const std::string SrsUdpMuxSocket::peer_id() { - char id_buf[1024]; - int len = snprintf(id_buf, sizeof(id_buf), "%s:%d", peer_ip.c_str(), peer_port); + if (peer_id_.empty()) { + static char id_buf[128]; + int len = snprintf(id_buf, sizeof(id_buf), "%s:%d", peer_ip.c_str(), peer_port); + peer_id_ = string(id_buf, len); + } + return peer_id_; +} - return string(id_buf, len); +uint64_t SrsUdpMuxSocket::fast_id() +{ + return fast_id_; } SrsUdpMuxSocket* SrsUdpMuxSocket::copy_sendonly() @@ -423,6 +434,10 @@ SrsUdpMuxSocket* SrsUdpMuxSocket::copy_sendonly() sendonly->peer_ip = peer_ip; sendonly->peer_port = peer_port; + // Copy the fast id. + sendonly->peer_id_ = peer_id_; + sendonly->fast_id_ = fast_id_; + return sendonly; } diff --git a/trunk/src/app/srs_app_listener.hpp b/trunk/src/app/srs_app_listener.hpp index 0f856548c..6d4a5dabd 100644 --- a/trunk/src/app/srs_app_listener.hpp +++ b/trunk/src/app/srs_app_listener.hpp @@ -145,8 +145,14 @@ private: srs_netfd_t lfd; sockaddr_storage from; int fromlen; +private: std::string peer_ip; int peer_port; +private: + // Cache for peer id. + std::string peer_id_; + // For IPv4 client, we use 8 bytes int id to find it fastly. + uint64_t fast_id_; public: SrsUdpMuxSocket(srs_netfd_t fd); virtual ~SrsUdpMuxSocket(); @@ -161,6 +167,7 @@ public: std::string get_peer_ip() const; int get_peer_port() const; std::string peer_id(); + uint64_t fast_id(); SrsUdpMuxSocket* copy_sendonly(); }; diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index c7830d19c..78cf2bc3b 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -2257,7 +2257,12 @@ void SrsRtcConnection::update_sendonly_socket(SrsUdpMuxSocket* skt) // If no cache, build cache and setup the relations in connection. if (!addr_cache) { peer_addresses_[peer_id] = addr_cache = skt->copy_sendonly(); - server_->insert_into_id_sessions(peer_id, this); + _srs_rtc_manager->add_with_id(peer_id, this); + + uint64_t fast_id = skt->fast_id(); + if (fast_id) { + _srs_rtc_manager->add_with_fast_id(fast_id, this); + } } // Update the transport. diff --git a/trunk/src/app/srs_app_rtc_server.cpp b/trunk/src/app/srs_app_rtc_server.cpp index 24fe1e721..322547bba 100644 --- a/trunk/src/app/srs_app_rtc_server.cpp +++ b/trunk/src/app/srs_app_rtc_server.cpp @@ -300,10 +300,19 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt) { srs_error_t err = srs_success; - string peer_id = skt->peer_id(); + SrsRtcConnection* session = NULL; char* data = skt->data(); int size = skt->size(); - SrsRtcConnection* session = (SrsRtcConnection*)_srs_rtc_manager->find_by_id(peer_id); + uint64_t fast_id = skt->fast_id(); + // Try fast id first, if not found, search by long peer id. + if (fast_id) { + session = (SrsRtcConnection*)_srs_rtc_manager->find_by_fast_id(fast_id); + } + if (!session) { + string peer_id = skt->peer_id(); + session = (SrsRtcConnection*)_srs_rtc_manager->find_by_id(peer_id); + } + if (session) { // Switch to the session to write logs to the context. session->switch_to_context(); @@ -326,12 +335,14 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt) // For STUN, the peer address may change. if (srs_is_stun((uint8_t*)data, size)) { + string peer_id = skt->peer_id(); + SrsStunPacket ping; if ((err = ping.decode(data, size)) != srs_success) { return srs_error_wrap(err, "decode stun packet failed"); } - srs_info("recv stun packet from %s, use-candidate=%d, ice-controlled=%d, ice-controlling=%d", - peer_id.c_str(), ping.get_use_candidate(), ping.get_ice_controlled(), ping.get_ice_controlling()); + srs_info("recv stun packet from %s, fast=%" PRId64 ", use-candidate=%d, ice-controlled=%d, ice-controlling=%d", + peer_id.c_str(), fast_id, ping.get_use_candidate(), ping.get_ice_controlled(), ping.get_ice_controlling()); if (!session) { session = find_session_by_username(ping.get_username()); @@ -344,8 +355,8 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt) // TODO: FIXME: For ICE trickle, we may get STUN packets before SDP answer, so maybe should response it. if (!session) { - return srs_error_new(ERROR_RTC_STUN, "no session, stun username=%s, peer_id=%s", - ping.get_username().c_str(), peer_id.c_str()); + return srs_error_new(ERROR_RTC_STUN, "no session, stun username=%s, peer_id=%s, fast=%" PRId64, + ping.get_username().c_str(), peer_id.c_str(), fast_id); } return session->on_stun(skt, &ping); @@ -353,7 +364,8 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt) // For DTLS, RTCP or RTP, which does not support peer address changing. if (!session) { - return srs_error_new(ERROR_RTC_STUN, "no session, peer_id=%s", peer_id.c_str()); + string peer_id = skt->peer_id(); + return srs_error_new(ERROR_RTC_STUN, "no session, peer_id=%s, fast=%" PRId64, peer_id.c_str(), fast_id); } if (srs_is_dtls((uint8_t*)data, size)) { @@ -576,11 +588,6 @@ srs_error_t SrsRtcServer::setup_session2(SrsRtcConnection* session, SrsRequest* return err; } -void SrsRtcServer::insert_into_id_sessions(const string& peer_id, SrsRtcConnection* session) -{ - _srs_rtc_manager->add_with_id(peer_id, session); -} - SrsRtcConnection* SrsRtcServer::find_session_by_username(const std::string& username) { ISrsResource* conn = _srs_rtc_manager->find_by_name(username); diff --git a/trunk/src/app/srs_app_rtc_server.hpp b/trunk/src/app/srs_app_rtc_server.hpp index e1f7d7397..8dd4b5530 100644 --- a/trunk/src/app/srs_app_rtc_server.hpp +++ b/trunk/src/app/srs_app_rtc_server.hpp @@ -122,8 +122,6 @@ public: // We start offering, create_session2 to generate offer, setup_session2 to handle answer. srs_error_t create_session2(SrsRequest* req, SrsSdp& local_sdp, const std::string& mock_eip, bool unified_plan, SrsRtcConnection** psession); srs_error_t setup_session2(SrsRtcConnection* session, SrsRequest* req, const SrsSdp& remote_sdp); -public: - void insert_into_id_sessions(const std::string& peer_id, SrsRtcConnection* session); public: SrsRtcConnection* find_session_by_username(const std::string& ufrag); // interface ISrsHourGlass diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index 672284cf9..72b58e431 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -24,6 +24,6 @@ #ifndef SRS_CORE_VERSION4_HPP #define SRS_CORE_VERSION4_HPP -#define SRS_VERSION4_REVISION 67 +#define SRS_VERSION4_REVISION 68 #endif