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
|
# 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
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
|
// 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")
|
||||||
);
|
);
|
||||||
|
|||||||
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