Port Forwarding Server

https://github.com/iriszero48/PortForwardingServer

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <err.h>
#include <pthread.h>
#include <stdbool.h>
#include <math.h>
#include <arpa/inet.h>

static uint64_t recvCount, sendCount;

void TimePrinter()
{
	time_t t = time(NULL);
	struct tm* lt = localtime(&t);
	fflush(stdout);
	printf("[ %d-%d-%d %d:%d:%d ] ", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min,
		lt->tm_sec);
}

void Show()
{
	while (true)
	{
		fflush(stdout);
		printf("\r\033[k");
		printf("recv:%.fkB - send:%.fkB", round(recvCount / 1024.), round(sendCount / 1024.));
		sleep(1);
	}
}

void Transfer(void* argv)
{
	void* buf[1024] = { 0 };
	int len;
	while ((len = read(((int*)argv)[0], buf, 1024)) > 0)
	{
		write(((int*)argv)[1], buf, len);
		if (((int*)argv)[2]) recvCount += len;
		else sendCount += len;
	}
	close(((int*)argv)[0]);
	close(((int*)argv)[1]);
}

int main(const int argc, char* argv[])
{
	if (argc != 3) err(1, "Usage: PortForwardingServer UserPort ClientPort.\n");
	TimePrinter();
	printf("init...\n");
	int one = 1;

	//User listen
	struct sockaddr_in inSerAddr, inCliAddr;
	socklen_t socklen = sizeof inCliAddr;
	const int inSock = socket(AF_INET, SOCK_STREAM, 0);
	if (inSock < 0) err(1, "(in)Can't open socket %d.", ntohs(inSerAddr.sin_port));
	setsockopt(inSock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
	inSerAddr.sin_family = AF_INET;
	inSerAddr.sin_addr.s_addr = INADDR_ANY;
	inSerAddr.sin_port = htons(atoi(argv[1]));
	if (bind(inSock, (struct sockaddr *)&inSerAddr, sizeof inSerAddr) == -1)
	{
		close(inSock);
		err(1, "(in)Can't bind %d.", ntohs(inSerAddr.sin_port));
	}
	listen(inSock, 5);

	//Client listen
	struct sockaddr_in outSerAddr, outCliAddr;
	const int outSock = socket(AF_INET, SOCK_STREAM, 0);
	if (outSock < 0) err(1, "(out)Can't open socket %d.", ntohs(outSerAddr.sin_port));
	setsockopt(outSock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
	outSerAddr.sin_family = AF_INET;
	outSerAddr.sin_addr.s_addr = INADDR_ANY;
	outSerAddr.sin_port = htons(atoi(argv[2]));
	if (bind(outSock, (struct sockaddr *)&outSerAddr, sizeof(outSerAddr)) == -1)
	{
		close(outSock);
		err(1, "(out)Can't bind %d.", ntohs(outSerAddr.sin_port));
	}
	listen(outSock, 5);

	//Start log
	pthread_t logThread;
	if (pthread_create(&logThread, NULL, (void *)&Show, NULL) != 0) perror("(log)Can't create thread");
	else
	{
		TimePrinter();
		printf("(log)Thread start.\n");
	}

	while (true)
	{
		TimePrinter();
		printf("Link start...\n");

		//User accept
		const int inCliFd = accept4(inSock, (struct sockaddr *)&inCliAddr, &socklen, SOCK_CLOEXEC);
		TimePrinter();
		printf("(in)Got connection %d.\n", ntohs(inSerAddr.sin_port));
		if (inCliFd == -1) perror("(in)Can't accept.");

		//Client accept
		const int outCliFd = accept4(outSock, (struct sockaddr *)&outCliAddr, &socklen, SOCK_CLOEXEC);
		TimePrinter();
		printf("(out)Got connection %d.\n", ntohs(outSerAddr.sin_port));
		if (outCliFd == -1) perror("(out)Can't accept.");

		//Swap data
		pthread_t i2oThread, o2iThread2;
		void* ret;
		int i2o[3] = { inCliFd, outCliFd, false };
		int o2i[3] = { outCliFd, inCliFd, true };
		if (pthread_create(&i2oThread, NULL, (void *)&Transfer, (void*)i2o) != 0)
			perror("(in2out)Can't create thread.");
		if (pthread_create(&o2iThread2, NULL, (void *)&Transfer, (void*)o2i) != 0)
			perror("(out2in)Can't create thread.");
		TimePrinter();
		printf("Swaping User-%s:%d <=> Client-%s:%d.\n", inet_ntoa(inCliAddr.sin_addr), ntohs(inCliAddr.sin_port),
			inet_ntoa(outCliAddr.sin_addr), ntohs(outCliAddr.sin_port));
		if (pthread_join(i2oThread, &ret) != 0) perror("(in2out)Can't join with thread.");
		if (pthread_join(o2iThread2, &ret) != 0) perror("(out2in)Can't join with thread.");
		TimePrinter();
		printf("Drop.\n");
	}
}

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注