I'm completely aware that I'm not using NIO, but this is my first polished C project. All criticism is welcome, if I'm doing something wrong, I want to nip it in the bud before I'm used to it.
/*
* TCPTunnel.c
*
* Created on: Jul 25, 2015
* Author: javaprophet
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <errno.h>
#include <signal.h>
int scl = -1;
int fcl = -1;
int ss = -1;
void ctf(void *arg) {
int scll = scl;
int fcll = fcl;
void* buf = malloc(1024);
while (1) {
int i = read(scll, buf, 1024);
if (i < 1) {
goto ret;
}
int w = 0;
while (w < i) {
w += write(fcll, buf + w, i - w);
}
}
ret: close(scll);
close(fcll);
free(buf);
}
void ftc(void *arg) {
int scll = scl;
int fcll = fcl;
void* buf = malloc(1024);
while (1) {
int i = read(fcll, buf, 1024);
if (i < 1) {
goto ret;
}
int w = 0;
while (w < i) {
w += write(scll, buf + w, i - w);
}
}
ret: close(scll);
close(fcll);
free(buf);
}
void lcl(int signum) {
close(ss);
}
int main(int argc, char** args) {
if (argc != 5) {
printf("Usage: TCPTunnel <bind-ip> <bind-port> <forward-ip> <forward-port>\n");
return 1;
}
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_handler = lcl;
sigaction(SIGTERM, &action, NULL);
ss = socket(AF_INET, SOCK_STREAM, 0);
if (ss < 0) {
printf("Failed to create socket, errno=%i\n", errno);
return 1;
}
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
if (inet_aton(args[1], &sa.sin_addr.s_addr) == 0) {
printf("Invalid bind IP!");
return 1;
}
sa.sin_family = AF_INET;
sa.sin_port = htons(strtol(args[2], NULL, 0));
struct sockaddr_in fa;
socklen_t fal;
memset(&fa, 0, sizeof(fa));
if (inet_aton(args[3], &fa.sin_addr.s_addr) == 0) {
printf("Invalid forward IP!");
return 1;
}
fa.sin_family = AF_INET;
fa.sin_port = htons(strtol(args[4], NULL, 0));
fal = sizeof(fa);
int e = bind(ss, (struct sockaddr *) &sa, sizeof(sa));
if (e < 0) {
printf("Failed to bind socket, errno=%i\n", errno);
return 1;
}
e = listen(ss, 50);
if (e < 0) {
printf("Failed to listen to socket, errno=%i\n", errno);
return 1;
}
struct sockaddr_in ca;
socklen_t cal;
while (1) {
int cs = accept(ss, (struct sockaddr *) &ca, &cal);
if (cs < 0) {
break;
}
scl = cs;
fcl = socket(AF_INET, SOCK_STREAM, 0);
if (fcl < 0) {
printf("Failed to connect to forwarding server for client!\n");
close(cs);
close(fcl);
continue;
}
if (connect(fcl, (struct sockaddr *) &fa, fal) < 0) {
printf("Failed to connect to forwarding server for client!\n");
close(cs);
close(fcl);
continue;
}
pthread_t ptt, ptt2;
pthread_create(&ptt, NULL, ctf, NULL);
pthread_create(&ptt2, NULL, ftc, NULL);
}
return 0;
}