diff --git a/configure.ac b/configure.ac index 1267825..bba5d00 100644 --- a/configure.ac +++ b/configure.ac @@ -13,8 +13,9 @@ AC_C_RESTRICT AC_TYPE_SIZE_T AC_TYPE_SSIZE_T AC_TYPE_UINT8_T +AC_TYPE_INT64_T AC_FUNC_MALLOC -AC_CHECK_FUNCS([socket strtol]) +AC_CHECK_FUNCS([clock_gettime socket strtol]) PKG_CHECK_MODULES([libsodium], [libsodium >= 1.0.4]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/glorytun.c b/glorytun.c index e23390a..1c64062 100644 --- a/glorytun.c +++ b/glorytun.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -18,6 +19,10 @@ #include +#ifndef CLOCK_MONOTONIC_COARSE +#define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC +#endif + #define GT_BUFFER_SIZE (4*1024*1024) struct option { @@ -42,6 +47,13 @@ struct crypto_ctx { volatile sig_atomic_t running; +static int64_t dt_ms (struct timespec *ta, struct timespec *tb) +{ + const int64_t s = ta->tv_sec-tb->tv_sec; + const int64_t n = ta->tv_nsec-tb->tv_nsec; + return s*1000LL+n/1000000LL; +} + static void fd_set_nonblock (int fd) { int ret; @@ -187,6 +199,35 @@ static char *sk_get_name (int fd) return str_cat(strs, COUNT(strs)); } +static socklen_t sk_get_info (int fd, struct tcp_info *ti) +{ + socklen_t len = sizeof(struct tcp_info); + + if (getsockopt(fd, SOL_TCP, TCP_INFO, ti, &len)==-1) { + perror("getsockopt TCP_INFO"); + return 0; + } + + return len; +} + +static void print_tcp_info (struct tcp_info *ti) +{ + fprintf(stderr, "tcpinfo" + " rto:%llu" " ato:%llu" " snd_mss:%llu" + " rcv_mss:%llu" " unacked:%llu" " sacked:%llu" + " lost:%llu" " retrans:%llu" " fackets:%llu" + " pmtu:%llu" " rcv_ssthresh:%llu" " rtt:%llu" + " rttvar:%llu" " snd_ssthresh:%llu" " snd_cwnd:%llu" + " advmss:%llu" " reordering:%llu" "\n", + ti->tcpi_rto, ti->tcpi_ato, ti->tcpi_snd_mss, + ti->tcpi_rcv_mss, ti->tcpi_unacked, ti->tcpi_sacked, + ti->tcpi_lost, ti->tcpi_retrans, ti->tcpi_fackets, + ti->tcpi_pmtu, ti->tcpi_rcv_ssthresh, ti->tcpi_rtt, + ti->tcpi_rttvar, ti->tcpi_snd_ssthresh, ti->tcpi_snd_cwnd, + ti->tcpi_advmss, ti->tcpi_reordering); +} + static struct addrinfo *ai_create (const char *host, const char *port, int listener) { if (!port || !port[0]) { @@ -596,6 +637,11 @@ int main (int argc, char **argv) char *congestion = NULL; int version = 0; + struct { + struct timespec time; + struct tcp_info info; + } tcpinfo = {0}; + struct option opts[] = { { "dev", &dev, option_str }, { "host", &host, option_str }, @@ -692,6 +738,15 @@ int main (int argc, char **argv) return 1; } + struct timespec now; + clock_gettime(CLOCK_MONOTONIC_COARSE, &now); + + if (dt_ms(&now, &tcpinfo.time)>1000LL) { + tcpinfo.time = now; + if (sk_get_info(sock.fd, &tcpinfo.info)) + print_tcp_info(&tcpinfo.info); + } + buffer_shift(&sock.write.buf); if (fds[0].revents & POLLIN) {