mirror of
https://github.com/berlin-open-wireless-lab/DAWN.git
synced 2025-03-09 15:40:12 +00:00
first version
This commit is contained in:
commit
f03f55ff92
28 changed files with 5682 additions and 0 deletions
41
src/network/broadcastsocket.c
Normal file
41
src/network/broadcastsocket.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "networksocket.h"
|
||||
#include "broadcastsocket.h"
|
||||
|
||||
int setup_broadcast_socket(const char *_broadcast_ip, unsigned short _broadcast_port, struct sockaddr_in *addr) {
|
||||
int sock;
|
||||
int broadcast_permission;
|
||||
|
||||
// Create socket
|
||||
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||
fprintf(stderr, "Failed to create socket.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Allow broadcast
|
||||
broadcast_permission = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *) &broadcast_permission,
|
||||
sizeof(broadcast_permission)) < 0) {
|
||||
fprintf(stderr, "Failed to create socket.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Constract addess
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
addr->sin_family = AF_INET;
|
||||
addr->sin_addr.s_addr = inet_addr(_broadcast_ip);
|
||||
addr->sin_port = htons(_broadcast_port);
|
||||
|
||||
// Bind socket
|
||||
while (bind(sock, (struct sockaddr *) addr, sizeof(*addr)) < 0) {
|
||||
fprintf(stderr, "Binding socket failed!\n");
|
||||
sleep(1);
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
83
src/network/multicastsocket.c
Normal file
83
src/network/multicastsocket.c
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "multicastsocket.h"
|
||||
|
||||
// based on: http://openbook.rheinwerk-verlag.de/linux_unix_programmierung/Kap11-018.htm
|
||||
|
||||
static struct ip_mreq command;
|
||||
|
||||
int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_port, struct sockaddr_in *addr) {
|
||||
int loop = 1;
|
||||
int sock;
|
||||
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
addr->sin_family = AF_INET;
|
||||
addr->sin_addr.s_addr = inet_addr(_multicast_ip);
|
||||
addr->sin_port = htons (_multicast_port);
|
||||
|
||||
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
|
||||
perror("socket()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// allow multiple processes to use the same port
|
||||
loop = 1;
|
||||
if (setsockopt(sock,
|
||||
SOL_SOCKET,
|
||||
SO_REUSEADDR,
|
||||
&loop, sizeof(loop)) < 0) {
|
||||
perror("setsockopt:SO_REUSEADDR");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (bind(sock,
|
||||
(struct sockaddr *) addr,
|
||||
sizeof(*addr)) < 0) {
|
||||
perror("bind");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// allow broadcast
|
||||
loop = 1;
|
||||
if (setsockopt(sock,
|
||||
IPPROTO_IP,
|
||||
IP_MULTICAST_LOOP,
|
||||
&loop, sizeof(loop)) < 0) {
|
||||
perror("setsockopt:IP_MULTICAST_LOOP");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// join broadcast group
|
||||
command.imr_multiaddr.s_addr = inet_addr(_multicast_ip);
|
||||
command.imr_interface.s_addr = htonl (INADDR_ANY);
|
||||
if (command.imr_multiaddr.s_addr == -1) {
|
||||
perror("Wrong multicast address!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (setsockopt(sock,
|
||||
IPPROTO_IP,
|
||||
IP_ADD_MEMBERSHIP,
|
||||
&command, sizeof(command)) < 0) {
|
||||
perror("setsockopt:IP_ADD_MEMBERSHIP");
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
int remove_multicast_socket(int socket) {
|
||||
if (setsockopt(socket,
|
||||
IPPROTO_IP,
|
||||
IP_DROP_MEMBERSHIP,
|
||||
&command, sizeof(command)) < 0) {
|
||||
perror("setsockopt:IP_DROP_MEMBERSHIP");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
162
src/network/networksocket.c
Normal file
162
src/network/networksocket.c
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <libubox/blobmsg_json.h>
|
||||
|
||||
#include "networksocket.h"
|
||||
#include "datastorage.h"
|
||||
#include "multicastsocket.h"
|
||||
#include "broadcastsocket.h"
|
||||
#include "ubus.h"
|
||||
#include "crypto.h"
|
||||
|
||||
/* Network Defines */
|
||||
#define MAX_RECV_STRING 2048
|
||||
|
||||
/* Network Attributes */
|
||||
int sock;
|
||||
struct sockaddr_in addr;
|
||||
const char *ip;
|
||||
unsigned short port;
|
||||
char recv_string[MAX_RECV_STRING + 1];
|
||||
int recv_string_len;
|
||||
int multicast_socket;
|
||||
|
||||
void *receive_msg(void *args);
|
||||
|
||||
void *receive_msg_enc(void *args);
|
||||
|
||||
int init_socket_runopts(const char *_ip, int _port, int _multicast_socket) {
|
||||
|
||||
port = _port;
|
||||
ip = _ip;
|
||||
multicast_socket = _multicast_socket;
|
||||
|
||||
if (multicast_socket) {
|
||||
printf("Settingup multicastsocket!\n");
|
||||
sock = setup_multicast_socket(ip, port, &addr);
|
||||
} else {
|
||||
sock = setup_broadcast_socket(ip, port, &addr);
|
||||
}
|
||||
|
||||
pthread_t sniffer_thread;
|
||||
if (network_config.use_symm_enc) {
|
||||
if (pthread_create(&sniffer_thread, NULL, receive_msg_enc, NULL)) {
|
||||
fprintf(stderr, "Could not create receiving thread!\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (pthread_create(&sniffer_thread, NULL, receive_msg, NULL)) {
|
||||
fprintf(stderr, "Could not create receiving thread!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stdout, "Connected to %s:%d\n", ip, port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *receive_msg(void *args) {
|
||||
while (1) {
|
||||
if ((recv_string_len =
|
||||
recvfrom(sock, recv_string, MAX_RECV_STRING, 0, NULL, 0)) < 0) {
|
||||
fprintf(stderr, "Could not receive message!");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (recv_string == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strlen(recv_string) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
recv_string[recv_string_len] = '\0';
|
||||
|
||||
printf("Received network message: %s\n", recv_string);
|
||||
handle_network_msg(recv_string);
|
||||
}
|
||||
}
|
||||
|
||||
void *receive_msg_enc(void *args) {
|
||||
while (1) {
|
||||
if ((recv_string_len =
|
||||
recvfrom(sock, recv_string, MAX_RECV_STRING, 0, NULL, 0)) < 0) {
|
||||
fprintf(stderr, "Could not receive message!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (recv_string == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strlen(recv_string) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
recv_string[recv_string_len] = '\0';
|
||||
|
||||
char *base64_dec_str = malloc(B64_DECODE_LEN(strlen(recv_string)));
|
||||
int base64_dec_length = b64_decode(recv_string, base64_dec_str, B64_DECODE_LEN(strlen(recv_string)));
|
||||
char *dec = gcrypt_decrypt_msg(base64_dec_str, base64_dec_length);
|
||||
|
||||
printf("Received network message: %s\n", dec);
|
||||
free(base64_dec_str);
|
||||
handle_network_msg(dec);
|
||||
free(dec);
|
||||
}
|
||||
}
|
||||
|
||||
int send_string(char *msg) {
|
||||
pthread_mutex_lock(&send_mutex);
|
||||
size_t msglen = strlen(msg);
|
||||
|
||||
if (sendto(sock,
|
||||
msg,
|
||||
msglen,
|
||||
0,
|
||||
(struct sockaddr *) &addr,
|
||||
sizeof(addr)) < 0) {
|
||||
perror("sendto()");
|
||||
pthread_mutex_unlock(&send_mutex);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
pthread_mutex_unlock(&send_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int send_string_enc(char *msg) {
|
||||
pthread_mutex_lock(&send_mutex);
|
||||
|
||||
int length_enc;
|
||||
size_t msglen = strlen(msg);
|
||||
char *enc = gcrypt_encrypt_msg(msg, msglen + 1, &length_enc);
|
||||
|
||||
char *base64_enc_str = malloc(B64_ENCODE_LEN(length_enc));
|
||||
size_t base64_enc_length = b64_encode(enc, length_enc, base64_enc_str, B64_ENCODE_LEN(length_enc));
|
||||
|
||||
if (sendto(sock,
|
||||
base64_enc_str,
|
||||
base64_enc_length, // very important to use actual length of string because of '\0' in encrypted msg
|
||||
0,
|
||||
(struct sockaddr *) &addr,
|
||||
sizeof(addr)) < 0) {
|
||||
perror("sendto()");
|
||||
pthread_mutex_unlock(&send_mutex);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
free(base64_enc_str);
|
||||
free(enc);
|
||||
pthread_mutex_unlock(&send_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void close_socket() {
|
||||
if (multicast_socket) {
|
||||
remove_multicast_socket(sock);
|
||||
}
|
||||
close(sock);
|
||||
}
|
||||
288
src/network/tcpsocket.c
Normal file
288
src/network/tcpsocket.c
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
#include <libubox/usock.h>
|
||||
#include <libubox/ustream.h>
|
||||
#include <libubox/uloop.h>
|
||||
#include <libubox/utils.h> // base64 encoding
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "tcpsocket.h"
|
||||
#include <arpa/inet.h>
|
||||
#include "ubus.h"
|
||||
#include "crypto.h"
|
||||
|
||||
LIST_HEAD(tcp_sock_list);
|
||||
|
||||
struct network_con_s *tcp_list_contains_address(struct sockaddr_in entry);
|
||||
|
||||
static struct uloop_fd server;
|
||||
struct client *next_client = NULL;
|
||||
|
||||
struct client {
|
||||
struct sockaddr_in sin;
|
||||
|
||||
struct ustream_fd s;
|
||||
int ctr;
|
||||
int counter;
|
||||
};
|
||||
|
||||
static void client_close(struct ustream *s) {
|
||||
struct client *cl = container_of(s,
|
||||
struct client, s.stream);
|
||||
|
||||
fprintf(stderr, "Connection closed\n");
|
||||
ustream_free(s);
|
||||
close(cl->s.fd.fd);
|
||||
free(cl);
|
||||
}
|
||||
|
||||
static void client_notify_write(struct ustream *s, int bytes) {
|
||||
return;
|
||||
}
|
||||
|
||||
static void client_notify_state(struct ustream *s) {
|
||||
struct client *cl = container_of(s,
|
||||
struct client, s.stream);
|
||||
|
||||
if (!s->eof)
|
||||
return;
|
||||
|
||||
fprintf(stderr, "eof!, pending: %d, total: %d\n", s->w.data_bytes, cl->ctr);
|
||||
|
||||
if (!s->w.data_bytes)
|
||||
return client_close(s);
|
||||
|
||||
}
|
||||
|
||||
static void client_to_server_close(struct ustream *s) {
|
||||
struct network_con_s *con = container_of(s,
|
||||
struct network_con_s, stream.stream);
|
||||
|
||||
fprintf(stderr, "Connection to server closed\n");
|
||||
ustream_free(s);
|
||||
close(con->fd.fd);
|
||||
list_del(&con->list);
|
||||
free(con);
|
||||
}
|
||||
|
||||
static void client_to_server_state(struct ustream *s) {
|
||||
struct client *cl = container_of(s,
|
||||
struct client, s.stream);
|
||||
|
||||
if (!s->eof)
|
||||
return;
|
||||
|
||||
fprintf(stderr, "eof!, pending: %d, total: %d\n", s->w.data_bytes, cl->ctr);
|
||||
|
||||
if (!s->w.data_bytes)
|
||||
return client_to_server_close(s);
|
||||
|
||||
}
|
||||
|
||||
static void client_read_cb(struct ustream *s, int bytes) {
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
do {
|
||||
str = ustream_get_read_buf(s, &len);
|
||||
if (!str)
|
||||
break;
|
||||
|
||||
if (network_config.use_symm_enc) {
|
||||
char *base64_dec_str = malloc(B64_DECODE_LEN(strlen(str)));
|
||||
int base64_dec_length = b64_decode(str, base64_dec_str, B64_DECODE_LEN(strlen(str)));
|
||||
char *dec = gcrypt_decrypt_msg(base64_dec_str, base64_dec_length);
|
||||
|
||||
free(base64_dec_str);
|
||||
handle_network_msg(dec);
|
||||
free(dec);
|
||||
} else {
|
||||
handle_network_msg(str);
|
||||
}
|
||||
|
||||
ustream_consume(s, len);
|
||||
|
||||
} while (1);
|
||||
|
||||
if (s->w.data_bytes > 256 && !ustream_read_blocked(s)) {
|
||||
fprintf(stderr, "Block read, bytes: %d\n", s->w.data_bytes);
|
||||
ustream_set_read_blocked(s, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void server_cb(struct uloop_fd *fd, unsigned int events) {
|
||||
struct client *cl;
|
||||
unsigned int sl = sizeof(struct sockaddr_in);
|
||||
int sfd;
|
||||
|
||||
if (!next_client)
|
||||
next_client = calloc(1, sizeof(*next_client));
|
||||
|
||||
cl = next_client;
|
||||
sfd = accept(server.fd, (struct sockaddr *) &cl->sin, &sl);
|
||||
if (sfd < 0) {
|
||||
fprintf(stderr, "Accept failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cl->s.stream.string_data = 1;
|
||||
cl->s.stream.notify_read = client_read_cb;
|
||||
cl->s.stream.notify_state = client_notify_state;
|
||||
cl->s.stream.notify_write = client_notify_write;
|
||||
ustream_fd_init(&cl->s, sfd);
|
||||
next_client = NULL;
|
||||
fprintf(stderr, "New connection\n");
|
||||
}
|
||||
|
||||
int run_server(int port) {
|
||||
char port_str[12];
|
||||
sprintf(port_str, "%d", port);
|
||||
|
||||
server.cb = server_cb;
|
||||
server.fd = usock(USOCK_TCP | USOCK_SERVER | USOCK_IPV4ONLY | USOCK_NUMERIC, INADDR_ANY, port_str);
|
||||
if (server.fd < 0) {
|
||||
perror("usock");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uloop_fd_add(&server, ULOOP_READ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void client_not_be_used_read_cb(struct ustream *s, int bytes) {
|
||||
int len;
|
||||
char buf[2048];
|
||||
|
||||
len = ustream_read(s, buf, sizeof(buf));
|
||||
buf[len] = '\0';
|
||||
printf("Read %d bytes from SSL connection: %s\n", len, buf);
|
||||
}
|
||||
|
||||
static void connect_cb(struct uloop_fd *f, unsigned int events) {
|
||||
|
||||
struct network_con_s *entry = container_of(f,
|
||||
struct network_con_s, fd);
|
||||
|
||||
if (f->eof || f->error) {
|
||||
fprintf(stderr, "Connection failed\n");
|
||||
close(entry->fd.fd);
|
||||
list_del(&entry->list);
|
||||
free(entry);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Connection established\n");
|
||||
uloop_fd_delete(&entry->fd);
|
||||
|
||||
entry->stream.stream.notify_read = client_not_be_used_read_cb;
|
||||
entry->stream.stream.notify_state = client_to_server_state;
|
||||
|
||||
ustream_fd_init(&entry->stream, entry->fd.fd);
|
||||
entry->connected = 1;
|
||||
}
|
||||
|
||||
int add_tcp_conncection(char *ipv4, int port) {
|
||||
struct sockaddr_in serv_addr;
|
||||
|
||||
char port_str[12];
|
||||
sprintf(port_str, "%d", port);
|
||||
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = inet_addr(ipv4);
|
||||
serv_addr.sin_port = htons(port);
|
||||
|
||||
struct network_con_s *tmp = tcp_list_contains_address(serv_addr);
|
||||
if (tmp != NULL) {
|
||||
if(tmp->connected == true)
|
||||
{
|
||||
return 0;
|
||||
} else{
|
||||
// Delete already existing entry
|
||||
close(tmp->fd.fd);
|
||||
list_del(&tmp->list);
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
struct network_con_s *tcp_entry = calloc(1, sizeof(struct network_con_s));
|
||||
tcp_entry->fd.fd = usock(USOCK_TCP | USOCK_NONBLOCK, ipv4, port_str);
|
||||
tcp_entry->sock_addr = serv_addr;
|
||||
|
||||
if (tcp_entry->fd.fd < 0) {
|
||||
free(tcp_entry);
|
||||
return -1;
|
||||
}
|
||||
tcp_entry->fd.cb = connect_cb;
|
||||
uloop_fd_add(&tcp_entry->fd, ULOOP_WRITE | ULOOP_EDGE_TRIGGER);
|
||||
|
||||
printf("New TCP connection to %s:%d\n", ipv4, port);
|
||||
list_add(&tcp_entry->list, &tcp_sock_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void send_tcp(char *msg) {
|
||||
print_tcp_array();
|
||||
if (network_config.use_symm_enc) {
|
||||
int length_enc;
|
||||
size_t msglen = strlen(msg);
|
||||
char *enc = gcrypt_encrypt_msg(msg, msglen + 1, &length_enc);
|
||||
|
||||
char *base64_enc_str = malloc(B64_ENCODE_LEN(length_enc));
|
||||
size_t base64_enc_length = b64_encode(enc, length_enc, base64_enc_str, B64_ENCODE_LEN(length_enc));
|
||||
struct network_con_s *con;
|
||||
list_for_each_entry(con, &tcp_sock_list, list)
|
||||
{
|
||||
if (con->connected) {
|
||||
int len_ustream = ustream_write(&con->stream.stream, base64_enc_str, base64_enc_length, 0);
|
||||
printf("Ustream send: %d\n", len_ustream);
|
||||
if (len_ustream <= 0) {
|
||||
fprintf(stderr,"Ustream error!\n");
|
||||
//TODO: ERROR HANDLING!
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free(base64_enc_str);
|
||||
free(enc);
|
||||
} else {
|
||||
struct network_con_s *con;
|
||||
|
||||
list_for_each_entry(con, &tcp_sock_list, list)
|
||||
{
|
||||
if (con->connected) {
|
||||
if (ustream_printf(&con->stream.stream, "%s", msg) == 0) {
|
||||
//TODO: ERROR HANDLING!
|
||||
fprintf(stderr,"Ustream error!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct network_con_s* tcp_list_contains_address(struct sockaddr_in entry) {
|
||||
struct network_con_s *con;
|
||||
|
||||
list_for_each_entry(con, &tcp_sock_list, list)
|
||||
{
|
||||
if(entry.sin_addr.s_addr == con->sock_addr.sin_addr.s_addr)
|
||||
{
|
||||
return con;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void print_tcp_array() {
|
||||
struct network_con_s *con;
|
||||
|
||||
printf("--------Connections------\n");
|
||||
list_for_each_entry(con, &tcp_sock_list, list)
|
||||
{
|
||||
printf("Conenctin to Port: %d, Connected: %s\n", con->sock_addr.sin_port, con->connected ? "True" : "False");
|
||||
}
|
||||
printf("------------------\n");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue