// g++ -Wall -Werror tcp_proxy.cpp -o tcp_proxy -lpthread -lws2_32
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#define Localhost "127.0.0.1"
#define ProxyPort 8080
#define HTTP_Server "192.168.1.1"
#define HTTP_Port "80"
#define MaxUsersQueue 10
#define MaxMsgSize 2048
struct sockets {
int source;
int dest;
};
void* conectarProxy(void*);
void* pushData(void*);
int main(int argc, char* argv[]) {
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
int proxy_socket = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(Localhost);
if (argc < 2)
server_addr.sin_port = htons(ProxyPort);
else // Usar puerto pasado desde la terminal
server_addr.sin_port = htons(atoi(argv[1]));
int server_addr_size = sizeof(server_addr);
bind(proxy_socket, (sockaddr*) &server_addr, server_addr_size);
listen(proxy_socket, MaxUsersQueue);
while (true) {
sockaddr_in client_addr;
int client_addr_size = sizeof(client_addr);
int socket_client = accept(proxy_socket, (sockaddr*) &client_addr, &client_addr_size);
pthread_t hilo_conectarProxy;
pthread_create(&hilo_conectarProxy, NULL, conectarProxy, &socket_client);
}
close(proxy_socket);
return 0;
}
void* conectarProxy(void* sc_param) {
int socket_client = *((int*)sc_param);
int httpServerSock = socket(AF_INET, SOCK_STREAM, 0);
addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
addrinfo* res;
getaddrinfo(HTTP_Server, HTTP_Port, &hints, &res);
connect(httpServerSock, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
sockets* cliente_proxy = new sockets{socket_client, httpServerSock};
pthread_t hilo_cliente_proxy;
pthread_create(&hilo_cliente_proxy, NULL, pushData, cliente_proxy);
sockets* proxy_cliente = new sockets{httpServerSock, socket_client};
pthread_t hilo_proxy_cliente;
pthread_create(&hilo_proxy_cliente, NULL, pushData, proxy_cliente);
pthread_join(hilo_cliente_proxy, NULL);
pthread_join(hilo_proxy_cliente, NULL);
return NULL;
}
void* pushData(void* args) {
sockets* src_dst = (sockets*)args;
int src = src_dst->source;
int dst = src_dst->dest;
char* data = new char[MaxMsgSize];
char buffer[MaxMsgSize];
while (true) {
strcpy(data, "");
strcpy(buffer, "");
int msg_size = 0;
do {
msg_size += recv(src, buffer, MaxMsgSize, 0);
if (msg_size == 0) break;
if (msg_size == -1) break;
printf("%d->%d Recibido: %d bytes\n", src, dst, msg_size);
strcat(data, buffer);
} while (strchr(data, '\n') == NULL);
if (msg_size == -1) break;
int sent_msg_size = send(dst, data, msg_size, 0);
printf("%d->%d Enviado: %d bytes\n", src, dst, msg_size);
if (sent_msg_size == -1) break;
}
delete (sockets*)args;
delete[] data;
close(src);
close(dst);
return NULL;
}