socket_request

This commit is contained in:
Martin/Geno 2018-08-05 10:17:42 +02:00
parent 9e4aa98c04
commit 9aec4435ec
No known key found for this signature in database
GPG Key ID: 9D7D3C6BFF600C6A
8 changed files with 239 additions and 20 deletions

View File

@ -10,13 +10,13 @@ struct wifi_client {
struct avl_node avl;
u8 addr[ETH_ALEN];
time_t time;
int try_probe;
int try_auth;
uint16_t try_probe;
uint16_t try_auth;
bool connected;
bool authed;
uint32_t freq_highest;
uint32_t signal_lowfreq;
uint32_t signal_highfreq;
uint16_t freq_highest;
uint16_t signal_lowfreq;
uint16_t signal_highfreq;
};
#endif

View File

@ -16,6 +16,7 @@
#include <libubox/usock.h>
#include <libubox/ustream.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>

View File

@ -1,8 +1,71 @@
#include "include.h"
#include "log.h"
#include "socket.h"
#include "socket_msg.h"
static struct uloop_fd server;
struct in6_addr ownaddr;
struct sockaddr_in6 client_addr;
int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer, struct timeval timeout) {
int ret = 0;
int sock = 0;
char msg[REQUEST_MAXLEN];
request->type = (request->type | SOCKET_MSG_TYPE_REQUEST);
ret = socket_msg_marshal(request, msg);
if (ret) {
log_error("socket_request: could not marshel message: %d\n", ret);
return ret;
}
sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (sock < 0) {
log_error("socket_request: could not create socket\n");
return -1;
}
int loop = 0;
if(setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) {
log_error("socket_request: unable to disable listen/loop own multicast package: %d\n", errno);
return -1;
}
ret = sendto(sock, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&client_addr, sizeof(client_addr));
if (ret < 0) {
close(sock);
log_error("socket_request: could not send message: %d\n", ret);
return ret;
}
ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,sizeof(timeout));
if(ret < 0) {
close(sock);
log_error("socket_request: unable to set timeout: %d\n", errno);
return ret;
}
ret = recv(sock, msg, REQUEST_MAXLEN, 0);
close(sock);
if (ret < 0) {
if(errno == EWOULDBLOCK)
return ret;
log_error("socket_request: could not recv message: %d\n", ret);
return ret;
}
ret = socket_msg_unmarshal(answer, msg);
if (ret) {
log_error("socket_request: could not unmarshel message: %d\n", ret);
return ret;
}
log_verbose("socket_request: end %d\n", ret);
if(answer->type & SOCKET_MSG_TYPE_RESPONSE) {
return -1;
}
return ret;
}
static void server_cb(struct uloop_fd *fd, unsigned int events) {
struct sockaddr_in6 addr;
@ -46,28 +109,34 @@ int socket_init(char *ifname) {
if (server.fd < 0) {
return 1;
}
struct in6_addr mgroup_addr;
if (!inet_pton(AF_INET6, SOCKET_MADDR, &mgroup_addr)) {
client_addr.sin6_family = AF_INET6;
client_addr.sin6_port = htons(atoi(SOCKET_PORT));
client_addr.sin6_scope_id = if_nametoindex(ifname);
// listen multicast
if (!inet_pton(AF_INET6, SOCKET_MADDR, &client_addr.sin6_addr)) {
log_error("socket: invalid multicast group\n");
return -1;
}
struct ipv6_mreq mreq;
mreq.ipv6mr_multiaddr = mgroup_addr;
mreq.ipv6mr_interface = if_nametoindex(ifname);
struct ipv6_mreq mreq = {
.ipv6mr_multiaddr = client_addr.sin6_addr,
.ipv6mr_interface = client_addr.sin6_scope_id,
};
if (setsockopt(server.fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1) {
log_error("socket: unable to join multicast group\n");
log_error("socket: unable to join multicast group: %d\n", errno);
return -1;
}
// end listen multicast
uloop_fd_add(&server, ULOOP_READ);
return 0;
}
void socket_close() {
uloop_fd_delete(&server);
//ustream_free(&(server.fd));
close(server.fd);
}

View File

@ -1,13 +1,25 @@
#ifndef __WIFICTLD_SOCKET_H
#define __WIFICTLD_SOCKET_H
#include "include.h"
#include "socket_msg.h"
#define SOCKET_ADDR "::"
#define SOCKET_MADDR "ff02::31f1"
#define SOCKET_PORT "1000"
#define REQUEST_MAXLEN 256
int socket_init();
void socket_close();
int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer, struct timeval timeout);
static inline int socket_request(struct socket_msg *request, struct socket_msg *answer)
{
struct timeval tv = {
.tv_sec = 0,
.tv_usec = 100000,
};
return socket_request_timeout(request, answer, tv);
}
#endif

View File

@ -0,0 +1,100 @@
#include "include.h"
#include "socket_msg.h"
int socket_msg_marshal(struct socket_msg *src, char dest[REQUEST_MAXLEN]) {
uint32_t nl = 0;
uint16_t ns = 0;
int pos = 0;
memset(dest, 0, REQUEST_MAXLEN);
nl = htonl(src->type);
memcpy(dest + pos, &nl, sizeof(nl));
pos += sizeof(nl);
if (src->type & SOCKET_MSG_TYPE_CLIENT) {
memcpy(dest + pos, src->client->addr, sizeof(src->client->addr));
pos += sizeof(src->client->addr);
nl = htonl(src->client->time);
memcpy(dest + pos, &nl, sizeof(nl));
pos += sizeof(nl);
ns = htons(src->client->try_probe);
memcpy(dest + pos, &ns, sizeof(ns));
pos += sizeof(ns);
ns = htons(src->client->try_auth);
memcpy(dest + pos, &ns, sizeof(ns));
pos += sizeof(ns);
memcpy(dest + pos, &src->client->connected, sizeof(src->client->connected));
pos += sizeof(src->client->connected);
memcpy(dest + pos, &src->client->authed, sizeof(src->client->authed));
pos += sizeof(src->client->authed);
ns = htons(src->client->freq_highest);
memcpy(dest + pos, &ns, sizeof(ns));
pos += sizeof(ns);
ns = htons(src->client->signal_lowfreq);
memcpy(dest + pos, &ns, sizeof(ns));
pos += sizeof(ns);
ns = htons(src->client->signal_highfreq);
memcpy(dest + pos, &ns, sizeof(ns));
pos += sizeof(ns);
}
memset(dest + pos, 0, REQUEST_MAXLEN-pos);
return 0;
}
int socket_msg_unmarshal(struct socket_msg *dest, char src[REQUEST_MAXLEN]) {
uint32_t nl = 0;
uint16_t ns = 0;
int pos = 0;
memcpy(&nl, src + pos, sizeof(nl));
pos += sizeof(nl);
dest->type = ntohl(nl);
if (dest->type & SOCKET_MSG_TYPE_CLIENT) {
memcpy(dest->client->addr, src + pos, sizeof(dest->client->addr));
pos += sizeof(dest->client->addr);
memcpy(&nl, src + pos, sizeof(nl));
pos += sizeof(nl);
dest->client->time = ntohl(nl);
memcpy(&ns, src + pos, sizeof(ns));
pos += sizeof(ns);
dest->client->try_probe = ntohs(ns);
memcpy(&ns, src + pos, sizeof(ns));
pos += sizeof(ns);
dest->client->try_auth = ntohs(ns);
memcpy(&dest->client->connected, src + pos, sizeof(dest->client->connected));
pos += sizeof(dest->client->connected);
memcpy(&dest->client->authed, src + pos, sizeof(dest->client->authed));
pos += sizeof(dest->client->authed);
memcpy(&ns, src + pos, sizeof(ns));
pos += sizeof(ns);
dest->client->freq_highest = ntohs(ns);
memcpy(&ns, src + pos, sizeof(ns));
pos += sizeof(ns);
dest->client->signal_lowfreq = ntohs(ns);
memcpy(&ns, src + pos, sizeof(ns));
pos += sizeof(ns);
dest->client->signal_highfreq = ntohs(ns);
}
return 0;
}

View File

@ -0,0 +1,24 @@
#ifndef __WIFICTLD_SOCKET_MSG_H
#define __WIFICTLD_SOCKET_MSG_H
#include "include.h"
#include "data.h"
#define REQUEST_MAXLEN 256
enum socket_msg_type {
SOCKET_MSG_TYPE_REQUEST = (1 << 0),
SOCKET_MSG_TYPE_RESPONSE = (1 << 1),
SOCKET_MSG_TYPE_CLIENT = (1 << 2),
SOCKET_MSG_TYPE_STATS = (1 << 3),
};
struct socket_msg {
uint32_t type;
struct wifi_client *client;
};
int socket_msg_marshal(struct socket_msg *src, char dest[REQUEST_MAXLEN]);
int socket_msg_unmarshal(struct socket_msg *dest, char src[REQUEST_MAXLEN]);
#endif

View File

@ -142,20 +142,20 @@ static int receive_notify(struct ubus_context *ctx, struct ubus_object *obj, str
if (!strcmp(method, "auth")) {
hclient.auth = true;
if (wifi_clients_try(&hclient)) {
log_debug(" -> reject\n");
log_verbose(" -> reject\n");
return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
}
log_debug(" -> accept\n");
log_verbose(" -> accept\n");
return WLAN_STATUS_SUCCESS;
}
if (!strcmp(method, "probe")) {
if(config_client_probe_steering) {
if (wifi_clients_try(&hclient)) {
log_debug(" -> reject\n");
log_verbose(" -> reject\n");
return WLAN_STATUS_UNSPECIFIED_FAILURE;
}
log_debug(" -> accept\n");
log_verbose(" -> accept\n");
return WLAN_STATUS_SUCCESS;
}
if(config_client_probe_learning) {

View File

@ -3,6 +3,9 @@
#include "log.h"
#include "data.h"
#include "wifi_clients.h"
#ifndef MINI
#include "socket.h"
#endif
void clean_cbhandler(struct uloop_timeout *t)
@ -100,6 +103,16 @@ struct wifi_client *__get_client(struct hostapd_client *hclient){
client->authed = false;
client->freq_highest = 0;
__client_setvalues(client, hclient);
#ifndef MINI
struct socket_msg req = {
.type = SOCKET_MSG_TYPE_CLIENT,
.client = client,
}, resp;
if(socket_request(&req, &resp) == 0){
log_debug("wifi_clients.__get_client("MACSTR"): get client from neigbour\n", MAC2STR(hclient->address));
return resp.client;
}
#endif
client->avl.key = client->addr;
log_debug("wifi_clients.__get_client("MACSTR"): add client to mem\n", MAC2STR(hclient->address));
avl_insert(&clients_by_addr, &client->avl);