structs, constructors, destructors, logging
This commit is contained in:
parent
e2dd49bbcb
commit
a7bfca5f50
@ -68,7 +68,7 @@ case "$TASK" in
|
||||
;;
|
||||
# creates executable with debug info and no optimizations
|
||||
build_exec_dbg)
|
||||
C_ARGS="-O0 -g3"
|
||||
C_ARGS="-O0 -g3 -DDEBUG"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
|
||||
PRE_TASK_SCRIPT=
|
||||
|
||||
67
src/Connectors.c
Normal file
67
src/Connectors.c
Normal 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
43
src/Listeners.c
Normal 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
22
src/PipeStorage.c
Normal 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
65
src/Pipes.c
Normal 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){
|
||||
|
||||
}
|
||||
@ -2,19 +2,25 @@
|
||||
|
||||
// option help definition
|
||||
#define HELP_OPT(ALIASES, PARAMS, DESCRIPTION...) \
|
||||
FWHI " " ALIASES " " PARAMS FGRY "\n" DESCRIPTION
|
||||
FWHI" " ALIASES " " PARAMS FGRY "\n" DESCRIPTION
|
||||
|
||||
// option parameter help definition
|
||||
#define HELP_PRM(PNAME) \
|
||||
FWHI "[" FCYN PNAME FWHI "]"
|
||||
FWHI"[" FCYN PNAME FWHI"]"
|
||||
|
||||
// option nullable parameter help definition
|
||||
#define HELP_PRMN(PNAME) \
|
||||
FWHI "[" FCYN PNAME FWHI "?]"
|
||||
FWHI"[" FCYN PNAME FWHI"?]"
|
||||
|
||||
// option parameter1/parameter2 help definition
|
||||
#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 = (
|
||||
FWHI"Usage: port-tunnel "
|
||||
@ -72,4 +78,8 @@ const char* help_message = (
|
||||
HELP_OPT("-e, --encrypt",
|
||||
HELP_PRM("key"),
|
||||
" 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")
|
||||
);
|
||||
|
||||
153
src/main.c
153
src/main.c
@ -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
213
src/port-tunnel.c
Normal 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
189
src/port-tunnel.h
Normal 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
17
src/time.c
Normal 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;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user