162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  net/dccp/output.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  An implementation of the DCCP protocol
662306a36Sopenharmony_ci *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/dccp.h>
1062306a36Sopenharmony_ci#include <linux/kernel.h>
1162306a36Sopenharmony_ci#include <linux/skbuff.h>
1262306a36Sopenharmony_ci#include <linux/slab.h>
1362306a36Sopenharmony_ci#include <linux/sched/signal.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <net/inet_sock.h>
1662306a36Sopenharmony_ci#include <net/sock.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include "ackvec.h"
1962306a36Sopenharmony_ci#include "ccid.h"
2062306a36Sopenharmony_ci#include "dccp.h"
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic inline void dccp_event_ack_sent(struct sock *sk)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci	inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
2562306a36Sopenharmony_ci}
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/* enqueue @skb on sk_send_head for retransmission, return clone to send now */
2862306a36Sopenharmony_cistatic struct sk_buff *dccp_skb_entail(struct sock *sk, struct sk_buff *skb)
2962306a36Sopenharmony_ci{
3062306a36Sopenharmony_ci	skb_set_owner_w(skb, sk);
3162306a36Sopenharmony_ci	WARN_ON(sk->sk_send_head);
3262306a36Sopenharmony_ci	sk->sk_send_head = skb;
3362306a36Sopenharmony_ci	return skb_clone(sk->sk_send_head, gfp_any());
3462306a36Sopenharmony_ci}
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/*
3762306a36Sopenharmony_ci * All SKB's seen here are completely headerless. It is our
3862306a36Sopenharmony_ci * job to build the DCCP header, and pass the packet down to
3962306a36Sopenharmony_ci * IP so it can do the same plus pass the packet off to the
4062306a36Sopenharmony_ci * device.
4162306a36Sopenharmony_ci */
4262306a36Sopenharmony_cistatic int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	if (likely(skb != NULL)) {
4562306a36Sopenharmony_ci		struct inet_sock *inet = inet_sk(sk);
4662306a36Sopenharmony_ci		const struct inet_connection_sock *icsk = inet_csk(sk);
4762306a36Sopenharmony_ci		struct dccp_sock *dp = dccp_sk(sk);
4862306a36Sopenharmony_ci		struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
4962306a36Sopenharmony_ci		struct dccp_hdr *dh;
5062306a36Sopenharmony_ci		/* XXX For now we're using only 48 bits sequence numbers */
5162306a36Sopenharmony_ci		const u32 dccp_header_size = sizeof(*dh) +
5262306a36Sopenharmony_ci					     sizeof(struct dccp_hdr_ext) +
5362306a36Sopenharmony_ci					  dccp_packet_hdr_len(dcb->dccpd_type);
5462306a36Sopenharmony_ci		int err, set_ack = 1;
5562306a36Sopenharmony_ci		u64 ackno = dp->dccps_gsr;
5662306a36Sopenharmony_ci		/*
5762306a36Sopenharmony_ci		 * Increment GSS here already in case the option code needs it.
5862306a36Sopenharmony_ci		 * Update GSS for real only if option processing below succeeds.
5962306a36Sopenharmony_ci		 */
6062306a36Sopenharmony_ci		dcb->dccpd_seq = ADD48(dp->dccps_gss, 1);
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci		switch (dcb->dccpd_type) {
6362306a36Sopenharmony_ci		case DCCP_PKT_DATA:
6462306a36Sopenharmony_ci			set_ack = 0;
6562306a36Sopenharmony_ci			fallthrough;
6662306a36Sopenharmony_ci		case DCCP_PKT_DATAACK:
6762306a36Sopenharmony_ci		case DCCP_PKT_RESET:
6862306a36Sopenharmony_ci			break;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci		case DCCP_PKT_REQUEST:
7162306a36Sopenharmony_ci			set_ack = 0;
7262306a36Sopenharmony_ci			/* Use ISS on the first (non-retransmitted) Request. */
7362306a36Sopenharmony_ci			if (icsk->icsk_retransmits == 0)
7462306a36Sopenharmony_ci				dcb->dccpd_seq = dp->dccps_iss;
7562306a36Sopenharmony_ci			fallthrough;
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci		case DCCP_PKT_SYNC:
7862306a36Sopenharmony_ci		case DCCP_PKT_SYNCACK:
7962306a36Sopenharmony_ci			ackno = dcb->dccpd_ack_seq;
8062306a36Sopenharmony_ci			fallthrough;
8162306a36Sopenharmony_ci		default:
8262306a36Sopenharmony_ci			/*
8362306a36Sopenharmony_ci			 * Set owner/destructor: some skbs are allocated via
8462306a36Sopenharmony_ci			 * alloc_skb (e.g. when retransmission may happen).
8562306a36Sopenharmony_ci			 * Only Data, DataAck, and Reset packets should come
8662306a36Sopenharmony_ci			 * through here with skb->sk set.
8762306a36Sopenharmony_ci			 */
8862306a36Sopenharmony_ci			WARN_ON(skb->sk);
8962306a36Sopenharmony_ci			skb_set_owner_w(skb, sk);
9062306a36Sopenharmony_ci			break;
9162306a36Sopenharmony_ci		}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci		if (dccp_insert_options(sk, skb)) {
9462306a36Sopenharmony_ci			kfree_skb(skb);
9562306a36Sopenharmony_ci			return -EPROTO;
9662306a36Sopenharmony_ci		}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci		/* Build DCCP header and checksum it. */
10062306a36Sopenharmony_ci		dh = dccp_zeroed_hdr(skb, dccp_header_size);
10162306a36Sopenharmony_ci		dh->dccph_type	= dcb->dccpd_type;
10262306a36Sopenharmony_ci		dh->dccph_sport	= inet->inet_sport;
10362306a36Sopenharmony_ci		dh->dccph_dport	= inet->inet_dport;
10462306a36Sopenharmony_ci		dh->dccph_doff	= (dccp_header_size + dcb->dccpd_opt_len) / 4;
10562306a36Sopenharmony_ci		dh->dccph_ccval	= dcb->dccpd_ccval;
10662306a36Sopenharmony_ci		dh->dccph_cscov = dp->dccps_pcslen;
10762306a36Sopenharmony_ci		/* XXX For now we're using only 48 bits sequence numbers */
10862306a36Sopenharmony_ci		dh->dccph_x	= 1;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci		dccp_update_gss(sk, dcb->dccpd_seq);
11162306a36Sopenharmony_ci		dccp_hdr_set_seq(dh, dp->dccps_gss);
11262306a36Sopenharmony_ci		if (set_ack)
11362306a36Sopenharmony_ci			dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), ackno);
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci		switch (dcb->dccpd_type) {
11662306a36Sopenharmony_ci		case DCCP_PKT_REQUEST:
11762306a36Sopenharmony_ci			dccp_hdr_request(skb)->dccph_req_service =
11862306a36Sopenharmony_ci							dp->dccps_service;
11962306a36Sopenharmony_ci			/*
12062306a36Sopenharmony_ci			 * Limit Ack window to ISS <= P.ackno <= GSS, so that
12162306a36Sopenharmony_ci			 * only Responses to Requests we sent are considered.
12262306a36Sopenharmony_ci			 */
12362306a36Sopenharmony_ci			dp->dccps_awl = dp->dccps_iss;
12462306a36Sopenharmony_ci			break;
12562306a36Sopenharmony_ci		case DCCP_PKT_RESET:
12662306a36Sopenharmony_ci			dccp_hdr_reset(skb)->dccph_reset_code =
12762306a36Sopenharmony_ci							dcb->dccpd_reset_code;
12862306a36Sopenharmony_ci			break;
12962306a36Sopenharmony_ci		}
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci		icsk->icsk_af_ops->send_check(sk, skb);
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci		if (set_ack)
13462306a36Sopenharmony_ci			dccp_event_ack_sent(sk);
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci		DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci		err = icsk->icsk_af_ops->queue_xmit(sk, skb, &inet->cork.fl);
13962306a36Sopenharmony_ci		return net_xmit_eval(err);
14062306a36Sopenharmony_ci	}
14162306a36Sopenharmony_ci	return -ENOBUFS;
14262306a36Sopenharmony_ci}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci/**
14562306a36Sopenharmony_ci * dccp_determine_ccmps  -  Find out about CCID-specific packet-size limits
14662306a36Sopenharmony_ci * @dp: socket to find packet size limits of
14762306a36Sopenharmony_ci *
14862306a36Sopenharmony_ci * We only consider the HC-sender CCID for setting the CCMPS (RFC 4340, 14.),
14962306a36Sopenharmony_ci * since the RX CCID is restricted to feedback packets (Acks), which are small
15062306a36Sopenharmony_ci * in comparison with the data traffic. A value of 0 means "no current CCMPS".
15162306a36Sopenharmony_ci */
15262306a36Sopenharmony_cistatic u32 dccp_determine_ccmps(const struct dccp_sock *dp)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci	const struct ccid *tx_ccid = dp->dccps_hc_tx_ccid;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	if (tx_ccid == NULL || tx_ccid->ccid_ops == NULL)
15762306a36Sopenharmony_ci		return 0;
15862306a36Sopenharmony_ci	return tx_ccid->ccid_ops->ccid_ccmps;
15962306a36Sopenharmony_ci}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ciunsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
16262306a36Sopenharmony_ci{
16362306a36Sopenharmony_ci	struct inet_connection_sock *icsk = inet_csk(sk);
16462306a36Sopenharmony_ci	struct dccp_sock *dp = dccp_sk(sk);
16562306a36Sopenharmony_ci	u32 ccmps = dccp_determine_ccmps(dp);
16662306a36Sopenharmony_ci	u32 cur_mps = ccmps ? min(pmtu, ccmps) : pmtu;
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	/* Account for header lengths and IPv4/v6 option overhead */
16962306a36Sopenharmony_ci	cur_mps -= (icsk->icsk_af_ops->net_header_len + icsk->icsk_ext_hdr_len +
17062306a36Sopenharmony_ci		    sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	/*
17362306a36Sopenharmony_ci	 * Leave enough headroom for common DCCP header options.
17462306a36Sopenharmony_ci	 * This only considers options which may appear on DCCP-Data packets, as
17562306a36Sopenharmony_ci	 * per table 3 in RFC 4340, 5.8. When running out of space for other
17662306a36Sopenharmony_ci	 * options (eg. Ack Vector which can take up to 255 bytes), it is better
17762306a36Sopenharmony_ci	 * to schedule a separate Ack. Thus we leave headroom for the following:
17862306a36Sopenharmony_ci	 *  - 1 byte for Slow Receiver (11.6)
17962306a36Sopenharmony_ci	 *  - 6 bytes for Timestamp (13.1)
18062306a36Sopenharmony_ci	 *  - 10 bytes for Timestamp Echo (13.3)
18162306a36Sopenharmony_ci	 *  - 8 bytes for NDP count (7.7, when activated)
18262306a36Sopenharmony_ci	 *  - 6 bytes for Data Checksum (9.3)
18362306a36Sopenharmony_ci	 *  - %DCCPAV_MIN_OPTLEN bytes for Ack Vector size (11.4, when enabled)
18462306a36Sopenharmony_ci	 */
18562306a36Sopenharmony_ci	cur_mps -= roundup(1 + 6 + 10 + dp->dccps_send_ndp_count * 8 + 6 +
18662306a36Sopenharmony_ci			   (dp->dccps_hc_rx_ackvec ? DCCPAV_MIN_OPTLEN : 0), 4);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	/* And store cached results */
18962306a36Sopenharmony_ci	icsk->icsk_pmtu_cookie = pmtu;
19062306a36Sopenharmony_ci	WRITE_ONCE(dp->dccps_mss_cache, cur_mps);
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci	return cur_mps;
19362306a36Sopenharmony_ci}
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(dccp_sync_mss);
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_civoid dccp_write_space(struct sock *sk)
19862306a36Sopenharmony_ci{
19962306a36Sopenharmony_ci	struct socket_wq *wq;
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci	rcu_read_lock();
20262306a36Sopenharmony_ci	wq = rcu_dereference(sk->sk_wq);
20362306a36Sopenharmony_ci	if (skwq_has_sleeper(wq))
20462306a36Sopenharmony_ci		wake_up_interruptible(&wq->wait);
20562306a36Sopenharmony_ci	/* Should agree with poll, otherwise some programs break */
20662306a36Sopenharmony_ci	if (sock_writeable(sk))
20762306a36Sopenharmony_ci		sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	rcu_read_unlock();
21062306a36Sopenharmony_ci}
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci/**
21362306a36Sopenharmony_ci * dccp_wait_for_ccid  -  Await CCID send permission
21462306a36Sopenharmony_ci * @sk:    socket to wait for
21562306a36Sopenharmony_ci * @delay: timeout in jiffies
21662306a36Sopenharmony_ci *
21762306a36Sopenharmony_ci * This is used by CCIDs which need to delay the send time in process context.
21862306a36Sopenharmony_ci */
21962306a36Sopenharmony_cistatic int dccp_wait_for_ccid(struct sock *sk, unsigned long delay)
22062306a36Sopenharmony_ci{
22162306a36Sopenharmony_ci	DEFINE_WAIT(wait);
22262306a36Sopenharmony_ci	long remaining;
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
22562306a36Sopenharmony_ci	sk->sk_write_pending++;
22662306a36Sopenharmony_ci	release_sock(sk);
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	remaining = schedule_timeout(delay);
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	lock_sock(sk);
23162306a36Sopenharmony_ci	sk->sk_write_pending--;
23262306a36Sopenharmony_ci	finish_wait(sk_sleep(sk), &wait);
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	if (signal_pending(current) || sk->sk_err)
23562306a36Sopenharmony_ci		return -1;
23662306a36Sopenharmony_ci	return remaining;
23762306a36Sopenharmony_ci}
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci/**
24062306a36Sopenharmony_ci * dccp_xmit_packet  -  Send data packet under control of CCID
24162306a36Sopenharmony_ci * @sk: socket to send data packet on
24262306a36Sopenharmony_ci *
24362306a36Sopenharmony_ci * Transmits next-queued payload and informs CCID to account for the packet.
24462306a36Sopenharmony_ci */
24562306a36Sopenharmony_cistatic void dccp_xmit_packet(struct sock *sk)
24662306a36Sopenharmony_ci{
24762306a36Sopenharmony_ci	int err, len;
24862306a36Sopenharmony_ci	struct dccp_sock *dp = dccp_sk(sk);
24962306a36Sopenharmony_ci	struct sk_buff *skb = dccp_qpolicy_pop(sk);
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	if (unlikely(skb == NULL))
25262306a36Sopenharmony_ci		return;
25362306a36Sopenharmony_ci	len = skb->len;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	if (sk->sk_state == DCCP_PARTOPEN) {
25662306a36Sopenharmony_ci		const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD;
25762306a36Sopenharmony_ci		/*
25862306a36Sopenharmony_ci		 * See 8.1.5 - Handshake Completion.
25962306a36Sopenharmony_ci		 *
26062306a36Sopenharmony_ci		 * For robustness we resend Confirm options until the client has
26162306a36Sopenharmony_ci		 * entered OPEN. During the initial feature negotiation, the MPS
26262306a36Sopenharmony_ci		 * is smaller than usual, reduced by the Change/Confirm options.
26362306a36Sopenharmony_ci		 */
26462306a36Sopenharmony_ci		if (!list_empty(&dp->dccps_featneg) && len > cur_mps) {
26562306a36Sopenharmony_ci			DCCP_WARN("Payload too large (%d) for featneg.\n", len);
26662306a36Sopenharmony_ci			dccp_send_ack(sk);
26762306a36Sopenharmony_ci			dccp_feat_list_purge(&dp->dccps_featneg);
26862306a36Sopenharmony_ci		}
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci		inet_csk_schedule_ack(sk);
27162306a36Sopenharmony_ci		inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
27262306a36Sopenharmony_ci					      inet_csk(sk)->icsk_rto,
27362306a36Sopenharmony_ci					      DCCP_RTO_MAX);
27462306a36Sopenharmony_ci		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK;
27562306a36Sopenharmony_ci	} else if (dccp_ack_pending(sk)) {
27662306a36Sopenharmony_ci		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK;
27762306a36Sopenharmony_ci	} else {
27862306a36Sopenharmony_ci		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATA;
27962306a36Sopenharmony_ci	}
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	err = dccp_transmit_skb(sk, skb);
28262306a36Sopenharmony_ci	if (err)
28362306a36Sopenharmony_ci		dccp_pr_debug("transmit_skb() returned err=%d\n", err);
28462306a36Sopenharmony_ci	/*
28562306a36Sopenharmony_ci	 * Register this one as sent even if an error occurred. To the remote
28662306a36Sopenharmony_ci	 * end a local packet drop is indistinguishable from network loss, i.e.
28762306a36Sopenharmony_ci	 * any local drop will eventually be reported via receiver feedback.
28862306a36Sopenharmony_ci	 */
28962306a36Sopenharmony_ci	ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len);
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	/*
29262306a36Sopenharmony_ci	 * If the CCID needs to transfer additional header options out-of-band
29362306a36Sopenharmony_ci	 * (e.g. Ack Vectors or feature-negotiation options), it activates this
29462306a36Sopenharmony_ci	 * flag to schedule a Sync. The Sync will automatically incorporate all
29562306a36Sopenharmony_ci	 * currently pending header options, thus clearing the backlog.
29662306a36Sopenharmony_ci	 */
29762306a36Sopenharmony_ci	if (dp->dccps_sync_scheduled)
29862306a36Sopenharmony_ci		dccp_send_sync(sk, dp->dccps_gsr, DCCP_PKT_SYNC);
29962306a36Sopenharmony_ci}
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci/**
30262306a36Sopenharmony_ci * dccp_flush_write_queue  -  Drain queue at end of connection
30362306a36Sopenharmony_ci * @sk: socket to be drained
30462306a36Sopenharmony_ci * @time_budget: time allowed to drain the queue
30562306a36Sopenharmony_ci *
30662306a36Sopenharmony_ci * Since dccp_sendmsg queues packets without waiting for them to be sent, it may
30762306a36Sopenharmony_ci * happen that the TX queue is not empty at the end of a connection. We give the
30862306a36Sopenharmony_ci * HC-sender CCID a grace period of up to @time_budget jiffies. If this function
30962306a36Sopenharmony_ci * returns with a non-empty write queue, it will be purged later.
31062306a36Sopenharmony_ci */
31162306a36Sopenharmony_civoid dccp_flush_write_queue(struct sock *sk, long *time_budget)
31262306a36Sopenharmony_ci{
31362306a36Sopenharmony_ci	struct dccp_sock *dp = dccp_sk(sk);
31462306a36Sopenharmony_ci	struct sk_buff *skb;
31562306a36Sopenharmony_ci	long delay, rc;
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	while (*time_budget > 0 && (skb = skb_peek(&sk->sk_write_queue))) {
31862306a36Sopenharmony_ci		rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci		switch (ccid_packet_dequeue_eval(rc)) {
32162306a36Sopenharmony_ci		case CCID_PACKET_WILL_DEQUEUE_LATER:
32262306a36Sopenharmony_ci			/*
32362306a36Sopenharmony_ci			 * If the CCID determines when to send, the next sending
32462306a36Sopenharmony_ci			 * time is unknown or the CCID may not even send again
32562306a36Sopenharmony_ci			 * (e.g. remote host crashes or lost Ack packets).
32662306a36Sopenharmony_ci			 */
32762306a36Sopenharmony_ci			DCCP_WARN("CCID did not manage to send all packets\n");
32862306a36Sopenharmony_ci			return;
32962306a36Sopenharmony_ci		case CCID_PACKET_DELAY:
33062306a36Sopenharmony_ci			delay = msecs_to_jiffies(rc);
33162306a36Sopenharmony_ci			if (delay > *time_budget)
33262306a36Sopenharmony_ci				return;
33362306a36Sopenharmony_ci			rc = dccp_wait_for_ccid(sk, delay);
33462306a36Sopenharmony_ci			if (rc < 0)
33562306a36Sopenharmony_ci				return;
33662306a36Sopenharmony_ci			*time_budget -= (delay - rc);
33762306a36Sopenharmony_ci			/* check again if we can send now */
33862306a36Sopenharmony_ci			break;
33962306a36Sopenharmony_ci		case CCID_PACKET_SEND_AT_ONCE:
34062306a36Sopenharmony_ci			dccp_xmit_packet(sk);
34162306a36Sopenharmony_ci			break;
34262306a36Sopenharmony_ci		case CCID_PACKET_ERR:
34362306a36Sopenharmony_ci			skb_dequeue(&sk->sk_write_queue);
34462306a36Sopenharmony_ci			kfree_skb(skb);
34562306a36Sopenharmony_ci			dccp_pr_debug("packet discarded due to err=%ld\n", rc);
34662306a36Sopenharmony_ci		}
34762306a36Sopenharmony_ci	}
34862306a36Sopenharmony_ci}
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_civoid dccp_write_xmit(struct sock *sk)
35162306a36Sopenharmony_ci{
35262306a36Sopenharmony_ci	struct dccp_sock *dp = dccp_sk(sk);
35362306a36Sopenharmony_ci	struct sk_buff *skb;
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	while ((skb = dccp_qpolicy_top(sk))) {
35662306a36Sopenharmony_ci		int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci		switch (ccid_packet_dequeue_eval(rc)) {
35962306a36Sopenharmony_ci		case CCID_PACKET_WILL_DEQUEUE_LATER:
36062306a36Sopenharmony_ci			return;
36162306a36Sopenharmony_ci		case CCID_PACKET_DELAY:
36262306a36Sopenharmony_ci			sk_reset_timer(sk, &dp->dccps_xmit_timer,
36362306a36Sopenharmony_ci				       jiffies + msecs_to_jiffies(rc));
36462306a36Sopenharmony_ci			return;
36562306a36Sopenharmony_ci		case CCID_PACKET_SEND_AT_ONCE:
36662306a36Sopenharmony_ci			dccp_xmit_packet(sk);
36762306a36Sopenharmony_ci			break;
36862306a36Sopenharmony_ci		case CCID_PACKET_ERR:
36962306a36Sopenharmony_ci			dccp_qpolicy_drop(sk, skb);
37062306a36Sopenharmony_ci			dccp_pr_debug("packet discarded due to err=%d\n", rc);
37162306a36Sopenharmony_ci		}
37262306a36Sopenharmony_ci	}
37362306a36Sopenharmony_ci}
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci/**
37662306a36Sopenharmony_ci * dccp_retransmit_skb  -  Retransmit Request, Close, or CloseReq packets
37762306a36Sopenharmony_ci * @sk: socket to perform retransmit on
37862306a36Sopenharmony_ci *
37962306a36Sopenharmony_ci * There are only four retransmittable packet types in DCCP:
38062306a36Sopenharmony_ci * - Request  in client-REQUEST  state (sec. 8.1.1),
38162306a36Sopenharmony_ci * - CloseReq in server-CLOSEREQ state (sec. 8.3),
38262306a36Sopenharmony_ci * - Close    in   node-CLOSING  state (sec. 8.3),
38362306a36Sopenharmony_ci * - Acks in client-PARTOPEN state (sec. 8.1.5, handled by dccp_delack_timer()).
38462306a36Sopenharmony_ci * This function expects sk->sk_send_head to contain the original skb.
38562306a36Sopenharmony_ci */
38662306a36Sopenharmony_ciint dccp_retransmit_skb(struct sock *sk)
38762306a36Sopenharmony_ci{
38862306a36Sopenharmony_ci	WARN_ON(sk->sk_send_head == NULL);
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk) != 0)
39162306a36Sopenharmony_ci		return -EHOSTUNREACH; /* Routing failure or similar. */
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	/* this count is used to distinguish original and retransmitted skb */
39462306a36Sopenharmony_ci	inet_csk(sk)->icsk_retransmits++;
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	return dccp_transmit_skb(sk, skb_clone(sk->sk_send_head, GFP_ATOMIC));
39762306a36Sopenharmony_ci}
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_cistruct sk_buff *dccp_make_response(const struct sock *sk, struct dst_entry *dst,
40062306a36Sopenharmony_ci				   struct request_sock *req)
40162306a36Sopenharmony_ci{
40262306a36Sopenharmony_ci	struct dccp_hdr *dh;
40362306a36Sopenharmony_ci	struct dccp_request_sock *dreq;
40462306a36Sopenharmony_ci	const u32 dccp_header_size = sizeof(struct dccp_hdr) +
40562306a36Sopenharmony_ci				     sizeof(struct dccp_hdr_ext) +
40662306a36Sopenharmony_ci				     sizeof(struct dccp_hdr_response);
40762306a36Sopenharmony_ci	struct sk_buff *skb;
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci	/* sk is marked const to clearly express we dont hold socket lock.
41062306a36Sopenharmony_ci	 * sock_wmalloc() will atomically change sk->sk_wmem_alloc,
41162306a36Sopenharmony_ci	 * it is safe to promote sk to non const.
41262306a36Sopenharmony_ci	 */
41362306a36Sopenharmony_ci	skb = sock_wmalloc((struct sock *)sk, MAX_DCCP_HEADER, 1,
41462306a36Sopenharmony_ci			   GFP_ATOMIC);
41562306a36Sopenharmony_ci	if (!skb)
41662306a36Sopenharmony_ci		return NULL;
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	skb_reserve(skb, MAX_DCCP_HEADER);
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci	skb_dst_set(skb, dst_clone(dst));
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	dreq = dccp_rsk(req);
42362306a36Sopenharmony_ci	if (inet_rsk(req)->acked)	/* increase GSS upon retransmission */
42462306a36Sopenharmony_ci		dccp_inc_seqno(&dreq->dreq_gss);
42562306a36Sopenharmony_ci	DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
42662306a36Sopenharmony_ci	DCCP_SKB_CB(skb)->dccpd_seq  = dreq->dreq_gss;
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci	/* Resolve feature dependencies resulting from choice of CCID */
42962306a36Sopenharmony_ci	if (dccp_feat_server_ccid_dependencies(dreq))
43062306a36Sopenharmony_ci		goto response_failed;
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci	if (dccp_insert_options_rsk(dreq, skb))
43362306a36Sopenharmony_ci		goto response_failed;
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ci	/* Build and checksum header */
43662306a36Sopenharmony_ci	dh = dccp_zeroed_hdr(skb, dccp_header_size);
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci	dh->dccph_sport	= htons(inet_rsk(req)->ir_num);
43962306a36Sopenharmony_ci	dh->dccph_dport	= inet_rsk(req)->ir_rmt_port;
44062306a36Sopenharmony_ci	dh->dccph_doff	= (dccp_header_size +
44162306a36Sopenharmony_ci			   DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
44262306a36Sopenharmony_ci	dh->dccph_type	= DCCP_PKT_RESPONSE;
44362306a36Sopenharmony_ci	dh->dccph_x	= 1;
44462306a36Sopenharmony_ci	dccp_hdr_set_seq(dh, dreq->dreq_gss);
44562306a36Sopenharmony_ci	dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_gsr);
44662306a36Sopenharmony_ci	dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service;
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	dccp_csum_outgoing(skb);
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci	/* We use `acked' to remember that a Response was already sent. */
45162306a36Sopenharmony_ci	inet_rsk(req)->acked = 1;
45262306a36Sopenharmony_ci	DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
45362306a36Sopenharmony_ci	return skb;
45462306a36Sopenharmony_ciresponse_failed:
45562306a36Sopenharmony_ci	kfree_skb(skb);
45662306a36Sopenharmony_ci	return NULL;
45762306a36Sopenharmony_ci}
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(dccp_make_response);
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci/* answer offending packet in @rcv_skb with Reset from control socket @ctl */
46262306a36Sopenharmony_cistruct sk_buff *dccp_ctl_make_reset(struct sock *sk, struct sk_buff *rcv_skb)
46362306a36Sopenharmony_ci{
46462306a36Sopenharmony_ci	struct dccp_hdr *rxdh = dccp_hdr(rcv_skb), *dh;
46562306a36Sopenharmony_ci	struct dccp_skb_cb *dcb = DCCP_SKB_CB(rcv_skb);
46662306a36Sopenharmony_ci	const u32 dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
46762306a36Sopenharmony_ci				       sizeof(struct dccp_hdr_ext) +
46862306a36Sopenharmony_ci				       sizeof(struct dccp_hdr_reset);
46962306a36Sopenharmony_ci	struct dccp_hdr_reset *dhr;
47062306a36Sopenharmony_ci	struct sk_buff *skb;
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	skb = alloc_skb(sk->sk_prot->max_header, GFP_ATOMIC);
47362306a36Sopenharmony_ci	if (skb == NULL)
47462306a36Sopenharmony_ci		return NULL;
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	skb_reserve(skb, sk->sk_prot->max_header);
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	/* Swap the send and the receive. */
47962306a36Sopenharmony_ci	dh = dccp_zeroed_hdr(skb, dccp_hdr_reset_len);
48062306a36Sopenharmony_ci	dh->dccph_type	= DCCP_PKT_RESET;
48162306a36Sopenharmony_ci	dh->dccph_sport	= rxdh->dccph_dport;
48262306a36Sopenharmony_ci	dh->dccph_dport	= rxdh->dccph_sport;
48362306a36Sopenharmony_ci	dh->dccph_doff	= dccp_hdr_reset_len / 4;
48462306a36Sopenharmony_ci	dh->dccph_x	= 1;
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci	dhr = dccp_hdr_reset(skb);
48762306a36Sopenharmony_ci	dhr->dccph_reset_code = dcb->dccpd_reset_code;
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	switch (dcb->dccpd_reset_code) {
49062306a36Sopenharmony_ci	case DCCP_RESET_CODE_PACKET_ERROR:
49162306a36Sopenharmony_ci		dhr->dccph_reset_data[0] = rxdh->dccph_type;
49262306a36Sopenharmony_ci		break;
49362306a36Sopenharmony_ci	case DCCP_RESET_CODE_OPTION_ERROR:
49462306a36Sopenharmony_ci	case DCCP_RESET_CODE_MANDATORY_ERROR:
49562306a36Sopenharmony_ci		memcpy(dhr->dccph_reset_data, dcb->dccpd_reset_data, 3);
49662306a36Sopenharmony_ci		break;
49762306a36Sopenharmony_ci	}
49862306a36Sopenharmony_ci	/*
49962306a36Sopenharmony_ci	 * From RFC 4340, 8.3.1:
50062306a36Sopenharmony_ci	 *   If P.ackno exists, set R.seqno := P.ackno + 1.
50162306a36Sopenharmony_ci	 *   Else set R.seqno := 0.
50262306a36Sopenharmony_ci	 */
50362306a36Sopenharmony_ci	if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
50462306a36Sopenharmony_ci		dccp_hdr_set_seq(dh, ADD48(dcb->dccpd_ack_seq, 1));
50562306a36Sopenharmony_ci	dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dcb->dccpd_seq);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	dccp_csum_outgoing(skb);
50862306a36Sopenharmony_ci	return skb;
50962306a36Sopenharmony_ci}
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(dccp_ctl_make_reset);
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci/* send Reset on established socket, to close or abort the connection */
51462306a36Sopenharmony_ciint dccp_send_reset(struct sock *sk, enum dccp_reset_codes code)
51562306a36Sopenharmony_ci{
51662306a36Sopenharmony_ci	struct sk_buff *skb;
51762306a36Sopenharmony_ci	/*
51862306a36Sopenharmony_ci	 * FIXME: what if rebuild_header fails?
51962306a36Sopenharmony_ci	 * Should we be doing a rebuild_header here?
52062306a36Sopenharmony_ci	 */
52162306a36Sopenharmony_ci	int err = inet_csk(sk)->icsk_af_ops->rebuild_header(sk);
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci	if (err != 0)
52462306a36Sopenharmony_ci		return err;
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci	skb = sock_wmalloc(sk, sk->sk_prot->max_header, 1, GFP_ATOMIC);
52762306a36Sopenharmony_ci	if (skb == NULL)
52862306a36Sopenharmony_ci		return -ENOBUFS;
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	/* Reserve space for headers and prepare control bits. */
53162306a36Sopenharmony_ci	skb_reserve(skb, sk->sk_prot->max_header);
53262306a36Sopenharmony_ci	DCCP_SKB_CB(skb)->dccpd_type	   = DCCP_PKT_RESET;
53362306a36Sopenharmony_ci	DCCP_SKB_CB(skb)->dccpd_reset_code = code;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	return dccp_transmit_skb(sk, skb);
53662306a36Sopenharmony_ci}
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci/*
53962306a36Sopenharmony_ci * Do all connect socket setups that can be done AF independent.
54062306a36Sopenharmony_ci */
54162306a36Sopenharmony_ciint dccp_connect(struct sock *sk)
54262306a36Sopenharmony_ci{
54362306a36Sopenharmony_ci	struct sk_buff *skb;
54462306a36Sopenharmony_ci	struct dccp_sock *dp = dccp_sk(sk);
54562306a36Sopenharmony_ci	struct dst_entry *dst = __sk_dst_get(sk);
54662306a36Sopenharmony_ci	struct inet_connection_sock *icsk = inet_csk(sk);
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	sk->sk_err = 0;
54962306a36Sopenharmony_ci	sock_reset_flag(sk, SOCK_DONE);
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci	dccp_sync_mss(sk, dst_mtu(dst));
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci	/* do not connect if feature negotiation setup fails */
55462306a36Sopenharmony_ci	if (dccp_feat_finalise_settings(dccp_sk(sk)))
55562306a36Sopenharmony_ci		return -EPROTO;
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	/* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */
55862306a36Sopenharmony_ci	dp->dccps_gar = dp->dccps_iss;
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci	skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation);
56162306a36Sopenharmony_ci	if (unlikely(skb == NULL))
56262306a36Sopenharmony_ci		return -ENOBUFS;
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ci	/* Reserve space for headers. */
56562306a36Sopenharmony_ci	skb_reserve(skb, sk->sk_prot->max_header);
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_ci	DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST;
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	dccp_transmit_skb(sk, dccp_skb_entail(sk, skb));
57062306a36Sopenharmony_ci	DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci	/* Timer for repeating the REQUEST until an answer. */
57362306a36Sopenharmony_ci	icsk->icsk_retransmits = 0;
57462306a36Sopenharmony_ci	inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
57562306a36Sopenharmony_ci				  icsk->icsk_rto, DCCP_RTO_MAX);
57662306a36Sopenharmony_ci	return 0;
57762306a36Sopenharmony_ci}
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(dccp_connect);
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_civoid dccp_send_ack(struct sock *sk)
58262306a36Sopenharmony_ci{
58362306a36Sopenharmony_ci	/* If we have been reset, we may not send again. */
58462306a36Sopenharmony_ci	if (sk->sk_state != DCCP_CLOSED) {
58562306a36Sopenharmony_ci		struct sk_buff *skb = alloc_skb(sk->sk_prot->max_header,
58662306a36Sopenharmony_ci						GFP_ATOMIC);
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci		if (skb == NULL) {
58962306a36Sopenharmony_ci			inet_csk_schedule_ack(sk);
59062306a36Sopenharmony_ci			inet_csk(sk)->icsk_ack.ato = TCP_ATO_MIN;
59162306a36Sopenharmony_ci			inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
59262306a36Sopenharmony_ci						  TCP_DELACK_MAX,
59362306a36Sopenharmony_ci						  DCCP_RTO_MAX);
59462306a36Sopenharmony_ci			return;
59562306a36Sopenharmony_ci		}
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci		/* Reserve space for headers */
59862306a36Sopenharmony_ci		skb_reserve(skb, sk->sk_prot->max_header);
59962306a36Sopenharmony_ci		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK;
60062306a36Sopenharmony_ci		dccp_transmit_skb(sk, skb);
60162306a36Sopenharmony_ci	}
60262306a36Sopenharmony_ci}
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(dccp_send_ack);
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci#if 0
60762306a36Sopenharmony_ci/* FIXME: Is this still necessary (11.3) - currently nowhere used by DCCP. */
60862306a36Sopenharmony_civoid dccp_send_delayed_ack(struct sock *sk)
60962306a36Sopenharmony_ci{
61062306a36Sopenharmony_ci	struct inet_connection_sock *icsk = inet_csk(sk);
61162306a36Sopenharmony_ci	/*
61262306a36Sopenharmony_ci	 * FIXME: tune this timer. elapsed time fixes the skew, so no problem
61362306a36Sopenharmony_ci	 * with using 2s, and active senders also piggyback the ACK into a
61462306a36Sopenharmony_ci	 * DATAACK packet, so this is really for quiescent senders.
61562306a36Sopenharmony_ci	 */
61662306a36Sopenharmony_ci	unsigned long timeout = jiffies + 2 * HZ;
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci	/* Use new timeout only if there wasn't a older one earlier. */
61962306a36Sopenharmony_ci	if (icsk->icsk_ack.pending & ICSK_ACK_TIMER) {
62062306a36Sopenharmony_ci		/* If delack timer was blocked or is about to expire,
62162306a36Sopenharmony_ci		 * send ACK now.
62262306a36Sopenharmony_ci		 *
62362306a36Sopenharmony_ci		 * FIXME: check the "about to expire" part
62462306a36Sopenharmony_ci		 */
62562306a36Sopenharmony_ci		if (icsk->icsk_ack.blocked) {
62662306a36Sopenharmony_ci			dccp_send_ack(sk);
62762306a36Sopenharmony_ci			return;
62862306a36Sopenharmony_ci		}
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci		if (!time_before(timeout, icsk->icsk_ack.timeout))
63162306a36Sopenharmony_ci			timeout = icsk->icsk_ack.timeout;
63262306a36Sopenharmony_ci	}
63362306a36Sopenharmony_ci	icsk->icsk_ack.pending |= ICSK_ACK_SCHED | ICSK_ACK_TIMER;
63462306a36Sopenharmony_ci	icsk->icsk_ack.timeout = timeout;
63562306a36Sopenharmony_ci	sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout);
63662306a36Sopenharmony_ci}
63762306a36Sopenharmony_ci#endif
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_civoid dccp_send_sync(struct sock *sk, const u64 ackno,
64062306a36Sopenharmony_ci		    const enum dccp_pkt_type pkt_type)
64162306a36Sopenharmony_ci{
64262306a36Sopenharmony_ci	/*
64362306a36Sopenharmony_ci	 * We are not putting this on the write queue, so
64462306a36Sopenharmony_ci	 * dccp_transmit_skb() will set the ownership to this
64562306a36Sopenharmony_ci	 * sock.
64662306a36Sopenharmony_ci	 */
64762306a36Sopenharmony_ci	struct sk_buff *skb = alloc_skb(sk->sk_prot->max_header, GFP_ATOMIC);
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci	if (skb == NULL) {
65062306a36Sopenharmony_ci		/* FIXME: how to make sure the sync is sent? */
65162306a36Sopenharmony_ci		DCCP_CRIT("could not send %s", dccp_packet_name(pkt_type));
65262306a36Sopenharmony_ci		return;
65362306a36Sopenharmony_ci	}
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci	/* Reserve space for headers and prepare control bits. */
65662306a36Sopenharmony_ci	skb_reserve(skb, sk->sk_prot->max_header);
65762306a36Sopenharmony_ci	DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
65862306a36Sopenharmony_ci	DCCP_SKB_CB(skb)->dccpd_ack_seq = ackno;
65962306a36Sopenharmony_ci
66062306a36Sopenharmony_ci	/*
66162306a36Sopenharmony_ci	 * Clear the flag in case the Sync was scheduled for out-of-band data,
66262306a36Sopenharmony_ci	 * such as carrying a long Ack Vector.
66362306a36Sopenharmony_ci	 */
66462306a36Sopenharmony_ci	dccp_sk(sk)->dccps_sync_scheduled = 0;
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_ci	dccp_transmit_skb(sk, skb);
66762306a36Sopenharmony_ci}
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(dccp_send_sync);
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci/*
67262306a36Sopenharmony_ci * Send a DCCP_PKT_CLOSE/CLOSEREQ. The caller locks the socket for us. This
67362306a36Sopenharmony_ci * cannot be allowed to fail queueing a DCCP_PKT_CLOSE/CLOSEREQ frame under
67462306a36Sopenharmony_ci * any circumstances.
67562306a36Sopenharmony_ci */
67662306a36Sopenharmony_civoid dccp_send_close(struct sock *sk, const int active)
67762306a36Sopenharmony_ci{
67862306a36Sopenharmony_ci	struct dccp_sock *dp = dccp_sk(sk);
67962306a36Sopenharmony_ci	struct sk_buff *skb;
68062306a36Sopenharmony_ci	const gfp_t prio = active ? GFP_KERNEL : GFP_ATOMIC;
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci	skb = alloc_skb(sk->sk_prot->max_header, prio);
68362306a36Sopenharmony_ci	if (skb == NULL)
68462306a36Sopenharmony_ci		return;
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci	/* Reserve space for headers and prepare control bits. */
68762306a36Sopenharmony_ci	skb_reserve(skb, sk->sk_prot->max_header);
68862306a36Sopenharmony_ci	if (dp->dccps_role == DCCP_ROLE_SERVER && !dp->dccps_server_timewait)
68962306a36Sopenharmony_ci		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSEREQ;
69062306a36Sopenharmony_ci	else
69162306a36Sopenharmony_ci		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE;
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci	if (active) {
69462306a36Sopenharmony_ci		skb = dccp_skb_entail(sk, skb);
69562306a36Sopenharmony_ci		/*
69662306a36Sopenharmony_ci		 * Retransmission timer for active-close: RFC 4340, 8.3 requires
69762306a36Sopenharmony_ci		 * to retransmit the Close/CloseReq until the CLOSING/CLOSEREQ
69862306a36Sopenharmony_ci		 * state can be left. The initial timeout is 2 RTTs.
69962306a36Sopenharmony_ci		 * Since RTT measurement is done by the CCIDs, there is no easy
70062306a36Sopenharmony_ci		 * way to get an RTT sample. The fallback RTT from RFC 4340, 3.4
70162306a36Sopenharmony_ci		 * is too low (200ms); we use a high value to avoid unnecessary
70262306a36Sopenharmony_ci		 * retransmissions when the link RTT is > 0.2 seconds.
70362306a36Sopenharmony_ci		 * FIXME: Let main module sample RTTs and use that instead.
70462306a36Sopenharmony_ci		 */
70562306a36Sopenharmony_ci		inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
70662306a36Sopenharmony_ci					  DCCP_TIMEOUT_INIT, DCCP_RTO_MAX);
70762306a36Sopenharmony_ci	}
70862306a36Sopenharmony_ci	dccp_transmit_skb(sk, skb);
70962306a36Sopenharmony_ci}
710