mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 11:51:57 +00:00
refine bandwidth server-side, use bandwidth sample and kbps limit service
This commit is contained in:
parent
019b25ea30
commit
79e7e2d6cc
5 changed files with 109 additions and 18 deletions
|
@ -36,6 +36,17 @@ using namespace std;
|
||||||
#include <srs_core_autofree.hpp>
|
#include <srs_core_autofree.hpp>
|
||||||
#include <srs_kernel_utility.hpp>
|
#include <srs_kernel_utility.hpp>
|
||||||
#include <srs_app_utility.hpp>
|
#include <srs_app_utility.hpp>
|
||||||
|
#include <srs_app_kbps.hpp>
|
||||||
|
|
||||||
|
SrsBandwidthSample::SrsBandwidthSample()
|
||||||
|
{
|
||||||
|
duration_ms = 3000;
|
||||||
|
interval_ms = actual_duration_ms = bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsBandwidthSample::~SrsBandwidthSample()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
SrsBandwidth::SrsBandwidth()
|
SrsBandwidth::SrsBandwidth()
|
||||||
{
|
{
|
||||||
|
@ -47,7 +58,7 @@ SrsBandwidth::~SrsBandwidth()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, SrsRequest* req, string local_ip)
|
int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io_stat, SrsRequest* req, string local_ip)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -68,7 +79,7 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, SrsRequest* req, string l
|
||||||
}
|
}
|
||||||
|
|
||||||
// shared global last check time,
|
// shared global last check time,
|
||||||
// to avoid attach by bandwidth check,
|
// to prevent bandwidth check attack,
|
||||||
// if client request check in the window(specifeid by interval),
|
// if client request check in the window(specifeid by interval),
|
||||||
// directly reject the request.
|
// directly reject the request.
|
||||||
static int64_t last_check_time = 0;
|
static int64_t last_check_time = 0;
|
||||||
|
@ -94,24 +105,22 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, SrsRequest* req, string l
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return do_bandwidth_check();
|
// create a limit object.
|
||||||
|
SrsKbps kbps;
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsBandwidth::do_bandwidth_check()
|
int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
int play_duration_ms = 3000;
|
SrsBandwidthSample play_sample;
|
||||||
int play_interval_ms = 0;
|
SrsBandwidthSample publish_sample;
|
||||||
int play_actual_duration_ms = 0;
|
|
||||||
int play_bytes = 0;
|
|
||||||
|
|
||||||
int publish_duration_ms = 3000;
|
|
||||||
int publish_interval_ms = 0;
|
|
||||||
int publish_actual_duration_ms = 0;
|
|
||||||
int publish_bytes = 0;
|
|
||||||
|
|
||||||
int limit_kbps = _srs_config->get_bw_check_limit_kbps(_req->vhost);
|
|
||||||
|
|
||||||
int64_t start_time = srs_get_system_time_ms();
|
int64_t start_time = srs_get_system_time_ms();
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
class SrsRequest;
|
class SrsRequest;
|
||||||
class SrsRtmpServer;
|
class SrsRtmpServer;
|
||||||
|
class SrsKbpsLimit;
|
||||||
|
class ISrsProtocolStatistic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bandwidth check/test sample.
|
||||||
|
*/
|
||||||
|
class SrsBandwidthSample
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* the plan, how long to do the test, in ms,
|
||||||
|
* if exceed the duration, abort the test.
|
||||||
|
*/
|
||||||
|
int duration_ms;
|
||||||
|
/**
|
||||||
|
* the plan, interval for each check/test packet, in ms
|
||||||
|
*/
|
||||||
|
int interval_ms;
|
||||||
|
/**
|
||||||
|
* the actual test duration, in ms.
|
||||||
|
*/
|
||||||
|
int actual_duration_ms;
|
||||||
|
/**
|
||||||
|
* the actual test bytes
|
||||||
|
*/
|
||||||
|
int bytes;
|
||||||
|
public:
|
||||||
|
SrsBandwidthSample();
|
||||||
|
virtual ~SrsBandwidthSample();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bandwidth test agent which provides the interfaces for bandwidth check.
|
* bandwidth test agent which provides the interfaces for bandwidth check.
|
||||||
|
@ -84,15 +114,17 @@ public:
|
||||||
/**
|
/**
|
||||||
* do the bandwidth check.
|
* do the bandwidth check.
|
||||||
* @param rtmp, server RTMP protocol object, send/recv RTMP packet to/from client.
|
* @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 req, client request object, specifies the request info from client.
|
||||||
* @param local_ip, the ip of server which client connected at
|
* @param local_ip, the ip of server which client connected at
|
||||||
*/
|
*/
|
||||||
virtual int bandwidth_check(SrsRtmpServer* rtmp, SrsRequest* req, std::string local_ip);
|
virtual int bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io_stat, SrsRequest* req, std::string local_ip);
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* used to process band width check from client.
|
* used to process band width check from client.
|
||||||
|
* @param limit, the bandwidth limit object, to slowdown if exceed the kbps.
|
||||||
*/
|
*/
|
||||||
virtual int do_bandwidth_check();
|
virtual int do_bandwidth_check(SrsKbpsLimit* limit);
|
||||||
virtual int check_play(int duration_ms, int interval_ms, int& actual_duration_ms, int& play_bytes, int max_play_kbps);
|
virtual int check_play(int duration_ms, int interval_ms, int& actual_duration_ms, int& play_bytes, int max_play_kbps);
|
||||||
virtual int check_publish(int duration_ms, int interval_ms, int& actual_duration_ms, int& publish_bytes, int max_pub_kbps);
|
virtual int check_publish(int duration_ms, int interval_ms, int& actual_duration_ms, int& publish_bytes, int max_pub_kbps);
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,6 +28,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <srs_protocol_io.hpp>
|
#include <srs_protocol_io.hpp>
|
||||||
#include <srs_kernel_utility.hpp>
|
#include <srs_kernel_utility.hpp>
|
||||||
|
|
||||||
|
#define _SRS_BANDWIDTH_LIMIT_INTERVAL_MS 100
|
||||||
|
|
||||||
SrsKbpsSample::SrsKbpsSample()
|
SrsKbpsSample::SrsKbpsSample()
|
||||||
{
|
{
|
||||||
bytes = time = 0;
|
bytes = time = 0;
|
||||||
|
@ -244,3 +246,29 @@ void SrsKbps::sample()
|
||||||
os.sample();
|
os.sample();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsKbpsLimit::SrsKbpsLimit(SrsKbps* kbps, int limit_kbps)
|
||||||
|
{
|
||||||
|
_kbps = kbps;
|
||||||
|
_limit_kbps = limit_kbps;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsKbpsLimit::~SrsKbpsLimit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsKbpsLimit::recv_limit()
|
||||||
|
{
|
||||||
|
while (_kbps->get_recv_kbps() > _limit_kbps) {
|
||||||
|
_kbps->sample();
|
||||||
|
st_usleep(_SRS_BANDWIDTH_LIMIT_INTERVAL_MS * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsKbpsLimit::send_limit()
|
||||||
|
{
|
||||||
|
while (_kbps->get_send_kbps() > _limit_kbps) {
|
||||||
|
_kbps->sample();
|
||||||
|
st_usleep(_SRS_BANDWIDTH_LIMIT_INTERVAL_MS * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,4 +198,26 @@ public:
|
||||||
virtual void sample();
|
virtual void sample();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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:
|
||||||
|
/**
|
||||||
|
* limit the recv bandwidth.
|
||||||
|
*/
|
||||||
|
virtual void recv_limit();
|
||||||
|
/**
|
||||||
|
* limit the send bandwidth.
|
||||||
|
*/
|
||||||
|
virtual void send_limit();
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -216,7 +216,7 @@ int SrsRtmpConn::service_cycle()
|
||||||
|
|
||||||
// do bandwidth test if connect to the vhost which is for bandwidth check.
|
// do bandwidth test if connect to the vhost which is for bandwidth check.
|
||||||
if (_srs_config->get_bw_check_enabled(req->vhost)) {
|
if (_srs_config->get_bw_check_enabled(req->vhost)) {
|
||||||
return bandwidth->bandwidth_check(rtmp, req, local_ip);
|
return bandwidth->bandwidth_check(rtmp, io, req, local_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = rtmp->response_connect_app(req, local_ip.c_str())) != ERROR_SUCCESS) {
|
if ((ret = rtmp->response_connect_app(req, local_ip.c_str())) != ERROR_SUCCESS) {
|
||||||
|
|
Loading…
Reference in a new issue