1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

Merge remote-tracking branch 'john/rtc' into feature/rtc

This commit is contained in:
winlin 2020-04-03 15:17:13 +08:00
commit 0ff3ce7464
4 changed files with 64 additions and 10 deletions

View file

@ -639,13 +639,15 @@ srs_error_t SrsRtcSession::on_stun(SrsUdpMuxSocket* udp_mux_skt, SrsStunPacket*
if ((err = on_binding_request(udp_mux_skt, stun_req)) != srs_success) { if ((err = on_binding_request(udp_mux_skt, stun_req)) != srs_success) {
return srs_error_wrap(err, "stun binding request failed"); return srs_error_wrap(err, "stun binding request failed");
} }
}
last_stun_time = srs_get_system_time(); last_stun_time = srs_get_system_time();
if (strd && strd->sendonly_ukt) { if (strd && strd->sendonly_ukt) {
if (strd->sendonly_ukt->get_peer_id() != udp_mux_skt->get_peer_id()) { // We are running in the ice-lite(server) mode. If client have multi network interface,
strd->update_sendonly_socket(udp_mux_skt); // we only choose one candidate pair which is determined by client.
if (stun_req->get_use_candidate() && strd->sendonly_ukt->get_peer_id() != udp_mux_skt->get_peer_id()) {
strd->update_sendonly_socket(udp_mux_skt);
}
} }
} }
@ -678,6 +680,10 @@ srs_error_t SrsRtcSession::on_binding_request(SrsUdpMuxSocket* udp_mux_skt, SrsS
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
if (stun_req->get_ice_controlled()) {
return srs_error_new(ERROR_RTC_STUN, "Peer must not in ice-controlled role in ice-lite mode.");
}
SrsStunPacket stun_binding_response; SrsStunPacket stun_binding_response;
char buf[1460]; char buf[1460];
SrsBuffer* stream = new SrsBuffer(buf, sizeof(buf)); SrsBuffer* stream = new SrsBuffer(buf, sizeof(buf));
@ -1159,13 +1165,14 @@ srs_error_t SrsRtcServer::on_stun(SrsUdpMuxSocket* udp_mux_skt)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
srs_verbose("recv stun packet from %s", udp_mux_skt->get_peer_id().c_str());
SrsStunPacket stun_req; SrsStunPacket stun_req;
if ((err = stun_req.decode(udp_mux_skt->data(), udp_mux_skt->size())) != srs_success) { if ((err = stun_req.decode(udp_mux_skt->data(), udp_mux_skt->size())) != srs_success) {
return srs_error_wrap(err, "decode stun packet failed"); return srs_error_wrap(err, "decode stun packet failed");
} }
srs_verbose("recv stun packet from %s, use-candidate=%d, ice-controlled=%d, ice-controlling=%d",
udp_mux_skt->get_peer_id().c_str(), stun_req.get_use_candidate(), stun_req.get_ice_controlled(), stun_req.get_ice_controlling());
std::string username = stun_req.get_username(); std::string username = stun_req.get_username();
SrsRtcSession* rtc_session = find_rtc_session_by_username(username); SrsRtcSession* rtc_session = find_rtc_session_by_username(username);
if (rtc_session == NULL) { if (rtc_session == NULL) {

View file

@ -349,9 +349,18 @@ srs_error_t SrsMediaDesc::encode(std::ostringstream& os)
} }
} }
// TODO: Candidate priority int foundation = 0;
int component_id = 1; /* RTP */
for (std::vector<SrsCandidate>::iterator iter = candidates_.begin(); iter != candidates_.end(); ++iter) { for (std::vector<SrsCandidate>::iterator iter = candidates_.begin(); iter != candidates_.end(); ++iter) {
os << "a=candidate:10 1 udp 2115783679 " << iter->ip_ << " " << iter->port_ <<" typ " << iter->type_ << " generation 0" << kCRLF; // @see: https://tools.ietf.org/html/draft-ietf-ice-rfc5245bis-00#section-4.2
uint32_t priority = (1<<24)*(126) + (1<<8)*(65535) + (1)*(256 - component_id);
// @see: https://tools.ietf.org/id/draft-ietf-mmusic-ice-sip-sdp-14.html#rfc.section.5.1
os << "a=candidate:" << foundation++ << " "
<< component_id << " udp " << priority << " "
<< iter->ip_ << " " << iter->port_
<< " typ " << iter->type_
<< " generation 0" << kCRLF;
} }
return err; return err;
@ -656,7 +665,7 @@ srs_error_t SrsSdp::encode(std::ostringstream& os)
os << "o=" << username_ << " " << session_id_ << " " << session_version_ << " " << nettype_ << " " << addrtype_ << " " << unicast_address_ << kCRLF; os << "o=" << username_ << " " << session_id_ << " " << session_version_ << " " << nettype_ << " " << addrtype_ << " " << unicast_address_ << kCRLF;
os << "s=" << session_name_ << kCRLF; os << "s=" << session_name_ << kCRLF;
os << "t=" << start_time_ << " " << end_time_ << kCRLF; os << "t=" << start_time_ << " " << end_time_ << kCRLF;
// @see: ice-lite is a minimal version of the ICE specification, intended for servers running on a public IP address. // ice-lite is a minimal version of the ICE specification, intended for servers running on a public IP address.
os << "a=ice-lite" << kCRLF; os << "a=ice-lite" << kCRLF;
if (! groups_.empty()) { if (! groups_.empty()) {

View file

@ -89,6 +89,9 @@ SrsStunPacket::SrsStunPacket()
message_type = 0; message_type = 0;
local_ufrag = ""; local_ufrag = "";
remote_ufrag = ""; remote_ufrag = "";
use_candidate = false;
ice_controlled = false;
ice_controlling = false;
} }
SrsStunPacket::~SrsStunPacket() SrsStunPacket::~SrsStunPacket()
@ -141,7 +144,31 @@ srs_error_t SrsStunPacket::decode(const char* buf, const int nb_buf)
break; break;
} }
case UseCandidate: {
use_candidate = true;
srs_verbose("stun use-candidate");
break;
}
// @see: https://tools.ietf.org/html/draft-ietf-ice-rfc5245bis-00#section-5.1.2
// One agent full, one lite: The full agent MUST take the controlling
// role, and the lite agent MUST take the controlled role. The full
// agent will form check lists, run the ICE state machines, and
// generate connectivity checks.
case IceControlled: {
ice_controlled = true;
srs_verbose("stun ice-controlled");
break;
}
case IceControlling: {
ice_controlling = true;
srs_verbose("stun ice-controlling");
break;
}
default: { default: {
srs_verbose("stun type=%u, no process", type);
break; break;
} }
} }

View file

@ -69,6 +69,11 @@ enum SrsStunMessageAttribute
Software = 0x8022, Software = 0x8022,
AlternateServer = 0x8023, AlternateServer = 0x8023,
Fingerprint = 0x8028, Fingerprint = 0x8028,
Priority = 0x0024,
UseCandidate = 0x0025,
IceControlled = 0x8029,
IceControlling = 0x802A,
}; };
class SrsStunPacket class SrsStunPacket
@ -81,6 +86,9 @@ private:
std::string transcation_id; std::string transcation_id;
uint32_t mapped_address; uint32_t mapped_address;
uint16_t mapped_port; uint16_t mapped_port;
bool use_candidate;
bool ice_controlled;
bool ice_controlling;
public: public:
SrsStunPacket(); SrsStunPacket();
virtual ~SrsStunPacket(); virtual ~SrsStunPacket();
@ -95,6 +103,9 @@ public:
std::string get_transcation_id() const { return transcation_id; } std::string get_transcation_id() const { return transcation_id; }
uint32_t get_mapped_address() const { return mapped_address; } uint32_t get_mapped_address() const { return mapped_address; }
uint16_t get_mapped_port() const { return mapped_port; } uint16_t get_mapped_port() const { return mapped_port; }
bool get_ice_controlled() const { return ice_controlled; }
bool get_ice_controlling() const { return ice_controlling; }
bool get_use_candidate() const { return use_candidate; }
void set_message_type(const uint16_t& m) { message_type = m; } void set_message_type(const uint16_t& m) { message_type = m; }
void set_local_ufrag(const std::string& u) { local_ufrag = u; } void set_local_ufrag(const std::string& u) { local_ufrag = u; }