initial commit

This commit is contained in:
AlexandreRouma
2026-03-14 22:18:46 -04:00
commit 4fc730ae06
17 changed files with 2037 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
#include "daemon.h"
#include "net/net.h"
#include <atomic>
#include <mutex>
#include <condition_variable>
#include "flog/flog.h"
#include "../../version.h"
#include "signal.h"
#include "openssl/evp.h"
#include "openssl/rsa.h"
#include "openssl/aes.h"
#include "udp_worker.h"
namespace cmd::daemon {
// Sigint handling variables
bool stop = false;
std::mutex stopMtx;
std::condition_variable stopCond;
void sigintHandler(int sig) {
// Set the stop flag
stopMtx.lock();
stop = true;
stopMtx.unlock();
// Notify the main thread
stopCond.notify_all();
}
int main(std::shared_ptr<cli::Command> cmd) {
// Show the information
flog::info("VPN v{}.{}.{}", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD);
// Register the sigint handler
signal(SIGINT, sigintHandler);
// Start the network worker
UDPWorker udpWorker((*cmd)["port"]);
udpWorker.start();
// Show the status
flog::info("Ready.");
// Wait for sigint
while (true) {
// Wait for a notification
std::unique_lock<std::mutex> lck(stopMtx);
stopCond.wait(lck);
// Check if required to stop
if (stop) { break; }
}
// Remove the sigint handler
signal(SIGINT, NULL);
// Show a confirmation message
printf("\n");
flog::info("SIGINT received, stopping...");
// Stop the workers
udpWorker.stop();
// Final info message
flog::info("All done! Exiting.");
// Return successfully
return 0;
}
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "cli/cli.h"
namespace cmd::daemon {
int main(std::shared_ptr<cli::Command> cmd);
}

View File

@@ -0,0 +1,23 @@
#include "routing_worker.h"
namespace cmd::daemon {
RoutingWorker::RoutingWorker() {}
RoutingWorker::~RoutingWorker() {
// Stop if running
stop();
}
void RoutingWorker::start() {
}
void RoutingWorker::stop() {
}
void RoutingWorker::worker() {
}
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include <thread>
#include <mutex>
namespace cmd::daemon {
class RoutingWorker {
public:
// Default constructor
RoutingWorker();
// Destructor
~RoutingWorker();
/**
* Start the worker.
*/
void start();
/**
* Stop the worker.
*/
void stop();
private:
void worker();
std::thread workerThread;
};
}

View File

@@ -0,0 +1,63 @@
#include "udp_worker.h"
#include "flog/flog.h"
#define DGRAM_MAX_SIZE 0x10000
namespace cmd::daemon {
UDPWorker::UDPWorker() {}
UDPWorker::~UDPWorker() {
// Stop if running
stop();
}
void UDPWorker::start() {
// If already running, do nothing
if (running) { return; }
// Open the socket
sock = net::openudp(net::Address(), net::Address("0.0.0.0", port));
// Set the run flag
running = true;
// Start the thread
workerThread = std::thread(&UDPWorker::worker, this);
}
void UDPWorker::stop() {
// If not running, do nothing
if (!running) { return; }
// Clear the run flag
running = false;
// Close the socket
sock->close();
// Wait for the worker to exit
workerThread.join();
// Free the socket
sock.reset();
}
void UDPWorker::worker() {
// Allocate a buffer for the datagram
uint8_t* dgram = new uint8_t[DGRAM_MAX_SIZE];
// Receive loop
while (running) {
// Receive a datagram
net::Address raddr;
int len = sock->recv(dgram, DGRAM_MAX_SIZE, false, net::NO_TIMEOUT, &raddr);
if (len <= 0) { break; }
// Send it to the proccesing worker
// TODO
}
// Free the datagram buffer
delete[] dgram;
}
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include <thread>
#include <atomic>
#include <mutex>
#include "net/net.h"
namespace cmd::daemon {
class UDPWorker {
public:
// Default constructor
UDPWorker();
/**
* Create a UDP worker.
* @param port Port on which to listen for datagrams.
*/
UDPWorker(int port);
// Destructor
~UDPWorker();
/**
* Start the worker.
*/
void start();
/**
* Stop the worker.
*/
void stop();
private:
void worker();
int port = -1;
std::shared_ptr<net::Socket> sock;
std::atomic_bool running = false;
std::thread workerThread;
};
}

51
src/main.cpp Normal file
View File

@@ -0,0 +1,51 @@
#include <stdio.h>
#include <stdexcept>
#include "cli/cli.h"
#include "commands/daemon/daemon.h"
int main(int argc, char** argv) {
try {
// Define the daemon interface
cli::Interface daemonCLI;
daemonCLI.arg("port", 'p', 4269, "Port on which to run the VPN");
// Define the root command line interface
cli::Interface rootCLI;
rootCLI.arg("help", 'h', false, "Show help information");
rootCLI.subcmd("daemon", daemonCLI, "Run the VPN daemon");
// Parse the command line
auto cmd = cli::parse(rootCLI, argc, argv);
// If there is no subcommand, show help
if (!cmd.subcommand) {
// Show help
// TODO
// Return unsuccessfully
return -1;
}
// Execute the command
if (cmd.subcommand->command == "daemon") {
cmd::daemon::main(cmd.subcommand);
}
else {
// Show help
// TODO
// Return unsuccessfully
return -1;
}
// Return successfully
return 0;
}
catch (const std::exception& e) {
// Show the error
fprintf(stderr, "ERROR: %s\n", e.what());
// Return unsuccessfully
return -1;
}
}

13
src/version.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#ifndef VERSION_MAJOR
#define VERSION_MAJOR 0
#endif
#ifndef VERSION_MINOR
#define VERSION_MINOR 0
#endif
#ifndef VERSION_BUILD
#define VERSION_BUILD 0
#endif