1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-13 03:41:55 +00:00

RTC: Refine UDP packet peer fast id. 4.0.68

This commit is contained in:
winlin 2021-02-05 18:04:29 +08:00
parent e95fd10462
commit c3414a30dc
9 changed files with 77 additions and 19 deletions

View file

@ -155,6 +155,7 @@ For previous versions, please read:
## V4 changes ## 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, 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-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 * v4.0, 2021-01-31, Enable -std=c++11 by default. 4.0.65

View file

@ -127,6 +127,12 @@ void SrsResourceManager::add_with_id(const std::string& id, ISrsResource* conn)
conns_id_[id] = 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) void SrsResourceManager::add_with_name(const std::string& name, ISrsResource* conn)
{ {
add(conn); add(conn);
@ -144,6 +150,12 @@ ISrsResource* SrsResourceManager::find_by_id(std::string id)
return (it != conns_id_.end())? it->second : NULL; return (it != conns_id_.end())? it->second : NULL;
} }
ISrsResource* SrsResourceManager::find_by_fast_id(uint64_t id)
{
map<uint64_t, ISrsResource*>::iterator it = conns_fast_id_.find(id);
return (it != conns_fast_id_.end())? it->second : NULL;
}
ISrsResource* SrsResourceManager::find_by_name(std::string name) ISrsResource* SrsResourceManager::find_by_name(std::string name)
{ {
map<string, ISrsResource*>::iterator it = conns_name_.find(name); map<string, ISrsResource*>::iterator it = conns_name_.find(name);
@ -316,6 +328,15 @@ void SrsResourceManager::dispose(ISrsResource* c)
} }
} }
for (map<uint64_t, ISrsResource*>::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<ISrsResource*>::iterator it = std::find(conns_.begin(), conns_.end(), c); vector<ISrsResource*>::iterator it = std::find(conns_.begin(), conns_.end(), c);
if (it != conns_.end()) { if (it != conns_.end()) {
conns_.erase(it); conns_.erase(it);

View file

@ -76,6 +76,8 @@ private:
std::vector<ISrsResource*> conns_; std::vector<ISrsResource*> conns_;
// The connections with resource id. // The connections with resource id.
std::map<std::string, ISrsResource*> conns_id_; std::map<std::string, ISrsResource*> conns_id_;
// The connections with resource fast(int) id.
std::map<uint64_t, ISrsResource*> conns_fast_id_;
// The connections with resource name. // The connections with resource name.
std::map<std::string, ISrsResource*> conns_name_; std::map<std::string, ISrsResource*> conns_name_;
public: public:
@ -91,9 +93,11 @@ public:
public: public:
void add(ISrsResource* conn); void add(ISrsResource* conn);
void add_with_id(const std::string& id, 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); void add_with_name(const std::string& name, ISrsResource* conn);
ISrsResource* at(int index); ISrsResource* at(int index);
ISrsResource* find_by_id(std::string id); ISrsResource* find_by_id(std::string id);
ISrsResource* find_by_fast_id(uint64_t id);
ISrsResource* find_by_name(std::string name); ISrsResource* find_by_name(std::string name);
public: public:
void subscribe(ISrsDisposingHandler* h); void subscribe(ISrsDisposingHandler* h);

View file

@ -293,6 +293,8 @@ SrsUdpMuxSocket::SrsUdpMuxSocket(srs_netfd_t fd)
fromlen = 0; fromlen = 0;
peer_port = 0; peer_port = 0;
fast_id_ = 0;
} }
SrsUdpMuxSocket::~SrsUdpMuxSocket() SrsUdpMuxSocket::~SrsUdpMuxSocket()
@ -327,7 +329,9 @@ int SrsUdpMuxSocket::recvfrom(srs_utime_t timeout)
peer_ip = it->second; peer_ip = it->second;
} }
peer_id_ = "";
peer_port = ntohs(addr->sin_port); peer_port = ntohs(addr->sin_port);
fast_id_ = uint64_t(peer_port)<<48 | uint64_t(addr->sin_addr.s_addr);
parsed = true; parsed = true;
} }
@ -403,10 +407,17 @@ int SrsUdpMuxSocket::get_peer_port() const
std::string SrsUdpMuxSocket::peer_id() std::string SrsUdpMuxSocket::peer_id()
{ {
char id_buf[1024]; if (peer_id_.empty()) {
int len = snprintf(id_buf, sizeof(id_buf), "%s:%d", peer_ip.c_str(), peer_port); 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() SrsUdpMuxSocket* SrsUdpMuxSocket::copy_sendonly()
@ -423,6 +434,10 @@ SrsUdpMuxSocket* SrsUdpMuxSocket::copy_sendonly()
sendonly->peer_ip = peer_ip; sendonly->peer_ip = peer_ip;
sendonly->peer_port = peer_port; sendonly->peer_port = peer_port;
// Copy the fast id.
sendonly->peer_id_ = peer_id_;
sendonly->fast_id_ = fast_id_;
return sendonly; return sendonly;
} }

View file

@ -145,8 +145,14 @@ private:
srs_netfd_t lfd; srs_netfd_t lfd;
sockaddr_storage from; sockaddr_storage from;
int fromlen; int fromlen;
private:
std::string peer_ip; std::string peer_ip;
int peer_port; 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: public:
SrsUdpMuxSocket(srs_netfd_t fd); SrsUdpMuxSocket(srs_netfd_t fd);
virtual ~SrsUdpMuxSocket(); virtual ~SrsUdpMuxSocket();
@ -161,6 +167,7 @@ public:
std::string get_peer_ip() const; std::string get_peer_ip() const;
int get_peer_port() const; int get_peer_port() const;
std::string peer_id(); std::string peer_id();
uint64_t fast_id();
SrsUdpMuxSocket* copy_sendonly(); SrsUdpMuxSocket* copy_sendonly();
}; };

View file

@ -2257,7 +2257,12 @@ void SrsRtcConnection::update_sendonly_socket(SrsUdpMuxSocket* skt)
// If no cache, build cache and setup the relations in connection. // If no cache, build cache and setup the relations in connection.
if (!addr_cache) { if (!addr_cache) {
peer_addresses_[peer_id] = addr_cache = skt->copy_sendonly(); 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. // Update the transport.

View file

@ -300,10 +300,19 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
string peer_id = skt->peer_id(); SrsRtcConnection* session = NULL;
char* data = skt->data(); int size = skt->size(); 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) { if (session) {
// Switch to the session to write logs to the context. // Switch to the session to write logs to the context.
session->switch_to_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. // For STUN, the peer address may change.
if (srs_is_stun((uint8_t*)data, size)) { if (srs_is_stun((uint8_t*)data, size)) {
string peer_id = skt->peer_id();
SrsStunPacket ping; SrsStunPacket ping;
if ((err = ping.decode(data, size)) != srs_success) { if ((err = ping.decode(data, size)) != srs_success) {
return srs_error_wrap(err, "decode stun packet failed"); 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", srs_info("recv stun packet from %s, fast=%" PRId64 ", 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()); peer_id.c_str(), fast_id, ping.get_use_candidate(), ping.get_ice_controlled(), ping.get_ice_controlling());
if (!session) { if (!session) {
session = find_session_by_username(ping.get_username()); 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. // TODO: FIXME: For ICE trickle, we may get STUN packets before SDP answer, so maybe should response it.
if (!session) { if (!session) {
return srs_error_new(ERROR_RTC_STUN, "no session, stun username=%s, peer_id=%s", 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()); ping.get_username().c_str(), peer_id.c_str(), fast_id);
} }
return session->on_stun(skt, &ping); 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. // For DTLS, RTCP or RTP, which does not support peer address changing.
if (!session) { 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)) { if (srs_is_dtls((uint8_t*)data, size)) {
@ -576,11 +588,6 @@ srs_error_t SrsRtcServer::setup_session2(SrsRtcConnection* session, SrsRequest*
return err; 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) SrsRtcConnection* SrsRtcServer::find_session_by_username(const std::string& username)
{ {
ISrsResource* conn = _srs_rtc_manager->find_by_name(username); ISrsResource* conn = _srs_rtc_manager->find_by_name(username);

View file

@ -122,8 +122,6 @@ public:
// We start offering, create_session2 to generate offer, setup_session2 to handle answer. // 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 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); 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: public:
SrsRtcConnection* find_session_by_username(const std::string& ufrag); SrsRtcConnection* find_session_by_username(const std::string& ufrag);
// interface ISrsHourGlass // interface ISrsHourGlass

View file

@ -24,6 +24,6 @@
#ifndef SRS_CORE_VERSION4_HPP #ifndef SRS_CORE_VERSION4_HPP
#define SRS_CORE_VERSION4_HPP #define SRS_CORE_VERSION4_HPP
#define SRS_VERSION4_REVISION 67 #define SRS_VERSION4_REVISION 68
#endif #endif