Commit 6e683743 authored by Andrei Vagin's avatar Andrei Vagin Committed by Pavel Emelyanov

soccr: add support for syn-sent sockets

For that we restore all sockets properties and then
disable the repair mode before calling connect() and
the kernel will sent a syn packet and move the socket
into the sys-sent state.

travis-ci: success for series starting with [01/21] build: install libnet-dev
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent b1751244
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/sockios.h> #include <linux/sockios.h>
#include <libnet.h> #include <libnet.h>
#include <assert.h> #include <assert.h>
#include <errno.h>
#include "soccr.h" #include "soccr.h"
...@@ -90,13 +91,15 @@ static int tcp_repair_on(int fd) ...@@ -90,13 +91,15 @@ static int tcp_repair_on(int fd)
return ret; return ret;
} }
static void tcp_repair_off(int fd) static int tcp_repair_off(int fd)
{ {
int aux = 0, ret; int aux = 0, ret;
ret = setsockopt(fd, SOL_TCP, TCP_REPAIR, &aux, sizeof(aux)); ret = setsockopt(fd, SOL_TCP, TCP_REPAIR, &aux, sizeof(aux));
if (ret < 0) if (ret < 0)
logerr("Failed to turn off repair mode on socket"); logerr("Failed to turn off repair mode on socket");
return ret;
} }
struct libsoccr_sk { struct libsoccr_sk {
...@@ -150,6 +153,7 @@ static int refresh_sk(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, str ...@@ -150,6 +153,7 @@ static int refresh_sk(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, str
case TCP_CLOSE_WAIT: case TCP_CLOSE_WAIT:
case TCP_CLOSING: case TCP_CLOSING:
case TCP_CLOSE: case TCP_CLOSE:
case TCP_SYN_SENT:
break; break;
default: default:
loge("Unknown state %d\n", ti->tcpi_state); loge("Unknown state %d\n", ti->tcpi_state);
...@@ -400,6 +404,7 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk, ...@@ -400,6 +404,7 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
struct tcp_repair_opt opts[4]; struct tcp_repair_opt opts[4];
int addr_size; int addr_size;
int onr = 0; int onr = 0;
__u32 seq;
if (!data || data_size < SOCR_DATA_MIN_SIZE) if (!data || data_size < SOCR_DATA_MIN_SIZE)
return -1; return -1;
...@@ -417,8 +422,12 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk, ...@@ -417,8 +422,12 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
if (set_queue_seq(sk, TCP_RECV_QUEUE, if (set_queue_seq(sk, TCP_RECV_QUEUE,
data->inq_seq - data->inq_len)) data->inq_seq - data->inq_len))
return -2; return -2;
if (set_queue_seq(sk, TCP_SEND_QUEUE,
data->outq_seq - data->outq_len)) seq = data->outq_seq - data->outq_len;
if (data->state == TCP_SYN_SENT)
seq--;
if (set_queue_seq(sk, TCP_SEND_QUEUE, seq))
return -3; return -3;
if (data->dst_addr.sa.sa_family == AF_INET) if (data->dst_addr.sa.sa_family == AF_INET)
...@@ -426,11 +435,18 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk, ...@@ -426,11 +435,18 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
else else
addr_size = sizeof(data->dst_addr.v6); addr_size = sizeof(data->dst_addr.v6);
if (connect(sk->fd, &data->dst_addr.sa, addr_size) == -1) { if (data->state == TCP_SYN_SENT && tcp_repair_off(sk->fd))
return -1;
if (connect(sk->fd, &data->dst_addr.sa, addr_size) == -1 &&
errno != EINPROGRESS) {
loge("Can't connect inet socket back\n"); loge("Can't connect inet socket back\n");
return -1; return -1;
} }
if (data->state == TCP_SYN_SENT && tcp_repair_on(sk->fd))
return -1;
logd("\tRestoring TCP options\n"); logd("\tRestoring TCP options\n");
if (data->opt_mask & TCPI_OPT_SACK) { if (data->opt_mask & TCPI_OPT_SACK) {
...@@ -460,7 +476,8 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk, ...@@ -460,7 +476,8 @@ int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
opts[onr].opt_val = data->mss_clamp; opts[onr].opt_val = data->mss_clamp;
onr++; onr++;
if (setsockopt(sk->fd, SOL_TCP, TCP_REPAIR_OPTIONS, if (data->state != TCP_SYN_SENT &&
setsockopt(sk->fd, SOL_TCP, TCP_REPAIR_OPTIONS,
opts, onr * sizeof(struct tcp_repair_opt)) < 0) { opts, onr * sizeof(struct tcp_repair_opt)) < 0) {
logerr("Can't repair options"); logerr("Can't repair options");
return -2; return -2;
......
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