Commit ee99ee5a by michaelpastushkov

cleanup formatting

parent 86fa807c
...@@ -68,7 +68,8 @@ unsigned char cipher[256]; ...@@ -68,7 +68,8 @@ unsigned char cipher[256];
int cipher_time; int cipher_time;
struct client_info clients[MAX_UDP_CLIENTS]; struct client_info clients[MAX_UDP_CLIENTS];
char *get_current_timestamp(void) { char *get_current_timestamp(void)
{
static char date_str[20]; static char date_str[20];
time_t date; time_t date;
time(&date); time(&date);
...@@ -76,34 +77,38 @@ char *get_current_timestamp(void) { ...@@ -76,34 +77,38 @@ char *get_current_timestamp(void) {
return date_str; return date_str;
} }
unsigned int xorshift32(unsigned int *state) { unsigned int xorshift32(unsigned int *state)
unsigned int x = *state; {
x ^= x << 13; unsigned int x = *state;
x ^= x >> 17; x ^= x << 13;
x ^= x << 5; x ^= x >> 17;
*state = x; x ^= x << 5;
return x; *state = x;
return x;
} }
void shuffle(unsigned char *array, int n, unsigned int seed) { void shuffle(unsigned char *array, int n, unsigned int seed)
unsigned int state = seed; {
srand(seed); unsigned int state = seed;
for (int i = n - 1; i > 0; i--) { srand(seed);
int j = xorshift32(&state) % (i + 1); for (int i = n - 1; i > 0; i--)
int temp = array[i]; {
array[i] = array[j]; int j = xorshift32(&state) % (i + 1);
array[j] = temp; int temp = array[i];
} array[i] = array[j];
array[j] = temp;
}
} }
unsigned int get_hash(unsigned int source) { unsigned int get_hash(unsigned int source)
unsigned int hash = source; {
hash = (hash ^ 61) ^ (hash >> 16); unsigned int hash = source;
hash = hash + (hash << 3); hash = (hash ^ 61) ^ (hash >> 16);
hash = hash ^ (hash >> 4); hash = hash + (hash << 3);
hash = hash * 0x27d4eb2d; hash = hash ^ (hash >> 4);
hash = hash ^ (hash >> 15); hash = hash * 0x27d4eb2d;
return hash; hash = hash ^ (hash >> 15);
return hash;
} }
int get_time() int get_time()
...@@ -112,12 +117,13 @@ int get_time() ...@@ -112,12 +117,13 @@ int get_time()
return now / (60 * 10); /* changing cipher every 10 minutes */ return now / (60 * 10); /* changing cipher every 10 minutes */
} }
void update_cipher() { void update_cipher()
{
int i; int i;
unsigned int seed; unsigned int seed;
int time = get_time(); int time = get_time();
if (time == cipher_time) if (time == cipher_time)
return; return;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
...@@ -127,48 +133,58 @@ void update_cipher() { ...@@ -127,48 +133,58 @@ void update_cipher() {
shuffle(cipher, sizeof(cipher), seed); shuffle(cipher, sizeof(cipher), seed);
if (options.log > 1) { if (options.log > 1)
{
printf("%s new cipher %i\n", get_current_timestamp(), time); printf("%s new cipher %i\n", get_current_timestamp(), time);
if (options.log > 2) { if (options.log > 2)
for (i=0; i<256; i++) { {
for (i = 0; i < 256; i++)
{
printf("%d ", cipher[i]); printf("%d ", cipher[i]);
if ((i + 1) % 16 == 0) if ((i + 1) % 16 == 0)
printf("\n"); printf("\n");
} }
} }
} }
cipher_time = time; cipher_time = time;
} }
int encode(unsigned char* buf, int len) { int encode(unsigned char *buf, int len)
{
int i; int i;
if (!options.encrypt) if (!options.encrypt)
return 0; return 0;
update_cipher(); update_cipher();
for (i=0; i<len; i++) for (i = 0; i < len; i++)
buf[i] = cipher[buf[i]]; buf[i] = cipher[buf[i]];
if (options.log) { if (options.log)
printf("\r%-50s", " "); {
printf("\r%-50s", " ");
printf("\r%s encode %i bytes ", get_current_timestamp(), len); printf("\r%s encode %i bytes ", get_current_timestamp(), len);
fflush(stdout); fflush(stdout);
} }
return 0; return 0;
} }
int decode(unsigned char* buf, int len) { int decode(unsigned char *buf, int len)
{
int i, j; int i, j;
if (!options.encrypt) if (!options.encrypt)
return 0; return 0;
update_cipher(); update_cipher();
for (i=0; i<len; i++) { for (i = 0; i < len; i++)
for (j=0; j<256; j++) { {
if (cipher[j] == buf[i]) { for (j = 0; j < 256; j++)
buf[i] = j; {
break; if (cipher[j] == buf[i])
} {
} buf[i] = j;
} break;
if (options.log) { }
}
}
if (options.log)
{
printf("\r%-50s", " "); printf("\r%-50s", " ");
printf("\r%s decode %i bytes ", get_current_timestamp(), len); printf("\r%s decode %i bytes ", get_current_timestamp(), len);
fflush(stdout); fflush(stdout);
...@@ -176,28 +192,32 @@ int decode(unsigned char* buf, int len) { ...@@ -176,28 +192,32 @@ int decode(unsigned char* buf, int len) {
return 0; return 0;
} }
int build_udp(void) { int build_udp(void)
{
/* Create local socket */ /* Create local socket */
rc.client_socket = socket(AF_INET, SOCK_DGRAM, 0); rc.client_socket = socket(AF_INET, SOCK_DGRAM, 0);
if ((rc.client_socket) < 0) { if ((rc.client_socket) < 0)
{
perror("build_udp: local socket()"); perror("build_udp: local socket()");
return 1; return 1;
} }
memset(&rc.client_addr, 0, sizeof(rc.client_addr)); memset(&rc.client_addr, 0, sizeof(rc.client_addr));
rc.client_addr.sin_family = AF_INET; rc.client_addr.sin_family = AF_INET;
rc.client_addr.sin_addr.s_addr = inet_addr(options.bind_address); rc.client_addr.sin_addr.s_addr = inet_addr(options.bind_address);
rc.client_addr.sin_port = htons(options.local_port); rc.client_addr.sin_port = htons(options.local_port);
if (bind(rc.client_socket, (struct sockaddr *)&rc.client_addr, sizeof(rc.client_addr)) < 0) { if (bind(rc.client_socket, (struct sockaddr *)&rc.client_addr, sizeof(rc.client_addr)) < 0)
{
perror("build_udp: bind()"); perror("build_udp: bind()");
return 1; return 1;
} }
return 0; return 0;
} }
int build_tcp(void) { int build_tcp(void)
{
memset(&rc.server_addr, 0, sizeof(rc.server_addr)); memset(&rc.server_addr, 0, sizeof(rc.server_addr));
...@@ -206,14 +226,15 @@ int build_tcp(void) { ...@@ -206,14 +226,15 @@ int build_tcp(void) {
rc.server_addr.sin_addr.s_addr = INADDR_ANY; rc.server_addr.sin_addr.s_addr = INADDR_ANY;
rc.server_socket = socket(AF_INET, options.proto, 0); rc.server_socket = socket(AF_INET, options.proto, 0);
if (rc.server_socket < 0) { if (rc.server_socket < 0)
{
perror("build_tcp: socket()"); perror("build_tcp: socket()");
return 1; return 1;
} }
int optval = 1; int optval = 1;
#ifdef __MINGW32__ #ifdef __MINGW32__
if (setsockopt(rc.server_socket, SOL_SOCKET, SO_REUSEADDR, (const char *) &optval, sizeof(optval)) < 0) if (setsockopt(rc.server_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof(optval)) < 0)
#else #else
if (setsockopt(rc.server_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) if (setsockopt(rc.server_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
#endif #endif
...@@ -222,16 +243,19 @@ int build_tcp(void) { ...@@ -222,16 +243,19 @@ int build_tcp(void) {
return 1; return 1;
} }
if (options.bind_address) { if (options.bind_address)
{
rc.server_addr.sin_addr.s_addr = inet_addr(options.bind_address); rc.server_addr.sin_addr.s_addr = inet_addr(options.bind_address);
} }
if (bind(rc.server_socket, (struct sockaddr *) &rc.server_addr, sizeof(rc.server_addr)) < 0) { if (bind(rc.server_socket, (struct sockaddr *)&rc.server_addr, sizeof(rc.server_addr)) < 0)
{
perror("build_server: bind()"); perror("build_server: bind()");
return 1; return 1;
} }
if (listen(rc.server_socket, 1) < 0) { if (listen(rc.server_socket, 1) < 0)
{
perror("build_server: listen()"); perror("build_server: listen()");
return 1; return 1;
} }
...@@ -239,7 +263,8 @@ int build_tcp(void) { ...@@ -239,7 +263,8 @@ int build_tcp(void) {
return 0; return 0;
} }
int wait_connection(void) { int wait_connection(void)
{
#if defined(__MINGW32__) #if defined(__MINGW32__)
int client_addr_size; int client_addr_size;
...@@ -248,17 +273,22 @@ int wait_connection(void) { ...@@ -248,17 +273,22 @@ int wait_connection(void) {
#endif #endif
client_addr_size = sizeof(struct sockaddr_in); client_addr_size = sizeof(struct sockaddr_in);
if (options.proto == SOCK_DGRAM) { if (options.proto == SOCK_DGRAM)
{
char buf[BUFFER_SIZE]; char buf[BUFFER_SIZE];
int bytes = recvfrom(rc.client_socket, buf, sizeof(buf), MSG_PEEK, (struct sockaddr *)&rc.client_addr, &client_addr_size); int bytes = recvfrom(rc.client_socket, buf, sizeof(buf), MSG_PEEK, (struct sockaddr *)&rc.client_addr, &client_addr_size);
if (bytes < 0) { if (bytes < 0)
{
if (errno != EINTR) if (errno != EINTR)
perror("wait_connection: recvfrom(PEEK)"); perror("wait_connection: recvfrom(PEEK)");
return 1; return 1;
} }
} else { }
rc.client_socket = accept(rc.server_socket, (struct sockaddr *) &rc.client_addr, &client_addr_size); else
if (rc.client_socket < 0) { {
rc.client_socket = accept(rc.server_socket, (struct sockaddr *)&rc.client_addr, &client_addr_size);
if (rc.client_socket < 0)
{
if (errno != EINTR) if (errno != EINTR)
perror("wait_connection: accept()"); perror("wait_connection: accept()");
return 1; return 1;
...@@ -267,7 +297,8 @@ int wait_connection(void) { ...@@ -267,7 +297,8 @@ int wait_connection(void) {
printf("%s request from %s\n", get_current_timestamp(), inet_ntoa(rc.client_addr.sin_addr)); printf("%s request from %s\n", get_current_timestamp(), inet_ntoa(rc.client_addr.sin_addr));
} }
if (options.client_address && (strcmp(inet_ntoa(rc.client_addr.sin_addr), options.client_address) != 0)) { if (options.client_address && (strcmp(inet_ntoa(rc.client_addr.sin_addr), options.client_address) != 0))
{
if (options.log) if (options.log)
printf("%s refused request from %s\n", get_current_timestamp(), inet_ntoa(rc.client_addr.sin_addr)); printf("%s refused request from %s\n", get_current_timestamp(), inet_ntoa(rc.client_addr.sin_addr));
close(rc.client_socket); close(rc.client_socket);
...@@ -277,9 +308,11 @@ int wait_connection(void) { ...@@ -277,9 +308,11 @@ int wait_connection(void) {
return 0; return 0;
} }
int build() { int build()
{
rc.remote_host = gethostbyname(options.remote_host); rc.remote_host = gethostbyname(options.remote_host);
if (rc.remote_host == NULL) { if (rc.remote_host == NULL)
{
perror("build: gethostbyname()"); perror("build: gethostbyname()");
return 1; return 1;
} }
...@@ -290,13 +323,16 @@ int build() { ...@@ -290,13 +323,16 @@ int build() {
memcpy(&rc.remote_addr.sin_addr.s_addr, rc.remote_host->h_addr, rc.remote_host->h_length); memcpy(&rc.remote_addr.sin_addr.s_addr, rc.remote_host->h_addr, rc.remote_host->h_length);
rc.remote_socket = socket(AF_INET, options.proto, 0); rc.remote_socket = socket(AF_INET, options.proto, 0);
if (rc.remote_socket < 0) { if (rc.remote_socket < 0)
{
perror("build: socket()"); perror("build: socket()");
return 1; return 1;
} }
if (options.proto == SOCK_STREAM) { if (options.proto == SOCK_STREAM)
if (connect(rc.remote_socket, (struct sockaddr *)&rc.remote_addr, sizeof(rc.remote_addr)) < 0) { {
if (connect(rc.remote_socket, (struct sockaddr *)&rc.remote_addr, sizeof(rc.remote_addr)) < 0)
{
perror("build: connect()"); perror("build: connect()");
return 1; return 1;
} }
...@@ -304,43 +340,52 @@ int build() { ...@@ -304,43 +340,52 @@ int build() {
return 0; return 0;
} }
int add_udp_client(struct sockaddr_in client_addr, pid_t pid) { int add_udp_client(struct sockaddr_in client_addr, pid_t pid)
{
int i; int i;
for (i=0; i<MAX_UDP_CLIENTS; i++) { for (i = 0; i < MAX_UDP_CLIENTS; i++)
if (clients[i].pid == 0) { {
clients[i].addr = client_addr; if (clients[i].pid == 0)
clients[i].pid = pid; {
return 0; clients[i].addr = client_addr;
} clients[i].pid = pid;
} return 0;
return -1; /* No space for new clients */ }
}
return -1; /* No space for new clients */
} }
void remove_udp_client(pid_t pid) { void remove_udp_client(pid_t pid)
{
int i; int i;
for (i = 0; i<MAX_UDP_CLIENTS; i++) { for (i = 0; i < MAX_UDP_CLIENTS; i++)
if (clients[i].pid == pid) { {
if (clients[i].pid == pid)
{
if (options.log) if (options.log)
printf("removing client %s, pid: %d\n", inet_ntoa(clients[i].addr.sin_addr), pid); printf("removing client %s, pid: %d\n", inet_ntoa(clients[i].addr.sin_addr), pid);
clients[i].pid = 0; clients[i].pid = 0;
memset(&clients[i].addr, 0, sizeof(clients[i].addr)); memset(&clients[i].addr, 0, sizeof(clients[i].addr));
break; break;
} }
} }
} }
int compare_clients(struct sockaddr_in client1, struct sockaddr_in client2) { int compare_clients(struct sockaddr_in client1, struct sockaddr_in client2)
return (client1.sin_addr.s_addr == client2.sin_addr.s_addr && {
client1.sin_port == client2.sin_port); return (client1.sin_addr.s_addr == client2.sin_addr.s_addr &&
client1.sin_port == client2.sin_port);
} }
int find_udp_client(struct sockaddr_in client_addr) { int find_udp_client(struct sockaddr_in client_addr)
{
int i; int i;
for (i=0; i<MAX_UDP_CLIENTS; i++) for (i = 0; i < MAX_UDP_CLIENTS; i++)
if (clients[i].pid > 0 && compare_clients(clients[i].addr, client_addr)) { if (clients[i].pid > 0 && compare_clients(clients[i].addr, client_addr))
return i; {
return i;
} }
return -1; return -1;
} }
int use() int use()
...@@ -359,25 +404,32 @@ int use() ...@@ -359,25 +404,32 @@ int use()
int max_fd = (rc.client_socket > rc.remote_socket) ? rc.client_socket : rc.remote_socket; int max_fd = (rc.client_socket > rc.remote_socket) ? rc.client_socket : rc.remote_socket;
/* Waiting for data */ /* Waiting for data */
if (select(max_fd+1, &io, NULL, NULL, NULL) < 0) { if (select(max_fd + 1, &io, NULL, NULL, NULL) < 0)
{
perror("use: select()"); perror("use: select()");
break; break;
} }
if (FD_ISSET(rc.client_socket, &io)) if (FD_ISSET(rc.client_socket, &io))
{ {
if (options.proto == SOCK_DGRAM && options.mode == MODE_SERVER) { if (options.proto == SOCK_DGRAM && options.mode == MODE_SERVER)
{
count_recv = recvfrom(rc.client_socket, buffer, sizeof(buffer), MSG_PEEK, (struct sockaddr *)&client_addr, &addr_len); count_recv = recvfrom(rc.client_socket, buffer, sizeof(buffer), MSG_PEEK, (struct sockaddr *)&client_addr, &addr_len);
if (count_recv < 0) { if (count_recv < 0)
{
perror("use() - PEEK"); perror("use() - PEEK");
return 1; return 1;
} }
if (rc.my_addr.sin_port == 0) { if (rc.my_addr.sin_port == 0)
{
rc.my_addr.sin_addr.s_addr = client_addr.sin_addr.s_addr; rc.my_addr.sin_addr.s_addr = client_addr.sin_addr.s_addr;
rc.my_addr.sin_port = client_addr.sin_port; rc.my_addr.sin_port = client_addr.sin_port;
if (options.log > 2) if (options.log > 2)
printf("my address %s:%d\tpid: %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), getpid()); printf("my address %s:%d\tpid: %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), getpid());
} else { }
if (!compare_clients(rc.my_addr, client_addr)) { else
{
if (!compare_clients(rc.my_addr, client_addr))
{
if (options.log > 2) if (options.log > 2)
printf("ignore %s:%d\tpid: %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), getpid()); printf("ignore %s:%d\tpid: %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), getpid());
continue; continue;
...@@ -386,28 +438,28 @@ int use() ...@@ -386,28 +438,28 @@ int use()
} }
/* Processing request from local, sending it to remote*/ /* Processing request from local, sending it to remote*/
count_recv = (options.proto == SOCK_DGRAM) ? count_recv = (options.proto == SOCK_DGRAM) ? recvfrom(rc.client_socket, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &addr_len) : recv(rc.client_socket, buffer, sizeof(buffer), 0);
recvfrom(rc.client_socket, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &addr_len) :
recv(rc.client_socket, buffer, sizeof(buffer), 0);
if (count_recv < 0) { if (count_recv < 0)
{
perror("use: recv(rc.client_socket)"); perror("use: recv(rc.client_socket)");
close(rc.client_socket); close(rc.client_socket);
close(rc.remote_socket); close(rc.remote_socket);
return 1; return 1;
} }
if (count_recv == 0) { if (count_recv == 0)
{
close(rc.client_socket); close(rc.client_socket);
close(rc.remote_socket); close(rc.remote_socket);
return 0; return 0;
} }
(options.mode == MODE_SERVER) ? (options.mode == MODE_SERVER) ?
decode(buffer, count_recv) : decode(buffer, count_recv) :
encode(buffer, count_recv); encode(buffer, count_recv);
(options.proto == SOCK_DGRAM) ? (options.proto == SOCK_DGRAM) ?
sendto(rc.remote_socket, buffer, count_recv, 0, (struct sockaddr *)&rc.remote_addr, sizeof(rc.remote_addr)) : sendto(rc.remote_socket, buffer, count_recv, 0, (struct sockaddr *)&rc.remote_addr, sizeof(rc.remote_addr)) :
send(rc.remote_socket, buffer, count_recv, 0); send(rc.remote_socket, buffer, count_recv, 0);
if (options.log > 1) if (options.log > 1)
...@@ -417,29 +469,29 @@ int use() ...@@ -417,29 +469,29 @@ int use()
if (FD_ISSET(rc.remote_socket, &io)) if (FD_ISSET(rc.remote_socket, &io))
{ {
/* Processing response from remote, sending it back to local */ /* Processing response from remote, sending it back to local */
count_recv = (options.proto == SOCK_DGRAM) ? count_recv = (options.proto == SOCK_DGRAM) ? recvfrom(rc.remote_socket, buffer, sizeof(buffer), 0, NULL, NULL) : recv(rc.remote_socket, buffer, sizeof(buffer), 0);
recvfrom(rc.remote_socket, buffer, sizeof(buffer), 0, NULL, NULL) :
recv(rc.remote_socket, buffer, sizeof(buffer), 0);
if (count_recv < 0) { if (count_recv < 0)
{
perror("use: recv(rc.remote_socket)"); perror("use: recv(rc.remote_socket)");
close(rc.client_socket); close(rc.client_socket);
close(rc.remote_socket); close(rc.remote_socket);
return 1; return 1;
} }
if (count_recv == 0) { if (count_recv == 0)
{
close(rc.client_socket); close(rc.client_socket);
close(rc.remote_socket); close(rc.remote_socket);
return 0; return 0;
} }
(options.mode == MODE_SERVER) ? (options.mode == MODE_SERVER) ?
encode(buffer, count_recv) : encode(buffer, count_recv) :
decode(buffer, count_recv); decode(buffer, count_recv);
/* count_sent = */(options.proto == SOCK_DGRAM) ? (options.proto == SOCK_DGRAM) ?
sendto(rc.client_socket, buffer, count_recv, 0, (struct sockaddr *)&client_addr, addr_len) : sendto(rc.client_socket, buffer, count_recv, 0, (struct sockaddr *)&client_addr, addr_len) :
send(rc.client_socket, buffer, count_recv, 0); send(rc.client_socket, buffer, count_recv, 0);
if (options.log > 1) if (options.log > 1)
printf("sent %d\t%s:%d\tpid: %d\n", count_recv, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), getpid()); printf("sent %d\t%s:%d\tpid: %d\n", count_recv, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), getpid());
} }
...@@ -448,41 +500,50 @@ int use() ...@@ -448,41 +500,50 @@ int use()
return 0; return 0;
} }
void run() { void run()
{
if (build() == 0) if (build() == 0)
use(); use();
} }
void fork_udp() { void fork_udp()
{
#ifndef __MINGW32__ #ifndef __MINGW32__
pid_t child_pid; pid_t child_pid;
int client_index = find_udp_client(rc.client_addr); int client_index = find_udp_client(rc.client_addr);
if (client_index == -1) { if (client_index == -1)
if ((child_pid = fork()) == 0) { {
if ((child_pid = fork()) == 0)
{
if (options.log) if (options.log)
printf("request from %s, forking %d ...\n", inet_ntoa(rc.client_addr.sin_addr), getpid()); printf("request from %s, forking %d ...\n", inet_ntoa(rc.client_addr.sin_addr), getpid());
run(); run();
exit(0); exit(0);
} }
if (add_udp_client(rc.client_addr, child_pid) < 0) { if (add_udp_client(rc.client_addr, child_pid) < 0)
{
printf("maximum clients %d reached: \n", MAX_UDP_CLIENTS); printf("maximum clients %d reached: \n", MAX_UDP_CLIENTS);
} }
/* Reap any zombie processes (clients that exited) */
while ((child_pid = waitpid(-1, NULL, WNOHANG)) > 0) {
remove_udp_client(child_pid);
}
} else { /* Reap any zombie processes (clients that exited) */
while ((child_pid = waitpid(-1, NULL, WNOHANG)) > 0)
{
remove_udp_client(child_pid);
}
}
else
{
if (options.log > 2) if (options.log > 2)
printf("existing udp client %s, handled by %d ...\n", inet_ntoa(rc.client_addr.sin_addr), clients[client_index].pid); printf("existing udp client %s, handled by %d ...\n", inet_ntoa(rc.client_addr.sin_addr), clients[client_index].pid);
} }
#endif #endif
} }
void fork_tcp() { void fork_tcp()
{
#ifndef __MINGW32__ #ifndef __MINGW32__
if (fork() == 0) { if (fork() == 0)
{
if (options.log) if (options.log)
printf("forking %d ...\n", getpid()); printf("forking %d ...\n", getpid());
close(rc.server_socket); close(rc.server_socket);
...@@ -493,30 +554,34 @@ void fork_tcp() { ...@@ -493,30 +554,34 @@ void fork_tcp() {
#endif #endif
} }
void serve() { void serve()
{
#ifdef __MINGW32__ #ifdef __MINGW32__
run(); run();
#else #else
if (options.fork) { if (options.fork)
(options.proto == SOCK_DGRAM) ? {
fork_udp() : (options.proto == SOCK_DGRAM) ? fork_udp() : fork_tcp();
fork_tcp();
} }
else { else
{
run(); run();
} }
#endif #endif
} }
void print_usage(void) { void print_usage(void)
{
printf("Usage: %s [config_path] [options]\n", name); printf("Usage: %s [config_path] [options]\n", name);
} }
void print_helpinfo(void) { void print_helpinfo(void)
{
printf("Try `%s --help' for more options\n", name); printf("Try `%s --help' for more options\n", name);
} }
void print_help(void) { void print_help(void)
{
fprintf(stderr, "\ fprintf(stderr, "\
Options:\n\ Options:\n\
...@@ -529,9 +594,9 @@ Options:\n\ ...@@ -529,9 +594,9 @@ Options:\n\
--client-address=IP only accept connections from this address\n\ --client-address=IP only accept connections from this address\n\
--buffer-size=BYTES buffer size\n" --buffer-size=BYTES buffer size\n"
#ifndef __MINGW32__ #ifndef __MINGW32__
" --fork fork-based concurrency (tcp-only)\n" " --fork fork-based concurrency (tcp-only)\n"
#endif #endif
" --log=LEVEL 0-3\n\ " --log=LEVEL 0-3\n\
--stay-alive don't exit on network errors\n\ --stay-alive don't exit on network errors\n\
--mode=MODE client [default] or server\n\ --mode=MODE client [default] or server\n\
--encrypt=ALG 0 - no encryption, 1 - time-based obfuscation\n\ --encrypt=ALG 0 - no encryption, 1 - time-based obfuscation\n\
...@@ -540,7 +605,8 @@ Options:\n\ ...@@ -540,7 +605,8 @@ Options:\n\
\n"); \n");
} }
void print_version(void) { void print_version(void)
{
fprintf(stderr, "\n\ fprintf(stderr, "\n\
bytevia v" VERSION " \n\n\ bytevia v" VERSION " \n\n\
...@@ -553,7 +619,8 @@ Written by by Michael Pastushkov <michael@pastushkov.com>\n\n\ ...@@ -553,7 +619,8 @@ Written by by Michael Pastushkov <michael@pastushkov.com>\n\n\
"); ");
} }
void init_options() { void init_options()
{
memset(&options, 0, sizeof(options)); memset(&options, 0, sizeof(options));
...@@ -570,129 +637,140 @@ void init_options() { ...@@ -570,129 +637,140 @@ void init_options() {
options.secret = 52341; options.secret = 52341;
} }
void set_options(int argc, char *argv[]) { void set_options(int argc, char *argv[])
{
int opt; int opt;
int index; int index;
do { do
{
opt = getopt_long(argc, argv, "", long_options, &index); opt = getopt_long(argc, argv, "", long_options, &index);
switch (opt) switch (opt)
{ {
case LOCAL_PORT_OPTION: case LOCAL_PORT_OPTION:
options.local_port = atoi(optarg); options.local_port = atoi(optarg);
break; break;
case REMOTE_HOST_OPTION: case REMOTE_HOST_OPTION:
options.remote_host = optarg; options.remote_host = optarg;
break; break;
case REMOTE_PORT_OPTION: case REMOTE_PORT_OPTION:
options.remote_port = atoi(optarg); options.remote_port = atoi(optarg);
break; break;
case BIND_ADDRESS_OPTION: case BIND_ADDRESS_OPTION:
options.bind_address = optarg; options.bind_address = optarg;
break; break;
case BUFFER_SIZE_OPTION: case BUFFER_SIZE_OPTION:
options.buffer_size = atoi(optarg); options.buffer_size = atoi(optarg);
break; break;
case CLIENT_ADDRESS_OPTION: case CLIENT_ADDRESS_OPTION:
options.client_address = optarg; options.client_address = optarg;
break; break;
case FORK_OPTION: case FORK_OPTION:
options.fork = 1; options.fork = 1;
break; break;
case LOG_OPTION: case LOG_OPTION:
options.log = atoi(optarg); options.log = atoi(optarg);
break; break;
case STAY_ALIVE_OPTION: case STAY_ALIVE_OPTION:
options.stay_alive = 1; options.stay_alive = 1;
break; break;
case MODE_OPTION: case MODE_OPTION:
options.mode = (strcmp(optarg, "server") == 0) ? MODE_SERVER : MODE_CLIENT; options.mode = (strcmp(optarg, "server") == 0) ? MODE_SERVER : MODE_CLIENT;
break; break;
case ENCRYPT_OPTION: case ENCRYPT_OPTION:
options.encrypt = atoi(optarg); options.encrypt = atoi(optarg);
break; break;
case SECRET_OPTION: case SECRET_OPTION:
options.secret = atoi(optarg); options.secret = atoi(optarg);
break; break;
case PROTO_OPTION: case PROTO_OPTION:
options.proto = (strcmp(optarg, "udp") == 0) ? SOCK_DGRAM : SOCK_STREAM; options.proto = (strcmp(optarg, "udp") == 0) ? SOCK_DGRAM : SOCK_STREAM;
break; break;
case HELP_OPTION: case HELP_OPTION:
print_usage(); print_usage();
print_help(); print_help();
exit(0); exit(0);
case VERSION_OPTION: case VERSION_OPTION:
print_version(); print_version();
exit(0); exit(0);
case '?': case '?':
print_usage(); print_usage();
print_helpinfo(); print_helpinfo();
exit(0); exit(0);
} }
} while (opt != -1); } while (opt != -1);
} }
void check_options() { void check_options()
{
int opt_error = 0; int opt_error = 0;
/* Required options */ /* Required options */
if (!options.local_port) { if (!options.local_port)
{
printf("%s: %s\n", name, "missing '--local-port=' option."); printf("%s: %s\n", name, "missing '--local-port=' option.");
opt_error++; opt_error++;
} }
if (!options.remote_port) { if (!options.remote_port)
{
printf("%s: %s\n", name, "missing '--remote-port=' option."); printf("%s: %s\n", name, "missing '--remote-port=' option.");
opt_error++; opt_error++;
} }
if (!options.remote_host) { if (!options.remote_host)
{
printf("%s: %s\n", name, "missing '--remote_address=' option."); printf("%s: %s\n", name, "missing '--remote_address=' option.");
opt_error++; opt_error++;
} }
if (opt_error) { if (opt_error)
{
print_usage(); print_usage();
print_help(); print_help();
exit(-1); exit(-1);
} }
/* Consistency checks */ /* Consistency checks */
if (options.mode == MODE_SERVER && !options.stay_alive) { if (options.mode == MODE_SERVER && !options.stay_alive)
{
printf("%s: option --stay-alive is switched on with --mode=server\n", name); printf("%s: option --stay-alive is switched on with --mode=server\n", name);
options.stay_alive = 0; options.stay_alive = 0;
} }
#ifdef __MINGW32__ #ifdef __MINGW32__
if (options.fork) { if (options.fork)
{
printf("%s: option --fork is switched off, Microsoft Windows is incompatible with forking\n", name); printf("%s: option --fork is switched off, Microsoft Windows is incompatible with forking\n", name);
options.fork = 0; options.fork = 0;
} }
#endif #endif
} }
#define MAX_ARGC 20 #define MAX_ARGC 20
#define MAX_LINE_LENGTH 256 #define MAX_LINE_LENGTH 256
void read_config(char *path) { void read_config(char *path)
{
int argc = 0; int argc = 0;
char *argv[MAX_ARGC]; char *argv[MAX_ARGC];
char line[MAX_LINE_LENGTH]; char line[MAX_LINE_LENGTH];
FILE *file = fopen(path, "r"); FILE *file = fopen(path, "r");
if (!file) { if (!file)
{
perror("cannot read config file"); perror("cannot read config file");
return; return;
} }
while (fgets(line, sizeof(line), file)) { while (fgets(line, sizeof(line), file))
if (strncmp(line, NAME, sizeof(NAME)-1) == 0) { {
if (strncmp(line, NAME, sizeof(NAME) - 1) == 0)
{
char *token = strtok(line, " \t\n"); char *token = strtok(line, " \t\n");
while (token && argc < MAX_ARGC) { while (token && argc < MAX_ARGC)
argv[argc++] = strdup(token); {
token = strtok(NULL, " \t\n"); argv[argc++] = strdup(token);
token = strtok(NULL, " \t\n");
} }
} }
} }
...@@ -700,12 +778,13 @@ void read_config(char *path) { ...@@ -700,12 +778,13 @@ void read_config(char *path) {
set_options(argc, argv); set_options(argc, argv);
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[])
{
int i, ret; int i, ret;
#ifdef __MINGW32__ #ifdef __MINGW32__
WSADATA info; WSADATA info;
if (WSAStartup(MAKEWORD(1,1), &info) != 0) if (WSAStartup(MAKEWORD(1, 1), &info) != 0)
{ {
perror("main: WSAStartup()"); perror("main: WSAStartup()");
exit(1); exit(1);
...@@ -715,11 +794,13 @@ int main(int argc, char *argv[]) { ...@@ -715,11 +794,13 @@ int main(int argc, char *argv[]) {
init_options(); init_options();
set_options(argc, argv); set_options(argc, argv);
for (i=1; i<argc; i++) { for (i = 1; i < argc; i++)
if (strncmp(argv[i], "--", 2) != 0) { {
read_config(argv[i]); if (strncmp(argv[i], "--", 2) != 0)
{
read_config(argv[i]);
break; break;
} }
} }
check_options(); check_options();
...@@ -727,7 +808,8 @@ int main(int argc, char *argv[]) { ...@@ -727,7 +808,8 @@ int main(int argc, char *argv[]) {
signal(SIGCHLD, SIG_IGN); signal(SIGCHLD, SIG_IGN);
#endif #endif
if (options.log) { if (options.log)
{
printf("%s %s started %s\n", NAME, VERSION, get_current_timestamp()); printf("%s %s started %s\n", NAME, VERSION, get_current_timestamp());
printf(" protocol: %s\n", options.proto == SOCK_DGRAM ? "udp" : "tcp"); printf(" protocol: %s\n", options.proto == SOCK_DGRAM ? "udp" : "tcp");
printf(" local: %s:%d\n", options.bind_address, options.local_port); printf(" local: %s:%d\n", options.bind_address, options.local_port);
...@@ -737,9 +819,7 @@ int main(int argc, char *argv[]) { ...@@ -737,9 +819,7 @@ int main(int argc, char *argv[]) {
printf(" fork: %s\n", options.fork ? "yes" : "no"); printf(" fork: %s\n", options.fork ? "yes" : "no");
} }
ret = (options.proto == SOCK_STREAM) ? ret = (options.proto == SOCK_STREAM) ? build_tcp() : build_udp();
build_tcp() :
build_udp();
if (ret != 0) if (ret != 0)
exit(1); exit(1);
...@@ -750,12 +830,10 @@ int main(int argc, char *argv[]) { ...@@ -750,12 +830,10 @@ int main(int argc, char *argv[]) {
{ {
serve(); serve();
} }
} } while (options.stay_alive);
while (options.stay_alive);
if (rc.server_socket) if (rc.server_socket)
close(rc.server_socket); close(rc.server_socket);
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment