socket_request
This commit is contained in:
		
							parent
							
								
									9e4aa98c04
								
							
						
					
					
						commit
						9aec4435ec
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue