diff -up vsftpd-3.0.2/ftpdataio.c.mrate vsftpd-3.0.2/ftpdataio.c --- vsftpd-3.0.2/ftpdataio.c.mrate 2014-03-06 16:22:44.547366196 +0100 +++ vsftpd-3.0.2/ftpdataio.c 2014-03-07 10:14:33.681097022 +0100 @@ -251,7 +251,7 @@ handle_io(int retval, int fd, void* p_pr { long curr_sec; long curr_usec; - unsigned int bw_rate; + unsigned long bw_rate; double elapsed; double pause_time; double rate_ratio; @@ -278,19 +278,16 @@ handle_io(int retval, int fd, void* p_pr { elapsed = (double) 0.01; } - bw_rate = (unsigned int) ((double) retval / elapsed); - if (bw_rate <= p_sess->bw_rate_max) + p_sess->bw_retval += retval; + bw_rate = (unsigned long) ((double) p_sess->bw_retval / elapsed); + if (bw_rate <= p_sess->bw_rate_max || p_sess->bw_retval < (unsigned long)(10*retval)) { - p_sess->bw_send_start_sec = curr_sec; - p_sess->bw_send_start_usec = curr_usec; return; } /* Tut! Rate exceeded, calculate a pause to bring things back into line */ rate_ratio = (double) bw_rate / (double) p_sess->bw_rate_max; pause_time = (rate_ratio - (double) 1) * elapsed; vsf_sysutil_sleep(pause_time); - p_sess->bw_send_start_sec = vsf_sysutil_get_time_sec(); - p_sess->bw_send_start_usec = vsf_sysutil_get_time_usec(); } int @@ -443,6 +440,9 @@ struct vsf_transfer_ret vsf_ftpdataio_transfer_file(struct vsf_session* p_sess, int remote_fd, int file_fd, int is_recv, int is_ascii) { + p_sess->bw_send_start_sec = vsf_sysutil_get_time_sec(); + p_sess->bw_send_start_usec = vsf_sysutil_get_time_usec(); + p_sess->bw_retval = 0; if (!is_recv) { if (is_ascii || p_sess->data_use_ssl) diff -up vsftpd-3.0.2/main.c.mrate vsftpd-3.0.2/main.c --- vsftpd-3.0.2/main.c.mrate 2014-03-06 16:22:28.475362449 +0100 +++ vsftpd-3.0.2/main.c 2014-03-06 16:24:27.056384556 +0100 @@ -40,7 +40,7 @@ main(int argc, const char* argv[]) /* Control connection */ 0, 0, 0, 0, 0, /* Data connection */ - -1, 0, -1, 0, 0, 0, 0, + -1, 0, -1, 0, 0, 0, 0, 0, /* Login */ 1, 0, INIT_MYSTR, INIT_MYSTR, /* Protocol state */ diff -up vsftpd-3.0.2/session.h.mrate vsftpd-3.0.2/session.h --- vsftpd-3.0.2/session.h.mrate 2014-03-06 16:22:15.376359081 +0100 +++ vsftpd-3.0.2/session.h 2014-03-06 16:23:58.860379868 +0100 @@ -29,9 +29,10 @@ struct vsf_session struct vsf_sysutil_sockaddr* p_port_sockaddr; int data_fd; int data_progress; - unsigned int bw_rate_max; + unsigned long bw_rate_max; long bw_send_start_sec; long bw_send_start_usec; + unsigned long bw_retval; /* Details of the login */ int is_anonymous;