structs, constructors, destructors, logging

This commit is contained in:
Timerix22 2024-01-04 17:21:44 +06:00
parent e2dd49bbcb
commit a7bfca5f50
10 changed files with 631 additions and 158 deletions

View File

@ -68,7 +68,7 @@ case "$TASK" in
;; ;;
# creates executable with debug info and no optimizations # creates executable with debug info and no optimizations
build_exec_dbg) build_exec_dbg)
C_ARGS="-O0 -g3" C_ARGS="-O0 -g3 -DDEBUG"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=

67
src/Connectors.c Normal file
View File

@ -0,0 +1,67 @@
#include "port-tunnel.h"
////////////////////////////////////////
// ConnectorUDP //
////////////////////////////////////////
void ConnectorUDP_construct(ConnectorUDP* ptr, knIPV4Endpoint listener_end, knIPV4Endpoint connector_end, OutputMode out_mode){
__PipeStorage_construct(&ptr->pipes);
if(out_mode == OutputMode_Bind){
tryLast(knSocketUDP_open(true), m_s, ;);
ptr->main_sock = m_s.value.VoidPtr;
tryLast(knSocketUDP_bind(ptr->main_sock, connector_end), _m7u7, ;);
}
else if(out_mode == OutputMode_Send){
tryLast(knSocketUDP_open(false), m_s, ;);
ptr->main_sock = m_s.value.VoidPtr;
}
else throw("no output mode has been selected");
ptr->listener_end = listener_end;
ptr->connector_end = connector_end;
ptr->out_mode = out_mode;
}
void ConnectorUDP_destruct(ConnectorUDP* ptr){
__PipeStorage_destruct(&ptr->pipes);
tryLast(knSocketUDP_close(ptr->main_sock), _m864, ;);
}
void ConnectorUDP_start(ConnectorUDP* ptr){
__PipeStorage_startGCAsync(&ptr->pipes);
}
////////////////////////////////////////
// ConnectorTCP //
////////////////////////////////////////
void ConnectorTCP_construct(ConnectorTCP* ptr, knIPV4Endpoint listener_end, knIPV4Endpoint connector_end, OutputMode out_mode){
__PipeStorage_construct(&ptr->pipes);
if(out_mode == OutputMode_Bind){
tryLast(knSocketTCP_open(true), m_s, ;);
ptr->main_sock = m_s.value.VoidPtr;
tryLast(knSocketTCP_bindAndListen(ptr->main_sock, connector_end), _m7u7, ;);
}
else if(out_mode == OutputMode_Send){
tryLast(knSocketTCP_open(false), m_s, ;);
ptr->main_sock = m_s.value.VoidPtr;
}
else throw("no output mode has been selected");
ptr->listener_end = listener_end;
ptr->connector_end = connector_end;
ptr->out_mode = out_mode;
}
void ConnectorTCP_destruct(ConnectorTCP* ptr){
__PipeStorage_destruct(&ptr->pipes);
tryLast(knSocketTCP_close(ptr->main_sock), _m864, ;);
}
void ConnectorTCP_start(ConnectorTCP* ptr){
__PipeStorage_startGCAsync(&ptr->pipes);
}

43
src/Listeners.c Normal file
View File

@ -0,0 +1,43 @@
#include "port-tunnel.h"
////////////////////////////////////////
// ListenerUDP //
////////////////////////////////////////
void ListenerUDP_construct(ListenerUDP* ptr, knIPV4Endpoint listener_end){
__PipeStorage_construct(&ptr->pipes);
tryLast(knSocketUDP_open(true), m_s, ;);
ptr->main_sock = m_s.value.VoidPtr;
tryLast(knSocketUDP_bind(ptr->main_sock, listener_end), _m7u7, ;);
ptr->connector_end = knIPV4Endpoint_INVALID;
}
void ListenerUDP_start(ListenerUDP* ptr){
}
void ListenerUDP_destruct(ListenerUDP* ptr){
__PipeStorage_destruct(&ptr->pipes);
tryLast(knSocketUDP_close(ptr->main_sock), _m864, ;);
}
////////////////////////////////////////
// ListenerTCP //
////////////////////////////////////////
void ListenerTCP_construct(ListenerTCP* ptr, knIPV4Endpoint listener_end){
__PipeStorage_construct(&ptr->pipes);
tryLast(knSocketTCP_open(true), m_s, ;);
ptr->main_sock = m_s.value.VoidPtr;
tryLast(knSocketTCP_bindAndListen(ptr->main_sock, listener_end), _m7u7, ;);
ptr->connector_end = knIPV4Endpoint_INVALID;
}
void ListenerTCP_destruct(ListenerTCP* ptr){
__PipeStorage_destruct(&ptr->pipes);
tryLast(knSocketTCP_close(ptr->main_sock), _m864, ;);
}
void ListenerTCP_start(ListenerTCP* ptr){
}

22
src/PipeStorage.c Normal file
View File

@ -0,0 +1,22 @@
#include "port-tunnel.h"
void __PipeStorage_construct(PipeStorage* s){
s->is_gc_stopped = true;
s->last_check_time = 0;
s->table = Hashtable_create();
}
void __PipeStorage_destruct(PipeStorage* s){
__PipeStorage_stopGCAsync(s);
Hashtable_free(s->table);
}
void __PipeStorage_startGCAsync(PipeStorage* s){
}
void __PipeStorage_stopGCAsync(PipeStorage* s){
s->is_gc_stopped = true;
s->last_check_time = 0;
}

65
src/Pipes.c Normal file
View File

@ -0,0 +1,65 @@
#include "port-tunnel.h"
////////////////////////////////////////
// PipeBase //
////////////////////////////////////////
static void PipeBase_construct(PipeBase* pipe){
pipe->is_closed = false;
pipe->is_transmitting = false;
pipe->last_transmit_time = getTimeUsec();
}
////////////////////////////////////////
// PipeUDP //
////////////////////////////////////////
void PipeUDP_construct(PipeUDP* pipe, knSocketUDP* pipe_in_sock, knIPV4Endpoint pipe_out_end){
PipeBase_construct(&pipe->base);
pipe->pipe_in_sock = pipe_in_sock;
pipe->pipe_out_end = pipe_out_end;
}
void PipeUDP_destruct(PipeUDP* pipe){
Maybe m = knSocketUDP_shutdown(pipe->pipe_in_sock, knShutdownType_Both);
if(m.errmsg)
logError("%s", m.errmsg);
m = knSocketUDP_close(pipe->pipe_in_sock);
if(m.errmsg)
logError("%s", m.errmsg);
}
void PipeUDP_startAsync(PipeUDP* pipe){
}
void PipeUDP_stop(PipeUDP* pipe){
}
////////////////////////////////////////
// PipeTCP //
////////////////////////////////////////
void PipeTCP_construct(PipeTCP* pipe, knSocketTCP* pipe_in_sock, knIPV4Endpoint pipe_out_end){
PipeBase_construct(&pipe->base);
pipe->pipe_in_sock = pipe_in_sock;
pipe->pipe_out_end = pipe_out_end;
}
void PipeTCP_destruct(PipeTCP* pipe){
Maybe m = knSocketTCP_shutdown(pipe->pipe_in_sock, knShutdownType_Both);
if(m.errmsg)
logError("%s", m.errmsg);
m = knSocketTCP_close(pipe->pipe_in_sock);
if(m.errmsg)
logError("%s", m.errmsg);
}
void PipeTCP_startAsync(PipeTCP* pipe){
}
void PipeTCP_stop(PipeTCP* pipe){
}

View File

@ -2,19 +2,25 @@
// option help definition // option help definition
#define HELP_OPT(ALIASES, PARAMS, DESCRIPTION...) \ #define HELP_OPT(ALIASES, PARAMS, DESCRIPTION...) \
FWHI " " ALIASES " " PARAMS FGRY "\n" DESCRIPTION FWHI" " ALIASES " " PARAMS FGRY "\n" DESCRIPTION
// option parameter help definition // option parameter help definition
#define HELP_PRM(PNAME) \ #define HELP_PRM(PNAME) \
FWHI "[" FCYN PNAME FWHI "]" FWHI"[" FCYN PNAME FWHI"]"
// option nullable parameter help definition // option nullable parameter help definition
#define HELP_PRMN(PNAME) \ #define HELP_PRMN(PNAME) \
FWHI "[" FCYN PNAME FWHI "?]" FWHI"[" FCYN PNAME FWHI"?]"
// option parameter1/parameter2 help definition // option parameter1/parameter2 help definition
#define HELP_PRM2(PNAME1, PNAME2) \ #define HELP_PRM2(PNAME1, PNAME2) \
FWHI "[" FCYN PNAME1 FWHI "/" FCYN PNAME2 FWHI "]" FWHI"[" FCYN PNAME1 FWHI"/" FCYN PNAME2 FWHI"]"
#define HELP_PRM3(PNAME1, PNAME2, PNAME3) \
FWHI"[" FCYN PNAME1 FWHI"/" FCYN PNAME2 FWHI"/" FCYN PNAME3 FWHI"]"
#define HELP_PRM4(PNAME1, PNAME2, PNAME3, PNAME4) \
FWHI"[" FCYN PNAME1 FWHI"/" FCYN PNAME2 FWHI"/" FCYN PNAME3 FWHI"/" FCYN PNAME4 FWHI"]"
const char* help_message = ( const char* help_message = (
FWHI"Usage: port-tunnel " FWHI"Usage: port-tunnel "
@ -72,4 +78,8 @@ const char* help_message = (
HELP_OPT("-e, --encrypt", HELP_OPT("-e, --encrypt",
HELP_PRM("key"), HELP_PRM("key"),
" Encrypt outgoing packets with a key.\n") " Encrypt outgoing packets with a key.\n")
HELP_OPT("-v, --verbosity, --log-level",
HELP_PRM4("debug", "info", "warning", "error"),
" Sets log verbocity level (default=info).\n")
); );

View File

@ -1,153 +0,0 @@
#include "../kerep/src/base/base.h"
#include "../kerep/src/Network/network.h"
extern const char* help_message;
int errs(char* err_msg){
throw(err_msg);
return -1;
}
#define argIs(STR) cptr_equals(arg, STR)
#define argNext() argv[++argi < argc ? argi : errs(cptr_concat("option '",arg,"' must have a parameter"))]
typedef enum {
TunnelProtocol_None,
TunnelProtocol_TCP,
TunnelProtocol_UDP
} TunnelProtocol;
typedef enum {
InputMode_None,
InputMode_Listen,
InputMode_Connect
} InputMode;
typedef enum {
OutputMode_None,
OutputMode_Bind,
OutputMode_Send
} OutputMode;
int main(int argc, const char* const* argv){
kt_beginInit(false);
kt_initKerepTypes();
// kt_register(...);
kt_endInit();
TunnelProtocol tunnel_protocol = TunnelProtocol_None;
InputMode input_mode = InputMode_None;
OutputMode output_mode = OutputMode_None;
knIPV4Endpoint input_end = knIPV4Endpoint_INVALID;
knIPV4Endpoint output_end = knIPV4Endpoint_INVALID;
const char* encryption_key = NULL;
const char* decryption_key = NULL;
if(argc < 2)
throw("No arguments provided. Run the program with argument -h to see help message");
for(int argi = 1; argi < argc; argi++){
const char* arg = argv[argi];
if(argIs("-h") || argIs("--help") || argIs("/?")){
kprintf("%s"FGRY"\n", help_message);
return 0;
}
else if(argIs("-p") || argIs("--protocol")){
if(tunnel_protocol != TunnelProtocol_None)
throw(cptr_concat("invalid option '",arg,"': tunnel protocol has been set already"));
const char* protocol_str = argNext();
char* protocol_str_lower = cptr_toLower(protocol_str);
if(cptr_equals(protocol_str_lower, "tcp"))
tunnel_protocol = TunnelProtocol_TCP;
else if(cptr_equals(protocol_str_lower, "udp"))
tunnel_protocol = TunnelProtocol_UDP;
else throw(cptr_concat("invalid parameter '",protocol_str,"': unknown protocol"));
free(protocol_str_lower);
}
else if(argIs("-l") || argIs("--listen")){
if(input_mode != InputMode_None)
throw(cptr_concat("invalid option '",arg,"': input mode has been set already"));
input_mode = InputMode_Listen;
const char* input_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(input_end_str, &input_end), _m8612, ;);
}
else if(argIs("-c") || argIs("--connect")){
if(input_mode != InputMode_None)
throw(cptr_concat("invalid option '",arg,"': input mode has been set already"));
input_mode = InputMode_Connect;
const char* input_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(input_end_str, &input_end), _m2612, ;);
}
else if(argIs("-s") || argIs("--send-to")){
if(output_mode != OutputMode_None)
throw(cptr_concat("invalid option '",arg,"': output mode has been set already"));
if(input_mode != InputMode_Connect)
throw(cptr_concat("invalid option '",arg,"': out endpoint setting is avaliable only in 'connect' program mode"));
output_mode = OutputMode_Send;
const char* output_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(output_end_str, &output_end), _m8613, ;);
}
else if(argIs("-b") || argIs("--bind-to")){
if(output_mode != OutputMode_None)
throw(cptr_concat("invalid option '",arg,"': output mode has been set already"));
if(input_mode != InputMode_Connect)
throw(cptr_concat("invalid option '",arg,"': out endpoint setting is avaliable only in 'connect' program mode"));
output_mode = OutputMode_Bind;
const char* output_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(output_end_str, &output_end), _m2613, ;);
}
else if(argIs("-e") || argIs("--encrypt")){
if(encryption_key != NULL)
throw(cptr_concat("invalid option '",arg,"': encryption key has been set already"));
encryption_key = argNext();
if(cptr_length(encryption_key) < 16)
throw("too short encryption key (min length 16)");
if(cptr_length(encryption_key) > 512)
throw("too long encryption key (max length 512)");
}
else if(argIs("-d") || argIs("--decrypt")){
if(decryption_key != NULL)
throw(cptr_concat("invalid option '",arg,"': decryption key has been set already"));
decryption_key = argNext();
if(cptr_length(decryption_key) < 16)
throw("too short decryption key (min length 16)");
if(cptr_length(decryption_key) > 512)
throw("too long decryption key (max length 512)");
}
else {
throw(cptr_concat("invalid argument: ", arg));
}
}
kprintf("tunnel_protocol: %i\n", tunnel_protocol);
kprintf("input_mode: %i\n", input_mode);
kprintf("output_mode: %i\n", output_mode);
char* temps;
if(!knIPV4Endpoint_isINVALID(input_end)){
temps = knIPV4Endpoint_toString(&input_end);
kprintf("input_end: %s\n", temps);
free(temps);
}
else kprintf("input_end: INVALID\n");
if(!knIPV4Endpoint_isINVALID(output_end)){
temps = knIPV4Endpoint_toString(&output_end);
kprintf("output_end: %s\n", temps);
free(temps);
}
else kprintf("output_end: INVALID\n");
kprintf("encryption_key: %s\n", encryption_key ? encryption_key : "NULL");
kprintf("decryption_key: %s\n", decryption_key ? decryption_key : "NULL");
return 0;
}

213
src/port-tunnel.c Normal file
View File

@ -0,0 +1,213 @@
#include "port-tunnel.h"
kt_define(PipeBase, NULL, NULL)
kt_define(PipeUDP, (freeMembers_t)PipeUDP_destruct, NULL)
kt_define(PipeTCP, (freeMembers_t)PipeTCP_destruct, NULL)
kt_define(PipeStorage, (freeMembers_t)__PipeStorage_destruct, NULL)
kt_define(ListenerUDP, (freeMembers_t)ListenerUDP_destruct, NULL)
kt_define(ListenerTCP, (freeMembers_t)ListenerTCP_destruct, NULL)
kt_define(ConnectorUDP, (freeMembers_t)ConnectorUDP_destruct, NULL)
kt_define(ConnectorTCP, (freeMembers_t)ConnectorTCP_destruct, NULL)
LogLevel _log_level = LogLevel_Info;
int errs(char* err_msg){
throw(err_msg);
return -1;
}
#define argIs(STR) cptr_equals(arg, STR)
#define argNext() argv[++argi < argc ? argi : errs(cptr_concat("option '",arg,"' must have a parameter"))]
int main(int argc, const char* const* argv){
#ifdef DEBUG
kt_beginInit(true);
#else
kt_beginInit(false);
#endif
kt_initKerepTypes();
kt_register(PipeBase);
kt_register(PipeUDP);
kt_register(PipeTCP);
kt_register(PipeStorage);
kt_register(ListenerUDP);
kt_register(ListenerTCP);
kt_register(ConnectorUDP);
kt_register(ConnectorTCP);
kt_endInit();
tryLast(kn_tryInit(), _m11257, ;)
TunnelProtocol tunnel_protocol = TunnelProtocol_None;
InputMode input_mode = InputMode_None;
OutputMode output_mode = OutputMode_None;
knIPV4Endpoint listener_end = knIPV4Endpoint_INVALID;
knIPV4Endpoint connector_end = knIPV4Endpoint_INVALID;
const char* encryption_key = NULL;
const char* decryption_key = NULL;
LogLevel log_level =
#ifdef DEBUG
LogLevel_Debug;
#else
LogLevel_Info;
#endif
// parse args
if(argc < 2)
throw("No arguments provided. Run the program with argument -h to see help message");
for(int argi = 1; argi < argc; argi++){
const char* arg = argv[argi];
if(argIs("-h") || argIs("--help") || argIs("/?")){
kprintf("%s"FGRY"", help_message);
return 0;
}
else if(argIs("-p") || argIs("--protocol")){
if(tunnel_protocol != TunnelProtocol_None)
throw(cptr_concat("invalid option '",arg,"': tunnel protocol has been set already"));
const char* protocol_str = argNext();
char* protocol_str_lower = cptr_toLower(protocol_str);
if(cptr_equals(protocol_str_lower, "tcp"))
tunnel_protocol = TunnelProtocol_TCP;
else if(cptr_equals(protocol_str_lower, "udp"))
tunnel_protocol = TunnelProtocol_UDP;
else throw(cptr_concat("invalid parameter '",protocol_str,"': unknown protocol"));
free(protocol_str_lower);
}
else if(argIs("-l") || argIs("--listen")){
if(input_mode != InputMode_None)
throw(cptr_concat("invalid option '",arg,"': input mode has been set already"));
input_mode = InputMode_Listen;
const char* input_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(input_end_str, &listener_end), _m8612, ;);
}
else if(argIs("-c") || argIs("--connect")){
if(input_mode != InputMode_None)
throw(cptr_concat("invalid option '",arg,"': input mode has been set already"));
input_mode = InputMode_Connect;
const char* input_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(input_end_str, &listener_end), _m2612, ;);
}
else if(argIs("-s") || argIs("--send-to")){
if(output_mode != OutputMode_None)
throw(cptr_concat("invalid option '",arg,"': output mode has been set already"));
if(input_mode != InputMode_Connect)
throw(cptr_concat("invalid option '",arg,"': out endpoint setting is avaliable only in 'connect' program mode"));
output_mode = OutputMode_Send;
const char* output_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(output_end_str, &connector_end), _m8613, ;);
}
else if(argIs("-b") || argIs("--bind-to")){
if(output_mode != OutputMode_None)
throw(cptr_concat("invalid option '",arg,"': output mode has been set already"));
if(input_mode != InputMode_Connect)
throw(cptr_concat("invalid option '",arg,"': out endpoint setting is avaliable only in 'connect' program mode"));
output_mode = OutputMode_Bind;
const char* output_end_str = argNext();
tryLast(knIPV4Endpoint_fromStr(output_end_str, &connector_end), _m2613, ;);
}
else if(argIs("-e") || argIs("--encrypt")){
if(encryption_key != NULL)
throw(cptr_concat("invalid option '",arg,"': encryption key has been set already"));
encryption_key = argNext();
if(cptr_length(encryption_key) < 16)
throw("too short encryption key (min length 16)");
if(cptr_length(encryption_key) > 512)
throw("too long encryption key (max length 512)");
}
else if(argIs("-d") || argIs("--decrypt")){
if(decryption_key != NULL)
throw(cptr_concat("invalid option '",arg,"': decryption key has been set already"));
decryption_key = argNext();
if(cptr_length(decryption_key) < 16)
throw("too short decryption key (min length 16)");
if(cptr_length(decryption_key) > 512)
throw("too long decryption key (max length 512)");
}
else if(argIs("-v") || argIs("--verbosity") || argIs("--log-level")){
char* log_level_str = argNext();
char* opt = cptr_toLower(log_level_str);
if(cptr_equals(opt, "debug"))
log_level = LogLevel_Debug;
else if(cptr_equals(opt, "info"))
log_level = LogLevel_Info;
else if(cptr_equals(opt, "warning"))
log_level = LogLevel_Warning;
else if(cptr_equals(opt, "error"))
log_level = LogLevel_Error;
else throw(cptr_concat("invalid parameter '",log_level_str,"': unknown log_level"));
free(opt);
}
else {
throw(cptr_concat("invalid argument: ", arg));
}
}
setLogLevel(log_level);
// print parsed args
logDebug("tunnel_protocol: %i", tunnel_protocol);
logDebug("input_mode: %i", input_mode);
logDebug("output_mode: %i", output_mode);
char* temps;
if(!knIPV4Endpoint_isINVALID(listener_end)){
temps = knIPV4Endpoint_toString(&listener_end);
logDebug("listener_end: %s", temps);
free(temps);
}
else logDebug("listener_end: INVALID");
if(!knIPV4Endpoint_isINVALID(connector_end)){
temps = knIPV4Endpoint_toString(&connector_end);
logDebug("connector_end: %s", temps);
free(temps);
}
else logDebug("connector_end: INVALID");
logDebug("encryption_key: %s", encryption_key ? encryption_key : "NULL");
logDebug("decryption_key: %s", decryption_key ? decryption_key : "NULL");
logDebug("log_level: %i", log_level);
// create and run Listener or Connector
if(input_mode == InputMode_Connect){
if(tunnel_protocol == TunnelProtocol_UDP){
ConnectorUDP connector;
ConnectorUDP_construct(&connector, listener_end, connector_end, output_mode);
ConnectorUDP_start(&connector);
ConnectorUDP_destruct(&connector);
}
else if(tunnel_protocol == TunnelProtocol_TCP){
ConnectorTCP connector;
ConnectorTCP_construct(&connector, listener_end, connector_end, output_mode);
ConnectorTCP_start(&connector);
ConnectorTCP_destruct(&connector);
}
else throw("no tunnel protocol has been selected");
}
else if(input_mode == InputMode_Listen){
if(tunnel_protocol == TunnelProtocol_UDP){
ListenerUDP listener;
ListenerUDP_construct(&listener, listener_end);
ListenerUDP_start(&listener);
ListenerUDP_destruct(&listener);
}
else if(tunnel_protocol == TunnelProtocol_TCP){
ListenerTCP listener;
ListenerTCP_construct(&listener, listener_end);
ListenerTCP_start(&listener);
ListenerTCP_destruct(&listener);
}
else throw("no tunnel protocol has been selected");
}
else throw("no input mode has been selected");
tryLast(kt_tryDispose(), _m11258, ;)
return 0;
}

189
src/port-tunnel.h Normal file
View File

@ -0,0 +1,189 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include <pthread.h>
#include "../kerep/src/Network/network.h"
#include "../kerep/src/Hashtable/Hashtable.h"
/// defined in help_message.c
extern const char* help_message;
////////////////////////////////////////
// Time //
////////////////////////////////////////
/// nanoseconds
typedef u64 nsec_t;
/// miliseconds
typedef u64 usec_t;
/// system time now in nanoseconds
///@return u64 will overflow in 13 years
nsec_t getTimeNsec();
/// system time now in microseconds
///@return u64 will overflow in 58494 years
usec_t getTimeUsec();
////////////////////////////////////////
// Enums //
////////////////////////////////////////
typedef enum {
TunnelProtocol_None,
TunnelProtocol_TCP,
TunnelProtocol_UDP
} TunnelProtocol;
typedef enum {
InputMode_None,
InputMode_Listen,
InputMode_Connect
} InputMode;
typedef enum {
OutputMode_None,
OutputMode_Bind,
OutputMode_Send
} OutputMode;
////////////////////////////////////////
// Logging //
////////////////////////////////////////
typedef enum LogLevel {
LogLevel_Error = 1,
LogLevel_Warning = 2,
LogLevel_Info = 3,
LogLevel_Debug = 4
} LogLevel;
extern LogLevel _log_level;
#define __logTryPrint(minimumLogLevel, format, args...)\
if(_log_level >= minimumLogLevel) \
kprintf(format "\n" ,##args)
#define logDebug(format, args...) __logTryPrint(LogLevel_Debug, FGRY format ,##args)
#define logInfo(format, args...) __logTryPrint(LogLevel_Info, FWHI format ,##args)
#define logWarning(format, args...) __logTryPrint(LogLevel_Warning, FYEL format ,##args)
#define logError(format, args...) __logTryPrint(LogLevel_Error, FRED format ,##args)
#define setLogLevel(l) _log_level = l
////////////////////////////////////////
// Pipes //
////////////////////////////////////////
STRUCT(PipeBase,
usec_t last_transmit_time;
bool is_transmitting;
bool is_closed;
)
STRUCT(PipeUDP,
PipeBase base;
knIPV4Endpoint pipe_out_end;
knSocketUDP* pipe_in_sock;
)
void PipeUDP_construct(PipeUDP* pipe, knSocketUDP* pipe_in_sock, knIPV4Endpoint pipe_out_end);
void PipeUDP_destruct(PipeUDP* pipe);
void PipeUDP_startAsync(PipeUDP* pipe);
void PipeUDP_stopAsync(PipeUDP* pipe);
STRUCT(PipeTCP,
PipeBase base;
knIPV4Endpoint pipe_out_end;
knSocketTCP* pipe_in_sock;
)
void PipeTCP_construct(PipeTCP* pipe, knSocketTCP* pipe_in_sock, knIPV4Endpoint pipe_out_end);
void PipeTCP_destruct(PipeTCP* pipe);
void PipeTCP_startAsync(PipeTCP* pipe);
void PipeTCP_stopAsync(PipeTCP* pipe);
////////////////////////////////////////
// Pipe Storage //
////////////////////////////////////////
STRUCT(PipeStorage,
/* Hashtable<EndpointString, PipeBase*> */
Hashtable* table;
usec_t last_check_time;
bool is_gc_stopped;
)
void __PipeStorage_construct(PipeStorage* s);
void __PipeStorage_destruct(PipeStorage* s);
void __PipeStorage_startGCAsync(PipeStorage* s);
void __PipeStorage_stopGCAsync(PipeStorage* s);
////////////////////////////////////////
// Listeners //
////////////////////////////////////////
STRUCT(ListenerUDP,
/* Hashtable<EndpointString, PipeUDP*> pipes.table */
PipeStorage pipes;
knIPV4Endpoint connector_end;
knSocketUDP* main_sock;
)
void ListenerUDP_construct(ListenerUDP* ptr, knIPV4Endpoint listener_end);
void ListenerUDP_destruct(ListenerUDP* ptr);
void ListenerUDP_start(ListenerUDP* ptr);
STRUCT(ListenerTCP,
/* Hashtable<EndpointString, PipeUDP*> pipes.table */
PipeStorage pipes;
knIPV4Endpoint connector_end;
knSocketTCP* main_sock;
)
void ListenerTCP_construct(ListenerTCP* ptr, knIPV4Endpoint listener_end);
void ListenerTCP_destruct(ListenerTCP* ptr);
void ListenerTCP_start(ListenerTCP* ptr);
////////////////////////////////////////
// Connectors //
////////////////////////////////////////
STRUCT(ConnectorUDP,
/* Hashtable<EndpointString, PipeUDP*> */
PipeStorage pipes;
knIPV4Endpoint listener_end;
knIPV4Endpoint connector_end;
knSocketUDP* main_sock;
OutputMode out_mode;
)
void ConnectorUDP_construct(ConnectorUDP* ptr, knIPV4Endpoint listener_end, knIPV4Endpoint connector_end, OutputMode out_mode);
void ConnectorUDP_destruct(ConnectorUDP* ptr);
///@return doesn't return, INFINITE LOOP
void ConnectorUDP_start(ConnectorUDP* ptr);
STRUCT(ConnectorTCP,
/* Hashtable<EndpointString, PipeTCP*> */
PipeStorage pipes;
knIPV4Endpoint listener_end;
knIPV4Endpoint connector_end;
knSocketTCP* main_sock;
OutputMode out_mode;
)
void ConnectorTCP_construct(ConnectorTCP* ptr, knIPV4Endpoint listener_end, knIPV4Endpoint connector_end, OutputMode out_mode);
void ConnectorTCP_destruct(ConnectorTCP* ptr);
///@return doesn't return, INFINITE LOOP
void ConnectorTCP_start(ConnectorTCP* ptr);
#if __cplusplus
}
#endif

17
src/time.c Normal file
View File

@ -0,0 +1,17 @@
#include "port-tunnel.h"
nsec_t getTimeNsec(){
struct timespec t;
if(clock_gettime(CLOCK_REALTIME, &t) != 0)
throw(ERR_UNEXPECTEDVAL);
u64 n = t.tv_sec * 10e9 + t.tv_nsec;
return n;
}
usec_t getTimeUsec(){
struct timespec t;
if(clock_gettime(CLOCK_REALTIME, &t) != 0)
throw(ERR_UNEXPECTEDVAL);
u64 n = t.tv_sec * 10e6 + t.tv_nsec / 10e3;
return n;
}