예제 #1
0
void dccp_write_xmit(struct sock *sk, int block)
{
	struct dccp_sock *dp = dccp_sk(sk);
	struct sk_buff *skb;

	while ((skb = skb_peek(&sk->sk_write_queue))) {
		int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);

		if (err > 0) {
			if (!block) {
				sk_reset_timer(sk, &dp->dccps_xmit_timer,
						msecs_to_jiffies(err)+jiffies);
				break;
			} else
				err = dccp_wait_for_ccid(sk, skb, err);
			if (err && err != -EINTR)
				DCCP_BUG("err=%d after dccp_wait_for_ccid", err);
		}

		skb_dequeue(&sk->sk_write_queue);
		if (err == 0) {
			struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
			const int len = skb->len;

			if (sk->sk_state == DCCP_PARTOPEN) {
				const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD;
				/*
				 * See 8.1.5 - Handshake Completion.
				 *
				 * For robustness we resend Confirm options until the client has
				 * entered OPEN. During the initial feature negotiation, the MPS
				 * is smaller than usual, reduced by the Change/Confirm options.
				 */
				if (!list_empty(&dp->dccps_featneg) && len > cur_mps) {
					DCCP_WARN("Payload too large (%d) for featneg.\n", len);
					dccp_send_ack(sk);
					dccp_feat_list_purge(&dp->dccps_featneg);
				}

				inet_csk_schedule_ack(sk);
				inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
						  inet_csk(sk)->icsk_rto,
						  DCCP_RTO_MAX);
				dcb->dccpd_type = DCCP_PKT_DATAACK;
			} else if (dccp_ack_pending(sk))
				dcb->dccpd_type = DCCP_PKT_DATAACK;
			else
				dcb->dccpd_type = DCCP_PKT_DATA;

			err = dccp_transmit_skb(sk, skb);
			ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
			if (err)
				DCCP_BUG("err=%d after ccid_hc_tx_packet_sent",
					 err);
		} else {
			dccp_pr_debug("packet discarded due to err=%d\n", err);
			kfree_skb(skb);
		}
	}
}
예제 #2
0
파일: output.c 프로젝트: 274914765/C
int dccp_connect(struct sock *sk)
{
    struct sk_buff *skb;
    struct inet_connection_sock *icsk = inet_csk(sk);

    dccp_connect_init(sk);

    skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation);
    if (unlikely(skb == NULL))
        return -ENOBUFS;

    /* Reserve space for headers. */
    skb_reserve(skb, sk->sk_prot->max_header);

    DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST;

    dccp_skb_entail(sk, skb);
    dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL));
    DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);

    /* Timer for repeating the REQUEST until an answer. */
    inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
                  icsk->icsk_rto, DCCP_RTO_MAX);
    return 0;
}
예제 #3
0
/*
 * Send a DCCP_PKT_CLOSE/CLOSEREQ. The caller locks the socket for us. This
 * cannot be allowed to fail queueing a DCCP_PKT_CLOSE/CLOSEREQ frame under
 * any circumstances.
 */
void dccp_send_close(struct sock *sk, const int active)
{
	struct dccp_sock *dp = dccp_sk(sk);
	struct sk_buff *skb;
	const gfp_t prio = active ? GFP_KERNEL : GFP_ATOMIC;

	skb = alloc_skb(sk->sk_prot->max_header, prio);
	if (skb == NULL)
		return;

	/* Reserve space for headers and prepare control bits. */
	skb_reserve(skb, sk->sk_prot->max_header);
	if (dp->dccps_role == DCCP_ROLE_SERVER && !dp->dccps_server_timewait)
		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSEREQ;
	else
		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE;

	if (active) {
		skb = dccp_skb_entail(sk, skb);
		/*
		 * Retransmission timer for active-close: RFC 4340, 8.3 requires
		 * to retransmit the Close/CloseReq until the CLOSING/CLOSEREQ
		 * state can be left. The initial timeout is 2 RTTs.
		 * Since RTT measurement is done by the CCIDs, there is no easy
		 * way to get an RTT sample. The fallback RTT from RFC 4340, 3.4
		 * is too low (200ms); we use a high value to avoid unnecessary
		 * retransmissions when the link RTT is > 0.2 seconds.
		 * FIXME: Let main module sample RTTs and use that instead.
		 */
		inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
					  DCCP_TIMEOUT_INIT, DCCP_RTO_MAX);
	}
	dccp_transmit_skb(sk, skb);
}
예제 #4
0
int dccp_connect(struct sock *sk)
{
	struct sk_buff *skb;
	struct inet_connection_sock *icsk = inet_csk(sk);

	
	if (dccp_feat_finalise_settings(dccp_sk(sk)))
		return -EPROTO;

	dccp_connect_init(sk);

	skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation);
	if (unlikely(skb == NULL))
		return -ENOBUFS;

	
	skb_reserve(skb, sk->sk_prot->max_header);

	DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST;

	dccp_skb_entail(sk, skb);
	dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL));
	DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);

	
	inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
				  icsk->icsk_rto, DCCP_RTO_MAX);
	return 0;
}
예제 #5
0
void dccp_send_close(struct sock *sk, const int active)
{
	struct dccp_sock *dp = dccp_sk(sk);
	struct sk_buff *skb;
	const gfp_t prio = active ? GFP_KERNEL : GFP_ATOMIC;

	skb = alloc_skb(sk->sk_prot->max_header, prio);
	if (skb == NULL)
		return;

	
	skb_reserve(skb, sk->sk_prot->max_header);
	if (dp->dccps_role == DCCP_ROLE_SERVER && !dp->dccps_server_timewait)
		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSEREQ;
	else
		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE;

	if (active) {
		dccp_write_xmit(sk, 1);
		dccp_skb_entail(sk, skb);
		dccp_transmit_skb(sk, skb_clone(skb, prio));
		
		inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
					  DCCP_TIMEOUT_INIT, DCCP_RTO_MAX);
	} else
		dccp_transmit_skb(sk, skb);
}
예제 #6
0
int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo)
{
	const struct dccp_sock *dp = dccp_sk(sk);
	int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb,
					 skb->len);

	if (err > 0)
		err = dccp_wait_for_ccid(sk, skb, timeo);

	if (err == 0) {
		struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
		const int len = skb->len;

		if (sk->sk_state == DCCP_PARTOPEN) {
			/* See 8.1.5.  Handshake Completion */
			inet_csk_schedule_ack(sk);
			inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
						  inet_csk(sk)->icsk_rto,
						  DCCP_RTO_MAX);
			dcb->dccpd_type = DCCP_PKT_DATAACK;
		} else if (dccp_ack_pending(sk))
			dcb->dccpd_type = DCCP_PKT_DATAACK;
		else
			dcb->dccpd_type = DCCP_PKT_DATA;

		err = dccp_transmit_skb(sk, skb);
		ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
	} else
		kfree_skb(skb);

	return err;
}
예제 #7
0
/**
 * dccp_xmit_packet  -  Send data packet under control of CCID
 * Transmits next-queued payload and informs CCID to account for the packet.
 */
static void dccp_xmit_packet(struct sock *sk)
{
	int err, len;
	struct dccp_sock *dp = dccp_sk(sk);
	struct sk_buff *skb = dccp_qpolicy_pop(sk);

	if (unlikely(skb == NULL))
		return;
	len = skb->len;

	if (sk->sk_state == DCCP_PARTOPEN) {
		const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD;
		/*
		 * See 8.1.5 - Handshake Completion.
		 *
		 * For robustness we resend Confirm options until the client has
		 * entered OPEN. During the initial feature negotiation, the MPS
		 * is smaller than usual, reduced by the Change/Confirm options.
		 */
		if (!list_empty(&dp->dccps_featneg) && len > cur_mps) {
			DCCP_WARN("Payload too large (%d) for featneg.\n", len);
			dccp_send_ack(sk);
			dccp_feat_list_purge(&dp->dccps_featneg);
		}

		inet_csk_schedule_ack(sk);
		inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
					      inet_csk(sk)->icsk_rto,
					      DCCP_RTO_MAX);
		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK;
	} else if (dccp_ack_pending(sk)) {
		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK;
	} else {
		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATA;
	}

	err = dccp_transmit_skb(sk, skb);
	if (err)
		dccp_pr_debug("transmit_skb() returned err=%d\n", err);
	/*
	 * Register this one as sent even if an error occurred. To the remote
	 * end a local packet drop is indistinguishable from network loss, i.e.
	 * any local drop will eventually be reported via receiver feedback.
	 */
	ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len);

	/*
	 * If the CCID needs to transfer additional header options out-of-band
	 * (e.g. Ack Vectors or feature-negotiation options), it activates this
	 * flag to schedule a Sync. The Sync will automatically incorporate all
	 * currently pending header options, thus clearing the backlog.
	 */
	if (dp->dccps_sync_scheduled)
		dccp_send_sync(sk, dp->dccps_gsr, DCCP_PKT_SYNC);
}
예제 #8
0
void dccp_write_xmit(struct sock *sk, int block)
{
	struct dccp_sock *dp = dccp_sk(sk);
	struct sk_buff *skb;

	while ((skb = skb_peek(&sk->sk_write_queue))) {
		int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);

		if (err > 0) {
			if (!block) {
				sk_reset_timer(sk, &dp->dccps_xmit_timer,
						msecs_to_jiffies(err)+jiffies);
				break;
			} else
				err = dccp_wait_for_ccid(sk, skb, err);
			if (err && err != -EINTR)
				DCCP_BUG("err=%d after dccp_wait_for_ccid", err);
		}

		skb_dequeue(&sk->sk_write_queue);
		if (err == 0) {
			struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
			const int len = skb->len;

			if (sk->sk_state == DCCP_PARTOPEN) {
				const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD;
				
				if (!list_empty(&dp->dccps_featneg) && len > cur_mps) {
					DCCP_WARN("Payload too large (%d) for featneg.\n", len);
					dccp_send_ack(sk);
					dccp_feat_list_purge(&dp->dccps_featneg);
				}

				inet_csk_schedule_ack(sk);
				inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
						  inet_csk(sk)->icsk_rto,
						  DCCP_RTO_MAX);
				dcb->dccpd_type = DCCP_PKT_DATAACK;
			} else if (dccp_ack_pending(sk))
				dcb->dccpd_type = DCCP_PKT_DATAACK;
			else
				dcb->dccpd_type = DCCP_PKT_DATA;

			err = dccp_transmit_skb(sk, skb);
			ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
			if (err)
				DCCP_BUG("err=%d after ccid_hc_tx_packet_sent",
					 err);
		} else {
			dccp_pr_debug("packet discarded due to err=%d\n", err);
			kfree_skb(skb);
		}
	}
}
예제 #9
0
void dccp_write_xmit(struct sock *sk, int block)
{
	struct dccp_sock *dp = dccp_sk(sk);
	struct sk_buff *skb;
	long timeo = 30000; 	/* If a packet is taking longer than 2 secs
				   we have other issues */

	while ((skb = skb_peek(&sk->sk_write_queue))) {
		int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb,
					 skb->len);

		if (err > 0) {
			if (!block) {
				sk_reset_timer(sk, &dp->dccps_xmit_timer,
						msecs_to_jiffies(err)+jiffies);
				break;
			} else
				err = dccp_wait_for_ccid(sk, skb, &timeo);
			if (err) {
				printk(KERN_CRIT "%s:err at dccp_wait_for_ccid"
						 " %d\n", __FUNCTION__, err);
				dump_stack();
			}
		}

		skb_dequeue(&sk->sk_write_queue);
		if (err == 0) {
			struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
			const int len = skb->len;

			if (sk->sk_state == DCCP_PARTOPEN) {
				/* See 8.1.5.  Handshake Completion */
				inet_csk_schedule_ack(sk);
				inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
						  inet_csk(sk)->icsk_rto,
						  DCCP_RTO_MAX);
				dcb->dccpd_type = DCCP_PKT_DATAACK;
			} else if (dccp_ack_pending(sk))
				dcb->dccpd_type = DCCP_PKT_DATAACK;
			else
				dcb->dccpd_type = DCCP_PKT_DATA;

			err = dccp_transmit_skb(sk, skb);
			ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
			if (err) {
				printk(KERN_CRIT "%s:err from "
					         "ccid_hc_tx_packet_sent %d\n",
					         __FUNCTION__, err);
				dump_stack();
			}
		} else
			kfree(skb);
	}
}
예제 #10
0
파일: output.c 프로젝트: 274914765/C
void dccp_write_xmit(struct sock *sk, int block)
{
    struct dccp_sock *dp = dccp_sk(sk);
    struct sk_buff *skb;

    while ((skb = skb_peek(&sk->sk_write_queue))) {
        int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);

        if (err > 0) {
            if (!block) {
                sk_reset_timer(sk, &dp->dccps_xmit_timer,
                        msecs_to_jiffies(err)+jiffies);
                break;
            } else
                err = dccp_wait_for_ccid(sk, skb, err);
            if (err && err != -EINTR)
                DCCP_BUG("err=%d after dccp_wait_for_ccid", err);
        }

        skb_dequeue(&sk->sk_write_queue);
        if (err == 0) {
            struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
            const int len = skb->len;

            if (sk->sk_state == DCCP_PARTOPEN) {
                /* See 8.1.5.  Handshake Completion */
                inet_csk_schedule_ack(sk);
                inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
                          inet_csk(sk)->icsk_rto,
                          DCCP_RTO_MAX);
                dcb->dccpd_type = DCCP_PKT_DATAACK;
            } else if (dccp_ack_pending(sk))
                dcb->dccpd_type = DCCP_PKT_DATAACK;
            else
                dcb->dccpd_type = DCCP_PKT_DATA;

            err = dccp_transmit_skb(sk, skb);
            ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
            if (err)
                DCCP_BUG("err=%d after ccid_hc_tx_packet_sent",
                     err);
        } else {
            dccp_pr_debug("packet discarded due to err=%d\n", err);
            kfree_skb(skb);
        }
    }
}
예제 #11
0
파일: output.c 프로젝트: 274914765/C
void dccp_send_ack(struct sock *sk)
{
    /* If we have been reset, we may not send again. */
    if (sk->sk_state != DCCP_CLOSED) {
        struct sk_buff *skb = alloc_skb(sk->sk_prot->max_header,
                        GFP_ATOMIC);

        if (skb == NULL) {
            inet_csk_schedule_ack(sk);
            inet_csk(sk)->icsk_ack.ato = TCP_ATO_MIN;
            inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
                          TCP_DELACK_MAX,
                          DCCP_RTO_MAX);
            return;
        }

        /* Reserve space for headers */
        skb_reserve(skb, sk->sk_prot->max_header);
        DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK;
        dccp_transmit_skb(sk, skb);
    }
}
예제 #12
0
/*
 * Do all connect socket setups that can be done AF independent.
 */
int dccp_connect(struct sock *sk)
{
	struct sk_buff *skb;
	struct dccp_sock *dp = dccp_sk(sk);
	struct dst_entry *dst = __sk_dst_get(sk);
	struct inet_connection_sock *icsk = inet_csk(sk);

	sk->sk_err = 0;
	sock_reset_flag(sk, SOCK_DONE);

	dccp_sync_mss(sk, dst_mtu(dst));

	/* do not connect if feature negotiation setup fails */
	if (dccp_feat_finalise_settings(dccp_sk(sk)))
		return -EPROTO;

	/* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */
	dp->dccps_gar = dp->dccps_iss;

	skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation);
	if (unlikely(skb == NULL))
		return -ENOBUFS;

	/* Reserve space for headers. */
	skb_reserve(skb, sk->sk_prot->max_header);

	DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST;

	dccp_transmit_skb(sk, dccp_skb_entail(sk, skb));
	DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);

	/* Timer for repeating the REQUEST until an answer. */
	icsk->icsk_retransmits = 0;
	inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
				  icsk->icsk_rto, DCCP_RTO_MAX);
	return 0;
}
예제 #13
0
void dccp_close(struct sock *sk, long timeout)
{
	struct sk_buff *skb;

	lock_sock(sk);

	sk->sk_shutdown = SHUTDOWN_MASK;

	if (sk->sk_state == DCCP_LISTEN) {
		dccp_set_state(sk, DCCP_CLOSED);

		/* Special case. */
		inet_csk_listen_stop(sk);

		goto adjudge_to_death;
	}

	/*
	 * We need to flush the recv. buffs.  We do this only on the
	 * descriptor close, not protocol-sourced closes, because the
	  *reader process may not have drained the data yet!
	 */
	/* FIXME: check for unread data */
	while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
		__kfree_skb(skb);
	}

	if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
		/* Check zero linger _after_ checking for unread data. */
		sk->sk_prot->disconnect(sk, 0);
	} else if (dccp_close_state(sk)) {
		dccp_send_close(sk, 1);
	}

	sk_stream_wait_close(sk, timeout);

adjudge_to_death:
	/*
	 * It is the last release_sock in its life. It will remove backlog.
	 */
	release_sock(sk);
	/*
	 * Now socket is owned by kernel and we acquire BH lock
	 * to finish close. No need to check for user refs.
	 */
	local_bh_disable();
	bh_lock_sock(sk);
	BUG_TRAP(!sock_owned_by_user(sk));

	sock_hold(sk);
	sock_orphan(sk);

	/*
	 * The last release_sock may have processed the CLOSE or RESET
	 * packet moving sock to CLOSED state, if not we have to fire
	 * the CLOSE/CLOSEREQ retransmission timer, see "8.3. Termination"
	 * in draft-ietf-dccp-spec-11. -acme
	 */
	if (sk->sk_state == DCCP_CLOSING) {
		/* FIXME: should start at 2 * RTT */
		/* Timer for repeating the CLOSE/CLOSEREQ until an answer. */
		inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
					  inet_csk(sk)->icsk_rto,
					  DCCP_RTO_MAX);
#if 0
		/* Yeah, we should use sk->sk_prot->orphan_count, etc */
		dccp_set_state(sk, DCCP_CLOSED);
#endif
	}

	atomic_inc(sk->sk_prot->orphan_count);
	if (sk->sk_state == DCCP_CLOSED)
		inet_csk_destroy_sock(sk);

	/* Otherwise, socket is reprieved until protocol close. */

	bh_unlock_sock(sk);
	local_bh_enable();
	sock_put(sk);
}
예제 #14
0
static bool tcp_fastopen_create_child(struct sock *sk,
                                      struct sk_buff *skb,
                                      struct dst_entry *dst,
                                      struct request_sock *req)
{
    struct tcp_sock *tp;
    struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
    struct sock *child;
    u32 end_seq;

    req->num_retrans = 0;
    req->num_timeout = 0;
    req->sk = NULL;

    child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
    if (!child)
        return false;

    spin_lock(&queue->fastopenq->lock);
    queue->fastopenq->qlen++;
    spin_unlock(&queue->fastopenq->lock);

    /* Initialize the child socket. Have to fix some values to take
     * into account the child is a Fast Open socket and is created
     * only out of the bits carried in the SYN packet.
     */
    tp = tcp_sk(child);

    tp->fastopen_rsk = req;
    tcp_rsk(req)->tfo_listener = true;

    /* RFC1323: The window in SYN & SYN/ACK segments is never
     * scaled. So correct it appropriately.
     */
    tp->snd_wnd = ntohs(tcp_hdr(skb)->window);

    /* Activate the retrans timer so that SYNACK can be retransmitted.
     * The request socket is not added to the SYN table of the parent
     * because it's been added to the accept queue directly.
     */
    inet_csk_reset_xmit_timer(child, ICSK_TIME_RETRANS,
                              TCP_TIMEOUT_INIT, TCP_RTO_MAX);

    atomic_set(&req->rsk_refcnt, 1);
    /* Add the child socket directly into the accept queue */
    inet_csk_reqsk_queue_add(sk, req, child);

    /* Now finish processing the fastopen child socket. */
    inet_csk(child)->icsk_af_ops->rebuild_header(child);
    tcp_init_congestion_control(child);
    tcp_mtup_init(child);
    tcp_init_metrics(child);
    tcp_init_buffer_space(child);

    /* Queue the data carried in the SYN packet. We need to first
     * bump skb's refcnt because the caller will attempt to free it.
     * Note that IPv6 might also have used skb_get() trick
     * in tcp_v6_conn_request() to keep this SYN around (treq->pktopts)
     * So we need to eventually get a clone of the packet,
     * before inserting it in sk_receive_queue.
     *
     * XXX (TFO) - we honor a zero-payload TFO request for now,
     * (any reason not to?) but no need to queue the skb since
     * there is no data. How about SYN+FIN?
     */
    end_seq = TCP_SKB_CB(skb)->end_seq;
    if (end_seq != TCP_SKB_CB(skb)->seq + 1) {
        struct sk_buff *skb2;

        if (unlikely(skb_shared(skb)))
            skb2 = skb_clone(skb, GFP_ATOMIC);
        else
            skb2 = skb_get(skb);

        if (likely(skb2)) {
            skb_dst_drop(skb2);
            __skb_pull(skb2, tcp_hdrlen(skb));
            skb_set_owner_r(skb2, child);
            __skb_queue_tail(&child->sk_receive_queue, skb2);
            tp->syn_data_acked = 1;

            /* u64_stats_update_begin(&tp->syncp) not needed here,
             * as we certainly are not changing upper 32bit value (0)
             */
            tp->bytes_received = end_seq - TCP_SKB_CB(skb)->seq - 1;
        } else {
            end_seq = TCP_SKB_CB(skb)->seq + 1;
        }
    }
    tcp_rsk(req)->rcv_nxt = tp->rcv_nxt = end_seq;
    sk->sk_data_ready(sk);
    bh_unlock_sock(child);
    sock_put(child);
    WARN_ON(!req->sk);
    return true;
}
예제 #15
0
static struct sock *tcp_fastopen_create_child(struct sock *sk,
					      struct sk_buff *skb,
					      struct dst_entry *dst,
					      struct request_sock *req)
{
	struct tcp_sock *tp;
	struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
	struct sock *child;
	bool own_req;

	req->num_retrans = 0;
	req->num_timeout = 0;
	req->sk = NULL;

	child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL,
							 NULL, &own_req);
	if (!child)
		return NULL;

	spin_lock(&queue->fastopenq.lock);
	queue->fastopenq.qlen++;
	spin_unlock(&queue->fastopenq.lock);

	/* Initialize the child socket. Have to fix some values to take
	 * into account the child is a Fast Open socket and is created
	 * only out of the bits carried in the SYN packet.
	 */
	tp = tcp_sk(child);

	tp->fastopen_rsk = req;
	tcp_rsk(req)->tfo_listener = true;

	/* RFC1323: The window in SYN & SYN/ACK segments is never
	 * scaled. So correct it appropriately.
	 */
	tp->snd_wnd = ntohs(tcp_hdr(skb)->window);
	tp->max_window = tp->snd_wnd;

	/* Activate the retrans timer so that SYNACK can be retransmitted.
	 * The request socket is not added to the ehash
	 * because it's been added to the accept queue directly.
	 */
	inet_csk_reset_xmit_timer(child, ICSK_TIME_RETRANS,
				  TCP_TIMEOUT_INIT, TCP_RTO_MAX);

	atomic_set(&req->rsk_refcnt, 2);

	/* Now finish processing the fastopen child socket. */
	inet_csk(child)->icsk_af_ops->rebuild_header(child);
	tcp_init_congestion_control(child);
	tcp_mtup_init(child);
	tcp_init_metrics(child);
	tcp_init_buffer_space(child);

	tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;

	tcp_fastopen_add_skb(child, skb);

	tcp_rsk(req)->rcv_nxt = tp->rcv_nxt;
	tp->rcv_wup = tp->rcv_nxt;
	/* tcp_conn_request() is sending the SYNACK,
	 * and queues the child into listener accept queue.
	 */
	return child;
}
예제 #16
0
static bool tcp_fastopen_create_child(struct sock *sk,
				      struct sk_buff *skb,
				      struct dst_entry *dst,
				      struct request_sock *req)
{
	struct tcp_sock *tp = tcp_sk(sk);
	struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
	struct sock *child;

	req->num_retrans = 0;
	req->num_timeout = 0;
	req->sk = NULL;

	child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
	if (child == NULL)
		return false;

	spin_lock(&queue->fastopenq->lock);
	queue->fastopenq->qlen++;
	spin_unlock(&queue->fastopenq->lock);

	/* Initialize the child socket. Have to fix some values to take
	 * into account the child is a Fast Open socket and is created
	 * only out of the bits carried in the SYN packet.
	 */
	tp = tcp_sk(child);

	tp->fastopen_rsk = req;
	/* Do a hold on the listner sk so that if the listener is being
	 * closed, the child that has been accepted can live on and still
	 * access listen_lock.
	 */
	sock_hold(sk);
	tcp_rsk(req)->listener = sk;

	/* RFC1323: The window in SYN & SYN/ACK segments is never
	 * scaled. So correct it appropriately.
	 */
	tp->snd_wnd = ntohs(tcp_hdr(skb)->window);

	/* Activate the retrans timer so that SYNACK can be retransmitted.
	 * The request socket is not added to the SYN table of the parent
	 * because it's been added to the accept queue directly.
	 */
	inet_csk_reset_xmit_timer(child, ICSK_TIME_RETRANS,
				  TCP_TIMEOUT_INIT, TCP_RTO_MAX);

	/* Add the child socket directly into the accept queue */
	inet_csk_reqsk_queue_add(sk, req, child);

	/* Now finish processing the fastopen child socket. */
	inet_csk(child)->icsk_af_ops->rebuild_header(child);
	tcp_init_congestion_control(child);
	tcp_mtup_init(child);
	tcp_init_metrics(child);
	tcp_init_buffer_space(child);

	/* Queue the data carried in the SYN packet. We need to first
	 * bump skb's refcnt because the caller will attempt to free it.
	 *
	 * XXX (TFO) - we honor a zero-payload TFO request for now,
	 * (any reason not to?) but no need to queue the skb since
	 * there is no data. How about SYN+FIN?
	 */
	if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1) {
		skb = skb_get(skb);
		skb_dst_drop(skb);
		__skb_pull(skb, tcp_hdr(skb)->doff * 4);
		skb_set_owner_r(skb, child);
		__skb_queue_tail(&child->sk_receive_queue, skb);
		tp->syn_data_acked = 1;
	}
	tcp_rsk(req)->rcv_nxt = tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
	sk->sk_data_ready(sk, 0);
	bh_unlock_sock(child);
	sock_put(child);
	WARN_ON(req->sk == NULL);
	return true;
}