Commit a356a2fd authored by Pavel Emelyanov's avatar Pavel Emelyanov

tcp: Get TCP_INFO once per socket

Right now we get SOL_TCP.TCP_INFO option twice, but one time
is enough.
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent e34fcc70
...@@ -75,17 +75,16 @@ static int tcp_repair_on(int fd) ...@@ -75,17 +75,16 @@ static int tcp_repair_on(int fd)
return ret; return ret;
} }
static int refresh_inet_sk(struct inet_sk_desc *sk) static int refresh_inet_sk(struct inet_sk_desc *sk, struct tcp_info *ti)
{ {
int size; int size;
struct tcp_info info;
if (dump_opt(sk->rfd, SOL_TCP, TCP_INFO, &info)) { if (dump_opt(sk->rfd, SOL_TCP, TCP_INFO, ti)) {
pr_perror("Failed to obtain TCP_INFO"); pr_perror("Failed to obtain TCP_INFO");
return -1; return -1;
} }
switch (info.tcpi_state) { switch (ti->tcpi_state) {
case TCP_ESTABLISHED: case TCP_ESTABLISHED:
case TCP_CLOSE: case TCP_CLOSE:
break; break;
...@@ -263,31 +262,25 @@ err_recv: ...@@ -263,31 +262,25 @@ err_recv:
goto err_buf; goto err_buf;
} }
static int tcp_stream_get_options(int sk, TcpStreamEntry *tse) static int tcp_stream_get_options(int sk, struct tcp_info *ti, TcpStreamEntry *tse)
{ {
int ret; int ret;
socklen_t auxl; socklen_t auxl;
struct tcp_info ti;
int val; int val;
auxl = sizeof(ti);
ret = getsockopt(sk, SOL_TCP, TCP_INFO, &ti, &auxl);
if (ret < 0)
goto err_sopt;
auxl = sizeof(tse->mss_clamp); auxl = sizeof(tse->mss_clamp);
ret = getsockopt(sk, SOL_TCP, TCP_MAXSEG, &tse->mss_clamp, &auxl); ret = getsockopt(sk, SOL_TCP, TCP_MAXSEG, &tse->mss_clamp, &auxl);
if (ret < 0) if (ret < 0)
goto err_sopt; goto err_sopt;
tse->opt_mask = ti.tcpi_options; tse->opt_mask = ti->tcpi_options;
if (ti.tcpi_options & TCPI_OPT_WSCALE) { if (ti->tcpi_options & TCPI_OPT_WSCALE) {
tse->snd_wscale = ti.tcpi_snd_wscale; tse->snd_wscale = ti->tcpi_snd_wscale;
tse->rcv_wscale = ti.tcpi_rcv_wscale; tse->rcv_wscale = ti->tcpi_rcv_wscale;
tse->has_rcv_wscale = true; tse->has_rcv_wscale = true;
} }
if (ti.tcpi_options & TCPI_OPT_TIMESTAMPS) { if (ti->tcpi_options & TCPI_OPT_TIMESTAMPS) {
auxl = sizeof(val); auxl = sizeof(val);
ret = getsockopt(sk, SOL_TCP, TCP_TIMESTAMP, &val, &auxl); ret = getsockopt(sk, SOL_TCP, TCP_TIMESTAMP, &val, &auxl);
if (ret < 0) if (ret < 0)
...@@ -299,9 +292,9 @@ static int tcp_stream_get_options(int sk, TcpStreamEntry *tse) ...@@ -299,9 +292,9 @@ static int tcp_stream_get_options(int sk, TcpStreamEntry *tse)
pr_info("\toptions: mss_clamp %x wscale %x tstamp %d sack %d\n", pr_info("\toptions: mss_clamp %x wscale %x tstamp %d sack %d\n",
(int)tse->mss_clamp, (int)tse->mss_clamp,
ti.tcpi_options & TCPI_OPT_WSCALE ? (int)tse->snd_wscale : -1, ti->tcpi_options & TCPI_OPT_WSCALE ? (int)tse->snd_wscale : -1,
ti.tcpi_options & TCPI_OPT_TIMESTAMPS ? 1 : 0, ti->tcpi_options & TCPI_OPT_TIMESTAMPS ? 1 : 0,
ti.tcpi_options & TCPI_OPT_SACK ? 1 : 0); ti->tcpi_options & TCPI_OPT_SACK ? 1 : 0);
return 0; return 0;
...@@ -313,11 +306,12 @@ err_sopt: ...@@ -313,11 +306,12 @@ err_sopt:
static int dump_tcp_conn_state(struct inet_sk_desc *sk) static int dump_tcp_conn_state(struct inet_sk_desc *sk)
{ {
int ret, aux; int ret, aux;
struct tcp_info ti;
struct cr_img *img; struct cr_img *img;
TcpStreamEntry tse = TCP_STREAM_ENTRY__INIT; TcpStreamEntry tse = TCP_STREAM_ENTRY__INIT;
char *in_buf, *out_buf; char *in_buf, *out_buf;
ret = refresh_inet_sk(sk); ret = refresh_inet_sk(sk, &ti);
if (ret < 0) if (ret < 0)
goto err_r; goto err_r;
...@@ -350,7 +344,7 @@ static int dump_tcp_conn_state(struct inet_sk_desc *sk) ...@@ -350,7 +344,7 @@ static int dump_tcp_conn_state(struct inet_sk_desc *sk)
*/ */
pr_info("Reading options for socket\n"); pr_info("Reading options for socket\n");
ret = tcp_stream_get_options(sk->rfd, &tse); ret = tcp_stream_get_options(sk->rfd, &ti, &tse);
if (ret < 0) if (ret < 0)
goto err_opt; goto err_opt;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment