diff options
author | Bobby Bingham <koorogi@koorogi.info> | 2016-01-31 16:29:03 -0600 |
---|---|---|
committer | Bobby Bingham <koorogi@koorogi.info> | 2016-01-31 16:29:03 -0600 |
commit | 24da062c6f75a3fa229d74359150f653b63d3c04 (patch) | |
tree | a92a3e6cea31c18f004ffc028aa689151f5d93a3 /latency.c |
initial commit
Diffstat (limited to 'latency.c')
-rw-r--r-- | latency.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/latency.c b/latency.c new file mode 100644 index 0000000..6181e84 --- /dev/null +++ b/latency.c @@ -0,0 +1,97 @@ +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include <errno.h> +#include <netdb.h> +#include <stdio.h> +#include <unistd.h> + +#include "proxy.h" + +static int parse_host(const char *host, const char *port, struct addrinfo **addr) +{ + struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + .ai_flags = AI_PASSIVE, + }; + + int err; + if ((err = getaddrinfo(host, port, &hints, addr))) { + fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(err)); + return -1; + } + + return 0; +} + +static int listen_source(struct addrinfo *source) +{ + int fd = -1; + for (struct addrinfo *a = source; a; a = a->ai_next) { + if ((fd = socket(a->ai_family, a->ai_socktype, a->ai_protocol)) == -1) + continue; + if (!bind(fd, a->ai_addr, a->ai_addrlen) && !listen(fd, 1)) + break; + close(fd); + fd = -1; + } + return fd; +} + +static int connect_target(struct addrinfo *target) +{ + int fd = -1; + for (struct addrinfo *a = target; a; a = a->ai_next) { + if ((fd = socket(a->ai_family, a->ai_socktype, a->ai_protocol)) == -1) + continue; + if (connect(fd, a->ai_addr, a->ai_addrlen) != -1) + break; + close(fd); + fd = -1; + } + return fd; +} + +int main(int argc, char **argv) +{ + struct addrinfo *source; + struct addrinfo *target; + + if (argc != 3) { + fprintf(stderr, "usage: %s targethost targetport\n", argv[0]); + return -1; + } + + if (parse_host(NULL, "1234", &source)) + return -1; + if (parse_host(argv[1], argv[2], &target)) + return -1; + + int listenfd = listen_source(source); + if (listenfd < 0) { + perror("listen_source"); + return -1; + } + + for (;;) { + int sourcefd = accept(listenfd, NULL, NULL); + if (sourcefd == -1) break; + + int targetfd = connect_target(target); + if (targetfd == -1) { + perror("connect_target"); + close(sourcefd); + break; + } + + proxy(sourcefd, targetfd, 500); + + close(targetfd); + close(sourcefd); + } + + close(listenfd); + return 0; +} + |