91 lines
2.5 KiB
C++
91 lines
2.5 KiB
C++
#include <vector>
|
|
#include <cerrno>
|
|
#include <unistd.h>
|
|
#include <cstring>
|
|
#include <sys/prctl.h>
|
|
#include <csignal>
|
|
|
|
#include "../common/common.h"
|
|
|
|
// Store Handlers
|
|
__attribute__((const)) static std::vector<proxy_handler_t> &get_handlers() {
|
|
static std::vector<proxy_handler_t> handlers;
|
|
return handlers;
|
|
}
|
|
void _add_handler(unsigned char unique_id, proxy_handler_t handler) {
|
|
if (get_handlers().size() > unique_id && get_handlers()[unique_id] != NULL) {
|
|
PROXY_ERR("Duplicate ID: %i", (int) unique_id);
|
|
}
|
|
if (get_handlers().size() <= unique_id) {
|
|
get_handlers().resize(unique_id + 1);
|
|
}
|
|
get_handlers()[unique_id] = handler;
|
|
}
|
|
|
|
// Store Parent PID
|
|
static int parent_is_alive = 1;
|
|
static void sigusr1_handler(__attribute__((unused)) int sig) {
|
|
// Mark Parent As Dead
|
|
parent_is_alive = 0;
|
|
}
|
|
// Check State Of Proxy And Exit If Invalid
|
|
void _check_proxy_state() {
|
|
// Check Server State
|
|
if (!parent_is_alive) {
|
|
PROXY_ERR("%s", "Server Terminated");
|
|
}
|
|
}
|
|
|
|
// Main
|
|
int main(int argc, char *argv[]) {
|
|
// Ignore SIGINT, Send Signal To Parent
|
|
signal(SIGINT, SIG_IGN);
|
|
|
|
// Send Signal On Parent Death To Interrupt Connection Read/Write And Exit
|
|
prctl(PR_SET_PDEATHSIG, SIGUSR1);
|
|
struct sigaction sa;
|
|
sigemptyset(&sa.sa_mask);
|
|
sa.sa_flags = SA_NOCLDSTOP;
|
|
sa.sa_handler = &sigusr1_handler;
|
|
if (sigaction(SIGUSR1, &sa, NULL) == -1) {
|
|
PROXY_ERR("Unable To Install Signal Handler: %s", strerror(errno));
|
|
}
|
|
|
|
// Get Connection
|
|
if (argc != 3) {
|
|
PROXY_ERR("%s", "Invalid Arguments");
|
|
}
|
|
char *read_str = argv[1];
|
|
char *write_str = argv[2];
|
|
set_connection(atoi(read_str), atoi(write_str));
|
|
PROXY_INFO("%s", "Connected");
|
|
|
|
// Send Connection Message
|
|
write_string((char *) CONNECTED_MSG);
|
|
flush_write_cache();
|
|
|
|
// Loop
|
|
int running = is_connection_open();
|
|
while (running) {
|
|
unsigned char unique_id = read_byte();
|
|
if (get_handlers().size() > unique_id && get_handlers()[unique_id] != NULL) {
|
|
// Run Method
|
|
get_handlers()[unique_id]();
|
|
// Check If Connection Is Still Open
|
|
if (!is_connection_open()) {
|
|
// Exit
|
|
running = 0;
|
|
} else {
|
|
// Flush Write Cache
|
|
flush_write_cache();
|
|
}
|
|
} else {
|
|
PROXY_ERR("Invalid Method ID: %i", (int) unique_id);
|
|
}
|
|
}
|
|
|
|
// Exit
|
|
PROXY_INFO("%s", "Stopped");
|
|
return 0;
|
|
}
|