mirror of
https://github.com/berlin-open-wireless-lab/DAWN.git
synced 2025-02-12 16:51:53 +00:00
network: add timeout for client connections
Somtimes client connetions will not close therfore add a timeout. Add a new timer that checks every 5s if we did not receive anything from a client for (default) 60s. Can be configured via client_timeout. Code is based on the work of ptpt52. Signed-off-by: Nick Hainke <vincent@systemli.org>
This commit is contained in:
parent
e596ff1317
commit
b50f9bff6d
8 changed files with 50 additions and 0 deletions
|
@ -263,6 +263,7 @@ grep 'CONFIG-T:' `find . -type f -name "*.[ch]"`|sed 's/^.*CONFIG-.: *\(.*\)$/|\
|
||||||
-->
|
-->
|
||||||
|Parameter|Purpose|Notes [Default is bracketed]|
|
|Parameter|Purpose|Notes [Default is bracketed]|
|
||||||
|---------|-------|-----|
|
|---------|-------|-----|
|
||||||
|
|client_timeout|Timespan until a client is seen as disconnected|[60]|
|
||||||
|remove_ap|Timer to remove expired AP entries from core data set|[460]|
|
|remove_ap|Timer to remove expired AP entries from core data set|[460]|
|
||||||
|remove_client|Timer to remove expired client entries from core data set|[15]|
|
|remove_client|Timer to remove expired client entries from core data set|[15]|
|
||||||
|remove_probe|Timer to remove expired PROBE and BEACON entries from core data set|[30]|
|
|remove_probe|Timer to remove expired PROBE and BEACON entries from core data set|[30]|
|
||||||
|
|
|
@ -17,6 +17,7 @@ config hostapd
|
||||||
option hostapd_dir '/var/run/hostapd'
|
option hostapd_dir '/var/run/hostapd'
|
||||||
|
|
||||||
config times
|
config times
|
||||||
|
option client_timeout '60'
|
||||||
option update_client '10'
|
option update_client '10'
|
||||||
option remove_client '15'
|
option remove_client '15'
|
||||||
option remove_probe '30'
|
option remove_probe '30'
|
||||||
|
|
|
@ -109,6 +109,7 @@ struct time_config_s {
|
||||||
time_t update_tcp_con; // Refresh network connections
|
time_t update_tcp_con; // Refresh network connections
|
||||||
time_t update_chan_util; // Refresh per radio / SSID channel util info
|
time_t update_chan_util; // Refresh per radio / SSID channel util info
|
||||||
time_t update_beacon_reports; // Request BEACON from capable clients
|
time_t update_beacon_reports; // Request BEACON from capable clients
|
||||||
|
time_t client_timeout; // Check for client timeouts.
|
||||||
};
|
};
|
||||||
|
|
||||||
struct local_config_s {
|
struct local_config_s {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#define ARRAY_NETWORK_LEN 50
|
#define ARRAY_NETWORK_LEN 50
|
||||||
|
#define CHECK_CLIENT_TIMEOUT 5
|
||||||
|
|
||||||
struct network_con_s {
|
struct network_con_s {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
@ -36,6 +37,11 @@ int run_server(int port);
|
||||||
*/
|
*/
|
||||||
void send_tcp(char *msg);
|
void send_tcp(char *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check sockets for client timeouts.
|
||||||
|
*/
|
||||||
|
void check_client_timeout(int timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug message.
|
* Debug message.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#define HEADER_SIZE sizeof(uint32_t)
|
#define HEADER_SIZE sizeof(uint32_t)
|
||||||
|
|
||||||
LIST_HEAD(tcp_sock_list);
|
LIST_HEAD(tcp_sock_list);
|
||||||
|
LIST_HEAD(cli_list);
|
||||||
|
|
||||||
struct network_con_s *tcp_list_contains_address(struct sockaddr_in entry);
|
struct network_con_s *tcp_list_contains_address(struct sockaddr_in entry);
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ enum socket_read_status {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct client {
|
struct client {
|
||||||
|
struct list_head list;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
struct ustream_fd s;
|
struct ustream_fd s;
|
||||||
|
@ -36,6 +38,7 @@ struct client {
|
||||||
enum socket_read_status state; // messge read state
|
enum socket_read_status state; // messge read state
|
||||||
uint32_t final_len; // full message length
|
uint32_t final_len; // full message length
|
||||||
uint32_t curr_len; // bytes read so far
|
uint32_t curr_len; // bytes read so far
|
||||||
|
time_t time_alive;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,6 +51,7 @@ static void client_close(struct ustream *s) {
|
||||||
ustream_free(s);
|
ustream_free(s);
|
||||||
dawn_unregmem(s);
|
dawn_unregmem(s);
|
||||||
close(cl->s.fd.fd);
|
close(cl->s.fd.fd);
|
||||||
|
list_del(&cl->list);
|
||||||
dawn_free(cl);
|
dawn_free(cl);
|
||||||
cl = NULL;
|
cl = NULL;
|
||||||
}
|
}
|
||||||
|
@ -199,6 +203,7 @@ static void client_read_cb(struct ustream *s, int bytes) {
|
||||||
cl->final_len = 0;
|
cl->final_len = 0;
|
||||||
dawn_free(cl->str);
|
dawn_free(cl->str);
|
||||||
cl->str = NULL;
|
cl->str = NULL;
|
||||||
|
cl->time_alive = time(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,6 +233,8 @@ static void server_cb(struct uloop_fd *fd, unsigned int events) {
|
||||||
cl->s.stream.notify_read = client_read_cb;
|
cl->s.stream.notify_read = client_read_cb;
|
||||||
cl->s.stream.notify_state = client_notify_state;
|
cl->s.stream.notify_state = client_notify_state;
|
||||||
cl->s.stream.notify_write = client_notify_write;
|
cl->s.stream.notify_write = client_notify_write;
|
||||||
|
cl->time_alive = time(0);
|
||||||
|
list_add(&cl->list, &cli_list);
|
||||||
ustream_fd_init(&cl->s, sfd);
|
ustream_fd_init(&cl->s, sfd);
|
||||||
dawn_regmem(&cl->s);
|
dawn_regmem(&cl->s);
|
||||||
next_client = NULL; // TODO: Why is this here? To avoid resetting if above return happens?
|
next_client = NULL; // TODO: Why is this here? To avoid resetting if above return happens?
|
||||||
|
@ -422,6 +429,18 @@ void send_tcp(char *msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check_client_timeout(int timeout) {
|
||||||
|
struct client *cl, *tmp;
|
||||||
|
time_t now = time(0);
|
||||||
|
list_for_each_entry_safe(cl, tmp, &cli_list, list)
|
||||||
|
{
|
||||||
|
if (now - cl->time_alive > timeout || now - cl->time_alive < -timeout) {
|
||||||
|
dawnlog_debug("Ustream client_close: timeout=%d\n", (int)(now - cl->time_alive));
|
||||||
|
client_close(&cl->s.stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct network_con_s* tcp_list_contains_address(struct sockaddr_in entry) {
|
struct network_con_s* tcp_list_contains_address(struct sockaddr_in entry) {
|
||||||
struct network_con_s *con;
|
struct network_con_s *con;
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ struct time_config_s uci_get_time_config() {
|
||||||
.update_tcp_con = 10,
|
.update_tcp_con = 10,
|
||||||
.update_chan_util = 5,
|
.update_chan_util = 5,
|
||||||
.update_beacon_reports = 20,
|
.update_beacon_reports = 20,
|
||||||
|
.client_timeout = 60,
|
||||||
};
|
};
|
||||||
|
|
||||||
dawnlog_debug_func("Entering...");
|
dawnlog_debug_func("Entering...");
|
||||||
|
@ -105,6 +106,8 @@ struct time_config_s uci_get_time_config() {
|
||||||
DAWN_SET_CONFIG_TIME(ret, s, update_chan_util);
|
DAWN_SET_CONFIG_TIME(ret, s, update_chan_util);
|
||||||
//CONFIG-T: update_beacon_reports|Timer to ask all connected clients for a new BEACON REPORT|[20]
|
//CONFIG-T: update_beacon_reports|Timer to ask all connected clients for a new BEACON REPORT|[20]
|
||||||
DAWN_SET_CONFIG_TIME(ret, s, update_beacon_reports);
|
DAWN_SET_CONFIG_TIME(ret, s, update_beacon_reports);
|
||||||
|
//CONFIG-T: client_timeout|Timespan to check if a client timed out|[60]
|
||||||
|
DAWN_SET_CONFIG_TIME(ret, s, client_timeout);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -656,6 +656,7 @@ enum {
|
||||||
UCI_UPDATE_TCP_CON,
|
UCI_UPDATE_TCP_CON,
|
||||||
UCI_UPDATE_CHAN_UTIL,
|
UCI_UPDATE_CHAN_UTIL,
|
||||||
UCI_UPDATE_BEACON_REPORTS,
|
UCI_UPDATE_BEACON_REPORTS,
|
||||||
|
UCI_CLIENT_TIMEOUT,
|
||||||
__UCI_TIMES_MAX,
|
__UCI_TIMES_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -713,6 +714,7 @@ static const struct blobmsg_policy uci_times_policy[__UCI_TIMES_MAX] = {
|
||||||
[UCI_UPDATE_TCP_CON] = {.name = "update_tcp_con", .type = BLOBMSG_TYPE_INT32},
|
[UCI_UPDATE_TCP_CON] = {.name = "update_tcp_con", .type = BLOBMSG_TYPE_INT32},
|
||||||
[UCI_UPDATE_CHAN_UTIL] = {.name = "update_chan_util", .type = BLOBMSG_TYPE_INT32},
|
[UCI_UPDATE_CHAN_UTIL] = {.name = "update_chan_util", .type = BLOBMSG_TYPE_INT32},
|
||||||
[UCI_UPDATE_BEACON_REPORTS] = {.name = "update_beacon_reports", .type = BLOBMSG_TYPE_INT32},
|
[UCI_UPDATE_BEACON_REPORTS] = {.name = "update_beacon_reports", .type = BLOBMSG_TYPE_INT32},
|
||||||
|
[UCI_CLIENT_TIMEOUT] = {.name = "client_timeout", .type = BLOBMSG_TYPE_INT32},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void set_uci_item(char* m, struct blob_attr* a)
|
static void set_uci_item(char* m, struct blob_attr* a)
|
||||||
|
@ -895,6 +897,8 @@ static int handle_uci_config(struct blob_attr* msg) {
|
||||||
|
|
||||||
set_uci_item("dawn.@times[0].update_beacon_reports=%d", tb_times[UCI_UPDATE_BEACON_REPORTS]);
|
set_uci_item("dawn.@times[0].update_beacon_reports=%d", tb_times[UCI_UPDATE_BEACON_REPORTS]);
|
||||||
|
|
||||||
|
set_uci_item("dawn.@times[0].client_timeout=%d", tb_times[UCI_CLIENT_TIMEOUT]);
|
||||||
|
|
||||||
uci_reset();
|
uci_reset();
|
||||||
dawn_metric = uci_get_dawn_metric();
|
dawn_metric = uci_get_dawn_metric();
|
||||||
timeout_config = uci_get_time_config();
|
timeout_config = uci_get_time_config();
|
||||||
|
|
|
@ -23,6 +23,8 @@ void update_clients(struct uloop_timeout *t);
|
||||||
|
|
||||||
void update_tcp_connections(struct uloop_timeout *t);
|
void update_tcp_connections(struct uloop_timeout *t);
|
||||||
|
|
||||||
|
void check_client_timeouts(struct uloop_timeout *t);
|
||||||
|
|
||||||
void update_channel_utilization(struct uloop_timeout *t);
|
void update_channel_utilization(struct uloop_timeout *t);
|
||||||
|
|
||||||
void run_server_update(struct uloop_timeout *t);
|
void run_server_update(struct uloop_timeout *t);
|
||||||
|
@ -38,6 +40,9 @@ struct uloop_timeout hostapd_timer = {
|
||||||
struct uloop_timeout tcp_con_timer = {
|
struct uloop_timeout tcp_con_timer = {
|
||||||
.cb = update_tcp_connections
|
.cb = update_tcp_connections
|
||||||
};
|
};
|
||||||
|
struct uloop_timeout client_timeout_timer = {
|
||||||
|
.cb = check_client_timeouts
|
||||||
|
};
|
||||||
struct uloop_timeout channel_utilization_timer = {
|
struct uloop_timeout channel_utilization_timer = {
|
||||||
.cb = update_channel_utilization
|
.cb = update_channel_utilization
|
||||||
};
|
};
|
||||||
|
@ -1148,11 +1153,20 @@ void update_tcp_connections(struct uloop_timeout *t) {
|
||||||
uloop_timeout_set(&tcp_con_timer, timeout_config.update_tcp_con * 1000);
|
uloop_timeout_set(&tcp_con_timer, timeout_config.update_tcp_con * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check_client_timeouts(struct uloop_timeout *t) {
|
||||||
|
dawnlog_debug_func("Entering...");
|
||||||
|
|
||||||
|
check_client_timeout(timeout_config.client_timeout);
|
||||||
|
|
||||||
|
uloop_timeout_set(&client_timeout_timer, CHECK_CLIENT_TIMEOUT * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
void start_tcp_con_update() {
|
void start_tcp_con_update() {
|
||||||
dawnlog_debug_func("Entering...");
|
dawnlog_debug_func("Entering...");
|
||||||
|
|
||||||
// update connections
|
// update connections
|
||||||
uloop_timeout_add(&tcp_con_timer); // callback = update_tcp_connections
|
uloop_timeout_add(&tcp_con_timer); // callback = update_tcp_connections
|
||||||
|
uloop_timeout_add(&client_timeout_timer); // callback = client_timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_hostapd_sockets(struct uloop_timeout *t) {
|
void update_hostapd_sockets(struct uloop_timeout *t) {
|
||||||
|
@ -1888,6 +1902,7 @@ int uci_send_via_network()
|
||||||
blobmsg_add_u32(&b, "update_tcp_con", timeout_config.update_tcp_con);
|
blobmsg_add_u32(&b, "update_tcp_con", timeout_config.update_tcp_con);
|
||||||
blobmsg_add_u32(&b, "update_chan_util", timeout_config.update_chan_util);
|
blobmsg_add_u32(&b, "update_chan_util", timeout_config.update_chan_util);
|
||||||
blobmsg_add_u32(&b, "update_beacon_reports", timeout_config.update_beacon_reports);
|
blobmsg_add_u32(&b, "update_beacon_reports", timeout_config.update_beacon_reports);
|
||||||
|
blobmsg_add_u32(&b, "client_timeout", timeout_config.client_timeout);
|
||||||
blobmsg_close_table(&b, times);
|
blobmsg_close_table(&b, times);
|
||||||
|
|
||||||
send_blob_attr_via_network(b.head, "uci");
|
send_blob_attr_via_network(b.head, "uci");
|
||||||
|
|
Loading…
Reference in a new issue