Setup fd for perf and always reconnect

This commit is contained in:
angt
2015-10-22 10:47:04 +02:00
parent 692a1c3c55
commit 4d98a16579

View File

@@ -18,60 +18,44 @@
volatile sig_atomic_t running;
static int gt_open_sock (char *host, char *port, int listener)
static void fd_set_nonblock (int fd)
{
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
.ai_flags = AI_PASSIVE,
};
int val, ret;
struct addrinfo *ai, *res = NULL;
do {
val = 1;
ret = ioctl(fd, FIONBIO, &val);
} while (ret==-1 && errno==EINTR);
if (getaddrinfo(host, port, &hints, &res)) {
printf("host not found\n");
return -1;
if (ret==-1)
printf("ioctl FIONBIO: %m\n");
}
static void fd_set_nodelay (int fd)
{
int val = 1;
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY , &val, sizeof(val))==-1)
printf("setsockopt TCP_NODELAY: %m\n");
}
static void fd_set_reuseaddr (int fd)
{
int val = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))==-1)
printf("setsockopt SO_REUSEADDR: %m\n");
}
static int gt_open_sock (struct addrinfo *res) // bad
{
for (struct addrinfo *ai=res; ai; ai=ai->ai_next) {
int fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (fd!=-1)
return fd;
}
int fd = -1;
for (ai=res; ai; ai=ai->ai_next) {
fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (fd==-1)
continue;
int ret;
if (listener) {
const int val = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))==-1)
printf("setsockopt: %m\n");
ret = bind(fd, ai->ai_addr, ai->ai_addrlen);
if (!ret)
ret = listen(fd, 1);
} else {
ret = connect(fd, ai->ai_addr, ai->ai_addrlen);
}
if (!ret)
break;
if (errno)
printf("socket: %m\n");
close(fd);
fd = -1;
}
freeaddrinfo(res);
return fd;
return -1;
}
static int gt_open_tun (char *name)
@@ -240,19 +224,56 @@ int main (int argc, char **argv)
if (option(argc, argv, COUNT(opts), opts))
return 1;
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
.ai_flags = AI_PASSIVE,
};
struct addrinfo *ai = NULL;
if (getaddrinfo(host, port, &hints, &ai)) {
printf("host not found\n");
return 1;
}
int fd = -1;
if (listener) {
fd = gt_open_sock(ai);
if (fd==-1)
return 1;
fd_set_reuseaddr(fd);
int ret = bind(fd, ai->ai_addr, ai->ai_addrlen);
if (ret==-1) {
printf("bind: %m\n");
return 1;
}
ret = listen(fd, 1);
if (ret==-1) {
printf("listen: %m\n");
return 1;
}
}
struct netio tun = { .fd = -1 };
struct netio sock = { .fd = -1 };
int fd = gt_open_sock(host, port, listener);
if (fd==-1)
return 1;
tun.fd = gt_open_tun(dev);
if (tun.fd==-1)
return 1;
buffer_setup(&tun.recv, NULL, GT_BUFFER_SIZE);
buffer_setup(&sock.recv, NULL, GT_BUFFER_SIZE);
while (running) {
if (listener) {
@@ -267,17 +288,28 @@ int main (int argc, char **argv)
printf("accept: %m\n");
return 1;
}
// setup socket
} else {
// reconnect
sock.fd = fd;
sock.fd = gt_open_sock(ai);
if (sock.fd==-1)
return 1;
int ret = connect(sock.fd, ai->ai_addr, ai->ai_addrlen);
if (ret==-1) { // check errno
close(sock.fd);
sock.fd = -1;
continue;
}
}
fd_set_nonblock(sock.fd);
fd_set_nodelay(sock.fd);
printf("running...\n");
buffer_setup(&tun.recv, NULL, GT_BUFFER_SIZE);
buffer_setup(&sock.recv, NULL, GT_BUFFER_SIZE);
buffer_format(&tun.recv);
buffer_format(&sock.recv);
while (running) {
@@ -348,9 +380,15 @@ int main (int argc, char **argv)
}
restart:
free(tun.recv.data);
free(sock.recv.data);
close(sock.fd);
sock.fd = -1;
}
if (ai)
freeaddrinfo(ai);
free(tun.recv.data);
free(sock.recv.data);
return 0;
}