first complete network stack version
This commit is contained in:
parent
a4961cc6f2
commit
2349afd777
|
@ -16,5 +16,6 @@ bool config_client_probe_steering = true;
|
||||||
bool config_client_probe_learning = false;
|
bool config_client_probe_learning = false;
|
||||||
|
|
||||||
#ifndef MINI
|
#ifndef MINI
|
||||||
|
bool config_client_socket_learning = true;
|
||||||
|
bool config_socket_always_answer = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,7 +28,8 @@ extern bool config_client_probe_steering;
|
||||||
extern bool config_client_probe_learning;
|
extern bool config_client_probe_learning;
|
||||||
|
|
||||||
#ifndef MINI
|
#ifndef MINI
|
||||||
|
extern bool config_client_socket_learning;
|
||||||
|
extern bool config_socket_always_answer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,11 +27,16 @@ struct option longopts[] = {
|
||||||
{"clean-every", required_argument, 0, 3},
|
{"clean-every", required_argument, 0, 3},
|
||||||
{"clean-older-then", required_argument, 0, 4},
|
{"clean-older-then", required_argument, 0, 4},
|
||||||
{"clean-authed", optional_argument, 0, 5},
|
{"clean-authed", optional_argument, 0, 5},
|
||||||
|
#ifndef MINI
|
||||||
// network options
|
// network options
|
||||||
{"addr", required_argument, 0, 6},
|
{"addr", required_argument, 0, 6},
|
||||||
{"maddr", required_argument, 0, 7},
|
{"maddr", required_argument, 0, 7},
|
||||||
{"port", required_argument, 0, 8},
|
{"port", required_argument, 0, 8},
|
||||||
{"ifname", required_argument, 0, 9},
|
{"ifname", required_argument, 0, 9},
|
||||||
|
// other extended option
|
||||||
|
{"socket-learning", optional_argument, 0, 10},
|
||||||
|
{"socket-always-answer", optional_argument, 0, 11},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void usage(int c) {
|
void usage(int c) {
|
||||||
|
@ -54,11 +59,16 @@ void usage(int c) {
|
||||||
printf(" --clean-every run cleaning every (current: %ds)\n", config_client_clean_every);
|
printf(" --clean-every run cleaning every (current: %ds)\n", config_client_clean_every);
|
||||||
printf(" --clean-older-then clean unseen for secound (current: %ds)\n", config_client_clean_older_then);
|
printf(" --clean-older-then clean unseen for secound (current: %ds)\n", config_client_clean_older_then);
|
||||||
printf(" --clean-authed clean already authed also (not only learned by probes) (current: %s)\n", BOOL2STR(config_client_clean_authed));
|
printf(" --clean-authed clean already authed also (not only learned by probes) (current: %s)\n", BOOL2STR(config_client_clean_authed));
|
||||||
|
#ifndef MINI
|
||||||
printf("\nnetwork options:\n");
|
printf("\nnetwork options:\n");
|
||||||
printf(" --addr listen on ip address (current: %s)\n", addr);
|
printf(" --addr listen on ip address (current: %s)\n", addr);
|
||||||
printf(" --maddr listen and request on multcast address (current: %s)\n", maddr);
|
printf(" --maddr listen and request on multcast address (current: %s)\n", maddr);
|
||||||
printf(" --port listen on port (current: %s)\n", port);
|
printf(" --port listen on port (current: %s)\n", port);
|
||||||
printf(" --ifname listen on interface for multicast (current: %s)\n", ifname);
|
printf(" --ifname listen on interface for multicast (current: %s)\n", ifname);
|
||||||
|
printf("\nother extended options:\n");
|
||||||
|
printf(" --socket-learning learn clients during listen on socket (current: %s)\n", BOOL2STR(config_client_socket_learning));
|
||||||
|
printf(" --socket-always-answer answer on socket only with useful information (current: %s)\n", BOOL2STR(config_socket_always_answer));
|
||||||
|
#endif
|
||||||
printf("\nSome config could be changed by ubus, see `ubus -v list wifictld`\n");
|
printf("\nSome config could be changed by ubus, see `ubus -v list wifictld`\n");
|
||||||
if(c)
|
if(c)
|
||||||
printf("Invalid parameter %c ignored.\n", c);
|
printf("Invalid parameter %c ignored.\n", c);
|
||||||
|
@ -143,6 +153,7 @@ int main(int argc, char *argv[])
|
||||||
else
|
else
|
||||||
config_client_clean_authed = !config_client_clean_authed;
|
config_client_clean_authed = !config_client_clean_authed;
|
||||||
break;
|
break;
|
||||||
|
#ifndef MINI
|
||||||
// network options
|
// network options
|
||||||
case 6:
|
case 6:
|
||||||
addr = optarg;
|
addr = optarg;
|
||||||
|
@ -156,6 +167,20 @@ int main(int argc, char *argv[])
|
||||||
case 9:
|
case 9:
|
||||||
ifname = optarg;
|
ifname = optarg;
|
||||||
break;
|
break;
|
||||||
|
// other extended option
|
||||||
|
case 10:
|
||||||
|
if(optarg)
|
||||||
|
config_client_socket_learning = atoi(optarg);
|
||||||
|
else
|
||||||
|
config_client_socket_learning = !config_client_socket_learning;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
if(optarg)
|
||||||
|
config_socket_always_answer = atoi(optarg);
|
||||||
|
else
|
||||||
|
config_socket_always_answer = !config_socket_always_answer;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
usage(c);
|
usage(c);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#include "include.h"
|
#include "include.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "data.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "socket_msg.h"
|
#include "socket_msg.h"
|
||||||
|
#include "socket_handler.h"
|
||||||
|
|
||||||
static struct uloop_fd server;
|
static struct uloop_fd server;
|
||||||
struct in6_addr ownaddr;
|
struct sockaddr_in6 ownaddr;
|
||||||
struct sockaddr_in6 client_addr;
|
struct sockaddr_in6 client_addr;
|
||||||
|
|
||||||
int socket_info(struct socket_msg *info) {
|
int socket_info(struct socket_msg *info) {
|
||||||
|
@ -13,14 +15,16 @@ int socket_info(struct socket_msg *info) {
|
||||||
|
|
||||||
ret = socket_msg_marshal(info, msg);
|
ret = socket_msg_marshal(info, msg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
log_error("socket_request: could not marshel message: %d\n", ret);
|
log_error("socket_info: could not marshel message: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sendto(server.fd, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&client_addr, sizeof(client_addr));
|
ret = sendto(server.fd, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&client_addr, sizeof(client_addr));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
log_error("socket_request: could not send message: %d\n", ret);
|
log_error("socket_info: could not send message: %d\n", ret);
|
||||||
}
|
}
|
||||||
|
if(info->type & SOCKET_MSG_TYPE_CLIENT)
|
||||||
|
log_verbose("net-send(type=client mac="MACSTR" freq=%d ssi_l=%d ssi_h=%d tprobe=%d tauth=%d authed=%s time=%d)\n", MAC2STR(info->client->addr), info->client->freq_highest, info->client->signal_lowfreq, info->client->signal_highfreq, info->client->try_probe, info->client->try_auth, BOOL2STR(info->client->authed), info->client->time);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +46,11 @@ int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(bind(sock, (struct sockaddr*)&ownaddr, sizeof(ownaddr))) {
|
||||||
|
log_error("socket_request: could not bind to addr\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int loop = 0;
|
int loop = 0;
|
||||||
if(setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) {
|
if(setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) {
|
||||||
|
@ -55,7 +64,10 @@ int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer
|
||||||
log_error("socket_request: could not send message: %d\n", ret);
|
log_error("socket_request: could not send message: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if(request->type & SOCKET_MSG_TYPE_CLIENT)
|
||||||
|
log_verbose("net-send(type=request,client mac="MACSTR" freq=%d ssi_l=%d ssi_h=%d tprobe=%d tauth=%d authed=%s time=%d)\n", MAC2STR(request->client->addr), request->client->freq_highest, request->client->signal_lowfreq, request->client->signal_highfreq, request->client->try_probe, request->client->try_auth, BOOL2STR(request->client->authed), request->client->time);
|
||||||
|
|
||||||
|
// repeat to recieve best answer till timeout
|
||||||
ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,sizeof(timeout));
|
ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,sizeof(timeout));
|
||||||
if(ret < 0) {
|
if(ret < 0) {
|
||||||
close(sock);
|
close(sock);
|
||||||
|
@ -78,22 +90,30 @@ int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_verbose("socket_request: end %d\n", ret);
|
|
||||||
if (answer->type & SOCKET_MSG_TYPE_RESPONSE) {
|
if (answer->type & SOCKET_MSG_TYPE_RESPONSE) {
|
||||||
|
if(answer->type & SOCKET_MSG_TYPE_CLIENT)
|
||||||
|
log_verbose("net-recv(type=response,client mac="MACSTR" freq=%d ssi_l=%d ssi_h=%d tprobe=%d tauth=%d authed=%s time=%d)\n", MAC2STR(answer->client->addr), answer->client->freq_highest, answer->client->signal_lowfreq, answer->client->signal_highfreq, answer->client->try_probe, answer->client->try_auth, BOOL2STR(answer->client->authed), answer->client->time);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
log_verbose("socket_request: end %d\n", ret);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void server_cb(struct uloop_fd *fd, unsigned int events) {
|
static void server_cb(struct uloop_fd *fd, unsigned int events) {
|
||||||
|
int ret;
|
||||||
struct sockaddr_in6 addr;
|
struct sockaddr_in6 addr;
|
||||||
char buf[REQUEST_MAXLEN];
|
|
||||||
char control[256];
|
char control[256];
|
||||||
|
char buf[REQUEST_MAXLEN];
|
||||||
|
|
||||||
|
struct socket_msg msg = {
|
||||||
|
.type = 0,
|
||||||
|
.client = malloc(sizeof(struct wifi_client)),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct iovec iv = {
|
struct iovec iv = {
|
||||||
.iov_base = buf,
|
.iov_base = buf,
|
||||||
.iov_len = sizeof(buf) - 1
|
.iov_len = sizeof(buf)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msghdr mh = {
|
struct msghdr mh = {
|
||||||
|
@ -110,15 +130,38 @@ static void server_cb(struct uloop_fd *fd, unsigned int events) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char addr_str[INET6_ADDRSTRLEN];
|
ret = socket_msg_unmarshal(&msg, buf);
|
||||||
inet_ntop(AF_INET6, &(addr.sin6_addr), addr_str, INET6_ADDRSTRLEN);
|
if (ret) {
|
||||||
log_info("socket:recv [%s]:%d - %s\n", addr_str, ntohs(addr.sin6_port), buf);
|
log_error("socket: could not unmarshel message: %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log_verbose("net-recv(type=");
|
||||||
|
if(msg.type & SOCKET_MSG_TYPE_REQUEST)
|
||||||
|
log_verbose("request,");
|
||||||
|
if(msg.type & SOCKET_MSG_TYPE_RESPONSE)
|
||||||
|
log_verbose("response,");
|
||||||
|
if(msg.type & SOCKET_MSG_TYPE_CLIENT)
|
||||||
|
log_verbose("client mac="MACSTR" freq=%d ssi_l=%d ssi_h=%d tprobe=%d tauth=%d authed=%s time=%d)\n", MAC2STR(msg.client->addr), msg.client->freq_highest, msg.client->signal_lowfreq, msg.client->signal_highfreq, msg.client->try_probe, msg.client->try_auth, BOOL2STR(msg.client->authed), msg.client->time);
|
||||||
|
|
||||||
|
// response only if message are recieve
|
||||||
|
ret = socket_handler(&msg);
|
||||||
|
if (ret != SOCKET_HANDLER_RESPONSE) {
|
||||||
|
if(ret == SOCKET_HANDLER_ERROR)
|
||||||
|
log_error("socket_handler: returned with %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (sendto(server.fd, addr_str, sizeof(addr_str) - 1, 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
ret = socket_msg_marshal(&msg, buf);
|
||||||
|
if (ret) {
|
||||||
|
log_error("socket: could not unmarshel message: %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sendto(server.fd, buf, sizeof(buf), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||||
log_error("socket: could not send answer\n");
|
log_error("socket: could not send answer\n");
|
||||||
}
|
}
|
||||||
log_info("socket: send answer\n");
|
if(msg.type & SOCKET_MSG_TYPE_CLIENT)
|
||||||
|
log_verbose("net-send(type=response,client mac="MACSTR" freq=%d ssi_l=%d ssi_h=%d tprobe=%d tauth=%d authed=%s time=%d)\n", MAC2STR(msg.client->addr), msg.client->freq_highest, msg.client->signal_lowfreq, msg.client->signal_highfreq, msg.client->try_probe, msg.client->try_auth, BOOL2STR(msg.client->authed), msg.client->time);
|
||||||
}
|
}
|
||||||
|
|
||||||
int socket_init(char *ifname, char *socket_bind, char *socket_maddr, char *socket_port) {
|
int socket_init(char *ifname, char *socket_bind, char *socket_maddr, char *socket_port) {
|
||||||
|
@ -132,6 +175,14 @@ int socket_init(char *ifname, char *socket_bind, char *socket_maddr, char *socke
|
||||||
client_addr.sin6_port = htons(atoi(socket_port));
|
client_addr.sin6_port = htons(atoi(socket_port));
|
||||||
client_addr.sin6_scope_id = if_nametoindex(ifname);
|
client_addr.sin6_scope_id = if_nametoindex(ifname);
|
||||||
|
|
||||||
|
ownaddr.sin6_family = AF_INET6;
|
||||||
|
ownaddr.sin6_scope_id = client_addr.sin6_scope_id;
|
||||||
|
|
||||||
|
if(!inet_pton(AF_INET6, socket_bind, &ownaddr.sin6_addr)) {
|
||||||
|
log_error("socket: could not parse address for socket_request\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// listen multicast
|
// listen multicast
|
||||||
if (!inet_pton(AF_INET6, socket_maddr, &client_addr.sin6_addr)) {
|
if (!inet_pton(AF_INET6, socket_maddr, &client_addr.sin6_addr)) {
|
||||||
log_error("socket: invalid multicast group\n");
|
log_error("socket: invalid multicast group\n");
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
#include "config.h"
|
||||||
|
#include "include.h"
|
||||||
|
#include "data.h"
|
||||||
|
#include "socket_msg.h"
|
||||||
|
#include "socket_handler.h"
|
||||||
|
|
||||||
|
static int handle_client(struct socket_msg *msg, int response) {
|
||||||
|
struct wifi_client *own_client;
|
||||||
|
|
||||||
|
own_client = avl_find_element(&clients_by_addr, msg->client->addr, own_client, avl);
|
||||||
|
if (own_client) {
|
||||||
|
// know client with higher freq
|
||||||
|
if (own_client->freq_highest < msg->client->freq_highest) {
|
||||||
|
return SOCKET_HANDLER_RESPONSE;
|
||||||
|
}
|
||||||
|
// learn freq
|
||||||
|
if (own_client->freq_highest < msg->client->freq_highest) {
|
||||||
|
own_client->freq_highest = msg->client->freq_highest;
|
||||||
|
}
|
||||||
|
if (!own_client->authed) {
|
||||||
|
own_client->authed = msg->client->authed;
|
||||||
|
}
|
||||||
|
if (own_client->time < msg->client->time) {
|
||||||
|
own_client->time = msg->client->time;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
if(!config_client_socket_learning)
|
||||||
|
return SOCKET_HANDLER_SILENCE;
|
||||||
|
// learn client
|
||||||
|
msg->client->try_probe = 0;
|
||||||
|
msg->client->try_auth = 0;
|
||||||
|
msg->client->connected = false;
|
||||||
|
|
||||||
|
msg->client->avl.key = msg->client->addr;
|
||||||
|
avl_insert(&clients_by_addr, &msg->client->avl);
|
||||||
|
return SOCKET_HANDLER_SILENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socket_handler(struct socket_msg *msg) {
|
||||||
|
if(msg->type & SOCKET_MSG_TYPE_RESPONSE) {
|
||||||
|
return SOCKET_HANDLER_ERROR;
|
||||||
|
}
|
||||||
|
int ret = SOCKET_HANDLER_RESPONSE;
|
||||||
|
if(msg->type & SOCKET_MSG_TYPE_REQUEST) {
|
||||||
|
msg->type = (msg->type ^ SOCKET_MSG_TYPE_REQUEST) | SOCKET_MSG_TYPE_RESPONSE;
|
||||||
|
|
||||||
|
// single handlers
|
||||||
|
if(msg->type & SOCKET_MSG_TYPE_CLIENT) ret = handle_client(msg, SOCKET_HANDLER_RESPONSE);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// single handlers
|
||||||
|
if(msg->type & SOCKET_MSG_TYPE_CLIENT) ret = handle_client(msg, SOCKET_HANDLER_SILENCE);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef __WIFICTLD_SOCKET_HANDLER_H
|
||||||
|
#define __WIFICTLD_SOCKET_HANDLER_H
|
||||||
|
|
||||||
|
#include "socket_msg.h"
|
||||||
|
|
||||||
|
#define SOCKET_HANDLER_ERROR 2
|
||||||
|
#define SOCKET_HANDLER_SILENCE 1
|
||||||
|
#define SOCKET_HANDLER_RESPONSE 0
|
||||||
|
|
||||||
|
int socket_handler(struct socket_msg *info);
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,7 +21,7 @@ int wifictld_ubus_init()
|
||||||
// connect to ubus
|
// connect to ubus
|
||||||
ctx = ubus_connect(UBUS_SOCKET);
|
ctx = ubus_connect(UBUS_SOCKET);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
log_error("Failed to connect to ubus");
|
log_error("failed to connect to ubus\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,14 +31,14 @@ int wifictld_ubus_init()
|
||||||
// add bbs
|
// add bbs
|
||||||
ret = wifictld_ubus_add_bss(ctx);
|
ret = wifictld_ubus_add_bss(ctx);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
log_error("Failed to add ubus service");
|
log_error("failed to add ubus service\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind events
|
// bind events
|
||||||
ret = wifictld_ubus_bind_events(ctx);
|
ret = wifictld_ubus_bind_events(ctx);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
log_error("Failed to bind for ubus events");
|
log_error("failed to bind for ubus events\n");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ int wifictld_ubus_bind_events(struct ubus_context *ctx)
|
||||||
// register subscriber on ubus
|
// register subscriber on ubus
|
||||||
int ret = ubus_register_subscriber(ctx, &sub);
|
int ret = ubus_register_subscriber(ctx, &sub);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
log_error("Error while registering subscriber: %s", ubus_strerror(ret));
|
log_error("error while registering subscriber: %s\n", ubus_strerror(ret));
|
||||||
ubus_free(ctx);
|
ubus_free(ctx);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -138,38 +138,33 @@ static int receive_notify(struct ubus_context *ctx, struct ubus_object *obj, str
|
||||||
|
|
||||||
|
|
||||||
// handle
|
// handle
|
||||||
log_verbose("%s["MACSTR"] freq: %d signal %d", method, MAC2STR(addr), hclient.freq, hclient.ssi_signal);
|
|
||||||
if (!strcmp(method, "auth")) {
|
if (!strcmp(method, "auth")) {
|
||||||
hclient.auth = true;
|
hclient.auth = true;
|
||||||
if (wifi_clients_try(&hclient)) {
|
if (wifi_clients_try(&hclient)) {
|
||||||
log_verbose(" -> reject\n");
|
log_verbose("%s["MACSTR"] freq: %d signal %d -> reject\n", method, MAC2STR(addr), hclient.freq, hclient.ssi_signal);
|
||||||
return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
|
return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
|
||||||
}
|
}
|
||||||
log_verbose(" -> accept\n");
|
log_verbose("%s["MACSTR"] freq: %d signal %d -> accept\n", method, MAC2STR(addr), hclient.freq, hclient.ssi_signal);
|
||||||
return WLAN_STATUS_SUCCESS;
|
return WLAN_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(method, "probe")) {
|
if (!strcmp(method, "probe")) {
|
||||||
if(config_client_probe_steering) {
|
if(config_client_probe_steering) {
|
||||||
if (wifi_clients_try(&hclient)) {
|
if (wifi_clients_try(&hclient)) {
|
||||||
log_verbose(" -> reject\n");
|
log_verbose("%s["MACSTR"] freq: %d signal %d -> reject\n", method, MAC2STR(addr), hclient.freq, hclient.ssi_signal);
|
||||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
}
|
}
|
||||||
log_verbose(" -> accept\n");
|
log_verbose("%s["MACSTR"] freq: %d signal %d -> accept\n", method, MAC2STR(addr), hclient.freq, hclient.ssi_signal);
|
||||||
return WLAN_STATUS_SUCCESS;
|
return WLAN_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
if(config_client_probe_learning) {
|
if(config_client_probe_learning) {
|
||||||
log_verbose(" learn");
|
log_verbose("%s["MACSTR"] freq: %d signal %d -> learn\n", method, MAC2STR(addr), hclient.freq, hclient.ssi_signal);
|
||||||
wifi_clients_learn(&hclient);
|
wifi_clients_learn(&hclient);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (!strcmp(method, "deauth")) {
|
|
||||||
wifi_clients_disconnect(&hclient);
|
wifi_clients_disconnect(&hclient);
|
||||||
log_verbose(" -> disconnect\n");
|
log_verbose("%s["MACSTR"] freq: %d signal %d -> disconnect\n", method, MAC2STR(addr), hclient.freq, hclient.ssi_signal);
|
||||||
return WLAN_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
log_verbose("\n");
|
|
||||||
|
|
||||||
return WLAN_STATUS_SUCCESS;
|
return WLAN_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,8 @@ static int ubus_get_config(struct ubus_context *ctx, struct ubus_object *obj,
|
||||||
blobmsg_add_bool(&b, "client_probe_steering", config_client_probe_steering);
|
blobmsg_add_bool(&b, "client_probe_steering", config_client_probe_steering);
|
||||||
blobmsg_add_bool(&b, "client_probe_learning", config_client_probe_learning);
|
blobmsg_add_bool(&b, "client_probe_learning", config_client_probe_learning);
|
||||||
#ifndef MINI
|
#ifndef MINI
|
||||||
|
blobmsg_add_bool(&b, "client_socket_learning", config_client_socket_learning);
|
||||||
|
blobmsg_add_bool(&b, "socket_always_answer", config_socket_always_answer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
blobmsg_close_table(&b, list);
|
blobmsg_close_table(&b, list);
|
||||||
|
@ -110,6 +112,8 @@ enum {
|
||||||
SET_CONFIG_CLIENT_PROBE_STEERING,
|
SET_CONFIG_CLIENT_PROBE_STEERING,
|
||||||
SET_CONFIG_CLIENT_PROBE_LEARNING,
|
SET_CONFIG_CLIENT_PROBE_LEARNING,
|
||||||
#ifndef MINI
|
#ifndef MINI
|
||||||
|
SET_CONFIG_CLIENT_SOCKET_LEARNING,
|
||||||
|
SET_CONFIG_SOCKET_ALWAYS_ANSWER,
|
||||||
#endif
|
#endif
|
||||||
__SET_CONFIG_MAX
|
__SET_CONFIG_MAX
|
||||||
};
|
};
|
||||||
|
@ -126,6 +130,8 @@ static const struct blobmsg_policy ubus_set_config_policy[__SET_CONFIG_MAX] = {
|
||||||
[SET_CONFIG_CLIENT_PROBE_STEERING] = { "client_probe_steering", 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 },
|
[SET_CONFIG_CLIENT_PROBE_LEARNING] = { "client_probe_learning", BLOBMSG_TYPE_BOOL },
|
||||||
#ifndef MINI
|
#ifndef MINI
|
||||||
|
[SET_CONFIG_CLIENT_SOCKET_LEARNING] = { "client_socket_learning", BLOBMSG_TYPE_BOOL },
|
||||||
|
[SET_CONFIG_SOCKET_ALWAYS_ANSWER] = { "socket_always_answer", BLOBMSG_TYPE_BOOL },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -147,7 +153,9 @@ static int ubus_set_config(struct ubus_context *ctx, struct ubus_object *obj,
|
||||||
!tb[SET_CONFIG_CLIENT_PROBE_STEERING] &&
|
!tb[SET_CONFIG_CLIENT_PROBE_STEERING] &&
|
||||||
!tb[SET_CONFIG_CLIENT_PROBE_LEARNING]
|
!tb[SET_CONFIG_CLIENT_PROBE_LEARNING]
|
||||||
#ifndef MINI
|
#ifndef MINI
|
||||||
// &&
|
&&
|
||||||
|
!tb[SET_CONFIG_CLIENT_SOCKET_LEARNING] &&
|
||||||
|
!tb[SET_CONFIG_SOCKET_ALWAYS_ANSWER]
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
return UBUS_STATUS_INVALID_ARGUMENT;
|
return UBUS_STATUS_INVALID_ARGUMENT;
|
||||||
|
@ -172,6 +180,10 @@ static int ubus_set_config(struct ubus_context *ctx, struct ubus_object *obj,
|
||||||
if (tb[SET_CONFIG_CLIENT_PROBE_LEARNING])
|
if (tb[SET_CONFIG_CLIENT_PROBE_LEARNING])
|
||||||
config_client_probe_learning = blobmsg_get_bool(tb[SET_CONFIG_CLIENT_PROBE_LEARNING]);
|
config_client_probe_learning = blobmsg_get_bool(tb[SET_CONFIG_CLIENT_PROBE_LEARNING]);
|
||||||
#ifndef MINI
|
#ifndef MINI
|
||||||
|
if (tb[SET_CONFIG_CLIENT_SOCKET_LEARNING])
|
||||||
|
config_client_socket_learning = blobmsg_get_bool(tb[SET_CONFIG_CLIENT_SOCKET_LEARNING]);
|
||||||
|
if (tb[SET_CONFIG_SOCKET_ALWAYS_ANSWER])
|
||||||
|
config_socket_always_answer = blobmsg_get_bool(tb[SET_CONFIG_SOCKET_ALWAYS_ANSWER]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -32,17 +32,20 @@ void clean_cbhandler(struct uloop_timeout *t)
|
||||||
}
|
}
|
||||||
uloop_timeout_set(t, config_client_clean_every * 1000);
|
uloop_timeout_set(t, config_client_clean_every * 1000);
|
||||||
|
|
||||||
if (count > 0) {
|
if (count == 0) {
|
||||||
log_info("remove %d of %d clients", count, all);
|
|
||||||
if(!config_client_clean_authed)
|
|
||||||
log_info(" (skipped %d authed clients)", auth);
|
|
||||||
log_info(" from memory\n");
|
|
||||||
}else{
|
|
||||||
log_verbose("remove %d of %d clients", count, all);
|
log_verbose("remove %d of %d clients", count, all);
|
||||||
if(!config_client_clean_authed)
|
if(!config_client_clean_authed)
|
||||||
log_verbose(" (skipped %d authed clients)", auth);
|
log_verbose(" (skipped %d authed clients)", auth);
|
||||||
log_verbose(" from memory\n");
|
log_verbose(" from memory\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_info("remove %d of %d clients", count, all);
|
||||||
|
|
||||||
|
if(!config_client_clean_authed)
|
||||||
|
log_info(" (skipped %d authed clients)", auth);
|
||||||
|
log_info(" from memory\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct uloop_timeout clean = {
|
struct uloop_timeout clean = {
|
||||||
|
@ -65,7 +68,8 @@ void wifi_clients_close() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __client_setvalues(struct wifi_client *client, struct hostapd_client *hclient) {
|
bool __client_setvalues(struct wifi_client *client, struct hostapd_client *hclient) {
|
||||||
|
bool updated = false;
|
||||||
log_debug("wifi_clients.__client_setvalues(., %d):", hclient->freq);
|
log_debug("wifi_clients.__client_setvalues(., %d):", hclient->freq);
|
||||||
if (client->freq_highest < hclient->freq) {
|
if (client->freq_highest < hclient->freq) {
|
||||||
client->freq_highest = hclient->freq;
|
client->freq_highest = hclient->freq;
|
||||||
|
@ -74,15 +78,18 @@ void __client_setvalues(struct wifi_client *client, struct hostapd_client *hclie
|
||||||
if (hclient->freq > WIFI_CLIENT_FREQ_THREASHOLD) {
|
if (hclient->freq > WIFI_CLIENT_FREQ_THREASHOLD) {
|
||||||
client->signal_highfreq = hclient->ssi_signal;
|
client->signal_highfreq = hclient->ssi_signal;
|
||||||
client->signal_lowfreq = 0;
|
client->signal_lowfreq = 0;
|
||||||
|
//here to skip socket_request
|
||||||
|
updated = true;
|
||||||
}else{
|
}else{
|
||||||
client->signal_highfreq = 0;
|
client->signal_highfreq = 0;
|
||||||
client->signal_lowfreq = hclient->ssi_signal;
|
client->signal_lowfreq = hclient->ssi_signal;
|
||||||
}
|
}
|
||||||
log_debug("\n");
|
|
||||||
time(&client->time);
|
time(&client->time);
|
||||||
if(!client->authed) {
|
if(!client->authed) {
|
||||||
client->authed = hclient->auth;
|
client->authed = hclient->auth;
|
||||||
}
|
}
|
||||||
|
log_debug("\n");
|
||||||
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wifi_client *__get_client(struct hostapd_client *hclient){
|
struct wifi_client *__get_client(struct hostapd_client *hclient){
|
||||||
|
@ -90,7 +97,17 @@ struct wifi_client *__get_client(struct hostapd_client *hclient){
|
||||||
|
|
||||||
client = avl_find_element(&clients_by_addr, hclient->address, client, avl);
|
client = avl_find_element(&clients_by_addr, hclient->address, client, avl);
|
||||||
if (client) {
|
if (client) {
|
||||||
|
#ifdef MINI
|
||||||
__client_setvalues(client, hclient);
|
__client_setvalues(client, hclient);
|
||||||
|
#else
|
||||||
|
if (__client_setvalues(client, hclient)) {
|
||||||
|
struct socket_msg msg = {
|
||||||
|
.type = SOCKET_MSG_TYPE_CLIENT,
|
||||||
|
.client = client,
|
||||||
|
};
|
||||||
|
socket_info(&msg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
log_debug("wifi_clients.__get_client("MACSTR"): found existing client\n", MAC2STR(hclient->address));
|
log_debug("wifi_clients.__get_client("MACSTR"): found existing client\n", MAC2STR(hclient->address));
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
@ -104,21 +121,24 @@ struct wifi_client *__get_client(struct hostapd_client *hclient){
|
||||||
client->freq_highest = 0;
|
client->freq_highest = 0;
|
||||||
__client_setvalues(client, hclient);
|
__client_setvalues(client, hclient);
|
||||||
|
|
||||||
#ifndef MINI
|
#ifdef MINI
|
||||||
struct socket_msg req = {
|
__client_setvalues(client, hclient);
|
||||||
.type = SOCKET_MSG_TYPE_CLIENT,
|
#else
|
||||||
.client = client,
|
if(__client_setvalues(client, hclient)) {
|
||||||
}, resp = {
|
struct socket_msg req = {
|
||||||
.client = malloc(sizeof(*client)),
|
.type = SOCKET_MSG_TYPE_CLIENT,
|
||||||
};
|
.client = client,
|
||||||
|
}, resp = {
|
||||||
|
.client = malloc(sizeof(struct wifi_client)),
|
||||||
|
};
|
||||||
|
|
||||||
if(socket_request(&req, &resp) == 0){
|
if(socket_request(&req, &resp) == 0){
|
||||||
log_debug("wifi_clients.__get_client("MACSTR"): get client from neigbour\n", MAC2STR(hclient->address));
|
if (client->freq_highest < resp.client->freq_highest) {
|
||||||
if (client->freq_highest < resp.client->freq_highest) {
|
client->freq_highest = resp.client->freq_highest;
|
||||||
client->freq_highest = resp.client->freq_highest;
|
}
|
||||||
}
|
if(!client->authed) {
|
||||||
if(!client->authed) {
|
client->authed = resp.client->authed;
|
||||||
client->authed = resp.client->authed;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -133,23 +153,10 @@ void wifi_clients_learn(struct hostapd_client *hclient) {
|
||||||
__get_client(hclient);
|
__get_client(hclient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MINI
|
|
||||||
#define returnINFO_CLIENT return
|
|
||||||
#else
|
|
||||||
#define returnINFO_CLIENT if(config_client_force_probe && !hclient->auth) socket_info(&msg); return
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int wifi_clients_try(struct hostapd_client *hclient) {
|
int wifi_clients_try(struct hostapd_client *hclient) {
|
||||||
struct wifi_client *client;
|
struct wifi_client *client;
|
||||||
|
|
||||||
client = __get_client(hclient);
|
client = __get_client(hclient);
|
||||||
#ifndef MINI
|
|
||||||
struct socket_msg msg = {
|
|
||||||
.type = SOCKET_MSG_TYPE_CLIENT,
|
|
||||||
.client = client,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (hclient->auth) {
|
if (hclient->auth) {
|
||||||
log_info("auth(try=%d mac="MACSTR" freq=%d ssi=%d): ", client->try_auth, MAC2STR(hclient->address), hclient->freq, hclient->ssi_signal);
|
log_info("auth(try=%d mac="MACSTR" freq=%d ssi=%d): ", client->try_auth, MAC2STR(hclient->address), hclient->freq, hclient->ssi_signal);
|
||||||
|
@ -167,12 +174,12 @@ int wifi_clients_try(struct hostapd_client *hclient) {
|
||||||
if(!hclient->auth){
|
if(!hclient->auth){
|
||||||
client->try_probe = 0;
|
client->try_probe = 0;
|
||||||
log_verbose("accept\n");
|
log_verbose("accept\n");
|
||||||
returnINFO_CLIENT 0;
|
return 0;
|
||||||
}
|
}
|
||||||
log_info("accept\n");
|
log_info("accept\n");
|
||||||
client->try_auth = 0;
|
client->try_auth = 0;
|
||||||
client->connected = 1;
|
client->connected = 1;
|
||||||
returnINFO_CLIENT 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (client->freq_highest > WIFI_CLIENT_FREQ_THREASHOLD) {
|
if (client->freq_highest > WIFI_CLIENT_FREQ_THREASHOLD) {
|
||||||
if (config_client_force || config_client_force_probe && !hclient->auth) {
|
if (config_client_force || config_client_force_probe && !hclient->auth) {
|
||||||
|
|
Loading…
Reference in New Issue