First commit
commit
d204627b73
@ -0,0 +1,155 @@
|
||||
#include <sys/socket.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
int create_socket(int network, char transport) {
|
||||
|
||||
/* 'network' contains 4 for ipv4 or 6 for ipv6.
|
||||
'transport' contains 'T' for TCP or 'U' for UDP.
|
||||
The function returns -1 if the paramters do not match the above statement. */
|
||||
|
||||
int domain;
|
||||
int type;
|
||||
|
||||
if (network == 4) {
|
||||
domain = AF_INET;
|
||||
} else if (network == 6) {
|
||||
domain = AF_INET6;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (transport == 'T') {
|
||||
type = SOCK_STREAM;
|
||||
} else if (transport == 'U') {
|
||||
type = SOCK_DGRAM;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int newSock = socket(domain,type,0);
|
||||
return newSock;
|
||||
}
|
||||
|
||||
|
||||
void create_addr(int network, char* address, int port,struct sockaddr* dest) {
|
||||
/* Takes the relevant values - network (4 or 6), address, port - and fills them
|
||||
into dest */
|
||||
|
||||
if (network == 4) {
|
||||
struct sockaddr_in listen_address;
|
||||
|
||||
listen_address.sin_family = AF_INET;
|
||||
listen_address.sin_port = htons(port);
|
||||
inet_pton(AF_INET,address,&listen_address.sin_addr);
|
||||
memcpy(dest,&listen_address,sizeof(listen_address));
|
||||
return;
|
||||
|
||||
} else if (network == 6) {
|
||||
struct sockaddr_in6 listen_ipv6;
|
||||
listen_ipv6.sin6_family = AF_INET6;
|
||||
listen_ipv6.sin6_port = htons(port);
|
||||
inet_pton(AF_INET6,address,&listen_ipv6.sin6_addr);
|
||||
memcpy(dest,&listen_ipv6,sizeof(listen_ipv6));
|
||||
return;
|
||||
|
||||
} else {
|
||||
exit(-2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int create_and_bind (int network, char transport, char* address, int port,struct sockaddr* addr_struct) {
|
||||
/* combines the socket creation and address creation into one
|
||||
function - simply pass the required values, and a structure,
|
||||
and this function does the legwork for you */
|
||||
|
||||
int socket = create_socket(network,transport);
|
||||
if (socket == -1) {
|
||||
exit(-1);
|
||||
}
|
||||
create_addr(network,address,port,addr_struct);
|
||||
int addrlen = sizeof(*addr_struct);
|
||||
int i = bind (socket,addr_struct,(socklen_t)addrlen);
|
||||
if (i < 0) {
|
||||
exit(-3);
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
|
||||
int create_remote (int network,char transport,char* address,int port) {
|
||||
/* same as 'create_and_bind', but for remote sockets - client rather
|
||||
than server sockets */
|
||||
|
||||
int socket = create_socket(network,transport);
|
||||
if (socket == -1) {
|
||||
exit(-1);
|
||||
}
|
||||
struct sockaddr remote_addr_struct;
|
||||
create_addr(network,address,port,&remote_addr_struct);
|
||||
int addrlen = sizeof(remote_addr_struct);
|
||||
int i = connect(socket,&remote_addr_struct,(socklen_t)addrlen);
|
||||
if (i < 0) {
|
||||
printf("Something went wrong: %s\n",strerror(errno));
|
||||
exit(-3);
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
|
||||
void forward_data(int from_fd, int to_fd) {
|
||||
int n = 0;
|
||||
char* buffer = malloc(3000*sizeof(char));
|
||||
while ((n = recv(to_fd, buffer, 3000, 0)) > 0) { // read data from input socket
|
||||
send(to_fd, buffer, n, 0); // send data to output socket
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
int preferred_network = 4;
|
||||
char preferred_transport = 'T';
|
||||
struct sockaddr addr_struct;
|
||||
int server_sock = create_and_bind(preferred_network,preferred_transport,"127.0.0.1",3000,&addr_struct);
|
||||
int addrlen = sizeof(addr_struct);
|
||||
|
||||
listen(server_sock,50); /* Arbitrary number, change later */
|
||||
|
||||
while (1) {
|
||||
int from_client = accept(server_sock,&addr_struct,(socklen_t *)&addrlen);
|
||||
int to_server = create_remote(preferred_network,preferred_transport,"127.0.0.1",5000);
|
||||
|
||||
if (fork() == 0) {
|
||||
|
||||
/* fork returns 0 for a child, so we're in the child's execution
|
||||
right now */
|
||||
close(server_sock);
|
||||
if (fork() == 0) {
|
||||
forward_data(from_client,to_server);
|
||||
exit(0);
|
||||
}
|
||||
if (fork() == 0) {
|
||||
forward_data(to_server,from_client);
|
||||
exit(0);
|
||||
}
|
||||
exit(0);
|
||||
|
||||
|
||||
}
|
||||
// recv(from_client,buffer,3000,0);
|
||||
|
||||
|
||||
// printf("%s",buffer);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue