Skip to content

Commit

Permalink
RTC: Refine UDP packet peer fast id. 4.0.68
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Feb 10, 2021
1 parent e95fd10 commit c3414a3
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 19 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 21 additions & 0 deletions trunk/src/app/srs_app_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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<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)
{
map<string, ISrsResource*>::iterator it = conns_name_.find(name);
Expand Down Expand Up @@ -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);
if (it != conns_.end()) {
conns_.erase(it);
Expand Down
4 changes: 4 additions & 0 deletions trunk/src/app/srs_app_conn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ class SrsResourceManager : virtual public ISrsCoroutineHandler, virtual public I
std::vector<ISrsResource*> conns_;
// The connections with resource 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.
std::map<std::string, ISrsResource*> conns_name_;
public:
Expand All @@ -91,9 +93,11 @@ class SrsResourceManager : virtual public ISrsCoroutineHandler, virtual public I
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);
Expand Down
21 changes: 18 additions & 3 deletions trunk/src/app/srs_app_listener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ SrsUdpMuxSocket::SrsUdpMuxSocket(srs_netfd_t fd)

fromlen = 0;
peer_port = 0;

fast_id_ = 0;
}

SrsUdpMuxSocket::~SrsUdpMuxSocket()
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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()
Expand All @@ -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;
}

Expand Down
7 changes: 7 additions & 0 deletions trunk/src/app/srs_app_listener.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,14 @@ class SrsUdpMuxSocket
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();
Expand All @@ -161,6 +167,7 @@ class SrsUdpMuxSocket
std::string get_peer_ip() const;
int get_peer_port() const;
std::string peer_id();
uint64_t fast_id();
SrsUdpMuxSocket* copy_sendonly();
};

Expand Down
7 changes: 6 additions & 1 deletion trunk/src/app/srs_app_rtc_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
31 changes: 19 additions & 12 deletions trunk/src/app/srs_app_rtc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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());
Expand All @@ -344,16 +355,17 @@ 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);
}

// 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)) {
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 0 additions & 2 deletions trunk/src/app/srs_app_rtc_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,6 @@ class SrsRtcServer : virtual public ISrsUdpMuxHandler, virtual public ISrsHourGl
// 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
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core_version4.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit c3414a3

Please sign in to comment.