Skip to content

Instantly share code, notes, and snippets.

@maaatts
Created August 22, 2015 16:30
Show Gist options
  • Save maaatts/d71e902ad309b6d6f5b0 to your computer and use it in GitHub Desktop.
Save maaatts/d71e902ad309b6d6f5b0 to your computer and use it in GitHub Desktop.
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define BACKLOG 10
#define BUF_SIZE 4096
#define PORT "1337"
unsigned int
transfer(int from, int to)
{
char buf[BUF_SIZE];
unsigned int disconnected = 0;
size_t bytes_read;
size_t bytes_written;
bytes_read = read(from, buf, BUF_SIZE);
if (bytes_read == 0)
{
disconnected = 1;
}
else
{
bytes_written = write(to, buf, bytes_read);
if (bytes_written == -1)
{
disconnected = 1;
}
}
return (disconnected);
}
void
handle(int client, const char *host, const char *port)
{
struct addrinfo hints;
struct addrinfo *res;
int server = -1;
unsigned int disconnected = 0;
fd_set set;
unsigned int max_sock;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(host, port, &hints, &res) != 0)
{
perror("getaddrinfo");
close(client);
return;
}
server = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (server == -1) {
perror("socket");
close(client);
return;
}
if (connect(server, res->ai_addr, res->ai_addrlen) == -1)
{
perror("connect");
close(client);
return;
}
if (client > server)
{
max_sock = client;
}
else
{
max_sock = server;
}
while (!disconnected) {
FD_ZERO(&set);
FD_SET(client, &set);
FD_SET(server, &set);
if (select(max_sock + 1, &set, NULL, NULL, NULL) == -1)
{
perror("select");
break;
}
if (FD_ISSET(client, &set))
{
disconnected = transfer(client, server);
}
if (FD_ISSET(server, &set))
{
disconnected = transfer(server, client);
}
}
close(server);
close(client);
return;
}
int
main(int argc, char **argv)
{
int sock;
struct addrinfo hints;
struct addrinfo *res;
int reuseaddr = 1;
const char *host;
const char *port;
if (argc < 3)
{
fprintf(stderr, "Usage: %s host port\n", argv[0]);
return (1);
}
host = argv[1];
port = argv[2];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(NULL, PORT, &hints, &res) != 0)
{
perror("getaddrinfo");
return (-1);
}
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock == -1)
{
perror("socket");
freeaddrinfo(res);
return (-1);
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
&reuseaddr, sizeof(int)) == -1)
{
perror("setsockopt");
freeaddrinfo(res);
return (-1);
}
if (bind(sock, res->ai_addr, res->ai_addrlen) == -1)
{
perror("bind");
freeaddrinfo(res);
return (-1);
}
if (listen(sock, BACKLOG) == -1)
{
perror("listen");
freeaddrinfo(res);
return (-1);
}
freeaddrinfo(res);
signal(SIGPIPE, SIG_IGN);
while (1)
{
socklen_t size = sizeof(struct sockaddr_in);
struct sockaddr_in their_addr;
int newsock = accept(sock, (struct sockaddr*)&their_addr, &size);
if (newsock == -1)
{
perror("accept");
}
else
{
printf("Got a connection from %s on port %d\n",
inet_ntoa(their_addr.sin_addr),
htons(their_addr.sin_port));
handle(newsock, host, port);
}
}
close(sock);
return (0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment