Beispiel #1
0
static int generic_restore_queues(struct sock *sk, struct cpt_sock_image *si,
                                  loff_t pos, struct cpt_context *ctx)
{
    loff_t endpos;

    pos = pos + si->cpt_hdrlen;
    endpos = pos + si->cpt_next;
    while (pos < endpos) {
        struct sk_buff *skb;
        __u32 type;

        skb = rst_skb(sk, &pos, NULL, &type, ctx);
        if (IS_ERR(skb)) {
            if (PTR_ERR(skb) == -EINVAL) {
                int err;

                err = rst_sock_attr(&pos, sk, ctx);
                if (err)
                    return err;
            }
            return PTR_ERR(skb);
        }

        if (type == CPT_SKB_RQ) {
            skb_set_owner_r(skb, sk);
            skb_queue_tail(&sk->sk_receive_queue, skb);
        } else {
            wprintk_ctx("strange socket queue type %u\n", type);
            kfree_skb(skb);
        }
    }
    return 0;
}
Beispiel #2
0
static int restore_unix_rqueue(struct sock *sk, struct cpt_sock_image *si,
                               loff_t pos, struct cpt_context *ctx)
{
    loff_t endpos;

    pos = pos + si->cpt_hdrlen;
    endpos = pos + si->cpt_next;
    while (pos < endpos) {
        struct sk_buff *skb;
        struct sock *owner_sk;
        __u32 owner;

        skb = rst_skb(sk, &pos, &owner, NULL, ctx);
        if (IS_ERR(skb)) {
            if (PTR_ERR(skb) == -EINVAL) {
                int err;

                err = rst_sock_attr(&pos, sk, ctx);
                if (err)
                    return err;
            }
            return PTR_ERR(skb);
        }

        owner_sk = unix_peer(sk);
        if (owner != -1) {
            cpt_object_t *pobj;
            pobj = lookup_cpt_obj_byindex(CPT_OBJ_SOCKET, owner, ctx);
            if (pobj == NULL) {
                eprintk_ctx("orphan af_unix skb?\n");
                kfree_skb(skb);
                continue;
            }
            owner_sk = pobj->o_obj;
        }
        if (owner_sk == NULL) {
            dprintk_ctx("orphan af_unix skb 2?\n");
            kfree_skb(skb);
            continue;
        }
        skb_set_owner_w(skb, owner_sk);
        if (UNIXCB(skb).fp)
            skb->destructor = unix_destruct_fds;
        skb_queue_tail(&sk->sk_receive_queue, skb);
        if (sk->sk_state == TCP_LISTEN) {
            struct socket *sock = skb->sk->sk_socket;
            if (sock == NULL) BUG();
            if (sock->file) BUG();
            skb->sk->sk_socket = NULL;
            skb->sk->sk_sleep = NULL;
            sock->sk = NULL;
            sock_release(sock);
        }
    }
    return 0;
}
Beispiel #3
0
static int restore_queues(struct sock *sk, struct cpt_sock_image *si,
			  loff_t pos, struct cpt_context *ctx)
{
	loff_t endpos;

	endpos = pos + si->cpt_next;
	pos = pos + si->cpt_hdrlen;
	while (pos < endpos) {
		struct sk_buff *skb;
		__u32 type;
		int err;

		err = rst_sock_attr(&pos, sk, ctx);
		if (!err)
			continue;
		if (err < 0)
			return err;

		skb = rst_skb(sk, &pos, NULL, &type, ctx);
		if (IS_ERR(skb))
			return PTR_ERR(skb);

		if (sk->sk_type == SOCK_STREAM) {
			if (type == CPT_SKB_RQ) {
				skb_set_owner_r(skb, sk);
				ub_tcprcvbuf_charge_forced(sk, skb);
				skb_queue_tail(&sk->sk_receive_queue, skb);
			} else if (type == CPT_SKB_OFOQ) {
				struct tcp_sock *tp = tcp_sk(sk);
				skb_set_owner_r(skb, sk);
				ub_tcprcvbuf_charge_forced(sk, skb);
				skb_queue_tail(&tp->out_of_order_queue, skb);
			} else if (type == CPT_SKB_WQ) {
				sk->sk_wmem_queued += skb->truesize;
				sk->sk_forward_alloc -= skb->truesize;
				ub_tcpsndbuf_charge_forced(sk, skb);
				skb_queue_tail(&sk->sk_write_queue, skb);
			} else {
				wprintk_ctx("strange stream queue type %u\n", type);
				kfree_skb(skb);
			}
		} else {
			if (type == CPT_SKB_RQ) {
				skb_set_owner_r(skb, sk);
				skb_queue_tail(&sk->sk_receive_queue, skb);
			} else if (type == CPT_SKB_WQ) {
				struct inet_sock *inet = inet_sk(sk);
				if (inet->cork.fragsize) {
					skb_set_owner_w(skb, sk);
					skb_queue_tail(&sk->sk_write_queue, skb);
				} else {
					eprintk_ctx("cork skb is dropped\n");
					kfree_skb(skb);
				}
			} else {
				wprintk_ctx("strange dgram queue type %u\n", type);
				kfree_skb(skb);
			}
		}
	}
	return 0;
}