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; }
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; }
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; }