Commit 4fdc20ed authored by Pavel Emelyanov's avatar Pavel Emelyanov

soccr/tcp: Introduce blob with connection info and getter for it

As an API for dumping and restoring the data the structure
with __u32-s is used. Getting one (and restoring) also involve
the size of the structure so that both -- caller and library --
can know which "version" of it the other one is using.

As a starting point all the fields that tcp_entry carries are
used.

Also note, that only tcp connection info is handled by the
library. Stuff like addresses and ports, socket options and
other are left for the caller to care for.
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent b8b113bf
...@@ -353,11 +353,22 @@ static int tcp_get_window(int sk, TcpStreamEntry *tse) ...@@ -353,11 +353,22 @@ static int tcp_get_window(int sk, TcpStreamEntry *tse)
static int dump_tcp_conn_state(struct inet_sk_desc *sk) static int dump_tcp_conn_state(struct inet_sk_desc *sk)
{ {
struct libsoccr_sk *socr = sk->priv;
int ret, aux; int ret, aux;
struct tcp_info ti; 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;
struct libsoccr_sk_data data;
ret = libsoccr_get_sk_data(socr, &data, sizeof(data));
if (ret < 0)
goto err_r;
if (ret != sizeof(data)) {
pr_err("This libsocr is not supported (%d vs %d)\n",
ret, (int)sizeof(data));
goto err_r;
}
ret = refresh_inet_sk(sk, &ti); ret = refresh_inet_sk(sk, &ti);
if (ret < 0) if (ret < 0)
......
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "soccr.h" #include "soccr.h"
static void (*log)(unsigned int loglevel, const char *format, ...) static void (*log)(unsigned int loglevel, const char *format, ...)
...@@ -61,3 +62,18 @@ void libsoccr_resume(struct libsoccr_sk *sk) ...@@ -61,3 +62,18 @@ void libsoccr_resume(struct libsoccr_sk *sk)
tcp_repair_off(sk->fd); tcp_repair_off(sk->fd);
free(sk); free(sk);
} }
/*
* This is how much data we've had in the initial libsoccr
*/
#define SOCR_DATA_MIN_SIZE (16 * sizeof(__u32))
int libsoccr_get_sk_data(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size)
{
if (!data || data_size < SOCR_DATA_MIN_SIZE)
return -1;
memset(data, 0, data_size);
return sizeof(struct libsoccr_sk_data);
}
...@@ -11,7 +11,45 @@ void libsoccr_set_log(unsigned int level, void (*fn)(unsigned int level, const c ...@@ -11,7 +11,45 @@ void libsoccr_set_log(unsigned int level, void (*fn)(unsigned int level, const c
struct libsoccr_sk; struct libsoccr_sk;
struct libsoccr_sk_data {
__u32 inq_len;
__u32 inq_seq;
__u32 outq_len;
__u32 outq_seq;
__u32 unsq_len;
__u32 opt_mask;
__u32 mss_clamp;
__u32 snd_wscale;
__u32 rcv_wscale;
__u32 timestamp;
__u32 flags; /* SOCCR_FLAGS_... below */
__u32 snd_wl1;
__u32 snd_wnd;
__u32 max_window;
__u32 rcv_wnd;
__u32 rcv_wup;
};
/*
* The flags below denote which data on libsoccr_sk_data was get
* from the kernel and is required for restore. Not present data
* is zeroified by the library.
*
* Ideally the caller should carry the whole _data structure between
* calls, but for optimization purposes it may analyze the flags
* field and drop the unneeded bits.
*/
/*
* Window parameters. Mark snd_wl1, snd_wnd, max_window, rcv_wnd
* and rcv_wup fields.
*/
#define SOCCR_FLAGS_WINDOW 0x1
struct libsoccr_sk *libsoccr_pause(int fd); struct libsoccr_sk *libsoccr_pause(int fd);
void libsoccr_resume(struct libsoccr_sk *sk); void libsoccr_resume(struct libsoccr_sk *sk);
int libsoccr_get_sk_data(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
#endif #endif
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