mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Remove bandwidth check because falsh is disabled. v5.0.52
This commit is contained in:
parent
1630918b0f
commit
937605b18c
16 changed files with 5 additions and 1490 deletions
|
|
@ -1,451 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2013-2022 The SRS Authors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT or MulanPSL-2.0
|
||||
//
|
||||
|
||||
#include <srs_app_bandwidth.hpp>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <srs_protocol_rtmp_stack.hpp>
|
||||
#include <srs_protocol_amf0.hpp>
|
||||
#include <srs_app_config.hpp>
|
||||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_app_utility.hpp>
|
||||
#include <srs_protocol_kbps.hpp>
|
||||
#include <srs_app_st.hpp>
|
||||
|
||||
#define _SRS_BANDWIDTH_LIMIT_INTERVAL 100 * SRS_UTIME_MILLISECONDS
|
||||
|
||||
// default sample duration, in ms
|
||||
#define _SRS_BANDWIDTH_SAMPLE_DURATION 3000 * SRS_UTIME_MILLISECONDS
|
||||
|
||||
// wait for a while for flash to got all packets.
|
||||
#define _SRS_BANDWIDTH_FINAL_WAIT 600 * SRS_UTIME_MILLISECONDS
|
||||
|
||||
SrsBandwidthSample::SrsBandwidthSample()
|
||||
{
|
||||
duration = _SRS_BANDWIDTH_SAMPLE_DURATION;
|
||||
kbps = interval = actual_duration = bytes = 0;
|
||||
}
|
||||
|
||||
SrsBandwidthSample::~SrsBandwidthSample()
|
||||
{
|
||||
}
|
||||
|
||||
void SrsBandwidthSample::calc_kbps(int _bytes, srs_utime_t _duration)
|
||||
{
|
||||
bytes = _bytes;
|
||||
actual_duration = _duration;
|
||||
|
||||
if (actual_duration <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
kbps = bytes * 8 / srsu2ms(actual_duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* recv bandwidth helper.
|
||||
*/
|
||||
typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt);
|
||||
bool _bandwidth_is_final(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_final();
|
||||
}
|
||||
bool _bandwidth_is_starting_play(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_starting_play();
|
||||
}
|
||||
bool _bandwidth_is_stopped_play(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_stopped_play();
|
||||
}
|
||||
bool _bandwidth_is_starting_publish(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_starting_publish();
|
||||
}
|
||||
bool _bandwidth_is_stopped_publish(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_stopped_publish();
|
||||
}
|
||||
srs_error_t srs_expect_bandwidth_packet(SrsRtmpServer* rtmp, _CheckPacketType pfn)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
while (true) {
|
||||
SrsCommonMessage* msg = NULL;
|
||||
SrsBandwidthPacket* pkt = NULL;
|
||||
if ((err = rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != srs_success) {
|
||||
return srs_error_wrap(err, "expect message");
|
||||
}
|
||||
SrsAutoFree(SrsCommonMessage, msg);
|
||||
SrsAutoFree(SrsBandwidthPacket, pkt);
|
||||
|
||||
if (pfn(pkt)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsBandwidth::SrsBandwidth()
|
||||
{
|
||||
_req = NULL;
|
||||
_rtmp = NULL;
|
||||
}
|
||||
|
||||
SrsBandwidth::~SrsBandwidth()
|
||||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io_stat, SrsRequest* req, string local_ip)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
_rtmp = rtmp;
|
||||
_req = req;
|
||||
|
||||
if (!_srs_config->get_bw_check_enabled(_req->vhost)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// validate the bandwidth check key
|
||||
std::string key = "key=" + _srs_config->get_bw_check_key(_req->vhost);
|
||||
if (_req->tcUrl.find(key) == std::string::npos) {
|
||||
return srs_error_new(ERROR_SYSTEM_BANDWIDTH_KEY, "check the vhost=%s %s failed, tcUrl=%s",
|
||||
_req->vhost.c_str(), key.c_str(), _req->tcUrl.c_str());
|
||||
}
|
||||
|
||||
// shared global last check time,
|
||||
// to prevent bandwidth check attack,
|
||||
// if client request check in the window(specifeid by interval),
|
||||
// directly reject the request.
|
||||
static srs_utime_t last_check_time = 0;
|
||||
srs_utime_t interval = _srs_config->get_bw_check_interval(_req->vhost);
|
||||
|
||||
srs_utime_t time_now = srs_update_system_time();
|
||||
// reject the connection in the interval window.
|
||||
if (last_check_time > 0 && time_now - last_check_time < interval) {
|
||||
_rtmp->response_connect_reject(_req, "bandcheck rejected");
|
||||
return srs_error_new(ERROR_SYSTEM_BANDWIDTH_DENIED, "reject, last_check=%" PRId64 ", now=%" PRId64 ", interval=%" PRId64 "", last_check_time, time_now, interval);
|
||||
}
|
||||
|
||||
// accept and do bandwidth check.
|
||||
last_check_time = time_now;
|
||||
|
||||
if ((err = _rtmp->response_connect_app(_req, local_ip.c_str())) != srs_success) {
|
||||
return srs_error_wrap(err, "response connect app");
|
||||
}
|
||||
|
||||
// create a limit object.
|
||||
SrsWallClock clk;
|
||||
SrsKbps kbps(&clk);
|
||||
kbps.set_io(io_stat, io_stat);
|
||||
|
||||
int limit_kbps = _srs_config->get_bw_check_limit_kbps(_req->vhost);
|
||||
SrsKbpsLimit limit(&kbps, limit_kbps);
|
||||
|
||||
return do_bandwidth_check(&limit);
|
||||
}
|
||||
|
||||
srs_error_t SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsBandwidthSample play_sample;
|
||||
SrsBandwidthSample publish_sample;
|
||||
|
||||
// timeout for a packet.
|
||||
_rtmp->set_send_timeout(play_sample.duration * 2);
|
||||
_rtmp->set_recv_timeout(publish_sample.duration * 2);
|
||||
|
||||
// start test.
|
||||
srs_utime_t start_time = srs_update_system_time();
|
||||
|
||||
// sample play
|
||||
if ((err = play_start(&play_sample, limit)) != srs_success) {
|
||||
return srs_error_wrap(err, "play start");
|
||||
}
|
||||
if ((err = play_checking(&play_sample, limit)) != srs_success) {
|
||||
return srs_error_wrap(err, "play check");
|
||||
}
|
||||
if ((err = play_stop(&play_sample, limit)) != srs_success) {
|
||||
return srs_error_wrap(err, "play stop");
|
||||
}
|
||||
|
||||
// sample publish
|
||||
if ((err = publish_start(&publish_sample, limit)) != srs_success) {
|
||||
return srs_error_wrap(err, "publish start");
|
||||
}
|
||||
if ((err = publish_checking(&publish_sample, limit)) != srs_success) {
|
||||
return srs_error_wrap(err, "publish check");
|
||||
}
|
||||
if ((err = publish_stop(&publish_sample, limit)) != srs_success) {
|
||||
return srs_error_wrap(err, "publish stop");
|
||||
}
|
||||
|
||||
// stop test.
|
||||
srs_utime_t end_time = srs_update_system_time();
|
||||
|
||||
if ((err = do_final(play_sample, publish_sample, start_time, end_time)) != srs_success) {
|
||||
return srs_error_wrap(err, "final");
|
||||
}
|
||||
|
||||
srs_trace("bandwidth ok. duartion=%dms(%d+%d), play=%dkbps, publish=%dkbps",
|
||||
srsu2msi(end_time - start_time), srsu2msi(play_sample.actual_duration), srsu2msi(publish_sample.actual_duration),
|
||||
play_sample.kbps, publish_sample.kbps);
|
||||
|
||||
srs_usleep(_SRS_BANDWIDTH_FINAL_WAIT);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsBandwidth::play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (true) {
|
||||
// send start play command to client
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_start_play();
|
||||
|
||||
pkt->data->set("limit_kbps", SrsAmf0Any::number(limit->limit_kbps()));
|
||||
pkt->data->set("duration_ms", SrsAmf0Any::number(srsu2msi(sample->duration)));
|
||||
pkt->data->set("interval_ms", SrsAmf0Any::number(srsu2msi(sample->interval)));
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
return srs_error_wrap(err, "send packet");
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_starting_play)) != srs_success) {
|
||||
return srs_error_wrap(err, "expect bandwidth");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// send play data to client
|
||||
int size = 1024; // TODO: FIXME: magic number
|
||||
char random_data[size];
|
||||
memset(random_data, 'A', size);
|
||||
|
||||
int data_count = 1;
|
||||
srs_utime_t starttime = srs_update_system_time();
|
||||
while (srs_get_system_time() - starttime < sample->duration) {
|
||||
srs_usleep(sample->interval);
|
||||
|
||||
// TODO: FIXME: use shared ptr message.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_playing();
|
||||
|
||||
// TODO: FIXME: magic number
|
||||
for (int i = 0; i < data_count; ++i) {
|
||||
std::stringstream seq;
|
||||
seq << i;
|
||||
std::string play_data = "SRS band check data from server's playing......";
|
||||
pkt->data->set(seq.str(), SrsAmf0Any::str(play_data.c_str()));
|
||||
}
|
||||
data_count += 2;
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
return srs_error_wrap(err, "send packet");
|
||||
}
|
||||
|
||||
limit->send_limit();
|
||||
}
|
||||
srs_update_system_time();
|
||||
sample->calc_kbps((int)_rtmp->get_send_bytes(), srs_get_system_time() - starttime);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsBandwidth::play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit*/)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (true) {
|
||||
// notify client to stop play
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_play();
|
||||
|
||||
pkt->data->set("duration_ms", SrsAmf0Any::number(srsu2msi(sample->duration)));
|
||||
pkt->data->set("interval_ms", SrsAmf0Any::number(srsu2msi(sample->interval)));
|
||||
pkt->data->set("duration_delta", SrsAmf0Any::number(srsu2msi(sample->actual_duration)));
|
||||
pkt->data->set("bytes_delta", SrsAmf0Any::number(sample->bytes));
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
return srs_error_wrap(err, "send packet");
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stopped_play)) != srs_success) {
|
||||
return srs_error_wrap(err, "expect bandwidth");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsBandwidth::publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (true) {
|
||||
// notify client to start publish
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_start_publish();
|
||||
|
||||
pkt->data->set("limit_kbps", SrsAmf0Any::number(limit->limit_kbps()));
|
||||
pkt->data->set("duration_ms", SrsAmf0Any::number(srsu2msi(sample->duration)));
|
||||
pkt->data->set("interval_ms", SrsAmf0Any::number(srsu2msi(sample->interval)));
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
return srs_error_wrap(err, "send packet");
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_starting_publish)) != srs_success) {
|
||||
return srs_error_wrap(err, "expect packet");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsBandwidth::publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// recv publish msgs until @duration ms
|
||||
srs_utime_t starttime = srs_update_system_time();
|
||||
while (srs_get_system_time() - starttime < sample->duration) {
|
||||
SrsCommonMessage* msg = NULL;
|
||||
SrsBandwidthPacket* pkt = NULL;
|
||||
if ((err = _rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != srs_success) {
|
||||
return srs_error_wrap(err, "expect message");
|
||||
}
|
||||
SrsAutoFree(SrsCommonMessage, msg);
|
||||
SrsAutoFree(SrsBandwidthPacket, pkt);
|
||||
srs_info("get publish message success.");
|
||||
|
||||
// client requires to stop.
|
||||
if (pkt->is_stop_publish()) {
|
||||
break;
|
||||
}
|
||||
|
||||
limit->recv_limit();
|
||||
}
|
||||
srs_update_system_time();
|
||||
sample->calc_kbps((int)_rtmp->get_recv_bytes(), srs_get_system_time() - starttime);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsBandwidth::publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit*/)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (true) {
|
||||
// notify client to stop publish
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_publish();
|
||||
pkt->data->set("duration_ms", SrsAmf0Any::number(srsu2msi(sample->duration)));
|
||||
pkt->data->set("interval_ms", SrsAmf0Any::number(srsu2msi(sample->interval)));
|
||||
pkt->data->set("duration_delta", SrsAmf0Any::number(srsu2msi(sample->actual_duration)));
|
||||
pkt->data->set("bytes_delta", SrsAmf0Any::number(sample->bytes));
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
return srs_error_wrap(err, "send packet");
|
||||
}
|
||||
}
|
||||
|
||||
// expect client to stop publish
|
||||
// if flash client, we never expect the client stop publish bytes,
|
||||
// for the flash send call packet to test publish bandwidth,
|
||||
// there are many many packets in the queue.
|
||||
// we just ignore the packet and send the bandwidth test data.
|
||||
bool is_flash = (_req->swfUrl != "");
|
||||
if (!is_flash) {
|
||||
if ((err = srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stopped_publish)) != srs_success) {
|
||||
return srs_error_wrap(err, "expect bandwidth");
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsBandwidth::do_final(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, srs_utime_t start_time, srs_utime_t& end_time)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// send finished msg,
|
||||
// flash client will close connection when got this packet,
|
||||
// for the publish queue may contains packets.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_finish();
|
||||
pkt->data->set("start_time", SrsAmf0Any::number(srsu2ms(start_time)));
|
||||
pkt->data->set("end_time", SrsAmf0Any::number(srsu2ms(end_time)));
|
||||
pkt->data->set("play_kbps", SrsAmf0Any::number(play_sample.kbps));
|
||||
pkt->data->set("publish_kbps", SrsAmf0Any::number(publish_sample.kbps));
|
||||
pkt->data->set("play_bytes", SrsAmf0Any::number(play_sample.bytes));
|
||||
pkt->data->set("publish_bytes", SrsAmf0Any::number(publish_sample.bytes));
|
||||
pkt->data->set("play_time", SrsAmf0Any::number(srsu2msi(play_sample.actual_duration)));
|
||||
pkt->data->set("publish_time", SrsAmf0Any::number(srsu2msi(publish_sample.actual_duration)));
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
return srs_error_wrap(err, "send packet");
|
||||
}
|
||||
|
||||
// we notice the result, and expect a final packet if not flash.
|
||||
// if flash client, client will disconnect when got finish packet.
|
||||
bool is_flash = (_req->swfUrl != "");
|
||||
if (!is_flash) {
|
||||
// ignore any error.
|
||||
err = srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_final);
|
||||
srs_error_reset(err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsKbpsLimit::SrsKbpsLimit(SrsKbps* kbps, int limit_kbps)
|
||||
{
|
||||
_kbps = kbps;
|
||||
_limit_kbps = limit_kbps;
|
||||
}
|
||||
|
||||
SrsKbpsLimit::~SrsKbpsLimit()
|
||||
{
|
||||
}
|
||||
|
||||
int SrsKbpsLimit::limit_kbps()
|
||||
{
|
||||
return _limit_kbps;
|
||||
}
|
||||
|
||||
void SrsKbpsLimit::recv_limit()
|
||||
{
|
||||
_kbps->sample();
|
||||
|
||||
while (_kbps->get_recv_kbps() > _limit_kbps) {
|
||||
_kbps->sample();
|
||||
|
||||
srs_usleep(_SRS_BANDWIDTH_LIMIT_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
void SrsKbpsLimit::send_limit()
|
||||
{
|
||||
_kbps->sample();
|
||||
|
||||
while (_kbps->get_send_kbps() > _limit_kbps) {
|
||||
_kbps->sample();
|
||||
|
||||
srs_usleep(_SRS_BANDWIDTH_LIMIT_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2013-2022 The SRS Authors
|
||||
//
|
||||
// SPDX-License-Identifier: MIT or MulanPSL-2.0
|
||||
//
|
||||
|
||||
#ifndef SRS_APP_BANDWIDTH_HPP
|
||||
#define SRS_APP_BANDWIDTH_HPP
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <srs_app_st.hpp>
|
||||
|
||||
class SrsKbps;
|
||||
class SrsRequest;
|
||||
class SrsRtmpServer;
|
||||
class SrsKbpsLimit;
|
||||
class ISrsProtocolStatistic;
|
||||
|
||||
// The bandwidth check/test sample.
|
||||
class SrsBandwidthSample
|
||||
{
|
||||
public:
|
||||
// The plan, how long to do the test,
|
||||
// if exceed the duration, abort the test.
|
||||
srs_utime_t duration;
|
||||
// The plan, interval for each check/test packet
|
||||
srs_utime_t interval;
|
||||
public:
|
||||
// The actual test duration.
|
||||
srs_utime_t actual_duration;
|
||||
// The actual test bytes
|
||||
int bytes;
|
||||
// The actual test kbps
|
||||
int kbps;
|
||||
public:
|
||||
SrsBandwidthSample();
|
||||
virtual ~SrsBandwidthSample();
|
||||
public:
|
||||
// Update the bytes and actual duration, then calc the kbps.
|
||||
// @param _bytes update the sample bytes.
|
||||
// @param _duration update the actual duration.
|
||||
virtual void calc_kbps(int _bytes, srs_utime_t _duration);
|
||||
};
|
||||
|
||||
// The bandwidth test agent which provides the interfaces for bandwidth check.
|
||||
// 1. if vhost disabled bandwidth check, ignore.
|
||||
// 2. otherwise, check the key, error if verify failed.
|
||||
// 3. check the interval limit, error if bandwidth in the interval window.
|
||||
// 4. check the bandwidth under the max kbps.
|
||||
// 5. send the bandwidth data to client.
|
||||
// bandwidth workflow:
|
||||
// +------------+ +----------+
|
||||
// | Client | | Server |
|
||||
// +-----+------+ +-----+----+
|
||||
// | |
|
||||
// | connect vhost------> | if vhost enable bandwidth,
|
||||
// | <-----result(success) | do bandwidth check.
|
||||
// | |
|
||||
// | <----call(start play) | onSrsBandCheckStartPlayBytes
|
||||
// | result(playing)-----> | onSrsBandCheckStartingPlayBytes
|
||||
// | <-------data(playing) | onSrsBandCheckStartingPlayBytes
|
||||
// | <-----call(stop play) | onSrsBandCheckStopPlayBytes
|
||||
// | result(stopped)-----> | onSrsBandCheckStoppedPlayBytes
|
||||
// | |
|
||||
// | <-call(start publish) | onSrsBandCheckStartPublishBytes
|
||||
// | result(publishing)--> | onSrsBandCheckStartingPublishBytes
|
||||
// | data(publishing)(3)-> | onSrsBandCheckStartingPublishBytes
|
||||
// | <--call(stop publish) | onSrsBandCheckStopPublishBytes
|
||||
// | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes
|
||||
// | |
|
||||
// | <--------------report |
|
||||
// | final(2)------------> | finalClientPacket
|
||||
// | <END> |
|
||||
//
|
||||
// 1. when flash client, server never wait the stop publish response,
|
||||
// for the flash client queue is fullfill with other packets.
|
||||
// 2. when flash client, server never wait the final packet,
|
||||
// for the flash client directly close when got report packet.
|
||||
// 3. for linux client, it will send the publish data then send a stop publish,
|
||||
// for the linux client donot know when to stop the publish.
|
||||
// when server got publishing and stop publish, stop publish.
|
||||
class SrsBandwidth
|
||||
{
|
||||
private:
|
||||
SrsRequest* _req;
|
||||
SrsRtmpServer* _rtmp;
|
||||
public:
|
||||
SrsBandwidth();
|
||||
virtual ~SrsBandwidth();
|
||||
public:
|
||||
// Do the bandwidth check.
|
||||
// @param rtmp, server RTMP protocol object, send/recv RTMP packet to/from client.
|
||||
// @param io_stat, the underlayer io statistic, provides send/recv bytes count.
|
||||
// @param req, client request object, specifies the request info from client.
|
||||
// @param local_ip, the ip of server which client connected at
|
||||
virtual srs_error_t bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io_stat, SrsRequest* req, std::string local_ip);
|
||||
private:
|
||||
// Used to process band width check from client.
|
||||
// @param limit, the bandwidth limit object, to slowdown if exceed the kbps.
|
||||
virtual srs_error_t do_bandwidth_check(SrsKbpsLimit* limit);
|
||||
// play check/test, downloading bandwidth kbps.
|
||||
private:
|
||||
// Start play/download bandwidth check/test,
|
||||
// send start-play command to client, client must response starting-play
|
||||
// to start the test.
|
||||
virtual srs_error_t play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
// Do play/download bandwidth check/test,
|
||||
// server send call messages to client in specified time,
|
||||
// calc the time and bytes sent, then we got the kbps.
|
||||
virtual srs_error_t play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
// stop play/download bandwidth check/test,
|
||||
// send stop-play command to client, client must response stopped-play
|
||||
// to stop the test.
|
||||
virtual srs_error_t play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
// publish check/test, publishing bandwidth kbps.
|
||||
private:
|
||||
// Start publish/upload bandwidth check/test,
|
||||
// send start-publish command to client, client must response starting-publish
|
||||
// to start the test.
|
||||
virtual srs_error_t publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
// Do publish/upload bandwidth check/test,
|
||||
// client send call messages to client in specified time,
|
||||
// server calc the time and bytes received, then we got the kbps.
|
||||
// @remark, for linux client, it will send a stop publish client, server will stop publishing.
|
||||
// then enter the publish-stop stage with client.
|
||||
// @remark, for flash client, it will send many many call messages, that is,
|
||||
// the send queue is fullfill with call messages, so we should never expect the
|
||||
// response message in the publish-stop stage.
|
||||
virtual srs_error_t publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
// Stop publish/upload bandwidth check/test,
|
||||
// send stop-publish command to client,
|
||||
// for linux client, always expect a stopped-publish response from client,
|
||||
// for flash client, the sent queue is fullfill with publishing call messages,
|
||||
// so server never expect the stopped-publish from it.
|
||||
virtual srs_error_t publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
private:
|
||||
// Report and final packet
|
||||
// report a finish packet, with the bytes/time/kbps bandwidth check/test result,
|
||||
// for linux client, server always expect a final packet from client,
|
||||
// for flash client, the sent queue is fullfill with publishing call messages,
|
||||
// so server never expect the final packet from it.
|
||||
virtual srs_error_t do_final(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, srs_utime_t start_time, srs_utime_t& end_time);
|
||||
};
|
||||
|
||||
// The kbps limit, if exceed the kbps, slow down.
|
||||
class SrsKbpsLimit
|
||||
{
|
||||
private:
|
||||
int _limit_kbps;
|
||||
SrsKbps* _kbps;
|
||||
public:
|
||||
SrsKbpsLimit(SrsKbps* kbps, int limit_kbps);
|
||||
virtual ~SrsKbpsLimit();
|
||||
public:
|
||||
// Get the system limit kbps.
|
||||
virtual int limit_kbps();
|
||||
// Limit the recv bandwidth.
|
||||
virtual void recv_limit();
|
||||
// Limit the send bandwidth.
|
||||
virtual void send_limit();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1505,7 +1505,7 @@ srs_error_t SrsConfig::reload_conf(SrsConfig* conf)
|
|||
//
|
||||
// always support reload without additional code:
|
||||
// chunk_size, ff_log_dir,
|
||||
// bandcheck, http_hooks, heartbeat,
|
||||
// http_hooks, heartbeat,
|
||||
// security
|
||||
|
||||
// merge config: listen
|
||||
|
|
@ -2593,13 +2593,6 @@ srs_error_t SrsConfig::check_normal_config()
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (n == "bandcheck") {
|
||||
for (int j = 0; j < (int)conf->directives.size(); j++) {
|
||||
string m = conf->at(j)->name;
|
||||
if (m != "enabled" && m != "key" && m != "interval" && m != "limit_kbps") {
|
||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal vhost.bandcheck.%s of %s", m.c_str(), vhost->arg0().c_str());
|
||||
}
|
||||
}
|
||||
} else if (n == "rtc") {
|
||||
for (int j = 0; j < (int)conf->directives.size(); j++) {
|
||||
string m = conf->at(j)->name;
|
||||
|
|
@ -4843,94 +4836,6 @@ SrsConfDirective* SrsConfig::get_vhost_on_hls_notify(string vhost)
|
|||
return conf->get("on_hls_notify");
|
||||
}
|
||||
|
||||
bool SrsConfig::get_bw_check_enabled(string vhost)
|
||||
{
|
||||
static bool DEFAULT = false;
|
||||
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("bandcheck");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("enabled");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
string SrsConfig::get_bw_check_key(string vhost)
|
||||
{
|
||||
static string DEFAULT = "";
|
||||
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("bandcheck");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("key");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return conf->arg0();
|
||||
}
|
||||
|
||||
srs_utime_t SrsConfig::get_bw_check_interval(string vhost)
|
||||
{
|
||||
static int64_t DEFAULT = 30 * SRS_UTIME_SECONDS;
|
||||
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("bandcheck");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("interval");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return (srs_utime_t)(::atof(conf->arg0().c_str()) * SRS_UTIME_SECONDS);
|
||||
}
|
||||
|
||||
int SrsConfig::get_bw_check_limit_kbps(string vhost)
|
||||
{
|
||||
static int DEFAULT = 1000;
|
||||
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("bandcheck");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("limit_kbps");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return ::atoi(conf->arg0().c_str());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_vhost_is_edge(string vhost)
|
||||
{
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
|
|
|
|||
|
|
@ -710,23 +710,6 @@ public:
|
|||
// Get the on_hls_notify callbacks of vhost.
|
||||
// @return the on_hls_notify callback directive, the args is the url to callback.
|
||||
virtual SrsConfDirective* get_vhost_on_hls_notify(std::string vhost);
|
||||
// bwct(bandwidth check tool) section
|
||||
public:
|
||||
// Whether bw check enabled for vhost.
|
||||
// If enabled, serve all clients with bandwidth check services.
|
||||
// oterwise, serve all cleints with stream.
|
||||
virtual bool get_bw_check_enabled(std::string vhost);
|
||||
// The key of server, if client key mot match, reject.
|
||||
virtual std::string get_bw_check_key(std::string vhost);
|
||||
// The check interval, in srs_utime_t.
|
||||
// If the client request check in very short time(in the interval),
|
||||
// SRS will reject client.
|
||||
// @remark this is used to prevent the bandwidth check attack.
|
||||
virtual srs_utime_t get_bw_check_interval(std::string vhost);
|
||||
// The max kbps that user can test,
|
||||
// If exceed the kbps, server will slowdown the send-recv.
|
||||
// @remark this is used to protect the service bandwidth.
|
||||
virtual int get_bw_check_limit_kbps(std::string vhost);
|
||||
// vhost cluster section
|
||||
public:
|
||||
// Whether vhost is edge mode.
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ using namespace std;
|
|||
#include <srs_app_config.hpp>
|
||||
#include <srs_app_refer.hpp>
|
||||
#include <srs_app_hls.hpp>
|
||||
#include <srs_app_bandwidth.hpp>
|
||||
#include <srs_app_st.hpp>
|
||||
#include <srs_app_http_hooks.hpp>
|
||||
#include <srs_app_edge.hpp>
|
||||
|
|
@ -107,7 +106,6 @@ SrsRtmpConn::SrsRtmpConn(SrsServer* svr, srs_netfd_t c, string cip, int cport)
|
|||
|
||||
rtmp = new SrsRtmpServer(skt);
|
||||
refer = new SrsRefer();
|
||||
bandwidth = new SrsBandwidth();
|
||||
security = new SrsSecurity();
|
||||
duration = 0;
|
||||
wakable = NULL;
|
||||
|
|
@ -142,7 +140,6 @@ SrsRtmpConn::~SrsRtmpConn()
|
|||
srs_freep(info);
|
||||
srs_freep(rtmp);
|
||||
srs_freep(refer);
|
||||
srs_freep(bandwidth);
|
||||
srs_freep(security);
|
||||
}
|
||||
|
||||
|
|
@ -368,14 +365,6 @@ srs_error_t SrsRtmpConn::service_cycle()
|
|||
// get the ip which client connected.
|
||||
std::string local_ip = srs_get_local_ip(srs_netfd_fileno(stfd));
|
||||
|
||||
// do bandwidth test if connect to the vhost which is for bandwidth check.
|
||||
if (_srs_config->get_bw_check_enabled(req->vhost)) {
|
||||
if ((err = bandwidth->bandwidth_check(rtmp, skt, req, local_ip)) != srs_success) {
|
||||
return srs_error_wrap(err, "rtmp: bandwidth check");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// set chunk size to larger.
|
||||
// set the chunk size before any larger response greater than 128,
|
||||
// to make OBS happy, @see https://github.com/ossrs/srs/issues/454
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue