From 62563bdd8196bf12acbb0f18152ecfd321cde4e8 Mon Sep 17 00:00:00 2001 From: xiaozhihong Date: Fri, 28 Feb 2020 23:18:39 +0800 Subject: [PATCH] rtc framework --- trunk/configure | 2 +- trunk/src/app/srs_app_http_api.cpp | 10 +- trunk/src/app/srs_app_listener.cpp | 39 +++++ trunk/src/app/srs_app_listener.hpp | 15 +- trunk/src/app/srs_app_rtc.cpp | 86 ++++++++++ trunk/src/app/srs_app_rtc.hpp | 52 ++++++ trunk/src/app/srs_app_rtc_conn.cpp | 143 ++++++++++++++++ trunk/src/app/srs_app_rtc_conn.hpp | 88 ++++++++++ trunk/src/app/srs_app_rtc_udp.cpp | 232 -------------------------- trunk/src/app/srs_app_rtc_udp.hpp | 96 ----------- trunk/src/app/srs_app_server.cpp | 28 ++-- trunk/src/app/srs_app_server.hpp | 14 +- trunk/src/protocol/srs_stun_stack.cpp | 6 +- trunk/src/protocol/srs_stun_stack.hpp | 9 +- 14 files changed, 448 insertions(+), 372 deletions(-) create mode 100644 trunk/src/app/srs_app_rtc.cpp create mode 100644 trunk/src/app/srs_app_rtc.hpp create mode 100644 trunk/src/app/srs_app_rtc_conn.cpp create mode 100644 trunk/src/app/srs_app_rtc_conn.hpp delete mode 100644 trunk/src/app/srs_app_rtc_udp.cpp delete mode 100644 trunk/src/app/srs_app_rtc_udp.hpp diff --git a/trunk/configure b/trunk/configure index 5de5bc31d..a29047e72 100755 --- a/trunk/configure +++ b/trunk/configure @@ -254,7 +254,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_edge" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static" "srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds" - "srs_app_mpegts_udp" "srs_app_rtc_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call" + "srs_app_mpegts_udp" "srs_app_rtc" "srs_app_rtc_conn" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call" "srs_app_caster_flv" "srs_app_process" "srs_app_ng_exec" "srs_app_hourglass" "srs_app_dash" "srs_app_fragment" "srs_app_dvr" "srs_app_coworkers" "srs_app_hybrid") diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 570d14662..fc54303b4 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -46,7 +46,7 @@ using namespace std; #include #include #include -#include +#include string test_sdp = "v=0\\r\\n" @@ -875,14 +875,6 @@ srs_error_t SrsGoApiSdp::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* SrsJsonObject* obj = SrsJsonAny::object(); SrsAutoFree(SrsJsonObject, obj); - SrsRtcListener* rtc_listener = dynamic_cast(server->find_listener(SrsListenerRtcOverUdp)); - if (rtc_listener == NULL) { - return srs_go_http_error(w, SRS_CONSTS_HTTP_Unauthorized); - } - - SrsRtcOverUdp* rtc = rtc_listener->get_rtc(); - rtc->create_rtc_session("192.168.170.169", "xiaozhihongjohn", "ok"); - obj->set("code", SrsJsonAny::integer(ERROR_SUCCESS)); obj->set("server", SrsJsonAny::integer(stat->server_id())); diff --git a/trunk/src/app/srs_app_listener.cpp b/trunk/src/app/srs_app_listener.cpp index b33b4f6f8..0cd389df5 100755 --- a/trunk/src/app/srs_app_listener.cpp +++ b/trunk/src/app/srs_app_listener.cpp @@ -207,3 +207,42 @@ srs_error_t SrsTcpListener::cycle() return err; } +SrsUdpRemuxListener::SrsUdpRemuxListener(ISrsUdpHandler* h, std::string i, int p) : SrsUdpListener(h, i, p) +{ +} + +SrsUdpRemuxListener::~SrsUdpRemuxListener() +{ +} + +srs_error_t SrsUdpRemuxListener::cycle() +{ + srs_error_t err = srs_success; + + while (true) { + if ((err = trd->pull()) != srs_success) { + return srs_error_wrap(err, "udp listener"); + } + + int nread = 0; + sockaddr_storage from; + int nb_from = sizeof(from); + if ((nread = srs_recvfrom(lfd, buf, nb_buf, (sockaddr*)&from, &nb_from, SRS_UTIME_NO_TIMEOUT)) <= 0) { + srs_error("udp recv error"); + // remux udp never return + continue; + } + + if ((err = handler->on_udp_packet((const sockaddr*)&from, nb_from, buf, nread)) != srs_success) { + //srs_error("udp handle packet error"); + // remux udp never return + continue; + } + + if (SrsUdpPacketRecvCycleInterval > 0) { + srs_usleep(SrsUdpPacketRecvCycleInterval); + } + } + + return err; +} diff --git a/trunk/src/app/srs_app_listener.hpp b/trunk/src/app/srs_app_listener.hpp index d7d930e91..a667af94d 100644 --- a/trunk/src/app/srs_app_listener.hpp +++ b/trunk/src/app/srs_app_listener.hpp @@ -68,13 +68,13 @@ public: // Bind udp port, start thread to recv packet and handler it. class SrsUdpListener : public ISrsCoroutineHandler { -private: +protected: srs_netfd_t lfd; SrsCoroutine* trd; -private: +protected: char* buf; int nb_buf; -private: +protected: ISrsUdpHandler* handler; std::string ip; int port; @@ -113,4 +113,13 @@ public: virtual srs_error_t cycle(); }; +class SrsUdpRemuxListener : public SrsUdpListener +{ +public: + SrsUdpRemuxListener(ISrsUdpHandler* h, std::string i, int p); + virtual ~SrsUdpRemuxListener(); +public: + virtual srs_error_t cycle(); +}; + #endif diff --git a/trunk/src/app/srs_app_rtc.cpp b/trunk/src/app/srs_app_rtc.cpp new file mode 100644 index 000000000..6f5378125 --- /dev/null +++ b/trunk/src/app/srs_app_rtc.cpp @@ -0,0 +1,86 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2013-2020 Winlin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include +using namespace std; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static bool is_stun(const char* data, const int size) { + return data != NULL && size > 0 && (data[0] == 0 || data[0] == 1); +} + +static bool is_rtp_or_rtcp(const char* data, const int size) { + return data != NULL && size > 0 && (data[0] >= 128 && data[0] <= 191); +} + +static bool is_dtls(const char* data, const int size) { + return data != NULL && size > 0 && (data[0] >= 20 && data[0] <= 64); +} + +SrsRtc::SrsRtc(SrsRtcServer* rtc_svr) +{ + rtc_server = rtc_svr; +} + +SrsRtc::~SrsRtc() +{ +} + +srs_error_t SrsRtc::on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf) +{ + char address_string[64]; + char port_string[16]; + if(getnameinfo(from, fromlen, + (char*)&address_string, sizeof(address_string), + (char*)&port_string, sizeof(port_string), + NI_NUMERICHOST|NI_NUMERICSERV)) { + return srs_error_new(ERROR_SYSTEM_IP_INVALID, "bad address"); + } + std::string peer_ip = std::string(address_string); + int peer_port = atoi(port_string); + + return rtc_server->on_udp_packet(peer_ip, peer_port, buf, nb_buf); +} diff --git a/trunk/src/app/srs_app_rtc.hpp b/trunk/src/app/srs_app_rtc.hpp new file mode 100644 index 000000000..6e1fb0651 --- /dev/null +++ b/trunk/src/app/srs_app_rtc.hpp @@ -0,0 +1,52 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2013-2020 Winlin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SRS_APP_RTC_HPP +#define SRS_APP_RTC_HPP + +#include + +struct sockaddr; +#include +#include + +#include +#include +#include + +class SrsRtcServer; + +// The rtc over udp stream receiver +class SrsRtc : virtual public ISrsUdpHandler +{ +private: + SrsRtcServer* rtc_server; +public: + SrsRtc(SrsRtcServer* rtc_svr); + virtual ~SrsRtc(); +// Interface ISrsUdpHandler +public: + virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf); +}; + +#endif diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp new file mode 100644 index 000000000..4f858da0a --- /dev/null +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -0,0 +1,143 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2013-2020 Winlin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +using namespace std; + +#include +#include +#include + +static bool is_stun(const char* data, const int size) { + return data != NULL && size > 0 && (data[0] == 0 || data[0] == 1); +} + +static bool is_rtp_or_rtcp(const char* data, const int size) { + return data != NULL && size > 0 && (data[0] >= 128 && data[0] <= 191); +} + +static bool is_dtls(const char* data, const int size) { + return data != NULL && size > 0 && (data[0] >= 20 && data[0] <= 64); +} + +SrsSDP::SrsSDP() +{ +} + +SrsSDP::~SrsSDP() +{ +} + +SrsRtcSession::SrsRtcSession() +{ + session_state = INIT; +} + +SrsRtcSession::~SrsRtcSession() +{ +} + +srs_error_t SrsRtcSession::on_stun(const SrsStunPacket& stun_packet) +{ + srs_error_t err = srs_success; + + return err; +} + +srs_error_t SrsRtcSession::send_packet() +{ +} + +SrsRtcServer::SrsRtcServer(SrsServer* svr) +{ + server = svr; +} + +SrsRtcServer::~SrsRtcServer() +{ +} + +srs_error_t SrsRtcServer::initialize() +{ + srs_error_t err = srs_success; + + return err; +} + +srs_error_t SrsRtcServer::on_udp_packet(const string& peer_ip, const int peer_port, const char* data, const int size) +{ + srs_error_t err = srs_success; + + if (is_stun(data, size)) { + return on_stun(peer_ip, peer_port, data, size); + } else if (is_dtls(data, size)) { + return on_dtls(peer_ip, peer_port, data, size); + } else if (is_rtp_or_rtcp(data, size)) { + return on_rtp_or_rtcp(peer_ip, peer_port, data, size); + } + + return srs_error_wrap(err, "unknown packet type"); +} + +srs_error_t SrsRtcServer::on_stun(const string& peer_ip, const int peer_port, const char* data, const int size) +{ + srs_error_t err = srs_success; + + srs_trace("peer %s:%d stun", peer_ip.c_str(), peer_port); + + SrsStunPacket stun_packet; + if (stun_packet.decode(data, size) != srs_success) { + return srs_error_wrap(err, "decode stun failed"); + } + + std::string peer_ufrag = stun_packet.ufrag(); + SrsRtcSession* rtc_session = find_rtc_session(peer_ufrag); + if (rtc_session == NULL) { + return srs_error_wrap(err, "can not find rtc_session, ufrag=%s", peer_ufrag.c_str()); + } + + return rtc_session->on_stun(stun_packet); +} + +srs_error_t SrsRtcServer::on_dtls(const string& peer_ip, const int peer_port, const char* data, const int size) +{ + srs_error_t err = srs_success; + return err; +} + +srs_error_t SrsRtcServer::on_rtp_or_rtcp(const string& peer_ip, const int peer_port, const char* data, const int size) +{ + srs_error_t err = srs_success; + return err; +} + +SrsRtcSession* SrsRtcServer::find_rtc_session(const std::string& ufrag) +{ + map::iterator iter = map_sessions.find(ufrag); + if (iter == map_sessions.end()) { + return NULL; + } + + return iter->second; +} diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp new file mode 100644 index 000000000..b5ba40235 --- /dev/null +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -0,0 +1,88 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2013-2020 Winlin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SRS_APP_RTC_CONN_HPP +#define SRS_APP_RTC_CONN_HPP + +#include + +#include +#include + +class SrsServer; +class SrsStunPacket; + +class SrsSDP +{ +private: +public: + SrsSDP(); + virtual ~SrsSDP(); +}; + +enum SrsRtcSessionStateType +{ + INIT = -1, + WAITING_STUN = 1, + DOING_DTLS_HANDSHAKE = 2, + ESTABLISHED = 3, + CLOSED = 4, +}; + +class SrsRtcSession +{ +public: +private: + SrsSDP peer_sdp; + SrsSDP offer_sdp; + SrsRtcSessionStateType session_state; +public: + SrsRtcSession(); + virtual ~SrsRtcSession(); + + srs_error_t on_udp_packet(const std::string& peer_ip, const int peer_port, const char* data, const int size); + srs_error_t on_stun(const SrsStunPacket& stun_packet); + srs_error_t send_packet(); +}; + +class SrsRtcServer +{ +private: + SrsServer* server; + std::map map_sessions; +public: + SrsRtcServer(SrsServer* svr); + virtual ~SrsRtcServer(); +public: + virtual srs_error_t initialize(); + virtual srs_error_t on_udp_packet(const std::string& peer_ip, const int peer_port, const char* data, const int size); +private: + srs_error_t on_stun(const std::string& peer_ip, const int peer_port, const char* data, const int size); + srs_error_t on_dtls(const std::string& peer_ip, const int peer_port, const char* data, const int size); + srs_error_t on_rtp_or_rtcp(const std::string& peer_ip, const int peer_port, const char* data, const int size); +private: + SrsRtcSession* find_rtc_session(const std::string& ufrag); +}; + +#endif + diff --git a/trunk/src/app/srs_app_rtc_udp.cpp b/trunk/src/app/srs_app_rtc_udp.cpp deleted file mode 100644 index 190c8b2c1..000000000 --- a/trunk/src/app/srs_app_rtc_udp.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2013-2020 Winlin - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include - -#include -#include -#include -#include -#include -using namespace std; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static bool is_stun(const char* data, const int size) { - return data != NULL && size > 0 && (data[0] == 0 || data[0] == 1); -} - -static bool is_rtp_or_rtcp(const char* data, const int size) { - return data != NULL && size > 0 && (data[0] >= 128 && data[0] <= 191); -} - -static bool is_dtls(const char* data, const int size) { - return data != NULL && size > 0 && (data[0] >= 20 && data[0] <= 64); -} - -SrsRtcUserInfo::SrsRtcUserInfo(const std::string& u, const std::string& p) -{ - username = u; - password = p; -} - -SrsRtcUserInfo::~SrsRtcUserInfo() -{ -} - -SrsRtcOverUdp::SrsRtcOverUdp() -{ -} - -SrsRtcOverUdp::~SrsRtcOverUdp() -{ -} - -SrsRtcSession* SrsRtcOverUdp::create_rtc_session(const std::string& peer_ip, const std::string& remote_username, const std::string& remote_password) -{ - SrsRtcSession* rtc_session = new SrsRtcSession(); - // TODO: process exception when session already exist - user_session_map[peer_ip].insert(make_pair(SrsRtcUserInfo(remote_username, remote_password), rtc_session)).second; - - return rtc_session; -} - -SrsRtcSession* SrsRtcOverUdp::find_rtc_session_by_user_info(const std::string& peer_ip, const std::string& remote_username, const std::string& remote_password) -{ - std::map >::iterator iter = user_session_map.find(peer_ip); - if (iter == user_session_map.end()) { - return NULL; - } - - std::map::iterator sub_iter = iter->second.find(SrsRtcUserInfo(remote_username, remote_password)); - if (sub_iter == iter->second.end()) { - return NULL; - } - - return sub_iter->second; -} - -srs_error_t SrsRtcOverUdp::on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf) -{ - char address_string[64]; - char port_string[16]; - if(getnameinfo(from, fromlen, - (char*)&address_string, sizeof(address_string), - (char*)&port_string, sizeof(port_string), - NI_NUMERICHOST|NI_NUMERICSERV)) { - return srs_error_new(ERROR_SYSTEM_IP_INVALID, "bad address"); - } - std::string peer_ip = std::string(address_string); - int peer_port = atoi(port_string); - - std::string peer_id = peer_ip + ":" + std::string(port_string); - - return on_udp_bytes(peer_ip, peer_port, peer_id, buf, nb_buf); -} - -SrsRtcSession* SrsRtcOverUdp::find_rtc_session_by_peer_id(const std::string& peer_id) -{ - map::iterator iter = id_session_map.find(peer_id); - if (iter == id_session_map.end()) { - return NULL; - } - - return iter->second; -} - -srs_error_t SrsRtcOverUdp::on_udp_bytes(const string& host, const int& port, const string& peer_id, char* buf, int nb_buf) -{ - srs_error_t err = srs_success; - - srs_trace("recv rtc udp packet from %s:%d, peer_id=%s, nb_buf=%d", host.c_str(), port, peer_id.c_str(), nb_buf); - - if (is_rtp_or_rtcp(buf, nb_buf)) { - err = on_rtp_or_rtcp(host, port, peer_id, buf, nb_buf); - } else if (is_stun(buf, nb_buf)) { - err = on_stun(host, port, peer_id, buf, nb_buf); - } else if (is_dtls(buf, nb_buf)) { - err = on_dtls(host, port, peer_id, buf, nb_buf); - } else { - return srs_error_wrap(err, "unknown udp packet"); - } - - return err; -} - -srs_error_t SrsRtcOverUdp::on_rtp_or_rtcp(const string& host, const int& port, const string& peer_id, const char* buf, int nb_buf) { - srs_error_t err = srs_success; - - SrsRtcSession* rtc_session = find_rtc_session_by_peer_id(peer_id); - if (rtc_session == NULL) { - return srs_error_wrap(err, "can't find rtc session in rtp/rtcp host=%s, port=%d", - host.c_str(), port); - } - - SrsRtpPacket rtp_packet; - SrsBuffer buffer(const_cast(buf), nb_buf); - rtp_packet.decode(&buffer); - - rtc_session->on_rtp_or_rtcp(&rtp_packet); - - return err; -} - -srs_error_t SrsRtcOverUdp::on_stun(const string& host, const int& port, const string& peer_id, const char* buf, int nb_buf) { - srs_error_t err = srs_success; - - SrsStunPacket stun_packet; - stun_packet.decode(buf, nb_buf); - - SrsRtcSession* rtc_session = find_rtc_session_by_user_info(host, stun_packet.username(), stun_packet.password()); - if (rtc_session == NULL) { - return err; - return srs_error_wrap(err, "can't find rtc session in stun host=%s, port=%d, username=%s, password=%s", - host.c_str(), port, stun_packet.username().c_str(), stun_packet.password().c_str()); - } - - // TODO: process when session mismatch - id_session_map[peer_id] = rtc_session; - - rtc_session->on_stun(&stun_packet); - - return err; -} - -srs_error_t SrsRtcOverUdp::on_dtls(const string& host, const int& port, const string& peer_id, const char* buf, int nb_buf) { - srs_error_t err = srs_success; - - SrsRtcSession* rtc_session = find_rtc_session_by_peer_id(peer_id); - if (rtc_session == NULL) { - return srs_error_wrap(err, "can't find rtc session in dtls host=%s, port=%d", - host.c_str(), port); - } - - rtc_session->on_dtls(); - - return err; -} - -SrsRtcSession::SrsRtcSession() -{ -} - -SrsRtcSession::~SrsRtcSession() -{ -} - -srs_error_t SrsRtcSession::on_rtp_or_rtcp(SrsRtpPacket* rtp_packet) -{ - srs_error_t err = srs_success; - - return err; -} - -srs_error_t SrsRtcSession::on_stun(SrsStunPacket* stun_packet) -{ - srs_error_t err = srs_success; - - return err; -} - -srs_error_t SrsRtcSession::on_dtls() -{ - srs_error_t err = srs_success; - - return err; -} - diff --git a/trunk/src/app/srs_app_rtc_udp.hpp b/trunk/src/app/srs_app_rtc_udp.hpp deleted file mode 100644 index 405805549..000000000 --- a/trunk/src/app/srs_app_rtc_udp.hpp +++ /dev/null @@ -1,96 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2013-2020 Winlin - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef SRS_APP_RTC_UDP_HPP -#define SRS_APP_RTC_UDP_HPP - -#include - -struct sockaddr; -#include -#include - -#include -#include -#include - -class SrsRtcSession; - -class SrsRtcUserInfo { -private: - std::string username; - std::string password; -public: - SrsRtcUserInfo(const std::string& u, const std::string& p); - ~SrsRtcUserInfo(); - - bool operator<(const SrsRtcUserInfo& rhs) const - { - return username < rhs.username && password < rhs.password; - } -}; - -// The rtc over udp stream receiver -class SrsRtcOverUdp : virtual public ISrsUdpHandler -{ -private: - std::map id_session_map; // ip:port => session - std::map > user_session_map; -public: - SrsRtcOverUdp(); - virtual ~SrsRtcOverUdp(); - - SrsRtcSession* create_rtc_session(const std::string& peer_ip, const std::string& remote_username, const std::string& remote_password); - SrsRtcSession* find_rtc_session_by_user_info(const std::string& peer_ip, const std::string& remote_username, const std::string& remote_password); - SrsRtcSession* find_rtc_session_by_peer_id(const std::string& peer_id); -// Interface ISrsUdpHandler -public: - virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf); -private: - virtual srs_error_t on_udp_bytes(const std::string& host, const int& port, const std::string& peer_id, char* buf, int nb_buf); - srs_error_t on_rtp_or_rtcp(const std::string& host, const int& port, const std::string& peer_id, const char* buf, int nb_buf); - srs_error_t on_stun(const std::string& host, const int& port, const std::string& peer_id, const char* buf, int nb_buf); - srs_error_t on_dtls(const std::string& host, const int& port, const std::string& peer_id, const char* buf, int nb_buf); -}; - -class SrsRtpPacket; -class SrsStunPacket; - -class SrsRtcSession -{ -private: - std::string local_username; - std::string local_password; - std::string remote_username; - std::string remote_password; -public: - SrsRtcSession(); - virtual ~SrsRtcSession(); - - srs_error_t on_rtp_or_rtcp(SrsRtpPacket* rtp_packet); - srs_error_t on_stun(SrsStunPacket* stun_packet); - srs_error_t on_dtls(); -}; - -#endif - diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index b833803f2..548ee3cdd 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -44,7 +44,8 @@ using namespace std; #include #include #include -#include +#include +#include #include #include #include @@ -109,8 +110,8 @@ std::string srs_listener_type2string(SrsListenerType type) return "RTSP"; case SrsListenerFlv: return "HTTP-FLV"; - case SrsListenerRtcOverUdp: - return "RTC over UDP"; + case SrsListenerRtc: + return "RTC"; default: return "UNKONWN"; } @@ -338,35 +339,29 @@ SrsUdpCasterListener::~SrsUdpCasterListener() srs_freep(caster); } -SrsRtcListener::SrsRtcListener(SrsServer* svr, SrsListenerType t) : SrsListener(svr, t) +SrsRtcListener::SrsRtcListener(SrsServer* svr, SrsRtcServer* rtc_svr, SrsListenerType t) : SrsListener(svr, t) { - srs_assert(type == SrsListenerRtcOverUdp); - rtc = new SrsRtcOverUdp(); + srs_assert(type == SrsListenerRtc); + rtc = new SrsRtc(rtc_svr); } SrsRtcListener::~SrsRtcListener() { } - -SrsRtcOverUdp* SrsRtcListener::get_rtc() -{ - return dynamic_cast(rtc); -} - srs_error_t SrsRtcListener::listen(std::string i, int p) { srs_error_t err = srs_success; // the caller already ensure the type is ok, // we just assert here for unknown stream caster. - srs_assert(type == SrsListenerRtcOverUdp); + srs_assert(type == SrsListenerRtc); ip = i; port = p; srs_freep(listener); - listener = new SrsUdpListener(rtc, ip, port); + listener = new SrsUdpRemuxListener(rtc, ip, port); if ((err = listener->listen()) != srs_success) { return srs_error_wrap(err, "listen %s:%d", ip.c_str(), port); @@ -533,6 +528,7 @@ SrsServer::SrsServer() // new these objects in initialize instead. http_api_mux = new SrsHttpServeMux(); http_server = new SrsHttpServer(this); + rtc_server = new SrsRtcServer(this); http_heartbeat = new SrsHttpHeartbeat(); ingester = new SrsIngester(); } @@ -1247,7 +1243,7 @@ srs_error_t SrsServer::listen_rtc() { srs_error_t err = srs_success; - close_listeners(SrsListenerRtcOverUdp); + close_listeners(SrsListenerRtc); if (!_srs_config->get_rtc_enabled()) { return err; @@ -1255,7 +1251,7 @@ srs_error_t SrsServer::listen_rtc() SrsListener* listener = NULL; - listener = new SrsRtcListener(this, SrsListenerRtcOverUdp); + listener = new SrsRtcListener(this, rtc_server, SrsListenerRtc); srs_assert(listener != NULL); listeners.push_back(listener); diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index a8ac87d78..36e4c8b3f 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -41,6 +41,7 @@ class SrsServer; class SrsConnection; class SrsHttpServeMux; class SrsHttpServer; +class SrsRtcServer; class SrsIngester; class SrsHttpHeartbeat; class SrsKbps; @@ -68,8 +69,8 @@ enum SrsListenerType SrsListenerRtsp = 4, // TCP stream, FLV stream over HTTP. SrsListenerFlv = 5, - // UDP sream, rtp over udp - SrsListenerRtcOverUdp = 6, + // UDP remux, rtp over udp + SrsListenerRtc = 6, }; // A common tcp listener, for RTMP/HTTP server. @@ -157,19 +158,15 @@ public: virtual ~SrsUdpCasterListener(); }; -class SrsRtcOverUdp; - -// A UDP listener, for udp stream caster server. +// A UDP listener, for udp remux rtc server class SrsRtcListener : public SrsListener { protected: SrsUdpListener* listener; ISrsUdpHandler* rtc; public: - SrsRtcListener(SrsServer* svr, SrsListenerType t); + SrsRtcListener(SrsServer* svr, SrsRtcServer* rtc_svr, SrsListenerType t); virtual ~SrsRtcListener(); - - SrsRtcOverUdp* get_rtc(); public: virtual srs_error_t listen(std::string i, int p); }; @@ -225,6 +222,7 @@ private: // TODO: FIXME: rename to http_api SrsHttpServeMux* http_api_mux; SrsHttpServer* http_server; + SrsRtcServer* rtc_server; SrsHttpHeartbeat* http_heartbeat; SrsIngester* ingester; SrsCoroutineManager* conn_manager; diff --git a/trunk/src/protocol/srs_stun_stack.cpp b/trunk/src/protocol/srs_stun_stack.cpp index 5273f5ee0..38c8c00a2 100644 --- a/trunk/src/protocol/srs_stun_stack.cpp +++ b/trunk/src/protocol/srs_stun_stack.cpp @@ -10,17 +10,17 @@ SrsStunPacket::~SrsStunPacket() { } -string SrsStunPacket::username() +string SrsStunPacket::ufrag() { return ""; } -string SrsStunPacket::password() +string SrsStunPacket::pwd() { return ""; } -srs_error_t SrsStunPacket::decode(const char* buf, const int& nb_buf) +srs_error_t SrsStunPacket::decode(const char* buf, const int nb_buf) { srs_error_t err = srs_success; diff --git a/trunk/src/protocol/srs_stun_stack.hpp b/trunk/src/protocol/srs_stun_stack.hpp index 7f1522c2a..61269050a 100644 --- a/trunk/src/protocol/srs_stun_stack.hpp +++ b/trunk/src/protocol/srs_stun_stack.hpp @@ -29,15 +29,16 @@ #include #include -class SrsStunPacket { +class SrsStunPacket +{ public: SrsStunPacket(); virtual ~SrsStunPacket(); - std::string username(); - std::string password(); + std::string ufrag(); + std::string pwd(); - srs_error_t decode(const char* buf, const int& nb_buf); + srs_error_t decode(const char* buf, const int nb_buf); }; #endif