Skip to content

Commit

Permalink
Merge pull request #59 from hamishcoleman/main
Browse files Browse the repository at this point in the history
Convert edge to use a new mainloop
  • Loading branch information
hamishcoleman authored Dec 9, 2024
2 parents 6086ae2 + 74be511 commit b0b6944
Show file tree
Hide file tree
Showing 68 changed files with 1,851 additions and 781 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/quick_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
export CFLAGS="-fprofile-arcs -ftest-coverage"
export LDFLAGS="--coverage"
./scripts/hack_fakeautoconf.sh
make -j4
make -k -j4
make test.builtin test.units
shell: bash

Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ OBJS=\
src/initfuncs.o \
src/json.o \
src/logging.o \
src/mainloop.o \
src/management.o \
src/metrics.o \
src/minilzo.o \
Expand Down Expand Up @@ -338,6 +339,11 @@ clean.cov:
apps/*.gcno apps/*.gcda \
tools/*.gcno tools/*.gcda

.PHONY: iwyu
iwyu: iwyu.out
iwyu.out:
CFLAGS="-Xiwyu --error_always" $(MAKE) -k CC=include-what-you-use 2> iwyu.out

.PHONY: clean
clean: clean.cov
rm -rf $(OBJS) $(SUBDIR_LIBS) $(DOCS) $(COVERAGEDIR)/ *.dSYM *~
Expand Down
6 changes: 6 additions & 0 deletions apps/example_edge_embed.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <n3n/conffile.h>
#include <n3n/edge.h> // for edge_init_conf_defaults, edge_verify_conf
#include <n3n/mainloop.h> // for mainloop_register_fd, fd_info_proto
#include <n3n/peer_info.h> // for n3n_peer_add_by_hostname
#include <stdbool.h>
#include <stdio.h> // for snprintf, NULL
Expand Down Expand Up @@ -68,6 +69,11 @@ int main () {
return -1;
}

#ifndef _WIN32
// TODO: this internal fn should not be called publicly
mainloop_register_fd(tuntap.fd, fd_info_proto_tuntap);
#endif

eee = edge_init(&conf, &rc);
if(eee == NULL) {
exit(1);
Expand Down
49 changes: 22 additions & 27 deletions apps/n3n-edge.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@


#include <ctype.h> // for isspace
#include <connslot/connslot.h> // for slots_listen_close
#include <errno.h> // for errno
#include <getopt.h> // for required_argument, no_argument
#include <inttypes.h> // for PRIu64
Expand All @@ -29,6 +28,7 @@
#include <n3n/ethernet.h> // for macaddr_str, macstr_t
#include <n3n/initfuncs.h> // for n3n_initfuncs()
#include <n3n/logging.h> // for traceEvent
#include <n3n/mainloop.h> // for mainloop_register_fd
#include <n3n/tests.h> // for test_hashing
#include <n3n/random.h> // for n3n_rand_seeds, n3n_rand_seeds_s...
#include <n3n/transform.h> // for n3n_transform_lookup_id
Expand Down Expand Up @@ -697,7 +697,7 @@ static void term_handler (int sig) {
#endif

#ifdef _WIN32
struct n3n_runtime_data *windows_stop_eee;
extern int windows_stop_fd;

// Note well, this gets called from a brand new thread, thus is completely
// different to how signals work in POSIX
Expand All @@ -718,7 +718,7 @@ BOOL WINAPI ConsoleCtrlHandler (DWORD sig) {
// mainloop to notice that we are no longer wanting to run.
//
// something something, darkside
slots_listen_close(windows_stop_eee->mgmt_slots);
closesocket(windows_stop_fd);

switch(sig) {
case CTRL_CLOSE_EVENT:
Expand All @@ -743,14 +743,8 @@ int main (int argc, char* argv[]) {
uint8_t seek_answer = 1; /* expecting answer from supernode */
time_t now, last_action = 0; /* timeout */
macstr_t mac_buf; /* output mac address */
fd_set socket_mask; /* for supernode answer */
struct timeval wait_time; /* timeout for sn answer */
peer_info_t *scan, *scan_tmp; /* supernode iteration */

uint16_t expected = sizeof(uint16_t);
uint16_t position = 0;
uint8_t pktbuf[N2N_SN_PKTBUF_SIZE + sizeof(uint16_t)]; /* buffer + prepended buffer length in case of tcp */

#ifdef HAVE_LIBCAP
cap_t caps;
#endif
Expand Down Expand Up @@ -830,6 +824,7 @@ int main (int argc, char* argv[]) {
traceEvent(TRACE_ERROR, "failed in edge_init");
exit(1);
}
eee->keep_running = &keep_on_running;

switch(eee->conf.tuntap_ip_mode) {
case TUNTAP_IP_MODE_SN_ASSIGN:
Expand All @@ -850,11 +845,18 @@ int main (int argc, char* argv[]) {
// for the sake of quickly establishing connection. REVISIT when a more elegant way to re-use main loop code
// is found

// find at least one supernode alive to faster establish connection
// find at least one supernode alive to faster establish connection.
// exceptions:
if((HASH_COUNT(eee->conf.supernodes) <= 1) || (eee->conf.connect_tcp) || (eee->conf.shared_secret)) {
// skip the initial supernode ping
traceEvent(TRACE_DEBUG, "skip PING to supernode");
if(eee->conf.connect_tcp) {
traceEvent(TRACE_DEBUG, "skip PING to supernode: TCP mode");
runlevel = 2;
}
if(eee->conf.shared_secret) {
traceEvent(TRACE_DEBUG, "skip PING to supernode: shared secret");
runlevel = 2;
}
if(HASH_COUNT(eee->conf.supernodes) <= 1) {
traceEvent(TRACE_DEBUG, "skip PING to supernode: only one supernode");
runlevel = 2;
}

Expand Down Expand Up @@ -957,6 +959,10 @@ int main (int argc, char* argv[]) {
eee->conf.mtu,
eee->conf.metric) < 0)
exit(1);
#ifndef _WIN32
// TODO: this internal fn should not be called publicly
mainloop_register_fd(eee->device.fd, fd_info_proto_tuntap);
#endif
in_addr_t addr = eee->conf.tuntap_v4.net_addr;
struct in_addr *tmp = (struct in_addr *)&addr;
traceEvent(TRACE_NORMAL, "created local tap device IPv4: %s/%u, MAC: %s",
Expand All @@ -970,19 +976,10 @@ int main (int argc, char* argv[]) {

// we usually wait for some answer, there however are exceptions when going back to a previous runlevel
if(seek_answer) {
FD_ZERO(&socket_mask);
FD_SET(eee->sock, &socket_mask);
wait_time.tv_sec = BOOTSTRAP_TIMEOUT;
wait_time.tv_usec = 0;

if(select(eee->sock + 1, &socket_mask, NULL, NULL, &wait_time) > 0) {
if(FD_ISSET(eee->sock, &socket_mask)) {
mainloop_runonce(eee);

fetch_and_eventually_process_data(eee, eee->sock,
pktbuf, &expected, &position,
now);
}
}
// FIXME: the mainloop could wait for BOOTSTRAP_TIMEOUT, not its
// usual timeout ?!?
}
seek_answer = 1;

Expand Down Expand Up @@ -1061,11 +1058,9 @@ int main (int argc, char* argv[]) {
signal(SIGINT, term_handler);
#endif
#ifdef _WIN32
windows_stop_eee = eee;
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
#endif

eee->keep_running = &keep_on_running;
traceEvent(TRACE_NORMAL, "edge started");
rc = run_edge_loop(eee);
print_edge_stats(eee);
Expand Down
61 changes: 47 additions & 14 deletions apps/n3n-supernode.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,15 +351,10 @@ static void n3n_sn_config (int argc, char **argv, char *defname, struct n3n_runt

/* *************************************************** */

static bool keep_running = true;
static bool keep_on_running = true;

#if defined(__linux__) || defined(_WIN32)
#ifdef _WIN32
BOOL WINAPI term_handler (DWORD sig)
#else
static void term_handler (int sig)
#endif
{
#ifndef _WIN32
static void term_handler (int sig) {
static int called = 0;

if(called) {
Expand All @@ -370,12 +365,44 @@ static void term_handler (int sig)
called = 1;
}

keep_running = false;
keep_on_running = false;
}
#endif

#ifdef _WIN32
extern int windows_stop_fd;

// Note well, this gets called from a brand new thread, thus is completely
// different to how signals work in POSIX
BOOL WINAPI ConsoleCtrlHandler (DWORD sig) {
// Tell the mainloop to exit next time it wakes
keep_on_running = false;

traceEvent(TRACE_INFO, "starting stopping");
// The windows environment claims to support signals, but they dont
// interrupt a running select() statement. Also, this console handler
// is run in its own thread, so it is also not interrupting the select()
// This is clearly contrary to how select was designed to be used and it
// makes process termination annoying, so we need a workaround.
//
// Since windows usually has a managment TCP port listening in the
// select fdset, we can close that - this immediately causes the select
// to return with activity on that file descriptor and allows the
// mainloop to notice that we are no longer wanting to run.
//
// something something, darkside
closesocket(windows_stop_fd);

switch(sig) {
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
// Will terminate us after we return, blocking it to cleanup
Sleep(INFINITE);
}
return(TRUE);
#endif
}
#endif /* defined(__linux__) || defined(_WIN32) */
#endif

/* *************************************************** */

Expand Down Expand Up @@ -546,6 +573,12 @@ int main (int argc, char * argv[]) {
}
traceEvent(TRACE_NORMAL, "supernode is listening on TCP %u (management)", sss_node.conf.mgmt_port);
}
#ifdef _WIN32
// HACK!
// Remove this once the supernode users mainloop and it also supports
// stopping on windows
windows_stop_fd = sss_node.mgmt_slots->listen[0];
#endif

n3n_config_setup_sessiondir(&sss_node.conf);

Expand Down Expand Up @@ -606,15 +639,15 @@ int main (int argc, char * argv[]) {

traceEvent(TRACE_NORMAL, "supernode started");

#ifdef __linux__
#ifndef _WIN32
signal(SIGPIPE, SIG_IGN);
signal(SIGTERM, term_handler);
signal(SIGINT, term_handler);
#endif
#ifdef _WIN32
SetConsoleCtrlHandler(term_handler, TRUE);
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
#endif

sss_node.keep_running = &keep_running;
sss_node.keep_running = &keep_on_running;
return run_sn_loop(&sss_node);
}
2 changes: 2 additions & 0 deletions include/auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@

#include <stddef.h> // for size_t
#include <stdint.h> // for uint8_t, uint32_t

#include "n2n.h" // for n2n_private_public_key_t, n2n_community_t, N2N_A...
#include "n2n_typedefs.h"


int bin_to_ascii(char *out, uint8_t *in, size_t in_len);
Expand Down
2 changes: 2 additions & 0 deletions include/hexdump.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#ifndef HEXDUMP_H
#define HEXDUMP_H

#include <stdio.h>

void fhexdump(unsigned int display_addr, void *in, int size, FILE *stream);

#endif
2 changes: 0 additions & 2 deletions include/n2n.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
#include <stdint.h> // for uint8_t, uint64_t, uint32_t, uint16_t
#include <sys/types.h> // for time_t
#include <unistd.h> // for close
#define closesocket(a) close(a)

#ifdef __linux__
#define N2N_CAN_NAME_IFACE 1
Expand Down Expand Up @@ -141,7 +140,6 @@ void update_supernode_reg (struct n3n_runtime_data * eee, time_t nowTime);
void readFromIPSocket (struct n3n_runtime_data * eee, int in_sock);
void edge_term (struct n3n_runtime_data *eee);
void edge_send_packet2net (struct n3n_runtime_data *eee, uint8_t *tap_pkt, size_t len);
void edge_read_from_tap (struct n3n_runtime_data *eee);
int run_edge_loop (struct n3n_runtime_data *eee);
int quick_edge_init (char *device_name, char *community_name,
char *encrypt_key, char *device_mac,
Expand Down
7 changes: 0 additions & 7 deletions include/n2n_define.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,5 @@ enum n3n_event_topic {
#define N2N_TRANSFORM_ID_USER_START 64
#define N2N_TRANSFORM_ID_MAX 65535

#ifndef max
#define max(a, b) (((a) < (b)) ? (b) : (a))
#endif

#ifndef min
#define min(a, b) (((a) >(b)) ? (b) : (a))
#endif

#endif
33 changes: 3 additions & 30 deletions include/n2n_typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,13 @@ typedef char devstr_t[N2N_IFNAMSIZ];


typedef struct tuntap_dev {
#ifndef _WIN32
int fd;
devstr_t dev_name;
#endif
in_addr_t ip_addr;
n2n_mac_t mac_addr;
uint16_t mtu;
devstr_t dev_name;
#ifdef _WIN32
HANDLE device_handle;
char *device_name;
Expand Down Expand Up @@ -375,34 +377,6 @@ struct network_traffic_filter {

/* *************************************************** */

/* Callbacks allow external programs to attach functions in response to
* N2N events. */
typedef struct n2n_edge_callbacks {
/* The supernode registration has been updated */
void (*sn_registration_updated)(struct n3n_runtime_data *eee, time_t now, const n2n_sock_t *sn);

/* A packet has been received from a peer. N2N_DROP can be returned to
* drop the packet. The packet payload can be modified. This only allows
* the packet size to be reduced */
n2n_verdict (*packet_from_peer)(struct n3n_runtime_data *eee, const n2n_sock_t *peer, uint8_t *payload, uint16_t *payload_size);

/* A packet has been received from the TAP interface. N2N_DROP can be
* returned to drop the packet. The packet payload can be modified.
* This only allows the packet size to be reduced */
n2n_verdict (*packet_from_tap)(struct n3n_runtime_data *eee, uint8_t *payload, uint16_t *payload_size);

/* Called whenever the IP address of the TAP interface changes. */
void (*ip_address_changed)(struct n3n_runtime_data *eee, uint32_t old_ip, uint32_t new_ip);

/* Called periodically in the main loop. */
void (*main_loop_period)(struct n3n_runtime_data *eee, time_t now);

/* Called when a new socket to supernode is created. */
void (*sock_opened)(struct n3n_runtime_data *eee);
} n2n_edge_callbacks_t;

/* *************************************************** */

typedef enum n2n_transform {
N2N_TRANSFORM_ID_INVAL = 0,
N2N_TRANSFORM_ID_NULL = 1,
Expand Down Expand Up @@ -554,7 +528,6 @@ struct n3n_runtime_data {
n2n_trans_op_t transop; /**< The transop to use when encoding */
n2n_trans_op_t transop_lzo; /**< The transop for LZO compression */
n2n_trans_op_t transop_zstd; /**< The transop for ZSTD compression */
n2n_edge_callbacks_t cb; /**< API callbacks */
SN_SELECTION_CRITERION_DATA_TYPE sn_selection_criterion_common_data;

/* Sockets */
Expand Down
3 changes: 2 additions & 1 deletion include/n2n_wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ int fill_sockaddr (struct sockaddr * addr,
const n2n_sock_t * sock);

int fill_n2nsock (n2n_sock_t* sock,
const struct sockaddr* sa);
const struct sockaddr* sa,
int type);

int encode_PACKET (uint8_t * base,
size_t * idx,
Expand Down
Loading

0 comments on commit b0b6944

Please sign in to comment.