diff --git a/wireless/wifictld/src/config.c b/wireless/wifictld/src/config.c index e5c40ea..cf56fa1 100644 --- a/wireless/wifictld/src/config.c +++ b/wireless/wifictld/src/config.c @@ -1,15 +1,16 @@ #include "config.h" -int verbose = 0; +bool config_verbose = false; -int client_try_threashold = 3; -int client_signal_threashold = -75; +int config_client_try_threashold = 3; +int config_client_signal_threashold = -75; -int clean_every = 600; //in ms = 10min -int clean_older_then = 3600; //in sec = 1h +int config_client_clean_every = 600; //in ms = 10min +int config_client_clean_older_then = 3600; //in sec = 1h +bool config_client_clean_authed = false; -bool client_force = false; -bool client_force_probe = false; -bool client_probe_steering = true; +bool config_client_force = false; +bool config_client_force_probe = false; +bool config_client_probe_steering = true; // steering contains learning already -bool client_probe_learning = false; +bool config_client_probe_learning = false; diff --git a/wireless/wifictld/src/config.h b/wireless/wifictld/src/config.h index d8aaeb6..4f3eebf 100644 --- a/wireless/wifictld/src/config.h +++ b/wireless/wifictld/src/config.h @@ -5,25 +5,26 @@ #define WIFI_CLIENT_FREQ_THREASHOLD 5000 -extern int verbose; +extern bool config_verbose; -extern int client_try_threashold; -extern int client_signal_threashold; +extern int config_client_try_threashold; +extern int config_client_signal_threashold; -extern int clean_every; -extern int clean_older_then; +extern int config_client_clean_every; +extern int config_client_clean_older_then; +extern bool config_client_clean_authed; // force (disable 2.4 Ghz) -extern bool client_force; +extern bool config_client_force; // force (disable 2.4 Ghz) for wifi probes -extern bool client_force_probe; +extern bool config_client_force_probe; // use client_try_threashold for probes, too -extern bool client_probe_steering; +extern bool config_client_probe_steering; /* steering contains learning already: when client_probe_steering is set, client_probe_learning is ignored */ -extern bool client_probe_learning; +extern bool config_client_probe_learning; #endif diff --git a/wireless/wifictld/src/include.h b/wireless/wifictld/src/include.h index 5be8329..1eee0fc 100644 --- a/wireless/wifictld/src/include.h +++ b/wireless/wifictld/src/include.h @@ -15,4 +15,5 @@ #include "hostapd/ieee802_11_defs.h" // ETH_ALEN + hwaddr_aton #include "hostapd/common.h" +#define blobmsg_add_bool blobmsg_add_u8 #endif diff --git a/wireless/wifictld/src/log.c b/wireless/wifictld/src/log.c index 0cfc655..ee05148 100644 --- a/wireless/wifictld/src/log.c +++ b/wireless/wifictld/src/log.c @@ -3,7 +3,7 @@ #ifdef DEBUG void log_debug(const char *format, ...) { - if (!verbose) + if (!config_verbose) return; va_list args; va_start(args, format); @@ -16,7 +16,7 @@ void log_debug(const char *format, ...) { #endif void log_verbose(const char *format, ...) { - if (!verbose) + if (!config_verbose) return; va_list args; va_start(args, format); diff --git a/wireless/wifictld/src/main.c b/wireless/wifictld/src/main.c index edd8e46..5aac203 100644 --- a/wireless/wifictld/src/main.c +++ b/wireless/wifictld/src/main.c @@ -18,7 +18,7 @@ int main(int argc, char *argv[]) while ((c = getopt(argc, argv, "v")) != -1) { switch (c) { case 'v': - verbose = 1; + config_verbose = 1; break; default: log_error("Invalid parameter %c ignored.\n", c); diff --git a/wireless/wifictld/src/ubus_events.c b/wireless/wifictld/src/ubus_events.c index 2a45fa3..180ae81 100644 --- a/wireless/wifictld/src/ubus_events.c +++ b/wireless/wifictld/src/ubus_events.c @@ -48,15 +48,22 @@ static void recieve_interfaces(struct ubus_context *ctx, struct ubus_object_data if (lenpath < lenpre || strncmp(path_prefix, obj->path, lenpre) != 0) { return; } + + /* create a copy of needed obj values + * to be safe for manipulation by ubus_invoke + */ + char *path = malloc((lenpath+1) * sizeof(char)); strncpy(path, obj->path, lenpath); path[lenpath] = '\0'; + int id = obj->id; + //change hostapd to wait for response struct blob_buf b = {}; blob_buf_init(&b, 0); blobmsg_add_u32(&b, str, 1); - ret = ubus_invoke(ctx, obj->id, str, b.head, NULL, NULL, 100); + ret = ubus_invoke(ctx, id, str, b.head, NULL, NULL, 100); blob_buf_free(&b); @@ -65,7 +72,7 @@ static void recieve_interfaces(struct ubus_context *ctx, struct ubus_object_data } //subscribe hostapd with THIS interface - ret = ubus_subscribe(ctx, &sub, obj->id); + ret = ubus_subscribe(ctx, &sub, id); if (ret) { log_error("Error while register subscribe for event '%s': %s\n", path, ubus_strerror(ret)); } @@ -111,7 +118,7 @@ static int receive_notify(struct ubus_context *ctx, struct ubus_object *obj, str } if (!strcmp(method, "probe")) { - if(client_probe_steering) { + if(config_client_probe_steering) { if (wifi_clients_try(false, addr, freq, ssi_signal)) { log_debug(" -> reject\n"); return WLAN_STATUS_UNSPECIFIED_FAILURE; @@ -119,7 +126,7 @@ static int receive_notify(struct ubus_context *ctx, struct ubus_object *obj, str log_debug(" -> accept\n"); return WLAN_STATUS_SUCCESS; } - if(client_probe_learning) { + if(config_client_probe_learning) { log_verbose(" learn"); wifi_clients_learn(addr, freq, ssi_signal); } diff --git a/wireless/wifictld/src/ubus_service.c b/wireless/wifictld/src/ubus_service.c index 50e78cd..c0bd5e0 100644 --- a/wireless/wifictld/src/ubus_service.c +++ b/wireless/wifictld/src/ubus_service.c @@ -22,11 +22,11 @@ static int ubus_get_clients(struct ubus_context *ctx, struct ubus_object *obj, sprintf(mac_buf, MACSTR, MAC2STR(el->addr)); c = blobmsg_open_table(&b, mac_buf); + blobmsg_add_u32(&b, "time", el->time); blobmsg_add_u32(&b, "try_probe", el->try_probe); blobmsg_add_u32(&b, "try_auth", el->try_auth); - blobmsg_add_u32(&b, "time", el->time); - blobmsg_add_u32(&b, "authed", el->authed); blobmsg_add_u32(&b, "connected", el->connected); + blobmsg_add_u32(&b, "authed", el->authed); blobmsg_add_u32(&b, "freq_highest", el->freq_highest); blobmsg_add_u32(&b, "signal_lowfreq", el->signal_lowfreq); blobmsg_add_u32(&b, "signal_highfreq", el->signal_highfreq); @@ -69,102 +69,20 @@ static int ubus_del_client(struct ubus_context *ctx, struct ubus_object *obj, return 0; } -static int ubus_get_client_threasholds(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, struct blob_attr *msg) -{ - blob_buf_init(&b, 0); - - blobmsg_add_u32(&b, "try", client_try_threashold); - blobmsg_add_u32(&b, "signal", client_signal_threashold); - - ubus_send_reply(ctx, req, b.head); - - return 0; -} - - -enum { - SET_CLIENT_TRY_THREASHOLD, - SET_CLIENT_SIGNAL_THREASHOLD, - __SET_CLIENT_THREASHOLD_VALUE_MAX -}; - -static const struct blobmsg_policy ubus_set_client_threashold_policy[__SET_CLIENT_THREASHOLD_VALUE_MAX] = { - [SET_CLIENT_TRY_THREASHOLD] = { "try", BLOBMSG_TYPE_INT32 }, - [SET_CLIENT_SIGNAL_THREASHOLD] = { "signal", BLOBMSG_TYPE_INT32 }, -}; - -static int ubus_set_client_threashold(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, struct blob_attr *msg) -{ - struct blob_attr *tb[__SET_CLIENT_THREASHOLD_VALUE_MAX]; - - blobmsg_parse(ubus_set_client_threashold_policy, __SET_CLIENT_THREASHOLD_VALUE_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[SET_CLIENT_TRY_THREASHOLD] && - !tb[SET_CLIENT_SIGNAL_THREASHOLD]) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[SET_CLIENT_TRY_THREASHOLD]) - client_try_threashold = blobmsg_get_u32(tb[SET_CLIENT_TRY_THREASHOLD]); - if (tb[SET_CLIENT_SIGNAL_THREASHOLD]) - client_signal_threashold = blobmsg_get_u32(tb[SET_CLIENT_SIGNAL_THREASHOLD]); - - return 0; -} - -static int ubus_get_clean_values(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, struct blob_attr *msg) -{ - blob_buf_init(&b, 0); - - blobmsg_add_u32(&b, "every", clean_every); - blobmsg_add_u32(&b, "older_then", clean_older_then); - - ubus_send_reply(ctx, req, b.head); - - return 0; -} - - -enum { - SET_CLEAN_EVERY, - SET_CLEAN_OLDER_THEN, - __SET_CLEAN_VALUES_MAX -}; - -static const struct blobmsg_policy ubus_set_clean_values_policy[__SET_CLEAN_VALUES_MAX] = { - [SET_CLEAN_EVERY] = { "every", BLOBMSG_TYPE_INT32 }, - [SET_CLEAN_OLDER_THEN] = { "older_then", BLOBMSG_TYPE_INT32 }, -}; - -static int ubus_set_clean_values(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, struct blob_attr *msg) -{ - struct blob_attr *tb[__SET_CLEAN_VALUES_MAX]; - - blobmsg_parse(ubus_set_clean_values_policy, __SET_CLEAN_VALUES_MAX, tb, blob_data(msg), blob_len(msg)); - - if (!tb[SET_CLEAN_EVERY] && - !tb[SET_CLEAN_OLDER_THEN]) - return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[SET_CLEAN_EVERY]) - clean_every = blobmsg_get_u32(tb[SET_CLEAN_EVERY]); - if (tb[SET_CLEAN_OLDER_THEN]) - clean_older_then = blobmsg_get_u32(tb[SET_CLEAN_OLDER_THEN]); - - return 0; -} - - static int ubus_get_config(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { blob_buf_init(&b, 0); - - blobmsg_add_u32(&b, "every", clean_every); - blobmsg_add_u32(&b, "older_then", clean_older_then); + blobmsg_add_bool(&b, "verbose", config_verbose); + blobmsg_add_u32(&b, "client_try_threashold", config_client_try_threashold); + blobmsg_add_u32(&b, "client_signal_threashold", config_client_signal_threashold); + blobmsg_add_u32(&b, "client_clean_every", config_client_clean_every); + blobmsg_add_u32(&b, "client_clean_older_then", config_client_clean_older_then); + blobmsg_add_bool(&b, "client_clean_authed", config_client_clean_authed); + blobmsg_add_bool(&b, "client_force", config_client_force); + blobmsg_add_bool(&b, "client_force_probe", config_client_force_probe); + blobmsg_add_bool(&b, "client_probe_steering", config_client_probe_steering); + blobmsg_add_bool(&b, "client_probe_learning", config_client_probe_learning); ubus_send_reply(ctx, req, b.head); @@ -173,18 +91,30 @@ static int ubus_get_config(struct ubus_context *ctx, struct ubus_object *obj, enum { - SET_CONFIG_FORCE, - SET_CONFIG_FORCE_PROBE, - SET_CONFIG_PROBE_STEERING, - SET_CONFIG_PROBE_LEARNING, + SET_CONFIG_VERBOSE, + SET_CONFIG_CLIENT_TRY_THREASHOLD, + SET_CONFIG_CLIENT_SIGNAL_THREASHOLD, + SET_CONFIG_CLIENT_CLEAN_EVERY, + SET_CONFIG_CLIENT_CLEAN_OLDER_THEN, + SET_CONFIG_CLIENT_CLEAN_AUTHED, + SET_CONFIG_CLIENT_FORCE, + SET_CONFIG_CLIENT_FORCE_PROBE, + SET_CONFIG_CLIENT_PROBE_STEERING, + SET_CONFIG_CLIENT_PROBE_LEARNING, __SET_CONFIG_MAX }; static const struct blobmsg_policy ubus_set_config_policy[__SET_CONFIG_MAX] = { - [SET_CONFIG_FORCE] = { "force", BLOBMSG_TYPE_BOOL }, - [SET_CONFIG_FORCE_PROBE] = { "force_probe", BLOBMSG_TYPE_BOOL }, - [SET_CONFIG_PROBE_STEERING] = { "probe_steering", BLOBMSG_TYPE_BOOL }, - [SET_CONFIG_PROBE_LEARNING] = { "probe_learning", BLOBMSG_TYPE_BOOL }, + [SET_CONFIG_VERBOSE] = { "verbose", BLOBMSG_TYPE_BOOL }, + [SET_CONFIG_CLIENT_TRY_THREASHOLD] = { "client_try_threashold", BLOBMSG_TYPE_INT32 }, + [SET_CONFIG_CLIENT_SIGNAL_THREASHOLD] = { "client_signal_threashold", BLOBMSG_TYPE_INT32 }, + [SET_CONFIG_CLIENT_CLEAN_EVERY] = { "client_clean_every", BLOBMSG_TYPE_INT32 }, + [SET_CONFIG_CLIENT_CLEAN_OLDER_THEN] = { "client_clean_older_then", BLOBMSG_TYPE_INT32 }, + [SET_CONFIG_CLIENT_CLEAN_AUTHED] = { "client_clean_authed", BLOBMSG_TYPE_BOOL }, + [SET_CONFIG_CLIENT_FORCE] = { "client_force", BLOBMSG_TYPE_BOOL }, + [SET_CONFIG_CLIENT_FORCE_PROBE] = { "client_force_probe", BLOBMSG_TYPE_BOOL }, + [SET_CONFIG_CLIENT_PROBE_STEERING] = { "client_probe_steering", BLOBMSG_TYPE_BOOL }, + [SET_CONFIG_CLIENT_PROBE_LEARNING] = { "client_probe_learning", BLOBMSG_TYPE_BOOL }, }; static int ubus_set_config(struct ubus_context *ctx, struct ubus_object *obj, @@ -194,20 +124,37 @@ static int ubus_set_config(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_parse(ubus_set_config_policy, __SET_CONFIG_MAX, tb, blob_data(msg), blob_len(msg)); - if (!tb[SET_CONFIG_FORCE] && - !tb[SET_CONFIG_FORCE_PROBE] && - !tb[SET_CONFIG_PROBE_STEERING] && - !tb[SET_CONFIG_PROBE_LEARNING]) + if (!tb[SET_CONFIG_VERBOSE] && + !tb[SET_CONFIG_CLIENT_TRY_THREASHOLD] && + !tb[SET_CONFIG_CLIENT_SIGNAL_THREASHOLD] && + !tb[SET_CONFIG_CLIENT_CLEAN_EVERY] && + !tb[SET_CONFIG_CLIENT_CLEAN_OLDER_THEN] && + !tb[SET_CONFIG_CLIENT_CLEAN_AUTHED] && + !tb[SET_CONFIG_CLIENT_FORCE] && + !tb[SET_CONFIG_CLIENT_FORCE_PROBE] && + !tb[SET_CONFIG_CLIENT_PROBE_STEERING] && + !tb[SET_CONFIG_CLIENT_PROBE_LEARNING]) return UBUS_STATUS_INVALID_ARGUMENT; - - if (tb[SET_CONFIG_FORCE]) - client_force = blobmsg_get_bool(tb[SET_CONFIG_FORCE]); - if (tb[SET_CONFIG_FORCE_PROBE]) - client_force_probe = blobmsg_get_bool(tb[SET_CONFIG_FORCE_PROBE]); - if (tb[SET_CONFIG_PROBE_STEERING]) - client_probe_steering = blobmsg_get_bool(tb[SET_CONFIG_PROBE_STEERING]); - if (tb[SET_CONFIG_PROBE_LEARNING]) - client_probe_learning = blobmsg_get_bool(tb[SET_CONFIG_PROBE_LEARNING]); + if (tb[SET_CONFIG_VERBOSE]) + config_verbose = blobmsg_get_bool(tb[SET_CONFIG_VERBOSE]); + if (tb[SET_CONFIG_CLIENT_TRY_THREASHOLD]) + config_client_try_threashold = blobmsg_get_u32(tb[SET_CONFIG_CLIENT_TRY_THREASHOLD]); + if (tb[SET_CONFIG_CLIENT_SIGNAL_THREASHOLD]) + config_client_signal_threashold = blobmsg_get_u32(tb[SET_CONFIG_CLIENT_SIGNAL_THREASHOLD]); + if (tb[SET_CONFIG_CLIENT_CLEAN_EVERY]) + config_client_clean_every = blobmsg_get_u32(tb[SET_CONFIG_CLIENT_CLEAN_EVERY]); + if (tb[SET_CONFIG_CLIENT_CLEAN_OLDER_THEN]) + config_client_clean_older_then = blobmsg_get_u32(tb[SET_CONFIG_CLIENT_CLEAN_OLDER_THEN]); + if (tb[SET_CONFIG_CLIENT_CLEAN_AUTHED]) + config_client_clean_authed = blobmsg_get_bool(tb[SET_CONFIG_CLIENT_CLEAN_AUTHED]); + if (tb[SET_CONFIG_CLIENT_FORCE]) + config_client_force = blobmsg_get_bool(tb[SET_CONFIG_CLIENT_FORCE]); + if (tb[SET_CONFIG_CLIENT_FORCE_PROBE]) + config_client_force_probe = blobmsg_get_bool(tb[SET_CONFIG_CLIENT_FORCE_PROBE]); + if (tb[SET_CONFIG_CLIENT_PROBE_STEERING]) + config_client_probe_steering = blobmsg_get_bool(tb[SET_CONFIG_CLIENT_PROBE_STEERING]); + if (tb[SET_CONFIG_CLIENT_PROBE_LEARNING]) + config_client_probe_learning = blobmsg_get_bool(tb[SET_CONFIG_CLIENT_PROBE_LEARNING]); return 0; } @@ -220,14 +167,6 @@ static const struct ubus_method wifictld_ubus_methods[] = { UBUS_METHOD_NOARG("get_clients", ubus_get_clients), UBUS_METHOD("del_client", ubus_del_client, ubus_del_client_policy), - // client threasholds - UBUS_METHOD_NOARG("get_client_threasholds", ubus_get_client_threasholds), - UBUS_METHOD("set_client_threasholds", ubus_set_client_threashold, ubus_set_client_threashold_policy), - - // client threasholds - UBUS_METHOD_NOARG("get_clean_values", ubus_get_clean_values), - UBUS_METHOD("set_clean_values", ubus_set_clean_values, ubus_set_clean_values_policy), - // config threasholds UBUS_METHOD_NOARG("get_config", ubus_get_config), UBUS_METHOD("set_config", ubus_set_config, ubus_set_config_policy), diff --git a/wireless/wifictld/src/wifi_clients.c b/wireless/wifictld/src/wifi_clients.c index eddbcb8..7374cd8 100644 --- a/wireless/wifictld/src/wifi_clients.c +++ b/wireless/wifictld/src/wifi_clients.c @@ -8,26 +8,37 @@ void clean_cbhandler(struct uloop_timeout *t) { int count = 0, + auth = 0, all = 0; time_t now; time(&now); - now -= clean_older_then; + now -= config_client_clean_older_then; struct wifi_client *client, *ptr; avl_for_each_element_safe(&clients_by_addr, client, avl, ptr) { - if (client->time < now && client->authed == 0) { + all++; + if(!config_client_clean_authed && client->authed) { + auth++; + continue; + } + if (client->time < now) { avl_delete(&clients_by_addr, &client->avl); log_verbose("clean_client(): "MACSTR" remove from memory\n", MAC2STR(client->addr)); free(client); count++; } - all++; } - uloop_timeout_set(t, clean_every * 1000); + uloop_timeout_set(t, config_client_clean_every * 1000); if (count > 0) { - log_info("remove %d/%d clients from memory\n", count, all); + log_info("remove %d of %d clients", count, all); + if(!config_client_clean_authed) + log_info(" (skipped %d authed clients)\n", auth); + log_info(" from memory\n"); }else{ - log_verbose("remove %d/%d clients from memory\n", count, all); + log_verbose("remove %d of %d clients", count, all); + if(!config_client_clean_authed) + log_verbose(" (skipped %d authed clients)\n", auth); + log_verbose(" from memory\n"); } } @@ -42,7 +53,7 @@ static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) int wifi_clients_init() { avl_init(&clients_by_addr, avl_compare_macaddr, false, NULL); - uloop_timeout_set(&clean, clean_every * 1000); + uloop_timeout_set(&clean, config_client_clean_every * 1000); uloop_timeout_add(&clean); return 0; } @@ -108,7 +119,7 @@ int wifi_clients_try(bool auth, const u8 *address, uint32_t freq, uint32_t ssi_s client->try_auth++; client->try_probe = 0; }else{ - if(client_force_probe){ + if(config_client_force_probe){ log_verbose("probe(try=%d mac="MACSTR" freq=%d ssi=%d): ", client->try_auth, MAC2STR(address), freq, ssi_signal); }else{ log_verbose("probe(try=%d mac="MACSTR" freq=%d ssi=%d): ", client->try_probe, MAC2STR(address), freq, ssi_signal); @@ -128,7 +139,7 @@ int wifi_clients_try(bool auth, const u8 *address, uint32_t freq, uint32_t ssi_s return 0; } if (client->freq_highest > WIFI_CLIENT_FREQ_THREASHOLD) { - if (client_force || client_force_probe && !auth) { + if (config_client_force || config_client_force_probe && !auth) { if(!auth){ log_verbose("reject - force\n"); return -1; @@ -137,7 +148,7 @@ int wifi_clients_try(bool auth, const u8 *address, uint32_t freq, uint32_t ssi_s return -1; } - if (ssi_signal > client_signal_threashold) { + if (ssi_signal > config_client_signal_threashold) { if(!auth){ log_verbose("reject - learned higher freq + ssi is high enough\n"); return -1; @@ -147,8 +158,8 @@ int wifi_clients_try(bool auth, const u8 *address, uint32_t freq, uint32_t ssi_s } } - if(auth && client->try_auth > client_try_threashold || - !auth && client->try_probe > client_try_threashold + if(auth && client->try_auth > config_client_try_threashold || + !auth && client->try_probe > config_client_try_threashold ) { if(!auth){ client->try_probe = 0;