aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/output.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/dccp/output.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'net/dccp/output.c')
-rw-r--r--net/dccp/output.c251
1 files changed, 149 insertions, 102 deletions
diff --git a/net/dccp/output.c b/net/dccp/output.c
index aadbdb58758b..fab108e51e5a 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -43,7 +43,7 @@ static void dccp_skb_entail(struct sock *sk, struct sk_buff *skb)
43static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) 43static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
44{ 44{
45 if (likely(skb != NULL)) { 45 if (likely(skb != NULL)) {
46 const struct inet_sock *inet = inet_sk(sk); 46 struct inet_sock *inet = inet_sk(sk);
47 const struct inet_connection_sock *icsk = inet_csk(sk); 47 const struct inet_connection_sock *icsk = inet_csk(sk);
48 struct dccp_sock *dp = dccp_sk(sk); 48 struct dccp_sock *dp = dccp_sk(sk);
49 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 49 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
@@ -136,14 +136,14 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
136 136
137 DCCP_INC_STATS(DCCP_MIB_OUTSEGS); 137 DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
138 138
139 err = icsk->icsk_af_ops->queue_xmit(skb); 139 err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl);
140 return net_xmit_eval(err); 140 return net_xmit_eval(err);
141 } 141 }
142 return -ENOBUFS; 142 return -ENOBUFS;
143} 143}
144 144
145/** 145/**
146 * dccp_determine_ccmps - Find out about CCID-specfic packet-size limits 146 * dccp_determine_ccmps - Find out about CCID-specific packet-size limits
147 * We only consider the HC-sender CCID for setting the CCMPS (RFC 4340, 14.), 147 * We only consider the HC-sender CCID for setting the CCMPS (RFC 4340, 14.),
148 * since the RX CCID is restricted to feedback packets (Acks), which are small 148 * since the RX CCID is restricted to feedback packets (Acks), which are small
149 * in comparison with the data traffic. A value of 0 means "no current CCMPS". 149 * in comparison with the data traffic. A value of 0 means "no current CCMPS".
@@ -209,108 +209,158 @@ void dccp_write_space(struct sock *sk)
209} 209}
210 210
211/** 211/**
212 * dccp_wait_for_ccid - Wait for ccid to tell us we can send a packet 212 * dccp_wait_for_ccid - Await CCID send permission
213 * @sk: socket to wait for 213 * @sk: socket to wait for
214 * @skb: current skb to pass on for waiting 214 * @delay: timeout in jiffies
215 * @delay: sleep timeout in milliseconds (> 0) 215 * This is used by CCIDs which need to delay the send time in process context.
216 * This function is called by default when the socket is closed, and
217 * when a non-zero linger time is set on the socket. For consistency
218 */ 216 */
219static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb, int delay) 217static int dccp_wait_for_ccid(struct sock *sk, unsigned long delay)
220{ 218{
221 struct dccp_sock *dp = dccp_sk(sk);
222 DEFINE_WAIT(wait); 219 DEFINE_WAIT(wait);
223 unsigned long jiffdelay; 220 long remaining;
224 int rc;
225 221
226 do { 222 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
227 dccp_pr_debug("delayed send by %d msec\n", delay); 223 sk->sk_write_pending++;
228 jiffdelay = msecs_to_jiffies(delay); 224 release_sock(sk);
229 225
230 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 226 remaining = schedule_timeout(delay);
231 227
232 sk->sk_write_pending++; 228 lock_sock(sk);
233 release_sock(sk); 229 sk->sk_write_pending--;
234 schedule_timeout(jiffdelay); 230 finish_wait(sk_sleep(sk), &wait);
235 lock_sock(sk);
236 sk->sk_write_pending--;
237 231
238 if (sk->sk_err) 232 if (signal_pending(current) || sk->sk_err)
239 goto do_error; 233 return -1;
240 if (signal_pending(current)) 234 return remaining;
241 goto do_interrupted; 235}
242 236
243 rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); 237/**
244 } while ((delay = rc) > 0); 238 * dccp_xmit_packet - Send data packet under control of CCID
245out: 239 * Transmits next-queued payload and informs CCID to account for the packet.
246 finish_wait(sk_sleep(sk), &wait); 240 */
247 return rc; 241static void dccp_xmit_packet(struct sock *sk)
248 242{
249do_error: 243 int err, len;
250 rc = -EPIPE; 244 struct dccp_sock *dp = dccp_sk(sk);
251 goto out; 245 struct sk_buff *skb = dccp_qpolicy_pop(sk);
252do_interrupted: 246
253 rc = -EINTR; 247 if (unlikely(skb == NULL))
254 goto out; 248 return;
249 len = skb->len;
250
251 if (sk->sk_state == DCCP_PARTOPEN) {
252 const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD;
253 /*
254 * See 8.1.5 - Handshake Completion.
255 *
256 * For robustness we resend Confirm options until the client has
257 * entered OPEN. During the initial feature negotiation, the MPS
258 * is smaller than usual, reduced by the Change/Confirm options.
259 */
260 if (!list_empty(&dp->dccps_featneg) && len > cur_mps) {
261 DCCP_WARN("Payload too large (%d) for featneg.\n", len);
262 dccp_send_ack(sk);
263 dccp_feat_list_purge(&dp->dccps_featneg);
264 }
265
266 inet_csk_schedule_ack(sk);
267 inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
268 inet_csk(sk)->icsk_rto,
269 DCCP_RTO_MAX);
270 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK;
271 } else if (dccp_ack_pending(sk)) {
272 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK;
273 } else {
274 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATA;
275 }
276
277 err = dccp_transmit_skb(sk, skb);
278 if (err)
279 dccp_pr_debug("transmit_skb() returned err=%d\n", err);
280 /*
281 * Register this one as sent even if an error occurred. To the remote
282 * end a local packet drop is indistinguishable from network loss, i.e.
283 * any local drop will eventually be reported via receiver feedback.
284 */
285 ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len);
286
287 /*
288 * If the CCID needs to transfer additional header options out-of-band
289 * (e.g. Ack Vectors or feature-negotiation options), it activates this
290 * flag to schedule a Sync. The Sync will automatically incorporate all
291 * currently pending header options, thus clearing the backlog.
292 */
293 if (dp->dccps_sync_scheduled)
294 dccp_send_sync(sk, dp->dccps_gsr, DCCP_PKT_SYNC);
255} 295}
256 296
257void dccp_write_xmit(struct sock *sk, int block) 297/**
298 * dccp_flush_write_queue - Drain queue at end of connection
299 * Since dccp_sendmsg queues packets without waiting for them to be sent, it may
300 * happen that the TX queue is not empty at the end of a connection. We give the
301 * HC-sender CCID a grace period of up to @time_budget jiffies. If this function
302 * returns with a non-empty write queue, it will be purged later.
303 */
304void dccp_flush_write_queue(struct sock *sk, long *time_budget)
258{ 305{
259 struct dccp_sock *dp = dccp_sk(sk); 306 struct dccp_sock *dp = dccp_sk(sk);
260 struct sk_buff *skb; 307 struct sk_buff *skb;
308 long delay, rc;
261 309
262 while ((skb = skb_peek(&sk->sk_write_queue))) { 310 while (*time_budget > 0 && (skb = skb_peek(&sk->sk_write_queue))) {
263 int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); 311 rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
264
265 if (err > 0) {
266 if (!block) {
267 sk_reset_timer(sk, &dp->dccps_xmit_timer,
268 msecs_to_jiffies(err)+jiffies);
269 break;
270 } else
271 err = dccp_wait_for_ccid(sk, skb, err);
272 if (err && err != -EINTR)
273 DCCP_BUG("err=%d after dccp_wait_for_ccid", err);
274 }
275 312
276 skb_dequeue(&sk->sk_write_queue); 313 switch (ccid_packet_dequeue_eval(rc)) {
277 if (err == 0) { 314 case CCID_PACKET_WILL_DEQUEUE_LATER:
278 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 315 /*
279 const int len = skb->len; 316 * If the CCID determines when to send, the next sending
280 317 * time is unknown or the CCID may not even send again
281 if (sk->sk_state == DCCP_PARTOPEN) { 318 * (e.g. remote host crashes or lost Ack packets).
282 const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD; 319 */
283 /* 320 DCCP_WARN("CCID did not manage to send all packets\n");
284 * See 8.1.5 - Handshake Completion. 321 return;
285 * 322 case CCID_PACKET_DELAY:
286 * For robustness we resend Confirm options until the client has 323 delay = msecs_to_jiffies(rc);
287 * entered OPEN. During the initial feature negotiation, the MPS 324 if (delay > *time_budget)
288 * is smaller than usual, reduced by the Change/Confirm options. 325 return;
289 */ 326 rc = dccp_wait_for_ccid(sk, delay);
290 if (!list_empty(&dp->dccps_featneg) && len > cur_mps) { 327 if (rc < 0)
291 DCCP_WARN("Payload too large (%d) for featneg.\n", len); 328 return;
292 dccp_send_ack(sk); 329 *time_budget -= (delay - rc);
293 dccp_feat_list_purge(&dp->dccps_featneg); 330 /* check again if we can send now */
294 } 331 break;
295 332 case CCID_PACKET_SEND_AT_ONCE:
296 inet_csk_schedule_ack(sk); 333 dccp_xmit_packet(sk);
297 inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, 334 break;
298 inet_csk(sk)->icsk_rto, 335 case CCID_PACKET_ERR:
299 DCCP_RTO_MAX); 336 skb_dequeue(&sk->sk_write_queue);
300 dcb->dccpd_type = DCCP_PKT_DATAACK;
301 } else if (dccp_ack_pending(sk))
302 dcb->dccpd_type = DCCP_PKT_DATAACK;
303 else
304 dcb->dccpd_type = DCCP_PKT_DATA;
305
306 err = dccp_transmit_skb(sk, skb);
307 ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
308 if (err)
309 DCCP_BUG("err=%d after ccid_hc_tx_packet_sent",
310 err);
311 } else {
312 dccp_pr_debug("packet discarded due to err=%d\n", err);
313 kfree_skb(skb); 337 kfree_skb(skb);
338 dccp_pr_debug("packet discarded due to err=%ld\n", rc);
339 }
340 }
341}
342
343void dccp_write_xmit(struct sock *sk)
344{
345 struct dccp_sock *dp = dccp_sk(sk);
346 struct sk_buff *skb;
347
348 while ((skb = dccp_qpolicy_top(sk))) {
349 int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
350
351 switch (ccid_packet_dequeue_eval(rc)) {
352 case CCID_PACKET_WILL_DEQUEUE_LATER:
353 return;
354 case CCID_PACKET_DELAY:
355 sk_reset_timer(sk, &dp->dccps_xmit_timer,
356 jiffies + msecs_to_jiffies(rc));
357 return;
358 case CCID_PACKET_SEND_AT_ONCE:
359 dccp_xmit_packet(sk);
360 break;
361 case CCID_PACKET_ERR:
362 dccp_qpolicy_drop(sk, skb);
363 dccp_pr_debug("packet discarded due to err=%d\n", rc);
314 } 364 }
315 } 365 }
316} 366}
@@ -474,8 +524,9 @@ int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code)
474/* 524/*
475 * Do all connect socket setups that can be done AF independent. 525 * Do all connect socket setups that can be done AF independent.
476 */ 526 */
477static inline void dccp_connect_init(struct sock *sk) 527int dccp_connect(struct sock *sk)
478{ 528{
529 struct sk_buff *skb;
479 struct dccp_sock *dp = dccp_sk(sk); 530 struct dccp_sock *dp = dccp_sk(sk);
480 struct dst_entry *dst = __sk_dst_get(sk); 531 struct dst_entry *dst = __sk_dst_get(sk);
481 struct inet_connection_sock *icsk = inet_csk(sk); 532 struct inet_connection_sock *icsk = inet_csk(sk);
@@ -485,22 +536,12 @@ static inline void dccp_connect_init(struct sock *sk)
485 536
486 dccp_sync_mss(sk, dst_mtu(dst)); 537 dccp_sync_mss(sk, dst_mtu(dst));
487 538
488 /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */
489 dp->dccps_gar = dp->dccps_iss;
490
491 icsk->icsk_retransmits = 0;
492}
493
494int dccp_connect(struct sock *sk)
495{
496 struct sk_buff *skb;
497 struct inet_connection_sock *icsk = inet_csk(sk);
498
499 /* do not connect if feature negotiation setup fails */ 539 /* do not connect if feature negotiation setup fails */
500 if (dccp_feat_finalise_settings(dccp_sk(sk))) 540 if (dccp_feat_finalise_settings(dccp_sk(sk)))
501 return -EPROTO; 541 return -EPROTO;
502 542
503 dccp_connect_init(sk); 543 /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */
544 dp->dccps_gar = dp->dccps_iss;
504 545
505 skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation); 546 skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation);
506 if (unlikely(skb == NULL)) 547 if (unlikely(skb == NULL))
@@ -516,6 +557,7 @@ int dccp_connect(struct sock *sk)
516 DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); 557 DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);
517 558
518 /* Timer for repeating the REQUEST until an answer. */ 559 /* Timer for repeating the REQUEST until an answer. */
560 icsk->icsk_retransmits = 0;
519 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, 561 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
520 icsk->icsk_rto, DCCP_RTO_MAX); 562 icsk->icsk_rto, DCCP_RTO_MAX);
521 return 0; 563 return 0;
@@ -602,6 +644,12 @@ void dccp_send_sync(struct sock *sk, const u64 ackno,
602 DCCP_SKB_CB(skb)->dccpd_type = pkt_type; 644 DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
603 DCCP_SKB_CB(skb)->dccpd_ack_seq = ackno; 645 DCCP_SKB_CB(skb)->dccpd_ack_seq = ackno;
604 646
647 /*
648 * Clear the flag in case the Sync was scheduled for out-of-band data,
649 * such as carrying a long Ack Vector.
650 */
651 dccp_sk(sk)->dccps_sync_scheduled = 0;
652
605 dccp_transmit_skb(sk, skb); 653 dccp_transmit_skb(sk, skb);
606} 654}
607 655
@@ -630,7 +678,6 @@ void dccp_send_close(struct sock *sk, const int active)
630 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE; 678 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE;
631 679
632 if (active) { 680 if (active) {
633 dccp_write_xmit(sk, 1);
634 dccp_skb_entail(sk, skb); 681 dccp_skb_entail(sk, skb);
635 dccp_transmit_skb(sk, skb_clone(skb, prio)); 682 dccp_transmit_skb(sk, skb_clone(skb, prio));
636 /* 683 /*