Start adding support for peers list

This commit is contained in:
Melon 2021-05-04 00:13:00 +01:00
parent 4b6e076888
commit d8dcd14621
14 changed files with 277 additions and 68 deletions

View File

@ -4,7 +4,7 @@ daemon_sourcefiles := $(shell find src/impl/daemon/ -name *.c)
refreshpeers_sourcefiles := $(shell find src/impl/refresh-peers/ -name *.c)
shared_sourcefiles := $(shell find src/impl/shared/ -name *.c)
libshared := "src/intf/"
hidedep := "-Wno-deprecated-declarations"
proj_version := $(shell cat project.json | jq .Version -r)
@ -21,15 +21,15 @@ all:
build-shared:
mkdir -p dist/ && \
mkdir -p dist/libmelonvpnshared-obj/ && \
./scripts/gcc_multiwrap.sh -I ${libshared} -- dist/libmelonvpnshared.a dist/libmelonvpnshared-obj/ ${shared_sourcefiles}
./scripts/gcc_multiwrap.sh ${hidedep} -I ${libshared} -- dist/libmelonvpnshared.a dist/libmelonvpnshared-obj/ ${shared_sourcefiles}
build-daemon:
mkdir -p dist/ && \
gcc -o dist/melonvpndaemon -I ${libshared} ${daemon_sourcefiles} dist/libmelonvpnshared.a -pthread
gcc -o dist/melonvpndaemon ${hidedep} -I ${libshared} ${daemon_sourcefiles} dist/libmelonvpnshared.a -pthread
build-refreshpeers:
mkdir -p dist/ && \
gcc -o dist/melonvpnrefreshpeers -I ${libshared} ${refreshpeers_sourcefiles} dist/libmelonvpnshared.a obj/mjson.o
gcc -o dist/melonvpnrefreshpeers ${hidedep} -I ${libshared} ${refreshpeers_sourcefiles} dist/libmelonvpnshared.a obj/mjson.o
build-user:
mkdir -p dist/ && \
@ -38,11 +38,11 @@ build-user:
build-cli:
mkdir -p dist/ && \
gcc -rdynamic -o dist/melonvpn -I ${libshared} ${cli_sourcefiles} dist/libmelonvpnshared.a -DPROJ_VERSION=\"${proj_version}\" -ldl -pthread
gcc -g -O0 -rdynamic -o dist/melonvpn ${hidedep} -I ${libshared} ${cli_sourcefiles} dist/libmelonvpnshared.a -DPROJ_VERSION=\"${proj_version}\" -ldl -pthread
build-gui:
mkdir -p dist/ && \
gcc `pkg-config --cflags gtk+-3.0 appindicator3-0.1` -shared -fPIC -o dist/libmelonvpngui.so -I ${libshared} ${gui_sourcefiles} dist/libmelonvpnshared.a `pkg-config --libs gtk+-3.0 appindicator3-0.1`
gcc ${hidedep} `pkg-config --cflags gtk+-3.0 appindicator3-0.1` -shared -fPIC -o dist/libmelonvpngui.so -I ${libshared} ${gui_sourcefiles} dist/libmelonvpnshared.a `pkg-config --libs gtk+-3.0 appindicator3-0.1`
build-logo:
mkdir -p dist/ && \

View File

@ -11,6 +11,7 @@
#include "unix_sockets.h"
#include "melon_vpn_sock.h"
#include "melon_vpn_about.h"
#include "is_arg.h"
#ifndef PROJ_VERSION
#define PROJ_VERSION "unknown"
@ -71,18 +72,6 @@ bool incoming_isrestart(char *isrestart) {
return true;
}
int is_arg(int ac, char **argv, char *arg) {
if (ac < 2) {
return 0;
}
for(int x=1; x < ac; x++) {
if (0 == strcmp(argv[x], arg)) {
return x; // return position of arg
}
}
return 0; // arg not present
}
void display_version() {
if(is_debug) printf("v%s-beta\n", version);
else printf("v%s\n", version);
@ -200,11 +189,14 @@ int start_client_server() {
char buf[BUF_SIZE];
int total = 0;
memset(msg,0,MAX_PEERS_LEN);
memset(buf,0,BUF_SIZE);
for(;;) {
int cfd = accept(sfd, NULL, NULL);
strcpy(msg, "");
strcpy(buf, "");
memset(msg,0,MAX_PEERS_LEN);
memset(buf,0,BUF_SIZE);
total = 0;
while ((numRead = read(cfd, buf, BUF_SIZE)) > 0) {
@ -212,22 +204,26 @@ int start_client_server() {
total+=numRead;
strcat(msg, buf);
msg[MAX_PEERS_LEN-1]=0;
memset(buf,0,BUF_SIZE);
}
if(is_debug) fprintf(stderr, "Incoming request: %s\n",msg);
// Don't bother checking an empty incoming message
if(total!=0) {
if(is_debug) fprintf(stderr, "Incoming request: %s\n",msg);
char *a = strtok(msg,"\1");
if(strcmp(a,"client")==0) {
char *b = strtok(NULL,"\1");
if(strcmp(b,"status")==0) {
char *c = strtok(NULL,"\1");
if(incoming_state(c)) break;
} else if(strcmp(b,"peers")==0) {
char *c = strtok(NULL,"\1");
if(incoming_peers(c)) break;
} else if(strcmp(b,"isrestart")==0) {
char *c = strtok(NULL,"\1");
if(incoming_isrestart(c)) break;
char *a = strtok(msg,"\1");
if(strcmp(a,"client")==0) {
char *b = strtok(NULL,"\1");
if(strcmp(b,"status")==0) {
char *c = strtok(NULL,"\1");
if(incoming_state(c)) break;
} else if(strcmp(b,"peers")==0) {
char *c = strtok(NULL,"\1");
if(incoming_peers(c)) break;
} else if(strcmp(b,"isrestart")==0) {
char *c = strtok(NULL,"\1");
if(incoming_isrestart(c)) break;
}
}
}
}

View File

@ -34,6 +34,9 @@ void send_to_client(char*, ssize_t);
int start_vpn_process();
void stop_vpn_process();
void send_vpn_status();
void send_is_restart_status();
thrd_t daemonthr;
thrd_t peersthr;
@ -110,7 +113,21 @@ void incoming_request(char *request) {
void incoming_peers(char *peers) {
storedpeers = peers;
send_to_client(peers, strlen(peers));
fprintf(stderr,peers);
char *prefix = "client\1peers\1";
int prel = strlen(prefix);
int l = strlen(peers);
int t = prel+l+1;
char *msg = malloc(t);
memset(msg,0,t);
strcpy(msg,prefix);
strcat(msg,peers);
send_to_client(msg, t);
free(msg);
}
void send_vpn_status() {
@ -190,7 +207,7 @@ void write_daemon_config() {
int start_vpn_process() {
fprintf(stderr, "ready to start: %d\n", vpn_process);
if(vpn_process != -1) return;
if(vpn_process != -1) return 1;
// Command line arguments for simple-vpn
char* const command[] = {"simple-vpn", "client", vpnconfig, NULL};
@ -257,7 +274,7 @@ int start_peers_server(void *thr_data) {
int sfd = unix_socket_server_start(SV_RPEERS_SOCK_PATH);
ssize_t numRead;
ssize_t numRead = 0;
int MAX_PEERS_LEN = 1000;
char msg[MAX_PEERS_LEN];
char buf[BUF_SIZE];
@ -266,8 +283,8 @@ int start_peers_server(void *thr_data) {
for(;;) {
int cfd = accept(sfd, NULL, NULL);
strcpy(msg, "");
strcpy(buf, "");
memset(msg,0,MAX_PEERS_LEN);
memset(buf,0,BUF_SIZE);
total = 0;
while ((numRead = read(cfd, buf, BUF_SIZE)) > 0) {
@ -277,6 +294,9 @@ int start_peers_server(void *thr_data) {
msg[MAX_PEERS_LEN-1]=0;
}
// Don't bother checking an empty incoming message
if(total==0) continue;
incoming_peers(msg);
}
@ -289,6 +309,8 @@ void send_to_client(char *buf, ssize_t n) {
return;
}
fprintf(stderr, "send to client: %s\n", buf);
write(sfd, buf, n);
close(sfd);

View File

@ -3,13 +3,15 @@
#include <libappindicator/app-indicator.h>
#include <stdbool.h>
#include <limits.h>
#include <pango-1.0/pango/pango-font.h>
#include "states.h"
#include "statusicon.h"
#include "magic_code.h"
#include "melon_vpn_about.h"
#include "peersview.h"
#define MAX_CURRENT_PEERS 5000
GtkApplication *app;
GdkPixbuf *appicon;
@ -28,6 +30,7 @@ GtkWidget *button2;
GtkWidget *button3;
GtkWidget *button4;
GtkWidget *statustxt;
GtkWidget *peerstreeview;
// Callback functions for the code in the CLI
int (*cli_start_vpn)();
@ -92,10 +95,15 @@ gboolean on_window_deleted(GtkWidget *widget, GdkEvent *event, gpointer data) {
void activate(GtkApplication* app) {
window = gtk_application_window_new(app);
// Setup window position and properties
gtk_window_set_title(GTK_WINDOW(window),"Melon VPN");
gtk_window_set_default_size(GTK_WINDOW(window),300,300);
gtk_window_set_resizable(GTK_WINDOW(window),false);
gtk_window_set_type_hint(GTK_WINDOW(window),GDK_WINDOW_TYPE_HINT_DIALOG);
//gtk_window_set_gravity(GTK_WINDOW(window),GDK_GRAVITY_CENTER);
//gtk_window_move(GTK_WINDOW(window),0,0);
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER_ALWAYS);
g_signal_connect(G_OBJECT(window),"delete-event",G_CALLBACK(on_window_deleted),NULL);
// Setup status icon now window is available
@ -135,6 +143,10 @@ void activate(GtkApplication* app) {
statustxt = gtk_label_new("");
gtk_widget_modify_font(GTK_WIDGET(statustxt), font);
// Create treeview for peers
peerstreeview = gtk_tree_view_new();
peersview_new(peerstreeview);
// Fixed box used to position the widgets
box = gtk_fixed_new();
@ -144,6 +156,9 @@ void activate(GtkApplication* app) {
gtk_fixed_put(GTK_FIXED(box),button3,190,40);
gtk_fixed_put(GTK_FIXED(box),button4,190,5);
gtk_fixed_put(GTK_FIXED(box),statustxt,10,10);
gtk_fixed_put(GTK_FIXED(box),peerstreeview,10,80);
gtk_widget_set_size_request(GTK_WIDGET(peerstreeview),280,220);
gtk_widget_show_all(window);
@ -165,6 +180,8 @@ int run_gui(int argc, char **argv, bool is_debug, int (*start_vpn)(), int (*stop
cli_refresh_vpn = refresh_vpn;
cli_restart_conf_vpn = restart_conf_vpn;
currentpeers = malloc(MAX_CURRENT_PEERS);
statusiconoff = "";
statusiconon = "";
@ -249,7 +266,9 @@ void mod_trigger_state(States state) {
}
void mod_trigger_peers(char *peers) {
memset(currentpeers,0,MAX_CURRENT_PEERS);
strcpy(currentpeers, peers);
peersview_update(currentpeers);
}
void mod_trigger_isrestart(bool isrestart) {

82
src/impl/gui/peersview.c Normal file
View File

@ -0,0 +1,82 @@
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#include "peers.h"
#include "ip_utils.h"
#include "peersview.h"
GtkWidget *peersview;
GtkListStore *list_store;
int peersview_sort(const void *v1, const void *v2);
gboolean peersview_setup_list_store(gpointer a);
struct peersview_list_store_and_peer {
GtkListStore *list_store;
struct peer_t *peer;
int length;
};
void peersview_new(GtkWidget *treeview) {
peersview = GTK_WIDGET(treeview);
list_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
GtkTreeViewColumn *c1;
GtkCellRenderer *r1 = gtk_cell_renderer_text_new();
c1 = gtk_tree_view_column_new_with_attributes("Name", r1, NULL);
GtkTreeViewColumn *c2;
GtkCellRenderer *r2 = gtk_cell_renderer_text_new();
c2 = gtk_tree_view_column_new_with_attributes("IP", r2, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(peersview),c1);
gtk_tree_view_append_column(GTK_TREE_VIEW(peersview),c2);
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(peersview)), GTK_SELECTION_NONE);
gtk_tree_view_set_model(GTK_TREE_VIEW(peersview), GTK_TREE_MODEL(list_store));
}
void peersview_update(char *peers) {
struct peersview_list_store_and_peer *a = g_slice_new(struct peersview_list_store_and_peer);
a->list_store = list_store;
a->length = string_to_peers(peers, a->peer);
qsort(a->peer, a->length, sizeof(struct peer_t), peersview_sort);
g_idle_add(&peersview_setup_list_store, (gpointer)a);
fprintf(stderr, "Finished adding list store items\n");
}
gboolean peersview_setup_list_store(gpointer a) {
// TODO: fix the segmentation fault here
struct peersview_list_store_and_peer *b = (struct peersview_list_store_and_peer *)a;
GtkListStore *list_store = b->list_store;
struct peer_t *devs = b->peer;
int l = b->length;
gtk_list_store_clear(GTK_LIST_STORE(list_store));
GtkTreeIter iter;
for(int i=0; i<l; i++) {
gtk_list_store_append(GTK_LIST_STORE(list_store), &iter);
gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, devs[i].name, 1, devs[i].ip, -1);
}
free(b->peer);
g_slice_free(struct peersview_list_store_and_peer, b);
}
int peersview_sort(const void *v1, const void *v2) {
struct peer_t *p1 = (struct peer_t*)v1;
struct peer_t *p2 = (struct peer_t*)v2;
int i1 = numericalIp(p1->ip);
int i2 = numericalIp(p2->ip);
if(i1 < i2) return -1;
else if(i1 > i2) return +1;
else return 0;
}

View File

@ -8,28 +8,21 @@
#include "mjson.h"
#include "unix_sockets.h"
#include "melon_vpn_sock.h"
#include "peers.h"
#define JBUF_SIZE 5000
#define NAME_MAX 25
#define IP_MAX 15
#define DEV_MAX 25
struct dev_t {
char name[NAME_MAX];
char ip[IP_MAX];
};
struct devlist_t {
int ndevices;
struct dev_t list[DEV_MAX];
struct peer_t list[PEER_DEV_MAX];
};
static struct devlist_t devicelist;
static int json_devicelist_read(const char *buf) {
const struct json_attr_t json_attrs_subdevice[] = {
{"Name",t_string,STRUCTOBJECT(struct dev_t,name),.len=NAME_MAX},
{"IP",t_string,STRUCTOBJECT(struct dev_t,ip),.len=IP_MAX},
{"Name",t_string,STRUCTOBJECT(struct peer_t,name),.len=PEER_NAME_MAX},
{"IP",t_string,STRUCTOBJECT(struct peer_t,ip),.len=PEER_IP_MAX},
{NULL},
};
const struct json_attr_t json_attrs_devices[] = {
@ -56,37 +49,24 @@ int main(int argc, char *argv[]) {
strcat(jbuf, ibuf);
strcat(jbuf, "}");
fprintf(stderr,ibuf);
int status = json_devicelist_read(jbuf);
if (status != 0) {
puts(json_error_string(status));
} else {
ssize_t l=0;
char obuf[JBUF_SIZE];
obuf[JBUF_SIZE-1]=0;
strcpy(obuf, "");
for (int i = 0; i < devicelist.ndevices; i++) {
l += strlen(devicelist.list[i].name)+strlen(devicelist.list[i].ip)+2;
strcat(obuf, devicelist.list[i].name);
strcat(obuf, "\t");
strcat(obuf, devicelist.list[i].ip);
strcat(obuf, "\n");
obuf[l]=0;
fprintf(stderr, "l: %d\nobuf: %d\n",l,strlen(obuf));
}
int l=peers_to_string(devicelist.list,devicelist.ndevices,obuf);
send_to_daemon(obuf,l);
}
}
void send_to_daemon(char *buf, ssize_t n) {
int sfd = unix_socket_client_start(SV_RPEERS_SOCK_PATH);
if(sfd==-1) {
return;
}
if(sfd==-1) return;
write(sfd, buf, n);
close(sfd);
fprintf(stderr, "Closed connection to socket");
fprintf(stderr, "Closed connection to socket\n");
}

View File

@ -0,0 +1,21 @@
#include "ip_utils.h"
unsigned long numericalIp(char *p) {
int parsedArray[IP_SEGMENTS];
int nb = 0;
while (nb < sizeof(parsedArray) && *p && nb < IP_SEGMENTS) {
parsedArray[nb++] = strtol(p, &p, 10);
if (*p != '.') break;
p++;
}
if(nb==4) {
unsigned long a=parsedArray[3];
a+=parsedArray[2]*(1<<8);
a+=parsedArray[1]*(1<<16);
a+=parsedArray[0]*(1<<24);
return a;
}
return 0;
}

57
src/impl/shared/peers.c Normal file
View File

@ -0,0 +1,57 @@
#include <stdlib.h>
#include <string.h>
#include "peers.h"
int peers_to_string(struct peer_t *peers, int n, char *obuf) {
int l=0;
int total = PEER_DEV_MAX * (PEER_NAME_MAX + PEER_IP_MAX + 2) + 2;
memset(obuf, 0, total);
for (int i = 0; i < n; i++) {
l += strlen(peers[i].name) + strlen(peers[i].ip) + 2;
strcat(obuf, peers[i].name);
strcat(obuf, "\t");
strcat(obuf, peers[i].ip);
strcat(obuf, "\n");
obuf[l]=0;
}
return l;
}
int string_to_peers(char *input, struct peer_t* output) {
char *list[PEER_DEV_MAX];
char *name;
char *ip;
int size = sizeof(struct peer_t) * (PEER_DEV_MAX+1);
output = malloc(size);
memset(output, 0, size);
struct peet_t *peer;
int count = 0;
char *full;
full = strtok(input,"\n");
while(full != NULL) {
list[count++] = full;
full = strtok(NULL, "\n");
}
for(int i=0; i<count; i++) {
char *a = strtok(list[i],"\t");
char *b = strtok(NULL,"\t");
// Incase this doesn't work?
if(a==NULL) a = "unknown?";
else if(b==NULL) b = "-1.-1.-1.-1";
// Copy them into the output
strncpy(output[i].name, a, PEER_NAME_MAX);
strncpy(output[i].ip, b, PEER_IP_MAX);
}
return 1;
//return count;
}

View File

@ -1,4 +1,5 @@
#include <stdlib.h>
#include <string.h>
#include "states.h"

5
src/intf/ip_utils.h Normal file
View File

@ -0,0 +1,5 @@
#include <stdlib.h>
#define IP_SEGMENTS 4
unsigned long numericalIp(char *p);

9
src/intf/is_arg.h Normal file
View File

@ -0,0 +1,9 @@
#include <string.h>
int is_arg(int ac, char **argv, char *arg) {
if (ac < 2) return 0;
for (int x = 1; x < ac; x++)
if (0 == strcmp(argv[x], arg))
return x; // return position of arg
return 0; // arg not present
}

11
src/intf/peers.h Normal file
View File

@ -0,0 +1,11 @@
#define PEER_NAME_MAX 25
#define PEER_IP_MAX 15
#define PEER_DEV_MAX 25
struct peer_t {
char name[PEER_NAME_MAX];
char ip[PEER_IP_MAX];
};
int peers_to_string(struct peer_t *peers, int n, char *obuf);
int string_to_peers(char *input, struct peer_t *output);

4
src/intf/peersview.h Normal file
View File

@ -0,0 +1,4 @@
#include <gtk/gtk.h>
void peersview_new(GtkWidget *treeview);
void peersview_update(char *peers);

View File

@ -6,5 +6,7 @@
void status_icon_create(GtkWidget *window, char *off, char *on);
void status_icon_set_state(AppIndicatorStatus state);
void status_icon_set_quit_callback(int (*func)());
void status_icon_set_connect_callback(int (*func)());
void status_icon_set_disconnect_callback(int (*func)());