parent
bffdbe1d4b
commit
012ed7541c
@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2004-2007 Jay Sorg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#if !defined(ARCH_H)
|
||||
#define ARCH_H
|
||||
|
||||
/* check endianess */
|
||||
#if defined(__sparc__) || defined(__PPC__) || defined(__ppc__)
|
||||
#define B_ENDIAN
|
||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define L_ENDIAN
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define B_ENDIAN
|
||||
#endif
|
||||
/* check if we need to align data */
|
||||
#if defined(__sparc__) || defined(__alpha__) || defined(__hppa__) || \
|
||||
defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \
|
||||
defined(__ia64__) || defined(__ppc__)
|
||||
#define NEED_ALIGN
|
||||
#endif
|
||||
|
||||
/* defines for thread creation factory functions */
|
||||
#if defined(_WIN32)
|
||||
#define THREAD_RV unsigned long
|
||||
#define THREAD_CC __stdcall
|
||||
#else
|
||||
#define THREAD_RV void*
|
||||
#define THREAD_CC
|
||||
#endif
|
||||
|
||||
#if defined(__BORLANDC__) || defined(_WIN32)
|
||||
#define APP_CC __fastcall
|
||||
#define DEFAULT_CC __cdecl
|
||||
#else
|
||||
#define APP_CC
|
||||
#define DEFAULT_CC
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(__BORLANDC__)
|
||||
#define EXPORT_CC _export __cdecl
|
||||
#else
|
||||
#define EXPORT_CC
|
||||
#endif
|
||||
#else
|
||||
#define EXPORT_CC
|
||||
#endif
|
||||
|
||||
typedef char ti8;
|
||||
typedef unsigned char tui8;
|
||||
typedef signed char tsi8;
|
||||
typedef short ti16;
|
||||
typedef unsigned short tui16;
|
||||
typedef signed short tsi16;
|
||||
typedef int ti32;
|
||||
typedef unsigned int tui32;
|
||||
typedef signed int tsi32;
|
||||
typedef long tbus;
|
||||
|
||||
#endif
|
@ -0,0 +1,265 @@
|
||||
|
||||
#include "os_calls.h"
|
||||
|
||||
int g_loc_io_count = 0; // bytes read from local port
|
||||
int g_rem_io_count = 0; // bytes read from remote port
|
||||
|
||||
static int g_terminated = 0;
|
||||
static char g_buf[1024 * 32];
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
main_loop(char* local_port, char* remote_ip, char* remote_port, int hexdump)
|
||||
{
|
||||
int lis_sck;
|
||||
int acc_sck;
|
||||
int con_sck;
|
||||
int sel;
|
||||
int count;
|
||||
int sent;
|
||||
int error;
|
||||
int i;
|
||||
int acc_to_con;
|
||||
int con_to_acc;
|
||||
|
||||
acc_to_con = 0;
|
||||
con_to_acc = 0;
|
||||
acc_sck = 0;
|
||||
|
||||
/* create the listening socket and setup options */
|
||||
lis_sck = g_tcp_socket();
|
||||
g_tcp_set_non_blocking(lis_sck);
|
||||
error = g_tcp_bind(lis_sck, local_port);
|
||||
if (error != 0)
|
||||
{
|
||||
g_writeln("bind failed");
|
||||
}
|
||||
|
||||
/* listen for an incomming connection */
|
||||
if (error == 0)
|
||||
{
|
||||
error = g_tcp_listen(lis_sck);
|
||||
if (error == 0)
|
||||
{
|
||||
g_writeln("listening for connection");
|
||||
}
|
||||
}
|
||||
|
||||
/* accept an incomming connection */
|
||||
if (error == 0)
|
||||
{
|
||||
while ((!g_terminated) && (error == 0))
|
||||
{
|
||||
acc_sck = g_tcp_accept(lis_sck);
|
||||
if ((acc_sck == -1) && g_tcp_last_error_would_block(lis_sck))
|
||||
{
|
||||
g_sleep(100);
|
||||
}
|
||||
else if (acc_sck == -1)
|
||||
{
|
||||
error = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error == 0)
|
||||
{
|
||||
error = g_terminated;
|
||||
}
|
||||
|
||||
/* stop listening */
|
||||
g_tcp_close(lis_sck);
|
||||
lis_sck = 0;
|
||||
if (error == 0)
|
||||
{
|
||||
g_writeln("got connection");
|
||||
}
|
||||
}
|
||||
|
||||
/* connect outgoing socket */
|
||||
con_sck = 0;
|
||||
if (error == 0)
|
||||
{
|
||||
con_sck = g_tcp_socket();
|
||||
g_tcp_set_non_blocking(con_sck);
|
||||
error = g_tcp_connect(con_sck, remote_ip, remote_port);
|
||||
if ((error == -1) && g_tcp_last_error_would_block(con_sck))
|
||||
{
|
||||
error = 0;
|
||||
i = 0;
|
||||
while ((!g_tcp_can_send(con_sck, 100)) && (!g_terminated) && (i < 100))
|
||||
{
|
||||
g_sleep(100);
|
||||
i++;
|
||||
}
|
||||
if (i > 99)
|
||||
{
|
||||
g_writeln("timout connecting");
|
||||
error = 1;
|
||||
}
|
||||
if (g_terminated)
|
||||
{
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
if ((error != 0) && (!g_terminated))
|
||||
{
|
||||
g_writeln("error connecting to remote\r\n");
|
||||
}
|
||||
}
|
||||
while ((!g_terminated) && (error == 0))
|
||||
{
|
||||
sel = g_tcp_select(con_sck, acc_sck);
|
||||
if (sel == 0)
|
||||
{
|
||||
g_sleep(10);
|
||||
continue;
|
||||
}
|
||||
if (sel & 1)
|
||||
{
|
||||
// can read from con_sck w/o blocking
|
||||
count = g_tcp_recv(con_sck, g_buf, 1024 * 16, 0);
|
||||
error = count < 1;
|
||||
if (error == 0)
|
||||
{
|
||||
g_loc_io_count += count;
|
||||
con_to_acc += count;
|
||||
if (hexdump)
|
||||
{
|
||||
g_writeln("from remove, the socket from connect");
|
||||
g_hexdump(g_buf, count);
|
||||
}
|
||||
#if 0
|
||||
g_writeln("local_io_count: %d\tremote_io_count: %d",
|
||||
g_loc_io_count, g_rem_io_count);
|
||||
#endif
|
||||
sent = 0;
|
||||
while ((sent < count) && (error == 0) && (!g_terminated))
|
||||
{
|
||||
i = g_tcp_send(acc_sck, g_buf + sent, count - sent, 0);
|
||||
if ((i == -1) && g_tcp_last_error_would_block(acc_sck))
|
||||
{
|
||||
g_tcp_can_send(acc_sck, 1000);
|
||||
}
|
||||
else if (i < 1)
|
||||
{
|
||||
error = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sent += i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sel & 2)
|
||||
{
|
||||
// can read from acc_sck w/o blocking
|
||||
count = g_tcp_recv(acc_sck, g_buf, 1024 * 16, 0);
|
||||
error = count < 1;
|
||||
if (error == 0)
|
||||
{
|
||||
g_rem_io_count += count;
|
||||
acc_to_con += count;
|
||||
if (hexdump)
|
||||
{
|
||||
g_writeln("from accepted, the socket from accept");
|
||||
g_hexdump(g_buf, count);
|
||||
}
|
||||
#if 0
|
||||
g_writeln("local_io_count: %d\tremote_io_count: %d",
|
||||
g_loc_io_count, g_rem_io_count);
|
||||
#endif
|
||||
sent = 0;
|
||||
while ((sent < count) && (error == 0) && (!g_terminated))
|
||||
{
|
||||
i = g_tcp_send(con_sck, g_buf + sent, count - sent, 0);
|
||||
if ((i == -1) && g_tcp_last_error_would_block(con_sck))
|
||||
{
|
||||
g_tcp_can_send(con_sck, 1000);
|
||||
}
|
||||
else if (i < 1)
|
||||
{
|
||||
error = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sent += i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g_tcp_close(lis_sck);
|
||||
g_tcp_close(con_sck);
|
||||
g_tcp_close(acc_sck);
|
||||
g_writeln("acc_to_con %d", acc_to_con);
|
||||
g_writeln("con_to_acc %d", con_to_acc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
usage(void)
|
||||
{
|
||||
g_writeln("tcp_proxy <local-port> <remote-ip> <remote-port> [dump]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
proxy_shutdown(int sig)
|
||||
{
|
||||
g_writeln("shutting down");
|
||||
g_terminated = 1;
|
||||
}
|
||||
|
||||
void
|
||||
clear_counters(int sig)
|
||||
{
|
||||
g_writeln("cleared counters at: local_io_count: %d remote_io_count: %d",
|
||||
g_loc_io_count, g_rem_io_count);
|
||||
g_loc_io_count = 0;
|
||||
g_rem_io_count = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
int dump;
|
||||
|
||||
if (argc < 4)
|
||||
{
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
g_init();
|
||||
g_signal(2, proxy_shutdown); /* SIGINT */
|
||||
g_signal(9, proxy_shutdown); /* SIGKILL */
|
||||
g_signal(10, clear_counters);/* SIGUSR1*/
|
||||
g_signal(15, proxy_shutdown);/* SIGTERM */
|
||||
if (argc < 5)
|
||||
{
|
||||
while (!g_terminated)
|
||||
{
|
||||
g_loc_io_count = 0;
|
||||
g_rem_io_count = 0;
|
||||
main_loop(argv[1], argv[2], argv[3], 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dump = g_strcasecmp(argv[4], "dump") == 0;
|
||||
while (!g_terminated)
|
||||
{
|
||||
main_loop(argv[1], argv[2], argv[3], dump);
|
||||
}
|
||||
}
|
||||
g_deinit();
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,208 @@
|
||||
/*
|
||||
Copyright (c) 2004-2007 Jay Sorg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
generic operating system calls
|
||||
*/
|
||||
|
||||
#if !defined(OS_CALLS_H)
|
||||
#define OS_CALLS_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
void APP_CC
|
||||
g_init(void);
|
||||
void APP_CC
|
||||
g_deinit(void);
|
||||
void* APP_CC
|
||||
g_malloc(int size, int zero);
|
||||
void APP_CC
|
||||
g_free(void* ptr);
|
||||
void DEFAULT_CC
|
||||
g_printf(const char *format, ...);
|
||||
void DEFAULT_CC
|
||||
g_sprintf(char* dest, const char* format, ...);
|
||||
void DEFAULT_CC
|
||||
g_snprintf(char* dest, int len, const char* format, ...);
|
||||
void DEFAULT_CC
|
||||
g_writeln(const char* format, ...);
|
||||
void DEFAULT_CC
|
||||
g_write(const char* format, ...);
|
||||
void APP_CC
|
||||
g_hexdump(char* p, int len);
|
||||
void APP_CC
|
||||
g_memset(void* ptr, int val, int size);
|
||||
void APP_CC
|
||||
g_memcpy(void* d_ptr, const void* s_ptr, int size);
|
||||
int APP_CC
|
||||
g_getchar(void);
|
||||
int APP_CC
|
||||
g_tcp_set_no_delay(int sck);
|
||||
int APP_CC
|
||||
g_tcp_socket(void);
|
||||
int APP_CC
|
||||
g_tcp_local_socket(void);
|
||||
void APP_CC
|
||||
g_tcp_close(int sck);
|
||||
int APP_CC
|
||||
g_tcp_connect(int sck, const char* address, const char* port);
|
||||
int APP_CC
|
||||
g_tcp_force_send(int sck, char* data, int len);
|
||||
int APP_CC
|
||||
g_tcp_force_recv(int sck, char* data, int len);
|
||||
int APP_CC
|
||||
g_tcp_set_non_blocking(int sck);
|
||||
int APP_CC
|
||||
g_tcp_bind(int sck, char* port);
|
||||
int APP_CC
|
||||
g_tcp_local_bind(int sck, char* port);
|
||||
int APP_CC
|
||||
g_tcp_listen(int sck);
|
||||
int APP_CC
|
||||
g_tcp_accept(int sck);
|
||||
int APP_CC
|
||||
g_tcp_recv(int sck, void* ptr, int len, int flags);
|
||||
int APP_CC
|
||||
g_tcp_send(int sck, const void* ptr, int len, int flags);
|
||||
int APP_CC
|
||||
g_tcp_last_error_would_block(int sck);
|
||||
int APP_CC
|
||||
g_tcp_can_send(int sck, int millis);
|
||||
int APP_CC
|
||||
g_tcp_can_recv(int sck, int millis);
|
||||
int APP_CC
|
||||
g_tcp_select(int sck1, int sck2);
|
||||
void APP_CC
|
||||
g_sleep(int msecs);
|
||||
void APP_CC
|
||||
g_random(char* data, int len);
|
||||
int APP_CC
|
||||
g_abs(int i);
|
||||
int APP_CC
|
||||
g_memcmp(const void* s1, const void* s2, int len);
|
||||
int APP_CC
|
||||
g_file_open(const char* file_name);
|
||||
int APP_CC
|
||||
g_file_close(int fd);
|
||||
int APP_CC
|
||||
g_file_read(int fd, char* ptr, int len);
|
||||
int APP_CC
|
||||
g_file_write(int fd, char* ptr, int len);
|
||||
int APP_CC
|
||||
g_file_seek(int fd, int offset);
|
||||
int APP_CC
|
||||
g_file_lock(int fd, int start, int len);
|
||||
int APP_CC
|
||||
g_set_file_rights(const char* filename, int read, int write);
|
||||
int APP_CC
|
||||
g_chmod_hex(const char* filename, int flags);
|
||||
int APP_CC
|
||||
g_mkdir(const char* dirname);
|
||||
char* APP_CC
|
||||
g_get_current_dir(char* dirname, int maxlen);
|
||||
int APP_CC
|
||||
g_set_current_dir(char* dirname);
|
||||
int APP_CC
|
||||
g_file_exist(const char* filename);
|
||||
int APP_CC
|
||||
g_directory_exist(const char* dirname);
|
||||
int APP_CC
|
||||
g_create_dir(const char* dirname);
|
||||
int APP_CC
|
||||
g_remove_dir(const char* dirname);
|
||||
int APP_CC
|
||||
g_file_delete(const char* filename);
|
||||
int APP_CC
|
||||
g_strlen(const char* text);
|
||||
char* APP_CC
|
||||
g_strcpy(char* dest, const char* src);
|
||||
char* APP_CC
|
||||
g_strncpy(char* dest, const char* src, int len);
|
||||
char* APP_CC
|
||||
g_strcat(char* dest, const char* src);
|
||||
char* APP_CC
|
||||
g_strdup(const char* in);
|
||||
int APP_CC
|
||||
g_strcmp(const char* c1, const char* c2);
|
||||
int APP_CC
|
||||
g_strncmp(const char* c1, const char* c2, int len);
|
||||
int APP_CC
|
||||
g_strcasecmp(const char* c1, const char* c2);
|
||||
int APP_CC
|
||||
g_strncasecmp(const char* c1, const char* c2, int len);
|
||||
int APP_CC
|
||||
g_atoi(char* str);
|
||||
int APP_CC
|
||||
g_pos(char* str, const char* to_find);
|
||||
long APP_CC
|
||||
g_load_library(char* in);
|
||||
int APP_CC
|
||||
g_free_library(long lib);
|
||||
void* APP_CC
|
||||
g_get_proc_address(long lib, const char* name);
|
||||
int APP_CC
|
||||
g_system(char* aexec);
|
||||
char* APP_CC
|
||||
g_get_strerror(void);
|
||||
int APP_CC
|
||||
g_execvp(const char* p1, char* args[]);
|
||||
int APP_CC
|
||||
g_execlp3(const char* a1, const char* a2, const char* a3);
|
||||
void APP_CC
|
||||
g_signal(int sig_num, void (*func)(int));
|
||||
void APP_CC
|
||||
g_signal_child_stop(void (*func)(int));
|
||||
void APP_CC
|
||||
g_unset_signals(void);
|
||||
int APP_CC
|
||||
g_fork(void);
|
||||
int APP_CC
|
||||
g_setgid(int pid);
|
||||
int APP_CC
|
||||
g_initgroups(const char* user, int gid);
|
||||
int APP_CC
|
||||
g_setuid(int pid);
|
||||
int APP_CC
|
||||
g_waitchild(void);
|
||||
int APP_CC
|
||||
g_waitpid(int pid);
|
||||
void APP_CC
|
||||
g_clearenv(void);
|
||||
int APP_CC
|
||||
g_setenv(const char* name, const char* value, int rewrite);
|
||||
char* APP_CC
|
||||
g_getenv(const char* name);
|
||||
int APP_CC
|
||||
g_exit(int exit_code);
|
||||
int APP_CC
|
||||
g_getpid(void);
|
||||
int APP_CC
|
||||
g_sigterm(int pid);
|
||||
int APP_CC
|
||||
g_getuser_info(const char* username, int* gid, int* uid, char* shell,
|
||||
char* dir, char* gecos);
|
||||
int APP_CC
|
||||
g_getgroup_info(const char* groupname, int* gid);
|
||||
int APP_CC
|
||||
g_check_user_in_group(const char* username, int gid, int* ok);
|
||||
int APP_CC
|
||||
g_time1(void);
|
||||
|
||||
#endif
|
Loading…
Reference in new issue