refine bandwidth server-side, use bandwidth sample and kbps limit service
正在显示
5 个修改的文件
包含
109 行增加
和
18 行删除
| @@ -36,6 +36,17 @@ using namespace std; | @@ -36,6 +36,17 @@ using namespace std; | ||
| 36 | #include <srs_core_autofree.hpp> | 36 | #include <srs_core_autofree.hpp> |
| 37 | #include <srs_kernel_utility.hpp> | 37 | #include <srs_kernel_utility.hpp> |
| 38 | #include <srs_app_utility.hpp> | 38 | #include <srs_app_utility.hpp> |
| 39 | +#include <srs_app_kbps.hpp> | ||
| 40 | + | ||
| 41 | +SrsBandwidthSample::SrsBandwidthSample() | ||
| 42 | +{ | ||
| 43 | + duration_ms = 3000; | ||
| 44 | + interval_ms = actual_duration_ms = bytes = 0; | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +SrsBandwidthSample::~SrsBandwidthSample() | ||
| 48 | +{ | ||
| 49 | +} | ||
| 39 | 50 | ||
| 40 | SrsBandwidth::SrsBandwidth() | 51 | SrsBandwidth::SrsBandwidth() |
| 41 | { | 52 | { |
| @@ -47,7 +58,7 @@ SrsBandwidth::~SrsBandwidth() | @@ -47,7 +58,7 @@ SrsBandwidth::~SrsBandwidth() | ||
| 47 | { | 58 | { |
| 48 | } | 59 | } |
| 49 | 60 | ||
| 50 | -int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, SrsRequest* req, string local_ip) | 61 | +int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io_stat, SrsRequest* req, string local_ip) |
| 51 | { | 62 | { |
| 52 | int ret = ERROR_SUCCESS; | 63 | int ret = ERROR_SUCCESS; |
| 53 | 64 | ||
| @@ -68,7 +79,7 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, SrsRequest* req, string l | @@ -68,7 +79,7 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, SrsRequest* req, string l | ||
| 68 | } | 79 | } |
| 69 | 80 | ||
| 70 | // shared global last check time, | 81 | // shared global last check time, |
| 71 | - // to avoid attach by bandwidth check, | 82 | + // to prevent bandwidth check attack, |
| 72 | // if client request check in the window(specifeid by interval), | 83 | // if client request check in the window(specifeid by interval), |
| 73 | // directly reject the request. | 84 | // directly reject the request. |
| 74 | static int64_t last_check_time = 0; | 85 | static int64_t last_check_time = 0; |
| @@ -93,25 +104,23 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, SrsRequest* req, string l | @@ -93,25 +104,23 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, SrsRequest* req, string l | ||
| 93 | srs_error("response connect app failed. ret=%d", ret); | 104 | srs_error("response connect app failed. ret=%d", ret); |
| 94 | return ret; | 105 | return ret; |
| 95 | } | 106 | } |
| 107 | + | ||
| 108 | + // create a limit object. | ||
| 109 | + SrsKbps kbps; | ||
| 110 | + kbps.set_io(io_stat, io_stat); | ||
| 96 | 111 | ||
| 97 | - return do_bandwidth_check(); | 112 | + int limit_kbps = _srs_config->get_bw_check_limit_kbps(_req->vhost); |
| 113 | + SrsKbpsLimit limit(&kbps, limit_kbps); | ||
| 114 | + | ||
| 115 | + return do_bandwidth_check(&limit); | ||
| 98 | } | 116 | } |
| 99 | 117 | ||
| 100 | -int SrsBandwidth::do_bandwidth_check() | 118 | +int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit) |
| 101 | { | 119 | { |
| 102 | int ret = ERROR_SUCCESS; | 120 | int ret = ERROR_SUCCESS; |
| 103 | 121 | ||
| 104 | - int play_duration_ms = 3000; | ||
| 105 | - int play_interval_ms = 0; | ||
| 106 | - int play_actual_duration_ms = 0; | ||
| 107 | - int play_bytes = 0; | ||
| 108 | - | ||
| 109 | - int publish_duration_ms = 3000; | ||
| 110 | - int publish_interval_ms = 0; | ||
| 111 | - int publish_actual_duration_ms = 0; | ||
| 112 | - int publish_bytes = 0; | ||
| 113 | - | ||
| 114 | - int limit_kbps = _srs_config->get_bw_check_limit_kbps(_req->vhost); | 122 | + SrsBandwidthSample play_sample; |
| 123 | + SrsBandwidthSample publish_sample; | ||
| 115 | 124 | ||
| 116 | int64_t start_time = srs_get_system_time_ms(); | 125 | int64_t start_time = srs_get_system_time_ms(); |
| 117 | 126 |
| @@ -35,6 +35,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -35,6 +35,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 35 | 35 | ||
| 36 | class SrsRequest; | 36 | class SrsRequest; |
| 37 | class SrsRtmpServer; | 37 | class SrsRtmpServer; |
| 38 | +class SrsKbpsLimit; | ||
| 39 | +class ISrsProtocolStatistic; | ||
| 40 | + | ||
| 41 | +/** | ||
| 42 | +* bandwidth check/test sample. | ||
| 43 | +*/ | ||
| 44 | +class SrsBandwidthSample | ||
| 45 | +{ | ||
| 46 | +public: | ||
| 47 | + /** | ||
| 48 | + * the plan, how long to do the test, in ms, | ||
| 49 | + * if exceed the duration, abort the test. | ||
| 50 | + */ | ||
| 51 | + int duration_ms; | ||
| 52 | + /** | ||
| 53 | + * the plan, interval for each check/test packet, in ms | ||
| 54 | + */ | ||
| 55 | + int interval_ms; | ||
| 56 | + /** | ||
| 57 | + * the actual test duration, in ms. | ||
| 58 | + */ | ||
| 59 | + int actual_duration_ms; | ||
| 60 | + /** | ||
| 61 | + * the actual test bytes | ||
| 62 | + */ | ||
| 63 | + int bytes; | ||
| 64 | +public: | ||
| 65 | + SrsBandwidthSample(); | ||
| 66 | + virtual ~SrsBandwidthSample(); | ||
| 67 | +}; | ||
| 38 | 68 | ||
| 39 | /** | 69 | /** |
| 40 | * bandwidth test agent which provides the interfaces for bandwidth check. | 70 | * bandwidth test agent which provides the interfaces for bandwidth check. |
| @@ -84,15 +114,17 @@ public: | @@ -84,15 +114,17 @@ public: | ||
| 84 | /** | 114 | /** |
| 85 | * do the bandwidth check. | 115 | * do the bandwidth check. |
| 86 | * @param rtmp, server RTMP protocol object, send/recv RTMP packet to/from client. | 116 | * @param rtmp, server RTMP protocol object, send/recv RTMP packet to/from client. |
| 117 | + * @param io_stat, the underlayer io statistic, provides send/recv bytes count. | ||
| 87 | * @param req, client request object, specifies the request info from client. | 118 | * @param req, client request object, specifies the request info from client. |
| 88 | * @param local_ip, the ip of server which client connected at | 119 | * @param local_ip, the ip of server which client connected at |
| 89 | */ | 120 | */ |
| 90 | - virtual int bandwidth_check(SrsRtmpServer* rtmp, SrsRequest* req, std::string local_ip); | 121 | + virtual int bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io_stat, SrsRequest* req, std::string local_ip); |
| 91 | private: | 122 | private: |
| 92 | /** | 123 | /** |
| 93 | * used to process band width check from client. | 124 | * used to process band width check from client. |
| 125 | + * @param limit, the bandwidth limit object, to slowdown if exceed the kbps. | ||
| 94 | */ | 126 | */ |
| 95 | - virtual int do_bandwidth_check(); | 127 | + virtual int do_bandwidth_check(SrsKbpsLimit* limit); |
| 96 | virtual int check_play(int duration_ms, int interval_ms, int& actual_duration_ms, int& play_bytes, int max_play_kbps); | 128 | virtual int check_play(int duration_ms, int interval_ms, int& actual_duration_ms, int& play_bytes, int max_play_kbps); |
| 97 | virtual int check_publish(int duration_ms, int interval_ms, int& actual_duration_ms, int& publish_bytes, int max_pub_kbps); | 129 | virtual int check_publish(int duration_ms, int interval_ms, int& actual_duration_ms, int& publish_bytes, int max_pub_kbps); |
| 98 | }; | 130 | }; |
| @@ -28,6 +28,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -28,6 +28,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 28 | #include <srs_protocol_io.hpp> | 28 | #include <srs_protocol_io.hpp> |
| 29 | #include <srs_kernel_utility.hpp> | 29 | #include <srs_kernel_utility.hpp> |
| 30 | 30 | ||
| 31 | +#define _SRS_BANDWIDTH_LIMIT_INTERVAL_MS 100 | ||
| 32 | + | ||
| 31 | SrsKbpsSample::SrsKbpsSample() | 33 | SrsKbpsSample::SrsKbpsSample() |
| 32 | { | 34 | { |
| 33 | bytes = time = 0; | 35 | bytes = time = 0; |
| @@ -244,3 +246,29 @@ void SrsKbps::sample() | @@ -244,3 +246,29 @@ void SrsKbps::sample() | ||
| 244 | os.sample(); | 246 | os.sample(); |
| 245 | } | 247 | } |
| 246 | 248 | ||
| 249 | +SrsKbpsLimit::SrsKbpsLimit(SrsKbps* kbps, int limit_kbps) | ||
| 250 | +{ | ||
| 251 | + _kbps = kbps; | ||
| 252 | + _limit_kbps = limit_kbps; | ||
| 253 | +} | ||
| 254 | + | ||
| 255 | +SrsKbpsLimit::~SrsKbpsLimit() | ||
| 256 | +{ | ||
| 257 | +} | ||
| 258 | + | ||
| 259 | +void SrsKbpsLimit::recv_limit() | ||
| 260 | +{ | ||
| 261 | + while (_kbps->get_recv_kbps() > _limit_kbps) { | ||
| 262 | + _kbps->sample(); | ||
| 263 | + st_usleep(_SRS_BANDWIDTH_LIMIT_INTERVAL_MS * 1000); | ||
| 264 | + } | ||
| 265 | +} | ||
| 266 | + | ||
| 267 | +void SrsKbpsLimit::send_limit() | ||
| 268 | +{ | ||
| 269 | + while (_kbps->get_send_kbps() > _limit_kbps) { | ||
| 270 | + _kbps->sample(); | ||
| 271 | + st_usleep(_SRS_BANDWIDTH_LIMIT_INTERVAL_MS * 1000); | ||
| 272 | + } | ||
| 273 | +} | ||
| 274 | + |
| @@ -198,4 +198,26 @@ public: | @@ -198,4 +198,26 @@ public: | ||
| 198 | virtual void sample(); | 198 | virtual void sample(); |
| 199 | }; | 199 | }; |
| 200 | 200 | ||
| 201 | +/** | ||
| 202 | +* the kbps limit, if exceed the kbps, slow down. | ||
| 203 | +*/ | ||
| 204 | +class SrsKbpsLimit | ||
| 205 | +{ | ||
| 206 | +private: | ||
| 207 | + int _limit_kbps; | ||
| 208 | + SrsKbps* _kbps; | ||
| 209 | +public: | ||
| 210 | + SrsKbpsLimit(SrsKbps* kbps, int limit_kbps); | ||
| 211 | + virtual ~SrsKbpsLimit(); | ||
| 212 | +public: | ||
| 213 | + /** | ||
| 214 | + * limit the recv bandwidth. | ||
| 215 | + */ | ||
| 216 | + virtual void recv_limit(); | ||
| 217 | + /** | ||
| 218 | + * limit the send bandwidth. | ||
| 219 | + */ | ||
| 220 | + virtual void send_limit(); | ||
| 221 | +}; | ||
| 222 | + | ||
| 201 | #endif | 223 | #endif |
| @@ -216,7 +216,7 @@ int SrsRtmpConn::service_cycle() | @@ -216,7 +216,7 @@ int SrsRtmpConn::service_cycle() | ||
| 216 | 216 | ||
| 217 | // do bandwidth test if connect to the vhost which is for bandwidth check. | 217 | // do bandwidth test if connect to the vhost which is for bandwidth check. |
| 218 | if (_srs_config->get_bw_check_enabled(req->vhost)) { | 218 | if (_srs_config->get_bw_check_enabled(req->vhost)) { |
| 219 | - return bandwidth->bandwidth_check(rtmp, req, local_ip); | 219 | + return bandwidth->bandwidth_check(rtmp, io, req, local_ip); |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | if ((ret = rtmp->response_connect_app(req, local_ip.c_str())) != ERROR_SUCCESS) { | 222 | if ((ret = rtmp->response_connect_app(req, local_ip.c_str())) != ERROR_SUCCESS) { |
-
请 注册 或 登录 后发表评论