[CRIU] [PATCH 3/3] soccr: Move src/dst address from _data
Pavel Emelyanov
xemul at virtuozzo.com
Wed Dec 14 00:05:55 PST 2016
On 12/14/2016 03:36 AM, Andrey Vagin wrote:
> On Tue, Dec 13, 2016 at 05:32:16PM +0300, Pavel Emelyanov wrote:
>>
>> Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
>> ---
>> criu/sk-tcp.c | 8 ++++++--
>> soccr/soccr.c | 58 ++++++++++++++++++++++++++++++++++++++++++----------------
>> soccr/soccr.h | 18 +++++++++++++++---
>> 3 files changed, 63 insertions(+), 21 deletions(-)
>>
>> diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
>> index c8d4069..2512624 100644
>> --- a/criu/sk-tcp.c
>> +++ b/criu/sk-tcp.c
>> @@ -285,6 +285,7 @@ static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_
>> struct cr_img *img;
>> TcpStreamEntry *tse;
>> struct libsoccr_sk_data data = {};
>> + union libsoccr_addr sa_src, sa_dst;
>>
>> pr_info("Restoring TCP connection id %x ino %x\n", ii->ie->id, ii->ie->ino);
>>
>> @@ -335,15 +336,18 @@ static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_
>> data.rcv_wup = tse->rcv_wup;
>> }
>>
>> - if (restore_sockaddr(&data.src_addr,
>> + if (restore_sockaddr(&sa_src,
>> ii->ie->family, ii->ie->src_port,
>> ii->ie->src_addr, 0) < 0)
>> goto err_c;
>> - if (restore_sockaddr(&data.dst_addr,
>> + if (restore_sockaddr(&sa_dst,
>> ii->ie->family, ii->ie->dst_port,
>> ii->ie->dst_addr, 0) < 0)
>> goto err_c;
>>
>> + libsoccr_set_addr(socr, 1, &sa_src);
>> + libsoccr_set_addr(socr, 0, &sa_dst);
>> +
>> /*
>> * O_NONBLOCK has to be set before libsoccr_restore(),
>> * it is required to restore syn-sent sockets.
>> diff --git a/soccr/soccr.c b/soccr/soccr.c
>> index e6d0692..7324f94 100644
>> --- a/soccr/soccr.c
>> +++ b/soccr/soccr.c
>> @@ -106,6 +106,8 @@ struct libsoccr_sk {
>> int fd;
>> char *recv_queue;
>> char *send_queue;
>> + union libsoccr_addr *src_addr;
>> + union libsoccr_addr *dst_addr;
>> };
>>
>> struct libsoccr_sk *libsoccr_pause(int fd)
>> @@ -123,6 +125,8 @@ struct libsoccr_sk *libsoccr_pause(int fd)
>>
>> ret->recv_queue = NULL;
>> ret->send_queue = NULL;
>> + ret->src_addr = NULL;
>> + ret->dst_addr = NULL;
>> ret->fd = fd;
>> return ret;
>> }
>> @@ -132,6 +136,8 @@ void libsoccr_resume(struct libsoccr_sk *sk)
>> tcp_repair_off(sk->fd);
>> free(sk->send_queue);
>> free(sk->recv_queue);
>> + free(sk->src_addr);
>
> src_addr is set to an extrernal buffer, is it ok to call free() for it?
Ouch... Yes, it's stated in the function description that it will be free()-ed,
but CRIU abuses this. Thanks for catching, will fix.
>> + free(sk->dst_addr);
>> free(sk);
>> }
>>
>> @@ -376,6 +382,12 @@ char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal)
>> return ret;
>> }
>>
>> +union libsoccr_addr *libsoccr_get_addr(struct libsoccr_sk *sk, int self, int steal)
>> +{
>> + /* FIXME -- implemeted in CRIU, makes sence to have it here too */
>> + return NULL;
>> +}
>> +
>> static int set_queue_seq(struct libsoccr_sk *sk, int queue, __u32 seq)
>> {
>> logd("\tSetting %d queue seq to %u\n", queue, seq);
>> @@ -408,6 +420,9 @@ static int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
>> if (!data || data_size < SOCR_DATA_MIN_SIZE)
>> return -1;
>>
>> + if (!sk->dst_addr || !sk->src_addr)
>> + return -1;
>> +
>> mstate = 1 << data->state;
>>
>> if (data->state == TCP_LISTEN)
>> @@ -431,15 +446,15 @@ static int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
>> if (set_queue_seq(sk, TCP_SEND_QUEUE, seq))
>> return -3;
>>
>> - if (data->dst_addr.sa.sa_family == AF_INET)
>> - addr_size = sizeof(data->dst_addr.v4);
>> + if (sk->dst_addr->sa.sa_family == AF_INET)
>> + addr_size = sizeof(sk->dst_addr->v4);
>> else
>> - addr_size = sizeof(data->dst_addr.v6);
>> + addr_size = sizeof(sk->dst_addr->v6);
>>
>> if (data->state == TCP_SYN_SENT && tcp_repair_off(sk->fd))
>> return -1;
>>
>> - if (connect(sk->fd, &data->dst_addr.sa, addr_size) == -1 &&
>> + if (connect(sk->fd, &sk->dst_addr->sa, addr_size) == -1 &&
>> errno != EINPROGRESS) {
>> loge("Can't connect inet socket back\n");
>> return -1;
>> @@ -495,7 +510,8 @@ static int libsoccr_set_sk_data_noq(struct libsoccr_sk *sk,
>> return 0;
>> }
>>
>> -static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t flags)
>> +static int send_fin(struct libsoccr_sk *sk, struct libsoccr_sk_data *data,
>> + unsigned data_size, uint8_t flags)
>> {
>> int ret, exit_code = -1;
>> char errbuf[LIBNET_ERRBUF_SIZE];
>> @@ -503,7 +519,7 @@ static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t f
>> int libnet_type;
>> libnet_t *l;
>>
>> - if (data->dst_addr.sa.sa_family == AF_INET6)
>> + if (sk->dst_addr->sa.sa_family == AF_INET6)
>> libnet_type = LIBNET_RAW6;
>> else
>> libnet_type = LIBNET_RAW4;
>> @@ -519,8 +535,8 @@ static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t f
>> goto err;
>>
>> ret = libnet_build_tcp(
>> - ntohs(data->dst_addr.v4.sin_port), /* source port */
>> - ntohs(data->src_addr.v4.sin_port), /* destination port */
>> + ntohs(sk->dst_addr->v4.sin_port), /* source port */
>> + ntohs(sk->src_addr->v4.sin_port), /* destination port */
>> data->inq_seq, /* sequence number */
>> data->outq_seq - data->outq_len, /* acknowledgement num */
>> flags, /* control flags */
>> @@ -537,11 +553,11 @@ static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t f
>> goto err;
>> }
>>
>> - if (data->dst_addr.sa.sa_family == AF_INET6) {
>> + if (sk->dst_addr->sa.sa_family == AF_INET6) {
>> struct libnet_in6_addr src, dst;
>>
>> - memcpy(&dst, &data->dst_addr.v6.sin6_addr, sizeof(dst));
>> - memcpy(&src, &data->src_addr.v6.sin6_addr, sizeof(src));
>> + memcpy(&dst, &sk->dst_addr->v6.sin6_addr, sizeof(dst));
>> + memcpy(&src, &sk->src_addr->v6.sin6_addr, sizeof(src));
>>
>> ret = libnet_build_ipv6(
>> 0, 0,
>> @@ -554,7 +570,7 @@ static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t f
>> 0, /* payload size */
>> l, /* libnet handle */
>> 0); /* libnet id */
>> - } else if (data->dst_addr.sa.sa_family == AF_INET)
>> + } else if (sk->dst_addr->sa.sa_family == AF_INET)
>> ret = libnet_build_ipv4(
>> LIBNET_IPV4_H + LIBNET_TCP_H + 20, /* length */
>> 0, /* TOS */
>> @@ -563,8 +579,8 @@ static int send_fin(struct libsoccr_sk_data *data, unsigned data_size, uint8_t f
>> 64, /* TTL */
>> IPPROTO_TCP, /* protocol */
>> 0, /* checksum */
>> - data->dst_addr.v4.sin_addr.s_addr, /* source IP */
>> - data->src_addr.v4.sin_addr.s_addr, /* destination IP */
>> + sk->dst_addr->v4.sin_addr.s_addr, /* source IP */
>> + sk->src_addr->v4.sin_addr.s_addr, /* destination IP */
>> NULL, /* payload */
>> 0, /* payload size */
>> l, /* libnet handle */
>> @@ -667,7 +683,7 @@ int libsoccr_restore(struct libsoccr_sk *sk,
>>
>> /* Send a fin packet to the socket to restore it in a receive queue. */
>> if (mstate & (RCVQ_FIRST_FIN | RCVQ_SECOND_FIN))
>> - if (send_fin(data, data_size, TH_ACK | TH_FIN) < 0)
>> + if (send_fin(sk, data, data_size, TH_ACK | TH_FIN) < 0)
>> return -1;
>>
>> if (mstate & SNDQ_SECOND_FIN)
>> @@ -678,7 +694,7 @@ int libsoccr_restore(struct libsoccr_sk *sk,
>>
>> if (mstate & SNDQ_FIN_ACKED) {
>> data->outq_seq++;
>> - if (send_fin(data, data_size, TH_ACK) < 0)
>> + if (send_fin(sk, data, data_size, TH_ACK) < 0)
>> return -1;
>> }
>>
>> @@ -806,3 +822,13 @@ int libsoccr_set_queue_bytes(struct libsoccr_sk *sk, int queue_id, char *bytes)
>>
>> return -1;
>> }
>> +
>> +int libsoccr_set_addr(struct libsoccr_sk *sk, int self, union libsoccr_addr *addr)
>> +{
>> + if (self)
>> + sk->src_addr = addr;
>> + else
>> + sk->dst_addr = addr;
>> +
>> + return 0;
>> +}
>> diff --git a/soccr/soccr.h b/soccr/soccr.h
>> index 36043ae..d6ad3cf 100644
>> --- a/soccr/soccr.h
>> +++ b/soccr/soccr.h
>> @@ -90,9 +90,6 @@ struct libsoccr_sk_data {
>> __u32 max_window;
>> __u32 rcv_wnd;
>> __u32 rcv_wup;
>> -
>> - union libsoccr_addr src_addr;
>> - union libsoccr_addr dst_addr;
>> };
>>
>> /*
>> @@ -172,6 +169,13 @@ int libsoccr_save(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigne
>> char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal);
>>
>> /*
>> + * Returns filled libsoccr_addr for a socket. This value is also required
>> + * on restore, but addresses may be obtained from somewhere else, these
>> + * are just common sockaddr-s.
>> + */
>> +union libsoccr_addr *libsoccr_get_addr(struct libsoccr_sk *sk, int self, int steal);
>> +
>> +/*
>> * RESTORING calls
>> *
>> * The restoring of a socket is like below
>> @@ -183,6 +187,8 @@ char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal);
>> * h = libsoccr_pause(sk)
>> * libsoccr_set_queue_bytes(h, TCP_SEND_QUEUE, outq);
>> * libsoccr_set_queue_bytes(h, TCP_RECV_QUEUE, inq);
>> + * libsoccr_set_addr(h, 1, src_addr);
>> + * libsoccr_set_addr(h, 0, dst_addr);
>> * libsoccr_restore(h, &data, sizeof(data))
>> *
>> * libsoccr_resume(h)
>> @@ -198,6 +204,12 @@ char *libsoccr_get_queue_bytes(struct libsoccr_sk *sk, int queue_id, int steal);
>> int libsoccr_set_queue_bytes(struct libsoccr_sk *sk, int queue_id, char *bytes);
>>
>> /*
>> + * Set a pointer on the libsoccr_addr for src/dst. The buffer is as
>> + * well stolen by the library and is fre()-ed after libsoccr_resume().
>> + */
>> +int libsoccr_set_addr(struct libsoccr_sk *sk, int self, union libsoccr_addr *);
>> +
>> +/*
>> * Performs restore actions on bind()-ed socket
>> */
>> int libsoccr_restore(struct libsoccr_sk *sk, struct libsoccr_sk_data *data, unsigned data_size);
>> --
>> 2.5.0
>>
> .
>
More information about the CRIU
mailing list