mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
count bandwidth in kb/sec to avoid overflows on high bandwidth.
This commit is contained in:
@@ -165,8 +165,8 @@ ping-leases = false
|
||||
|
||||
# Unset to enable bandwidth restrictions (in bytes/sec). The
|
||||
# setting here is global, but can also be set per user or per group.
|
||||
#rx-per-sec = 40960
|
||||
#tx-per-sec = 40960
|
||||
#rx-data-per-sec = 40960
|
||||
#tx-data-per-sec = 40960
|
||||
|
||||
# The number of packets (of MTU size) that are available in
|
||||
# the output buffer. The default is low to improve latency.
|
||||
@@ -180,7 +180,7 @@ route = 192.168.1.0/255.255.255.0
|
||||
# per group. Each file name on these directories must match the username
|
||||
# or the groupname.
|
||||
# The options allowed in the configuration files are ipv?-dns, ipv?-nbns,
|
||||
# ipv?-network, ipv?-netmask, ipv6-prefix, iroute and route.
|
||||
# ipv?-network, ipv?-netmask, ipv6-prefix, rx/tx-per-sec, iroute and route.
|
||||
#
|
||||
# Note that the 'iroute' option allows to add routes on the server
|
||||
# based on a user or group. The syntax depends on the input accepted
|
||||
|
||||
10
src/config.c
10
src/config.c
@@ -86,8 +86,8 @@ static struct cfg_options available_options[] = {
|
||||
{ .name = "min-reauth-time", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
{ .name = "max-same-clients", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
|
||||
{ .name = "rx-per-sec", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
{ .name = "tx-per-sec", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
{ .name = "rx-data-per-sec", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
{ .name = "tx-data-per-sec", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
|
||||
{ .name = "run-as-user", .type = OPTION_STRING, .mandatory = 0 },
|
||||
{ .name = "run-as-group", .type = OPTION_STRING, .mandatory = 0 },
|
||||
@@ -319,8 +319,10 @@ unsigned prefix = 0;
|
||||
READ_NUMERIC("mtu", config->default_mtu);
|
||||
READ_NUMERIC("output-buffer", config->output_buffer);
|
||||
|
||||
READ_NUMERIC("rx-per-sec", config->rx_per_sec);
|
||||
READ_NUMERIC("tx-per-sec", config->tx_per_sec);
|
||||
READ_NUMERIC("rx-data-per-sec", config->rx_per_sec);
|
||||
READ_NUMERIC("tx-data-per-sec", config->tx_per_sec);
|
||||
config->rx_per_sec /= 1000; /* in kb */
|
||||
config->tx_per_sec /= 1000;
|
||||
|
||||
READ_NUMERIC("cookie-validity", config->cookie_validity);
|
||||
READ_NUMERIC("auth-timeout", config->auth_timeout);
|
||||
|
||||
@@ -51,8 +51,8 @@ static struct cfg_options available_options[] = {
|
||||
{ .name = "ipv4-netmask", .type = OPTION_STRING },
|
||||
{ .name = "ipv6-prefix", .type = OPTION_NUMERIC },
|
||||
{ .name = "ipv6-netmask", .type = OPTION_STRING },
|
||||
{ .name = "rx-per-sec", .type = OPTION_NUMERIC, },
|
||||
{ .name = "tx-per-sec", .type = OPTION_NUMERIC, },
|
||||
{ .name = "rx-data-per-sec", .type = OPTION_NUMERIC, },
|
||||
{ .name = "tx-data-per-sec", .type = OPTION_NUMERIC, },
|
||||
};
|
||||
|
||||
#define READ_RAW_MULTI_LINE(name, s_name, num) \
|
||||
@@ -144,8 +144,10 @@ unsigned prefix = 0;
|
||||
if (prefix > 0)
|
||||
config->ipv6_netmask = ipv6_prefix_to_mask(prefix);
|
||||
|
||||
READ_RAW_NUMERIC("rx-per-sec", config->rx_per_sec);
|
||||
READ_RAW_NUMERIC("tx-per-sec", config->tx_per_sec);
|
||||
READ_RAW_NUMERIC("rx-data-per-sec", config->rx_per_sec);
|
||||
READ_RAW_NUMERIC("tx-data-per-sec", config->tx_per_sec);
|
||||
config->rx_per_sec /= 1000; /* in kb */
|
||||
config->tx_per_sec /= 1000; /* in kb */
|
||||
|
||||
optionUnloadNested(pov);
|
||||
|
||||
|
||||
@@ -257,8 +257,8 @@ ping-leases = false
|
||||
|
||||
# Unset to enable bandwidth restrictions (in bytes/sec). The
|
||||
# setting here is global, but can also be set per user or per group.
|
||||
#rx-per-sec = 40000
|
||||
#tx-per-sec = 40000
|
||||
#rx-data-per-sec = 40000
|
||||
#tx-data-per-sec = 40000
|
||||
|
||||
# The number of packets (of MTU size) that are available in
|
||||
# the output buffer. The default is low to improve latency.
|
||||
@@ -275,7 +275,7 @@ route = 192.168.5.0/255.255.255.0
|
||||
# per group. Each file name on these directories must match the username
|
||||
# or the groupname.
|
||||
# The options allowed in the configuration files are ipv?-dns, ipv?-nbns,
|
||||
# ipv?-network, ipv?-netmask, ipv6-prefix, iroute and route.
|
||||
# ipv?-network, ipv?-netmask, ipv6-prefix, rx/tx-per-sec, iroute and route.
|
||||
#
|
||||
# Note that the 'iroute' option allows to add routes on the server
|
||||
# based on a user or group. The syntax depends on the input accepted
|
||||
|
||||
@@ -26,40 +26,35 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define COUNT_UPDATE_MS 500
|
||||
|
||||
int bandwidth_update(bandwidth_st* b, size_t bytes, size_t mtu)
|
||||
int _bandwidth_update(bandwidth_st* b, size_t bytes, size_t mtu)
|
||||
{
|
||||
size_t sum;
|
||||
struct timespec now;
|
||||
ssize_t t, new_allowed_bytes, remain;
|
||||
ssize_t t, remain;
|
||||
unsigned int diff;
|
||||
|
||||
/* if bandwidth control is disabled */
|
||||
if (b->bytes_per_sec == 0)
|
||||
return 1;
|
||||
size_t transferred_kb;
|
||||
|
||||
gettime(&now);
|
||||
|
||||
diff = timespec_sub_ms(&now, &b->count_start);
|
||||
if (diff >= COUNT_UPDATE_MS) {
|
||||
b->transferred_bytes = (b->transferred_bytes*COUNT_UPDATE_MS)/diff;
|
||||
transferred_kb = b->transferred_bytes / 1000;
|
||||
transferred_kb = (transferred_kb*COUNT_UPDATE_MS)/diff;
|
||||
|
||||
memcpy(&b->count_start, &now, sizeof(now));
|
||||
|
||||
new_allowed_bytes = mtu - 1 + ((b->bytes_per_sec*COUNT_UPDATE_MS)/1000);
|
||||
remain = b->allowed_kb - transferred_kb;
|
||||
t = b->allowed_kb_per_count + remain;
|
||||
|
||||
remain = b->allowed_bytes - b->transferred_bytes;
|
||||
t = new_allowed_bytes + remain;
|
||||
|
||||
b->allowed_bytes = MIN(t, new_allowed_bytes*1000/COUNT_UPDATE_MS);
|
||||
b->allowed_kb = MIN(t, b->kb_per_sec);
|
||||
b->transferred_bytes = bytes;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sum = b->transferred_bytes + bytes;
|
||||
if (sum > b->allowed_bytes)
|
||||
if (sum > b->allowed_kb*1000)
|
||||
return 0; /* NO */
|
||||
|
||||
b->transferred_bytes = sum;
|
||||
|
||||
@@ -24,23 +24,38 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define COUNT_UPDATE_MS 500
|
||||
|
||||
typedef struct bandwidth_st {
|
||||
struct timespec count_start;
|
||||
size_t transferred_bytes;
|
||||
size_t allowed_bytes;
|
||||
size_t allowed_kb;
|
||||
|
||||
size_t bytes_per_sec;
|
||||
/* only touched once */
|
||||
size_t allowed_kb_per_count;
|
||||
size_t kb_per_sec;
|
||||
} bandwidth_st;
|
||||
|
||||
inline static void bandwidth_init(bandwidth_st* b, size_t bytes_per_sec)
|
||||
inline static void bandwidth_init(bandwidth_st* b, size_t kb_per_sec)
|
||||
{
|
||||
memset(b, 0, sizeof(*b));
|
||||
b->bytes_per_sec = bytes_per_sec;
|
||||
b->kb_per_sec = kb_per_sec;
|
||||
b->allowed_kb_per_count = (b->kb_per_sec*COUNT_UPDATE_MS)/1000;
|
||||
}
|
||||
|
||||
int _bandwidth_update(bandwidth_st* b, size_t bytes, size_t mtu);
|
||||
|
||||
/* returns true or false, depending on whether to send
|
||||
* the bytes */
|
||||
int bandwidth_update(bandwidth_st* b, size_t bytes, size_t mtu);
|
||||
inline static
|
||||
int bandwidth_update(bandwidth_st* b, size_t bytes, size_t mtu)
|
||||
{
|
||||
/* if bandwidth control is disabled */
|
||||
if (b->kb_per_sec == 0)
|
||||
return 1;
|
||||
|
||||
return _bandwidth_update(b, bytes, mtu);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user