diff options
Diffstat (limited to 'net/dccp/output.c')
-rw-r--r-- | net/dccp/output.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/net/dccp/output.c b/net/dccp/output.c index 45b91853f5ae..784d30210543 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -242,7 +242,7 @@ static void dccp_xmit_packet(struct sock *sk) | |||
242 | { | 242 | { |
243 | int err, len; | 243 | int err, len; |
244 | struct dccp_sock *dp = dccp_sk(sk); | 244 | struct dccp_sock *dp = dccp_sk(sk); |
245 | struct sk_buff *skb = skb_dequeue(&sk->sk_write_queue); | 245 | struct sk_buff *skb = dccp_qpolicy_pop(sk); |
246 | 246 | ||
247 | if (unlikely(skb == NULL)) | 247 | if (unlikely(skb == NULL)) |
248 | return; | 248 | return; |
@@ -283,6 +283,15 @@ static void dccp_xmit_packet(struct sock *sk) | |||
283 | * any local drop will eventually be reported via receiver feedback. | 283 | * any local drop will eventually be reported via receiver feedback. |
284 | */ | 284 | */ |
285 | ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len); | 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); | ||
286 | } | 295 | } |
287 | 296 | ||
288 | /** | 297 | /** |
@@ -336,7 +345,7 @@ void dccp_write_xmit(struct sock *sk) | |||
336 | struct dccp_sock *dp = dccp_sk(sk); | 345 | struct dccp_sock *dp = dccp_sk(sk); |
337 | struct sk_buff *skb; | 346 | struct sk_buff *skb; |
338 | 347 | ||
339 | while ((skb = skb_peek(&sk->sk_write_queue))) { | 348 | while ((skb = dccp_qpolicy_top(sk))) { |
340 | int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); | 349 | int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); |
341 | 350 | ||
342 | switch (ccid_packet_dequeue_eval(rc)) { | 351 | switch (ccid_packet_dequeue_eval(rc)) { |
@@ -350,8 +359,7 @@ void dccp_write_xmit(struct sock *sk) | |||
350 | dccp_xmit_packet(sk); | 359 | dccp_xmit_packet(sk); |
351 | break; | 360 | break; |
352 | case CCID_PACKET_ERR: | 361 | case CCID_PACKET_ERR: |
353 | skb_dequeue(&sk->sk_write_queue); | 362 | dccp_qpolicy_drop(sk, skb); |
354 | kfree_skb(skb); | ||
355 | dccp_pr_debug("packet discarded due to err=%d\n", rc); | 363 | dccp_pr_debug("packet discarded due to err=%d\n", rc); |
356 | } | 364 | } |
357 | } | 365 | } |
@@ -636,6 +644,12 @@ void dccp_send_sync(struct sock *sk, const u64 ackno, | |||
636 | DCCP_SKB_CB(skb)->dccpd_type = pkt_type; | 644 | DCCP_SKB_CB(skb)->dccpd_type = pkt_type; |
637 | DCCP_SKB_CB(skb)->dccpd_ack_seq = ackno; | 645 | DCCP_SKB_CB(skb)->dccpd_ack_seq = ackno; |
638 | 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 | |||
639 | dccp_transmit_skb(sk, skb); | 653 | dccp_transmit_skb(sk, skb); |
640 | } | 654 | } |
641 | 655 | ||