Blame view

net/dccp/output.c 20.1 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
2
3
  /*
   *  net/dccp/output.c
8109b02b5   Arnaldo Carvalho de Melo   [DCCP]: Whitespac...
4
   *
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
5
6
   *  An implementation of the DCCP protocol
   *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
7
   */
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
8
  #include <linux/dccp.h>
48918a4db   Herbert Xu   [DCCP]: Simplify ...
9
  #include <linux/kernel.h>
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
10
  #include <linux/skbuff.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
11
  #include <linux/slab.h>
174cd4b1e   Ingo Molnar   sched/headers: Pr...
12
  #include <linux/sched/signal.h>
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
13

14c850212   Arnaldo Carvalho de Melo   [INET_SOCK]: Move...
14
  #include <net/inet_sock.h>
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
15
  #include <net/sock.h>
ae31c3399   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
16
  #include "ackvec.h"
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
17
18
19
20
21
22
23
  #include "ccid.h"
  #include "dccp.h"
  
  static inline void dccp_event_ack_sent(struct sock *sk)
  {
  	inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
  }
8695e8019   Gerrit Renker   dccp: combine the...
24
25
  /* enqueue @skb on sk_send_head for retransmission, return clone to send now */
  static struct sk_buff *dccp_skb_entail(struct sock *sk, struct sk_buff *skb)
48918a4db   Herbert Xu   [DCCP]: Simplify ...
26
27
28
29
  {
  	skb_set_owner_w(skb, sk);
  	WARN_ON(sk->sk_send_head);
  	sk->sk_send_head = skb;
8695e8019   Gerrit Renker   dccp: combine the...
30
  	return skb_clone(sk->sk_send_head, gfp_any());
48918a4db   Herbert Xu   [DCCP]: Simplify ...
31
  }
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
32
33
34
35
36
37
  /*
   * All SKB's seen here are completely headerless. It is our
   * job to build the DCCP header, and pass the packet down to
   * IP so it can do the same plus pass the packet off to the
   * device.
   */
48918a4db   Herbert Xu   [DCCP]: Simplify ...
38
  static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
39
40
  {
  	if (likely(skb != NULL)) {
d9d8da805   David S. Miller   inet: Pass flowi ...
41
  		struct inet_sock *inet = inet_sk(sk);
57cca05af   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
42
  		const struct inet_connection_sock *icsk = inet_csk(sk);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
43
44
45
46
  		struct dccp_sock *dp = dccp_sk(sk);
  		struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
  		struct dccp_hdr *dh;
  		/* XXX For now we're using only 48 bits sequence numbers */
118b2c953   Arnaldo Carvalho de Melo   [DCCP]: Use sk->s...
47
  		const u32 dccp_header_size = sizeof(*dh) +
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
48
  					     sizeof(struct dccp_hdr_ext) +
7690af3ff   Arnaldo Carvalho de Melo   [DCCP]: Just refl...
49
  					  dccp_packet_hdr_len(dcb->dccpd_type);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
50
51
  		int err, set_ack = 1;
  		u64 ackno = dp->dccps_gsr;
73f18fdbc   Gerrit Renker   dccp: Bug-Fix - A...
52
53
54
55
56
  		/*
  		 * Increment GSS here already in case the option code needs it.
  		 * Update GSS for real only if option processing below succeeds.
  		 */
  		dcb->dccpd_seq = ADD48(dp->dccps_gss, 1);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
57

7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
58
59
60
  		switch (dcb->dccpd_type) {
  		case DCCP_PKT_DATA:
  			set_ack = 0;
df561f668   Gustavo A. R. Silva   treewide: Use fal...
61
  			fallthrough;
edc9e8191   Herbert Xu   [DCCP]: Set socke...
62
  		case DCCP_PKT_DATAACK:
ee1a15922   Gerrit Renker   [DCCP]: Remove du...
63
  		case DCCP_PKT_RESET:
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
64
  			break;
edc9e8191   Herbert Xu   [DCCP]: Set socke...
65

afe00251d   Andrea Bittau   [DCCP]: Initial f...
66
67
  		case DCCP_PKT_REQUEST:
  			set_ack = 0;
73f18fdbc   Gerrit Renker   dccp: Bug-Fix - A...
68
69
70
  			/* Use ISS on the first (non-retransmitted) Request. */
  			if (icsk->icsk_retransmits == 0)
  				dcb->dccpd_seq = dp->dccps_iss;
df561f668   Gustavo A. R. Silva   treewide: Use fal...
71
  			fallthrough;
afe00251d   Andrea Bittau   [DCCP]: Initial f...
72

7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
73
74
  		case DCCP_PKT_SYNC:
  		case DCCP_PKT_SYNCACK:
b0d045ca4   Gerrit Renker   [DCCP]: Parameter...
75
  			ackno = dcb->dccpd_ack_seq;
df561f668   Gustavo A. R. Silva   treewide: Use fal...
76
  			fallthrough;
edc9e8191   Herbert Xu   [DCCP]: Set socke...
77
78
  		default:
  			/*
ee1a15922   Gerrit Renker   [DCCP]: Remove du...
79
80
81
82
  			 * Set owner/destructor: some skbs are allocated via
  			 * alloc_skb (e.g. when retransmission may happen).
  			 * Only Data, DataAck, and Reset packets should come
  			 * through here with skb->sk set.
edc9e8191   Herbert Xu   [DCCP]: Set socke...
83
84
85
  			 */
  			WARN_ON(skb->sk);
  			skb_set_owner_w(skb, sk);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
86
87
  			break;
  		}
24117727b   Arnaldo Carvalho de Melo   [DCCP]: Fix ackno...
88

2d0817d11   Arnaldo Carvalho de Melo   [DCCP] options: M...
89
90
91
92
  		if (dccp_insert_options(sk, skb)) {
  			kfree_skb(skb);
  			return -EPROTO;
  		}
c9eaf1734   YOSHIFUJI Hideaki   [NET] DCCP: Fix w...
93

fda0fd6c5   Herbert Xu   [DCCP]: Use skb_s...
94

7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
95
  		/* Build DCCP header and checksum it. */
9b42078ed   Gerrit Renker   [DCCP]: Combine a...
96
  		dh = dccp_zeroed_hdr(skb, dccp_header_size);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
97
  		dh->dccph_type	= dcb->dccpd_type;
c720c7e83   Eric Dumazet   inet: rename some...
98
99
  		dh->dccph_sport	= inet->inet_sport;
  		dh->dccph_dport	= inet->inet_dport;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
100
101
  		dh->dccph_doff	= (dccp_header_size + dcb->dccpd_opt_len) / 4;
  		dh->dccph_ccval	= dcb->dccpd_ccval;
6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
102
  		dh->dccph_cscov = dp->dccps_pcslen;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
103
104
  		/* XXX For now we're using only 48 bits sequence numbers */
  		dh->dccph_x	= 1;
73f18fdbc   Gerrit Renker   dccp: Bug-Fix - A...
105
  		dccp_update_gss(sk, dcb->dccpd_seq);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
106
107
108
109
110
111
  		dccp_hdr_set_seq(dh, dp->dccps_gss);
  		if (set_ack)
  			dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), ackno);
  
  		switch (dcb->dccpd_type) {
  		case DCCP_PKT_REQUEST:
7690af3ff   Arnaldo Carvalho de Melo   [DCCP]: Just refl...
112
  			dccp_hdr_request(skb)->dccph_req_service =
67e6b6292   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
113
  							dp->dccps_service;
73f18fdbc   Gerrit Renker   dccp: Bug-Fix - A...
114
115
116
117
118
  			/*
  			 * Limit Ack window to ISS <= P.ackno <= GSS, so that
  			 * only Responses to Requests we sent are considered.
  			 */
  			dp->dccps_awl = dp->dccps_iss;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
119
120
  			break;
  		case DCCP_PKT_RESET:
7690af3ff   Arnaldo Carvalho de Melo   [DCCP]: Just refl...
121
122
  			dccp_hdr_reset(skb)->dccph_reset_code =
  							dcb->dccpd_reset_code;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
123
124
  			break;
  		}
bb2962461   Herbert Xu   inet: Remove unus...
125
  		icsk->icsk_af_ops->send_check(sk, skb);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
126

7ad07e7cf   Arnaldo Carvalho de Melo   [DCCP]: Implement...
127
  		if (set_ack)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
128
129
130
  			dccp_event_ack_sent(sk);
  
  		DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
b0270e910   Eric Dumazet   ipv4: add a sock ...
131
  		err = icsk->icsk_af_ops->queue_xmit(sk, skb, &inet->cork.fl);
b9df3cb8c   Gerrit Renker   [TCP/DCCP]: Intro...
132
  		return net_xmit_eval(err);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
133
134
135
  	}
  	return -ENOBUFS;
  }
6179983ad   Gerrit Renker   [DCCP]: Introduci...
136
  /**
25985edce   Lucas De Marchi   Fix common misspe...
137
   * dccp_determine_ccmps  -  Find out about CCID-specific packet-size limits
6179983ad   Gerrit Renker   [DCCP]: Introduci...
138
139
140
141
142
143
144
145
146
147
148
149
   * We only consider the HC-sender CCID for setting the CCMPS (RFC 4340, 14.),
   * since the RX CCID is restricted to feedback packets (Acks), which are small
   * in comparison with the data traffic. A value of 0 means "no current CCMPS".
   */
  static u32 dccp_determine_ccmps(const struct dccp_sock *dp)
  {
  	const struct ccid *tx_ccid = dp->dccps_hc_tx_ccid;
  
  	if (tx_ccid == NULL || tx_ccid->ccid_ops == NULL)
  		return 0;
  	return tx_ccid->ccid_ops->ccid_ccmps;
  }
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
150
151
  unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
  {
d83d8461f   Arnaldo Carvalho de Melo   [IP_SOCKGLUE]: Re...
152
  	struct inet_connection_sock *icsk = inet_csk(sk);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
153
  	struct dccp_sock *dp = dccp_sk(sk);
6179983ad   Gerrit Renker   [DCCP]: Introduci...
154
  	u32 ccmps = dccp_determine_ccmps(dp);
361a5c1dd   Gerrit Renker   dccp: Minimise he...
155
  	u32 cur_mps = ccmps ? min(pmtu, ccmps) : pmtu;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
156

6179983ad   Gerrit Renker   [DCCP]: Introduci...
157
158
159
  	/* Account for header lengths and IPv4/v6 option overhead */
  	cur_mps -= (icsk->icsk_af_ops->net_header_len + icsk->icsk_ext_hdr_len +
  		    sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
160
161
  
  	/*
361a5c1dd   Gerrit Renker   dccp: Minimise he...
162
163
164
165
166
167
168
169
170
171
172
  	 * Leave enough headroom for common DCCP header options.
  	 * This only considers options which may appear on DCCP-Data packets, as
  	 * per table 3 in RFC 4340, 5.8. When running out of space for other
  	 * options (eg. Ack Vector which can take up to 255 bytes), it is better
  	 * to schedule a separate Ack. Thus we leave headroom for the following:
  	 *  - 1 byte for Slow Receiver (11.6)
  	 *  - 6 bytes for Timestamp (13.1)
  	 *  - 10 bytes for Timestamp Echo (13.3)
  	 *  - 8 bytes for NDP count (7.7, when activated)
  	 *  - 6 bytes for Data Checksum (9.3)
  	 *  - %DCCPAV_MIN_OPTLEN bytes for Ack Vector size (11.4, when enabled)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
173
  	 */
361a5c1dd   Gerrit Renker   dccp: Minimise he...
174
175
  	cur_mps -= roundup(1 + 6 + 10 + dp->dccps_send_ndp_count * 8 + 6 +
  			   (dp->dccps_hc_rx_ackvec ? DCCPAV_MIN_OPTLEN : 0), 4);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
176
177
  
  	/* And store cached results */
d83d8461f   Arnaldo Carvalho de Melo   [IP_SOCKGLUE]: Re...
178
  	icsk->icsk_pmtu_cookie = pmtu;
6179983ad   Gerrit Renker   [DCCP]: Introduci...
179
  	dp->dccps_mss_cache = cur_mps;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
180

6179983ad   Gerrit Renker   [DCCP]: Introduci...
181
  	return cur_mps;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
182
  }
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
183
  EXPORT_SYMBOL_GPL(dccp_sync_mss);
c530cfb1c   Arnaldo Carvalho de Melo   [CCID3]: Call sk-...
184
185
  void dccp_write_space(struct sock *sk)
  {
438154823   Eric Dumazet   net: sock_def_rea...
186
  	struct socket_wq *wq;
c530cfb1c   Arnaldo Carvalho de Melo   [CCID3]: Call sk-...
187

438154823   Eric Dumazet   net: sock_def_rea...
188
189
  	rcu_read_lock();
  	wq = rcu_dereference(sk->sk_wq);
1ce0bf50a   Herbert Xu   net: Generalise w...
190
  	if (skwq_has_sleeper(wq))
438154823   Eric Dumazet   net: sock_def_rea...
191
  		wake_up_interruptible(&wq->wait);
c530cfb1c   Arnaldo Carvalho de Melo   [CCID3]: Call sk-...
192
193
  	/* Should agree with poll, otherwise some programs break */
  	if (sock_writeable(sk))
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
194
  		sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
c530cfb1c   Arnaldo Carvalho de Melo   [CCID3]: Call sk-...
195

438154823   Eric Dumazet   net: sock_def_rea...
196
  	rcu_read_unlock();
c530cfb1c   Arnaldo Carvalho de Melo   [CCID3]: Call sk-...
197
  }
d6809c12b   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
198
  /**
b1fcf55ee   Gerrit Renker   dccp: Refine the ...
199
   * dccp_wait_for_ccid  -  Await CCID send permission
bc8498721   Gerrit Renker   [DCCP]: Wait for ...
200
   * @sk:    socket to wait for
b1fcf55ee   Gerrit Renker   dccp: Refine the ...
201
   * @delay: timeout in jiffies
2c53040f0   Ben Hutchings   net: Fix (nearly-...
202
   *
b1fcf55ee   Gerrit Renker   dccp: Refine the ...
203
   * This is used by CCIDs which need to delay the send time in process context.
d6809c12b   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
204
   */
b1fcf55ee   Gerrit Renker   dccp: Refine the ...
205
  static int dccp_wait_for_ccid(struct sock *sk, unsigned long delay)
d6809c12b   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
206
  {
d6809c12b   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
207
  	DEFINE_WAIT(wait);
b1fcf55ee   Gerrit Renker   dccp: Refine the ...
208
  	long remaining;
d6809c12b   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
209

b1fcf55ee   Gerrit Renker   dccp: Refine the ...
210
211
212
  	prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
  	sk->sk_write_pending++;
  	release_sock(sk);
bc8498721   Gerrit Renker   [DCCP]: Wait for ...
213

b1fcf55ee   Gerrit Renker   dccp: Refine the ...
214
  	remaining = schedule_timeout(delay);
d6809c12b   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
215

b1fcf55ee   Gerrit Renker   dccp: Refine the ...
216
217
  	lock_sock(sk);
  	sk->sk_write_pending--;
aa3951451   Eric Dumazet   net: sk_sleep() h...
218
  	finish_wait(sk_sleep(sk), &wait);
b1fcf55ee   Gerrit Renker   dccp: Refine the ...
219
220
221
222
  
  	if (signal_pending(current) || sk->sk_err)
  		return -1;
  	return remaining;
d6809c12b   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
223
  }
dc841e30e   Gerrit Renker   dccp: Extend CCID...
224
225
226
227
228
229
230
231
  /**
   * 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);
871a2c16c   Tomasz Grobelny   dccp: Policy-base...
232
  	struct sk_buff *skb = dccp_qpolicy_pop(sk);
dc841e30e   Gerrit Renker   dccp: Extend CCID...
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
  
  	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.
  ", 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
  ", 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);
d83447f09   Gerrit Renker   dccp ccid-2: Sche...
275
276
277
278
279
280
281
282
283
  
  	/*
  	 * 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);
dc841e30e   Gerrit Renker   dccp: Extend CCID...
284
  }
b1fcf55ee   Gerrit Renker   dccp: Refine the ...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  /**
   * dccp_flush_write_queue  -  Drain queue at end of connection
   * Since dccp_sendmsg queues packets without waiting for them to be sent, it may
   * happen that the TX queue is not empty at the end of a connection. We give the
   * HC-sender CCID a grace period of up to @time_budget jiffies. If this function
   * returns with a non-empty write queue, it will be purged later.
   */
  void dccp_flush_write_queue(struct sock *sk, long *time_budget)
  {
  	struct dccp_sock *dp = dccp_sk(sk);
  	struct sk_buff *skb;
  	long delay, rc;
  
  	while (*time_budget > 0 && (skb = skb_peek(&sk->sk_write_queue))) {
  		rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
  
  		switch (ccid_packet_dequeue_eval(rc)) {
  		case CCID_PACKET_WILL_DEQUEUE_LATER:
  			/*
  			 * If the CCID determines when to send, the next sending
  			 * time is unknown or the CCID may not even send again
  			 * (e.g. remote host crashes or lost Ack packets).
  			 */
  			DCCP_WARN("CCID did not manage to send all packets
  ");
  			return;
  		case CCID_PACKET_DELAY:
  			delay = msecs_to_jiffies(rc);
  			if (delay > *time_budget)
  				return;
  			rc = dccp_wait_for_ccid(sk, delay);
  			if (rc < 0)
  				return;
  			*time_budget -= (delay - rc);
  			/* check again if we can send now */
  			break;
  		case CCID_PACKET_SEND_AT_ONCE:
  			dccp_xmit_packet(sk);
  			break;
  		case CCID_PACKET_ERR:
  			skb_dequeue(&sk->sk_write_queue);
  			kfree_skb(skb);
  			dccp_pr_debug("packet discarded due to err=%ld
  ", rc);
  		}
  	}
  }
  
  void dccp_write_xmit(struct sock *sk)
27258ee54   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
334
  {
97e5848dd   Ian McDonald   [DCCP]: Introduce...
335
336
  	struct dccp_sock *dp = dccp_sk(sk);
  	struct sk_buff *skb;
97e5848dd   Ian McDonald   [DCCP]: Introduce...
337

871a2c16c   Tomasz Grobelny   dccp: Policy-base...
338
  	while ((skb = dccp_qpolicy_top(sk))) {
dc841e30e   Gerrit Renker   dccp: Extend CCID...
339
  		int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
d6809c12b   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
340

dc841e30e   Gerrit Renker   dccp: Extend CCID...
341
342
343
344
  		switch (ccid_packet_dequeue_eval(rc)) {
  		case CCID_PACKET_WILL_DEQUEUE_LATER:
  			return;
  		case CCID_PACKET_DELAY:
b1fcf55ee   Gerrit Renker   dccp: Refine the ...
345
346
347
  			sk_reset_timer(sk, &dp->dccps_xmit_timer,
  				       jiffies + msecs_to_jiffies(rc));
  			return;
dc841e30e   Gerrit Renker   dccp: Extend CCID...
348
349
350
351
  		case CCID_PACKET_SEND_AT_ONCE:
  			dccp_xmit_packet(sk);
  			break;
  		case CCID_PACKET_ERR:
871a2c16c   Tomasz Grobelny   dccp: Policy-base...
352
  			dccp_qpolicy_drop(sk, skb);
dc841e30e   Gerrit Renker   dccp: Extend CCID...
353
354
  			dccp_pr_debug("packet discarded due to err=%d
  ", rc);
f6282f4da   Gerrit Renker   [DCCP]: Warn when...
355
  		}
97e5848dd   Ian McDonald   [DCCP]: Introduce...
356
  	}
27258ee54   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
357
  }
59435444a   Gerrit Renker   dccp: Allow to di...
358
359
360
361
362
363
364
365
366
367
  /**
   * dccp_retransmit_skb  -  Retransmit Request, Close, or CloseReq packets
   * There are only four retransmittable packet types in DCCP:
   * - Request  in client-REQUEST  state (sec. 8.1.1),
   * - CloseReq in server-CLOSEREQ state (sec. 8.3),
   * - Close    in   node-CLOSING  state (sec. 8.3),
   * - Acks in client-PARTOPEN state (sec. 8.1.5, handled by dccp_delack_timer()).
   * This function expects sk->sk_send_head to contain the original skb.
   */
  int dccp_retransmit_skb(struct sock *sk)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
368
  {
59435444a   Gerrit Renker   dccp: Allow to di...
369
  	WARN_ON(sk->sk_send_head == NULL);
57cca05af   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
370
  	if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk) != 0)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
371
  		return -EHOSTUNREACH; /* Routing failure or similar. */
59435444a   Gerrit Renker   dccp: Allow to di...
372
373
374
375
  	/* this count is used to distinguish original and retransmitted skb */
  	inet_csk(sk)->icsk_retransmits++;
  
  	return dccp_transmit_skb(sk, skb_clone(sk->sk_send_head, GFP_ATOMIC));
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
376
  }
802885fc0   Eric Dumazet   dccp: constify dc...
377
  struct sk_buff *dccp_make_response(const struct sock *sk, struct dst_entry *dst,
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
378
379
380
  				   struct request_sock *req)
  {
  	struct dccp_hdr *dh;
67e6b6292   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
381
  	struct dccp_request_sock *dreq;
118b2c953   Arnaldo Carvalho de Melo   [DCCP]: Use sk->s...
382
  	const u32 dccp_header_size = sizeof(struct dccp_hdr) +
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
383
384
  				     sizeof(struct dccp_hdr_ext) +
  				     sizeof(struct dccp_hdr_response);
802885fc0   Eric Dumazet   dccp: constify dc...
385
386
387
388
389
390
391
392
393
  	struct sk_buff *skb;
  
  	/* sk is marked const to clearly express we dont hold socket lock.
  	 * sock_wmalloc() will atomically change sk->sk_wmem_alloc,
  	 * it is safe to promote sk to non const.
  	 */
  	skb = sock_wmalloc((struct sock *)sk, MAX_DCCP_HEADER, 1,
  			   GFP_ATOMIC);
  	if (!skb)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
394
  		return NULL;
802885fc0   Eric Dumazet   dccp: constify dc...
395
  	skb_reserve(skb, MAX_DCCP_HEADER);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
396

adf30907d   Eric Dumazet   net: skb->dst acc...
397
  	skb_dst_set(skb, dst_clone(dst));
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
398

67e6b6292   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
399
  	dreq = dccp_rsk(req);
f541fb7e2   Samuel Jero   dccp: fix bug in ...
400
401
  	if (inet_rsk(req)->acked)	/* increase GSS upon retransmission */
  		dccp_inc_seqno(&dreq->dreq_gss);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
402
  	DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
f541fb7e2   Samuel Jero   dccp: fix bug in ...
403
  	DCCP_SKB_CB(skb)->dccpd_seq  = dreq->dreq_gss;
2d0817d11   Arnaldo Carvalho de Melo   [DCCP] options: M...
404

0c1168398   Gerrit Renker   dccp: Mechanism t...
405
406
407
408
409
410
  	/* Resolve feature dependencies resulting from choice of CCID */
  	if (dccp_feat_server_ccid_dependencies(dreq))
  		goto response_failed;
  
  	if (dccp_insert_options_rsk(dreq, skb))
  		goto response_failed;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
411

09dbc3895   Gerrit Renker   [DCCP]: Miscellan...
412
  	/* Build and checksum header */
9b42078ed   Gerrit Renker   [DCCP]: Combine a...
413
  	dh = dccp_zeroed_hdr(skb, dccp_header_size);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
414

b44084c2c   Eric Dumazet   inet: rename ir_l...
415
  	dh->dccph_sport	= htons(inet_rsk(req)->ir_num);
634fb979e   Eric Dumazet   inet: includes a ...
416
  	dh->dccph_dport	= inet_rsk(req)->ir_rmt_port;
7690af3ff   Arnaldo Carvalho de Melo   [DCCP]: Just refl...
417
418
  	dh->dccph_doff	= (dccp_header_size +
  			   DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
419
420
  	dh->dccph_type	= DCCP_PKT_RESPONSE;
  	dh->dccph_x	= 1;
f541fb7e2   Samuel Jero   dccp: fix bug in ...
421
422
  	dccp_hdr_set_seq(dh, dreq->dreq_gss);
  	dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_gsr);
67e6b6292   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
423
  	dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
424

6f4e5fff1   Gerrit Renker   [DCCP]: Support f...
425
  	dccp_csum_outgoing(skb);
e11d9d308   Gerrit Renker   [DCCP]: Increment...
426
427
  	/* We use `acked' to remember that a Response was already sent. */
  	inet_rsk(req)->acked = 1;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
428
429
  	DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
  	return skb;
0c1168398   Gerrit Renker   dccp: Mechanism t...
430
431
432
  response_failed:
  	kfree_skb(skb);
  	return NULL;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
433
  }
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
434
  EXPORT_SYMBOL_GPL(dccp_make_response);
e356d37a0   Gerrit Renker   [DCCP]: Factor ou...
435
  /* answer offending packet in @rcv_skb with Reset from control socket @ctl */
7630f0268   Denis V. Lunev   [DCCP]: Replace s...
436
  struct sk_buff *dccp_ctl_make_reset(struct sock *sk, struct sk_buff *rcv_skb)
e356d37a0   Gerrit Renker   [DCCP]: Factor ou...
437
438
439
440
441
442
443
444
  {
  	struct dccp_hdr *rxdh = dccp_hdr(rcv_skb), *dh;
  	struct dccp_skb_cb *dcb = DCCP_SKB_CB(rcv_skb);
  	const u32 dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
  				       sizeof(struct dccp_hdr_ext) +
  				       sizeof(struct dccp_hdr_reset);
  	struct dccp_hdr_reset *dhr;
  	struct sk_buff *skb;
7630f0268   Denis V. Lunev   [DCCP]: Replace s...
445
  	skb = alloc_skb(sk->sk_prot->max_header, GFP_ATOMIC);
e356d37a0   Gerrit Renker   [DCCP]: Factor ou...
446
447
  	if (skb == NULL)
  		return NULL;
7630f0268   Denis V. Lunev   [DCCP]: Replace s...
448
  	skb_reserve(skb, sk->sk_prot->max_header);
e356d37a0   Gerrit Renker   [DCCP]: Factor ou...
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
  
  	/* Swap the send and the receive. */
  	dh = dccp_zeroed_hdr(skb, dccp_hdr_reset_len);
  	dh->dccph_type	= DCCP_PKT_RESET;
  	dh->dccph_sport	= rxdh->dccph_dport;
  	dh->dccph_dport	= rxdh->dccph_sport;
  	dh->dccph_doff	= dccp_hdr_reset_len / 4;
  	dh->dccph_x	= 1;
  
  	dhr = dccp_hdr_reset(skb);
  	dhr->dccph_reset_code = dcb->dccpd_reset_code;
  
  	switch (dcb->dccpd_reset_code) {
  	case DCCP_RESET_CODE_PACKET_ERROR:
  		dhr->dccph_reset_data[0] = rxdh->dccph_type;
  		break;
df561f668   Gustavo A. R. Silva   treewide: Use fal...
465
  	case DCCP_RESET_CODE_OPTION_ERROR:
e356d37a0   Gerrit Renker   [DCCP]: Factor ou...
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
  	case DCCP_RESET_CODE_MANDATORY_ERROR:
  		memcpy(dhr->dccph_reset_data, dcb->dccpd_reset_data, 3);
  		break;
  	}
  	/*
  	 * From RFC 4340, 8.3.1:
  	 *   If P.ackno exists, set R.seqno := P.ackno + 1.
  	 *   Else set R.seqno := 0.
  	 */
  	if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
  		dccp_hdr_set_seq(dh, ADD48(dcb->dccpd_ack_seq, 1));
  	dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dcb->dccpd_seq);
  
  	dccp_csum_outgoing(skb);
  	return skb;
  }
  
  EXPORT_SYMBOL_GPL(dccp_ctl_make_reset);
ee1a15922   Gerrit Renker   [DCCP]: Remove du...
484
  /* send Reset on established socket, to close or abort the connection */
017487d7d   Arnaldo Carvalho de Melo   [DCCP]: Generaliz...
485
486
  int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code)
  {
ee1a15922   Gerrit Renker   [DCCP]: Remove du...
487
  	struct sk_buff *skb;
017487d7d   Arnaldo Carvalho de Melo   [DCCP]: Generaliz...
488
489
490
491
  	/*
  	 * FIXME: what if rebuild_header fails?
  	 * Should we be doing a rebuild_header here?
  	 */
f53dc67c5   Gerrit Renker   [DCCP]: Use AF-in...
492
  	int err = inet_csk(sk)->icsk_af_ops->rebuild_header(sk);
017487d7d   Arnaldo Carvalho de Melo   [DCCP]: Generaliz...
493

ee1a15922   Gerrit Renker   [DCCP]: Remove du...
494
495
496
497
498
499
500
501
502
503
504
  	if (err != 0)
  		return err;
  
  	skb = sock_wmalloc(sk, sk->sk_prot->max_header, 1, GFP_ATOMIC);
  	if (skb == NULL)
  		return -ENOBUFS;
  
  	/* Reserve space for headers and prepare control bits. */
  	skb_reserve(skb, sk->sk_prot->max_header);
  	DCCP_SKB_CB(skb)->dccpd_type	   = DCCP_PKT_RESET;
  	DCCP_SKB_CB(skb)->dccpd_reset_code = code;
017487d7d   Arnaldo Carvalho de Melo   [DCCP]: Generaliz...
505

ee1a15922   Gerrit Renker   [DCCP]: Remove du...
506
  	return dccp_transmit_skb(sk, skb);
017487d7d   Arnaldo Carvalho de Melo   [DCCP]: Generaliz...
507
  }
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
508
509
510
  /*
   * Do all connect socket setups that can be done AF independent.
   */
93344af44   Gerrit Renker   dccp: merge now-r...
511
  int dccp_connect(struct sock *sk)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
512
  {
93344af44   Gerrit Renker   dccp: merge now-r...
513
  	struct sk_buff *skb;
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
514
  	struct dccp_sock *dp = dccp_sk(sk);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
515
516
517
518
519
  	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);
c9eaf1734   YOSHIFUJI Hideaki   [NET] DCCP: Fix w...
520

7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
521
  	dccp_sync_mss(sk, dst_mtu(dst));
9eca0a47d   Gerrit Renker   dccp: Resolve dep...
522
523
524
  	/* do not connect if feature negotiation setup fails */
  	if (dccp_feat_finalise_settings(dccp_sk(sk)))
  		return -EPROTO;
93344af44   Gerrit Renker   dccp: merge now-r...
525
526
  	/* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */
  	dp->dccps_gar = dp->dccps_iss;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
527

118b2c953   Arnaldo Carvalho de Melo   [DCCP]: Use sk->s...
528
  	skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
529
530
531
532
  	if (unlikely(skb == NULL))
  		return -ENOBUFS;
  
  	/* Reserve space for headers. */
118b2c953   Arnaldo Carvalho de Melo   [DCCP]: Use sk->s...
533
  	skb_reserve(skb, sk->sk_prot->max_header);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
534
535
  
  	DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
536

8695e8019   Gerrit Renker   dccp: combine the...
537
  	dccp_transmit_skb(sk, dccp_skb_entail(sk, skb));
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
538
539
540
  	DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);
  
  	/* Timer for repeating the REQUEST until an answer. */
93344af44   Gerrit Renker   dccp: merge now-r...
541
  	icsk->icsk_retransmits = 0;
27258ee54   Arnaldo Carvalho de Melo   [DCCP]: Introduce...
542
543
  	inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
  				  icsk->icsk_rto, DCCP_RTO_MAX);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
544
545
  	return 0;
  }
f21e68caa   Arnaldo Carvalho de Melo   [DCCP]: Prepare t...
546
  EXPORT_SYMBOL_GPL(dccp_connect);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
547
548
549
550
  void dccp_send_ack(struct sock *sk)
  {
  	/* If we have been reset, we may not send again. */
  	if (sk->sk_state != DCCP_CLOSED) {
118b2c953   Arnaldo Carvalho de Melo   [DCCP]: Use sk->s...
551
552
  		struct sk_buff *skb = alloc_skb(sk->sk_prot->max_header,
  						GFP_ATOMIC);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
553
554
555
556
  
  		if (skb == NULL) {
  			inet_csk_schedule_ack(sk);
  			inet_csk(sk)->icsk_ack.ato = TCP_ATO_MIN;
7690af3ff   Arnaldo Carvalho de Melo   [DCCP]: Just refl...
557
558
559
  			inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
  						  TCP_DELACK_MAX,
  						  DCCP_RTO_MAX);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
560
561
562
563
  			return;
  		}
  
  		/* Reserve space for headers */
118b2c953   Arnaldo Carvalho de Melo   [DCCP]: Use sk->s...
564
  		skb_reserve(skb, sk->sk_prot->max_header);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
565
  		DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
566
567
568
569
570
  		dccp_transmit_skb(sk, skb);
  	}
  }
  
  EXPORT_SYMBOL_GPL(dccp_send_ack);
1e2f0e5e8   Gerrit Renker   dccp: Fix sparse ...
571
  #if 0
727ecc5fa   Gerrit Renker   [DCCP]: Add FIXME...
572
  /* FIXME: Is this still necessary (11.3) - currently nowhere used by DCCP. */
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
  void dccp_send_delayed_ack(struct sock *sk)
  {
  	struct inet_connection_sock *icsk = inet_csk(sk);
  	/*
  	 * FIXME: tune this timer. elapsed time fixes the skew, so no problem
  	 * with using 2s, and active senders also piggyback the ACK into a
  	 * DATAACK packet, so this is really for quiescent senders.
  	 */
  	unsigned long timeout = jiffies + 2 * HZ;
  
  	/* Use new timeout only if there wasn't a older one earlier. */
  	if (icsk->icsk_ack.pending & ICSK_ACK_TIMER) {
  		/* If delack timer was blocked or is about to expire,
  		 * send ACK now.
  		 *
  		 * FIXME: check the "about to expire" part
  		 */
  		if (icsk->icsk_ack.blocked) {
  			dccp_send_ack(sk);
  			return;
  		}
  
  		if (!time_before(timeout, icsk->icsk_ack.timeout))
  			timeout = icsk->icsk_ack.timeout;
  	}
  	icsk->icsk_ack.pending |= ICSK_ACK_SCHED | ICSK_ACK_TIMER;
  	icsk->icsk_ack.timeout = timeout;
  	sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout);
  }
1e2f0e5e8   Gerrit Renker   dccp: Fix sparse ...
602
  #endif
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
603

b0d045ca4   Gerrit Renker   [DCCP]: Parameter...
604
  void dccp_send_sync(struct sock *sk, const u64 ackno,
e92ae93a8   Arnaldo Carvalho de Melo   [DCCP]: Send SYNC...
605
  		    const enum dccp_pkt_type pkt_type)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
606
607
608
609
610
611
  {
  	/*
  	 * We are not putting this on the write queue, so
  	 * dccp_transmit_skb() will set the ownership to this
  	 * sock.
  	 */
118b2c953   Arnaldo Carvalho de Melo   [DCCP]: Use sk->s...
612
  	struct sk_buff *skb = alloc_skb(sk->sk_prot->max_header, GFP_ATOMIC);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
613

b0d045ca4   Gerrit Renker   [DCCP]: Parameter...
614
  	if (skb == NULL) {
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
615
  		/* FIXME: how to make sure the sync is sent? */
b0d045ca4   Gerrit Renker   [DCCP]: Parameter...
616
  		DCCP_CRIT("could not send %s", dccp_packet_name(pkt_type));
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
617
  		return;
b0d045ca4   Gerrit Renker   [DCCP]: Parameter...
618
  	}
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
619
620
  
  	/* Reserve space for headers and prepare control bits. */
118b2c953   Arnaldo Carvalho de Melo   [DCCP]: Use sk->s...
621
  	skb_reserve(skb, sk->sk_prot->max_header);
e92ae93a8   Arnaldo Carvalho de Melo   [DCCP]: Send SYNC...
622
  	DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
b0d045ca4   Gerrit Renker   [DCCP]: Parameter...
623
  	DCCP_SKB_CB(skb)->dccpd_ack_seq = ackno;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
624

d83447f09   Gerrit Renker   dccp ccid-2: Sche...
625
626
627
628
629
  	/*
  	 * Clear the flag in case the Sync was scheduled for out-of-band data,
  	 * such as carrying a long Ack Vector.
  	 */
  	dccp_sk(sk)->dccps_sync_scheduled = 0;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
630
631
  	dccp_transmit_skb(sk, skb);
  }
b61fafc4e   Arnaldo Carvalho de Melo   [DCCP]: Move the ...
632
  EXPORT_SYMBOL_GPL(dccp_send_sync);
7690af3ff   Arnaldo Carvalho de Melo   [DCCP]: Just refl...
633
634
635
636
  /*
   * 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.
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
637
   */
7ad07e7cf   Arnaldo Carvalho de Melo   [DCCP]: Implement...
638
  void dccp_send_close(struct sock *sk, const int active)
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
639
640
641
  {
  	struct dccp_sock *dp = dccp_sk(sk);
  	struct sk_buff *skb;
7d877f3bd   Al Viro   [PATCH] gfp_t: net/*
642
  	const gfp_t prio = active ? GFP_KERNEL : GFP_ATOMIC;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
643

7ad07e7cf   Arnaldo Carvalho de Melo   [DCCP]: Implement...
644
645
646
  	skb = alloc_skb(sk->sk_prot->max_header, prio);
  	if (skb == NULL)
  		return;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
647
648
649
  
  	/* Reserve space for headers and prepare control bits. */
  	skb_reserve(skb, sk->sk_prot->max_header);
b8599d207   Gerrit Renker   [DCCP]: Support f...
650
651
652
653
  	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;
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
654

7ad07e7cf   Arnaldo Carvalho de Melo   [DCCP]: Implement...
655
  	if (active) {
8695e8019   Gerrit Renker   dccp: combine the...
656
  		skb = dccp_skb_entail(sk, skb);
92d31920b   Gerrit Renker   [DCCP]: Shift the...
657
658
659
660
661
662
663
664
665
666
667
668
  		/*
  		 * 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);
8695e8019   Gerrit Renker   dccp: combine the...
669
670
  	}
  	dccp_transmit_skb(sk, skb);
7c657876b   Arnaldo Carvalho de Melo   [DCCP]: Initial i...
671
  }