Use writev to write in tun

This commit is contained in:
angt
2015-10-27 12:55:41 +01:00
parent 575796fc6f
commit e48333d955

View File

@@ -16,7 +16,7 @@
# include <linux/if_tun.h> # include <linux/if_tun.h>
#endif #endif
#define GT_BUFFER_SIZE (256*1024) #define GT_BUFFER_SIZE (32*1024)
volatile sig_atomic_t running; volatile sig_atomic_t running;
@@ -239,6 +239,24 @@ static ssize_t fd_write (int fd, const void *data, size_t size)
return ret; return ret;
} }
static ssize_t fd_writev (int fd, const struct iovec *iov, int count)
{
if (!count)
return -2;
ssize_t ret = writev(fd, iov, count);
if (ret==-1) {
if (errno==EAGAIN || errno==EINTR)
return -1;
if (errno)
perror("write");
return 0;
}
return ret;
}
enum option_type { enum option_type {
option_flag, option_flag,
option_string, option_string,
@@ -392,14 +410,19 @@ int main (int argc, char **argv)
buffer_shift(&tun.recv); buffer_shift(&tun.recv);
if (fds[0].revents & POLLIN) { if (fds[0].revents & POLLIN) {
size_t size = buffer_write_size(&tun.recv); while (1) {
ssize_t r = fd_read(fds[0].fd, tun.recv.write, size); size_t size = buffer_write_size(&tun.recv);
ssize_t r = fd_read(fds[0].fd, tun.recv.write, size);
if (!r) if (!r)
return 2; return 2;
if (r>0 && r==get_ip_size(tun.recv.write, size)) if (r==-1)
tun.recv.write += r; break;
if (r>0 && r==get_ip_size(tun.recv.write, size))
tun.recv.write += r;
}
} }
if (fds[1].revents & POLLOUT) if (fds[1].revents & POLLOUT)
@@ -433,11 +456,32 @@ int main (int argc, char **argv)
if (fds[0].revents & POLLOUT) if (fds[0].revents & POLLOUT)
fds[0].events = POLLIN; fds[0].events = POLLIN;
size_t size = buffer_read_size(&sock.recv); struct iovec iov[16];
ssize_t ip_size = get_ip_size(sock.recv.read, size); int count;
if (ip_size>0 && (size_t)ip_size<=size) { uint8_t *data = sock.recv.read;
ssize_t r = fd_write(fds[0].fd, sock.recv.read, ip_size);
for (count=0; count<COUNT(iov); count++) {
size_t size = sock.recv.write-data;
ssize_t ip_size = get_ip_size(data, size);
if (!ip_size)
goto restart;
if (ip_size==-1)
break;
if (ip_size>size)
break;
iov[count].iov_base = data;
iov[count].iov_len = ip_size;
data += ip_size;
}
if (count) {
ssize_t r = fd_writev(fds[0].fd, iov, count);
if (!r) if (!r)
return 2; return 2;
@@ -448,9 +492,6 @@ int main (int argc, char **argv)
if (r>0) if (r>0)
sock.recv.read += r; sock.recv.read += r;
} }
if (!ip_size)
goto restart;
} }
restart: restart: