mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-10-14 02:22:03 +08:00
Added directives to allow bandwidth limitation.
This commit is contained in:
@@ -163,6 +163,11 @@ ping-leases = false
|
||||
# Leave empty to assign the default MTU of the device
|
||||
# mtu =
|
||||
|
||||
# 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
|
||||
|
||||
# The number of packets (of MTU size) that are available in
|
||||
# the output buffer. The default is low to improve latency.
|
||||
# Setting it higher will improve throughput.
|
||||
|
||||
@@ -23,6 +23,7 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
|
||||
main-user.c worker-misc.c setproctitle.h route-add.c route-add.h \
|
||||
setproctitle.c worker-privs.c plain.c plain.h common.h common.c \
|
||||
sec-mod.c sec-mod.h script-list.h system.c system.h icmp-ping.c icmp-ping.h \
|
||||
worker-bandwidth.c worker-bandwidth.h \
|
||||
str.c str.h gettime.h $(CCAN_SOURCES)
|
||||
|
||||
ocserv_SOURCES += ocserv-args.def ocserv-args.c ocserv-args.h
|
||||
|
||||
@@ -87,6 +87,9 @@ 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 = "run-as-user", .type = OPTION_STRING, .mandatory = 0 },
|
||||
{ .name = "run-as-group", .type = OPTION_STRING, .mandatory = 0 },
|
||||
{ .name = "device", .type = OPTION_STRING, .mandatory = 1 },
|
||||
@@ -317,6 +320,9 @@ 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("cookie-validity", config->cookie_validity);
|
||||
READ_NUMERIC("auth-timeout", config->auth_timeout);
|
||||
READ_NUMERIC("max-clients", config->max_clients);
|
||||
|
||||
@@ -42,4 +42,12 @@ struct timeval tv;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline static
|
||||
unsigned int
|
||||
timespec_sub_ms (struct timespec *a, struct timespec *b)
|
||||
{
|
||||
return (a->tv_sec * 1000 + a->tv_nsec / (1000 * 1000) -
|
||||
(b->tv_sec * 1000 + b->tv_nsec / (1000 * 1000)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -91,6 +91,7 @@ int serialize_additional_data(main_server_st* s, struct proc_st* proc)
|
||||
int ret;
|
||||
unsigned i;
|
||||
uint8_t len;
|
||||
uint32_t t;
|
||||
str_st buffer;
|
||||
|
||||
str_init(&buffer);
|
||||
@@ -138,6 +139,16 @@ str_st buffer;
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
t = proc->config.rx_per_sec;
|
||||
ret = str_append_data(&buffer, &t, sizeof(t));
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
t = proc->config.tx_per_sec;
|
||||
ret = str_append_data(&buffer, &t, sizeof(t));
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* routes */
|
||||
len = proc->config.routes_size;
|
||||
ret = str_append_data(&buffer, &len, 1);
|
||||
@@ -155,6 +166,7 @@ str_st buffer;
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
|
||||
@@ -52,6 +52,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, },
|
||||
};
|
||||
|
||||
#define READ_RAW_MULTI_LINE(name, s_name, num) \
|
||||
@@ -143,6 +145,9 @@ 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);
|
||||
|
||||
optionUnloadNested(pov);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -239,6 +239,14 @@ unsigned i;
|
||||
cfg.ipv6_netmask = NULL;
|
||||
}
|
||||
|
||||
if (proc->config.rx_per_sec == 0) {
|
||||
proc->config.rx_per_sec = cfg.rx_per_sec;
|
||||
}
|
||||
|
||||
if (proc->config.tx_per_sec == 0) {
|
||||
proc->config.tx_per_sec = cfg.tx_per_sec;
|
||||
}
|
||||
|
||||
del_additional_config(&cfg);
|
||||
|
||||
} else
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* DO NOT EDIT THIS FILE (ocserv-args.c)
|
||||
*
|
||||
* It has been AutoGen-ed November 2, 2013 at 04:25:18 PM by AutoGen 5.17
|
||||
* It has been AutoGen-ed November 3, 2013 at 05:05:30 PM by AutoGen 5.17
|
||||
* From the definitions ocserv-args.def
|
||||
* and the template file options
|
||||
*
|
||||
|
||||
@@ -247,6 +247,11 @@ ping-leases = false
|
||||
# Unset to assign the default MTU of the device
|
||||
# mtu =
|
||||
|
||||
# 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
|
||||
|
||||
# The number of packets (of MTU size) that are available in
|
||||
# the output buffer. The default is low to improve latency.
|
||||
# Setting it higher will improve throughput.
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* DO NOT EDIT THIS FILE (ocserv-args.h)
|
||||
*
|
||||
* It has been AutoGen-ed November 2, 2013 at 04:25:18 PM by AutoGen 5.17
|
||||
* It has been AutoGen-ed November 3, 2013 at 05:05:30 PM by AutoGen 5.17
|
||||
* From the definitions ocserv-args.def
|
||||
* and the template file options
|
||||
*
|
||||
|
||||
@@ -131,7 +131,7 @@ int str_append_str(str_st * dest, const char *src)
|
||||
/* Makes sure that the data read are null terminated (but not counted in *data_size)
|
||||
* If the size of the data is zero then *data will be null;
|
||||
*/
|
||||
int str_read_data_prefix1(str_st * src, char **data, size_t *data_size)
|
||||
int str_read_str_prefix1(str_st * src, char **data, size_t *data_size)
|
||||
{
|
||||
uint8_t prefix;
|
||||
|
||||
@@ -168,3 +168,15 @@ int str_read_data_prefix1(str_st * src, char **data, size_t *data_size)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int str_read_data(str_st * src, void *data, size_t data_size)
|
||||
{
|
||||
if (src->length < data_size)
|
||||
return ERR_MEM;
|
||||
|
||||
memcpy(data, src->data, data_size);
|
||||
src->data += data_size;
|
||||
src->length -= data_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,8 @@ int str_append_str(str_st *, const char *str);
|
||||
int str_append_data(str_st *, const void *data, size_t data_size);
|
||||
int str_append_size(str_st *, size_t data_size);
|
||||
int str_append_data_prefix1(str_st *, const void *data, size_t data_size);
|
||||
int str_read_data_prefix1(str_st * src, char **data, size_t *data_size);
|
||||
int str_read_str_prefix1(str_st * src, char **data, size_t *data_size);
|
||||
int str_read_data(str_st * src, void *data, size_t data_size);
|
||||
|
||||
#define str_append_str_prefix1(s, str) (((str)==NULL)?str_append_data_prefix1(s, NULL, 0):str_append_data_prefix1(s, str, strlen(str)))
|
||||
|
||||
|
||||
@@ -76,6 +76,9 @@ struct group_cfg_st {
|
||||
char *ipv6_network;
|
||||
char *ipv4_netmask;
|
||||
char *ipv6_netmask;
|
||||
|
||||
size_t rx_per_sec;
|
||||
size_t tx_per_sec;
|
||||
};
|
||||
|
||||
struct vpn_st {
|
||||
@@ -137,6 +140,9 @@ struct cfg_st {
|
||||
unsigned rate_limit_ms; /* if non zero force a connection every rate_limit milliseconds */
|
||||
unsigned ping_leases; /* non zero if we need to ping prior to leasing */
|
||||
|
||||
size_t rx_per_sec;
|
||||
size_t tx_per_sec;
|
||||
|
||||
unsigned output_buffer;
|
||||
unsigned default_mtu;
|
||||
|
||||
|
||||
+21
-7
@@ -289,6 +289,7 @@ int deserialize_additional_data(worker_st* ws)
|
||||
int ret;
|
||||
unsigned i;
|
||||
str_st b;
|
||||
uint32_t t;
|
||||
|
||||
str_init(&b);
|
||||
|
||||
@@ -297,32 +298,32 @@ str_st b;
|
||||
goto cleanup;
|
||||
|
||||
/* IPV4 DNS */
|
||||
ret = str_read_data_prefix1(&b, &ws->ipv4_dns, NULL);
|
||||
ret = str_read_str_prefix1(&b, &ws->ipv4_dns, NULL);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* IPV6 DNS */
|
||||
ret = str_read_data_prefix1(&b, &ws->ipv6_dns, NULL);
|
||||
ret = str_read_str_prefix1(&b, &ws->ipv6_dns, NULL);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* IPV4 NBNS */
|
||||
ret = str_read_data_prefix1(&b, &ws->ipv4_nbns, NULL);
|
||||
ret = str_read_str_prefix1(&b, &ws->ipv4_nbns, NULL);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* IPV6 NBNS */
|
||||
ret = str_read_data_prefix1(&b, &ws->ipv6_nbns, NULL);
|
||||
ret = str_read_str_prefix1(&b, &ws->ipv6_nbns, NULL);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* IPV4 netmask */
|
||||
ret = str_read_data_prefix1(&b, &ws->ipv4_netmask, NULL);
|
||||
ret = str_read_str_prefix1(&b, &ws->ipv4_netmask, NULL);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* IPV6 netmask */
|
||||
ret = str_read_data_prefix1(&b, &ws->ipv6_netmask, NULL);
|
||||
ret = str_read_str_prefix1(&b, &ws->ipv6_netmask, NULL);
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
@@ -332,13 +333,26 @@ str_st b;
|
||||
ret = ERR_BAD_COMMAND;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = str_read_data(&b, &t, sizeof(t));
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
ws->rx_per_sec = t;
|
||||
|
||||
ret = str_read_data(&b, &t, sizeof(t));
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
ws->tx_per_sec = t;
|
||||
|
||||
ws->routes_size = b.data[0];
|
||||
b.length--;
|
||||
b.data++;
|
||||
|
||||
/* routes */
|
||||
for (i=0;i<ws->routes_size;i++) {
|
||||
ret = str_read_data_prefix1(&b, &ws->routes[i], NULL);
|
||||
ret = str_read_str_prefix1(&b, &ws->routes[i], NULL);
|
||||
if (ret < 0) {
|
||||
oclog(ws, LOG_ERR, "Error receiving private routes from main");
|
||||
ret = ERR_BAD_COMMAND;
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Nikos Mavrogiannopoulos
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <vpn.h>
|
||||
#include <worker.h>
|
||||
#include <worker-bandwidth.h>
|
||||
#include <gettime.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define COUNT_UPDATE_MS 500
|
||||
|
||||
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;
|
||||
unsigned int diff;
|
||||
|
||||
/* if bandwidth control is disabled */
|
||||
if (b->bytes_per_sec == 0)
|
||||
return 1;
|
||||
|
||||
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;
|
||||
|
||||
memcpy(&b->count_start, &now, sizeof(now));
|
||||
|
||||
new_allowed_bytes = mtu - 1 + ((b->bytes_per_sec*COUNT_UPDATE_MS)/1000);
|
||||
|
||||
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->transferred_bytes = bytes;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sum = b->transferred_bytes + bytes;
|
||||
if (sum > b->allowed_bytes)
|
||||
return 0; /* NO */
|
||||
|
||||
b->transferred_bytes = sum;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef WORKER_BANDWIDTH_H
|
||||
# define WORKER_BANDWIDTH_H
|
||||
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef struct bandwidth_st {
|
||||
struct timespec count_start;
|
||||
size_t transferred_bytes;
|
||||
size_t allowed_bytes;
|
||||
|
||||
size_t bytes_per_sec;
|
||||
} bandwidth_st;
|
||||
|
||||
inline static void bandwidth_init(bandwidth_st* b, size_t bytes_per_sec)
|
||||
{
|
||||
memset(b, 0, sizeof(*b));
|
||||
b->bytes_per_sec = bytes_per_sec;
|
||||
}
|
||||
|
||||
/* returns true or false, depending on whether to send
|
||||
* the bytes */
|
||||
int bandwidth_update(bandwidth_st* b, size_t bytes, size_t mtu);
|
||||
|
||||
|
||||
#endif
|
||||
+58
-40
@@ -41,6 +41,7 @@
|
||||
#include <system.h>
|
||||
#include <time.h>
|
||||
#include <common.h>
|
||||
#include <worker-bandwidth.h>
|
||||
|
||||
#include <vpn.h>
|
||||
#include "ipc.h"
|
||||
@@ -765,6 +766,8 @@ unsigned tls_pending, dtls_pending = 0, i;
|
||||
time_t udp_recv_time = 0, now;
|
||||
unsigned mtu_overhead = 0;
|
||||
socklen_t sl;
|
||||
bandwidth_st b_tx;
|
||||
bandwidth_st b_rx;
|
||||
|
||||
ws->buffer_size = 16*1024;
|
||||
ws->buffer = malloc(ws->buffer_size);
|
||||
@@ -1040,6 +1043,14 @@ socklen_t sl;
|
||||
/* start dead peer detection */
|
||||
ws->last_msg_tcp = ws->last_msg_udp = time(0);
|
||||
|
||||
if (ws->rx_per_sec == 0)
|
||||
ws->rx_per_sec = ws->config->rx_per_sec;
|
||||
if (ws->tx_per_sec == 0)
|
||||
ws->tx_per_sec = ws->config->tx_per_sec;
|
||||
|
||||
bandwidth_init(&b_rx, ws->rx_per_sec);
|
||||
bandwidth_init(&b_tx, ws->tx_per_sec);
|
||||
|
||||
/* main loop */
|
||||
for(;;) {
|
||||
FD_ZERO(&rfds);
|
||||
@@ -1107,38 +1118,40 @@ socklen_t sl;
|
||||
continue;
|
||||
}
|
||||
|
||||
tls_retry = 0;
|
||||
oclog(ws, LOG_DEBUG, "sending %d byte(s)\n", l);
|
||||
if (ws->udp_state == UP_ACTIVE) {
|
||||
ws->buffer[7] = AC_PKT_DATA;
|
||||
/* only transmit if allowed */
|
||||
if (bandwidth_update(&b_tx, l-1, ws->conn_mtu) != 0) {
|
||||
tls_retry = 0;
|
||||
oclog(ws, LOG_DEBUG, "sending %d byte(s)\n", l);
|
||||
if (ws->udp_state == UP_ACTIVE) {
|
||||
ws->buffer[7] = AC_PKT_DATA;
|
||||
|
||||
ret = tls_send_nowait(ws->dtls_session, ws->buffer + 7, l + 1);
|
||||
GNUTLS_FATAL_ERR(ret);
|
||||
ret = tls_send_nowait(ws->dtls_session, ws->buffer + 7, l + 1);
|
||||
GNUTLS_FATAL_ERR(ret);
|
||||
|
||||
if (ret == GNUTLS_E_LARGE_PACKET) {
|
||||
mtu_not_ok(ws);
|
||||
if (ret == GNUTLS_E_LARGE_PACKET) {
|
||||
mtu_not_ok(ws);
|
||||
|
||||
oclog(ws, LOG_DEBUG, "retrying (TLS) %d\n", l);
|
||||
tls_retry = 1;
|
||||
} else if (ret >= ws->conn_mtu && ws->config->try_mtu != 0) {
|
||||
mtu_ok(ws);
|
||||
oclog(ws, LOG_DEBUG, "retrying (TLS) %d\n", l);
|
||||
tls_retry = 1;
|
||||
} else if (ret >= ws->conn_mtu && ws->config->try_mtu != 0) {
|
||||
mtu_ok(ws);
|
||||
}
|
||||
}
|
||||
|
||||
if (ws->udp_state != UP_ACTIVE || tls_retry != 0) {
|
||||
ws->buffer[0] = 'S';
|
||||
ws->buffer[1] = 'T';
|
||||
ws->buffer[2] = 'F';
|
||||
ws->buffer[3] = 1;
|
||||
ws->buffer[4] = l >> 8;
|
||||
ws->buffer[5] = l & 0xff;
|
||||
ws->buffer[6] = AC_PKT_DATA;
|
||||
ws->buffer[7] = 0;
|
||||
|
||||
ret = tls_send(ws->session, ws->buffer, l + 8);
|
||||
GNUTLS_FATAL_ERR(ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (ws->udp_state != UP_ACTIVE || tls_retry != 0) {
|
||||
ws->buffer[0] = 'S';
|
||||
ws->buffer[1] = 'T';
|
||||
ws->buffer[2] = 'F';
|
||||
ws->buffer[3] = 1;
|
||||
ws->buffer[4] = l >> 8;
|
||||
ws->buffer[5] = l & 0xff;
|
||||
ws->buffer[6] = AC_PKT_DATA;
|
||||
ws->buffer[7] = 0;
|
||||
|
||||
ret = tls_send(ws->session, ws->buffer, l + 8);
|
||||
GNUTLS_FATAL_ERR(ret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (FD_ISSET(ws->conn_fd, &rfds) || tls_pending != 0) {
|
||||
@@ -1152,19 +1165,22 @@ socklen_t sl;
|
||||
goto exit_nomsg;
|
||||
}
|
||||
|
||||
|
||||
if (ret > 0) {
|
||||
l = ret;
|
||||
|
||||
ret = parse_cstp_data(ws, ws->buffer, l, now);
|
||||
if (ret < 0) {
|
||||
oclog(ws, LOG_INFO, "error parsing CSTP data");
|
||||
goto exit;
|
||||
}
|
||||
if (bandwidth_update(&b_rx, l-8, ws->conn_mtu) != 0) {
|
||||
ret = parse_cstp_data(ws, ws->buffer, l, now);
|
||||
if (ret < 0) {
|
||||
oclog(ws, LOG_INFO, "error parsing CSTP data");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ret == AC_PKT_DATA && ws->udp_state == UP_ACTIVE) {
|
||||
/* client switched to TLS for some reason */
|
||||
if (now - udp_recv_time > UDP_SWITCH_TIME)
|
||||
ws->udp_state = UP_INACTIVE;
|
||||
if (ret == AC_PKT_DATA && ws->udp_state == UP_ACTIVE) {
|
||||
/* client switched to TLS for some reason */
|
||||
if (now - udp_recv_time > UDP_SWITCH_TIME)
|
||||
ws->udp_state = UP_INACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1183,10 +1199,12 @@ socklen_t sl;
|
||||
l = ret;
|
||||
ws->udp_state = UP_ACTIVE;
|
||||
|
||||
ret = parse_dtls_data(ws, ws->buffer, l, now);
|
||||
if (ret < 0) {
|
||||
oclog(ws, LOG_INFO, "error parsing CSTP data");
|
||||
goto exit;
|
||||
if (bandwidth_update(&b_rx, l-1, ws->conn_mtu) != 0) {
|
||||
ret = parse_dtls_data(ws, ws->buffer, l, now);
|
||||
if (ret < 0) {
|
||||
oclog(ws, LOG_INFO, "error parsing CSTP data");
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
|
||||
@@ -128,6 +128,9 @@ typedef struct worker_st {
|
||||
unsigned routes_size;
|
||||
char* routes[MAX_ROUTES];
|
||||
|
||||
size_t rx_per_sec;
|
||||
size_t tx_per_sec;
|
||||
|
||||
struct http_req_st req;
|
||||
} worker_st;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user