diff options
Diffstat (limited to 'net/dccp/output.c')
| -rw-r--r-- | net/dccp/output.c | 91 |
1 files changed, 65 insertions, 26 deletions
diff --git a/net/dccp/output.c b/net/dccp/output.c index 7409e4a3abdf..7102e3aed4ca 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
| @@ -10,7 +10,6 @@ | |||
| 10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/config.h> | ||
| 14 | #include <linux/dccp.h> | 13 | #include <linux/dccp.h> |
| 15 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 16 | #include <linux/skbuff.h> | 15 | #include <linux/skbuff.h> |
| @@ -199,7 +198,7 @@ static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb, | |||
| 199 | while (1) { | 198 | while (1) { |
| 200 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 199 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); |
| 201 | 200 | ||
| 202 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) | 201 | if (sk->sk_err) |
| 203 | goto do_error; | 202 | goto do_error; |
| 204 | if (!*timeo) | 203 | if (!*timeo) |
| 205 | goto do_nonblock; | 204 | goto do_nonblock; |
| @@ -235,37 +234,72 @@ do_interrupted: | |||
| 235 | goto out; | 234 | goto out; |
| 236 | } | 235 | } |
| 237 | 236 | ||
| 238 | int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo) | 237 | static void dccp_write_xmit_timer(unsigned long data) { |
| 238 | struct sock *sk = (struct sock *)data; | ||
| 239 | struct dccp_sock *dp = dccp_sk(sk); | ||
| 240 | |||
| 241 | bh_lock_sock(sk); | ||
| 242 | if (sock_owned_by_user(sk)) | ||
| 243 | sk_reset_timer(sk, &dp->dccps_xmit_timer, jiffies+1); | ||
| 244 | else | ||
| 245 | dccp_write_xmit(sk, 0); | ||
| 246 | bh_unlock_sock(sk); | ||
| 247 | sock_put(sk); | ||
| 248 | } | ||
| 249 | |||
| 250 | void dccp_write_xmit(struct sock *sk, int block) | ||
| 239 | { | 251 | { |
| 240 | const struct dccp_sock *dp = dccp_sk(sk); | 252 | struct dccp_sock *dp = dccp_sk(sk); |
| 241 | int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb, | 253 | struct sk_buff *skb; |
| 254 | long timeo = 30000; /* If a packet is taking longer than 2 secs | ||
| 255 | we have other issues */ | ||
| 256 | |||
| 257 | while ((skb = skb_peek(&sk->sk_write_queue))) { | ||
| 258 | int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb, | ||
| 242 | skb->len); | 259 | skb->len); |
| 243 | 260 | ||
| 244 | if (err > 0) | 261 | if (err > 0) { |
| 245 | err = dccp_wait_for_ccid(sk, skb, timeo); | 262 | if (!block) { |
| 263 | sk_reset_timer(sk, &dp->dccps_xmit_timer, | ||
| 264 | msecs_to_jiffies(err)+jiffies); | ||
| 265 | break; | ||
| 266 | } else | ||
| 267 | err = dccp_wait_for_ccid(sk, skb, &timeo); | ||
| 268 | if (err) { | ||
| 269 | printk(KERN_CRIT "%s:err at dccp_wait_for_ccid" | ||
| 270 | " %d\n", __FUNCTION__, err); | ||
| 271 | dump_stack(); | ||
| 272 | } | ||
| 273 | } | ||
| 246 | 274 | ||
| 247 | if (err == 0) { | 275 | skb_dequeue(&sk->sk_write_queue); |
| 248 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); | 276 | if (err == 0) { |
| 249 | const int len = skb->len; | 277 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); |
| 278 | const int len = skb->len; | ||
| 250 | 279 | ||
| 251 | if (sk->sk_state == DCCP_PARTOPEN) { | 280 | if (sk->sk_state == DCCP_PARTOPEN) { |
| 252 | /* See 8.1.5. Handshake Completion */ | 281 | /* See 8.1.5. Handshake Completion */ |
| 253 | inet_csk_schedule_ack(sk); | 282 | inet_csk_schedule_ack(sk); |
| 254 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, | 283 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, |
| 255 | inet_csk(sk)->icsk_rto, | 284 | inet_csk(sk)->icsk_rto, |
| 256 | DCCP_RTO_MAX); | 285 | DCCP_RTO_MAX); |
| 257 | dcb->dccpd_type = DCCP_PKT_DATAACK; | 286 | dcb->dccpd_type = DCCP_PKT_DATAACK; |
| 258 | } else if (dccp_ack_pending(sk)) | 287 | } else if (dccp_ack_pending(sk)) |
| 259 | dcb->dccpd_type = DCCP_PKT_DATAACK; | 288 | dcb->dccpd_type = DCCP_PKT_DATAACK; |
| 260 | else | 289 | else |
| 261 | dcb->dccpd_type = DCCP_PKT_DATA; | 290 | dcb->dccpd_type = DCCP_PKT_DATA; |
| 262 | 291 | ||
| 263 | err = dccp_transmit_skb(sk, skb); | 292 | err = dccp_transmit_skb(sk, skb); |
| 264 | ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len); | 293 | ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len); |
| 265 | } else | 294 | if (err) { |
| 266 | kfree_skb(skb); | 295 | printk(KERN_CRIT "%s:err from " |
| 267 | 296 | "ccid_hc_tx_packet_sent %d\n", | |
| 268 | return err; | 297 | __FUNCTION__, err); |
| 298 | dump_stack(); | ||
| 299 | } | ||
| 300 | } else | ||
| 301 | kfree(skb); | ||
| 302 | } | ||
| 269 | } | 303 | } |
| 270 | 304 | ||
| 271 | int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | 305 | int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb) |
| @@ -427,6 +461,9 @@ static inline void dccp_connect_init(struct sock *sk) | |||
| 427 | dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss)); | 461 | dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss)); |
| 428 | 462 | ||
| 429 | icsk->icsk_retransmits = 0; | 463 | icsk->icsk_retransmits = 0; |
| 464 | init_timer(&dp->dccps_xmit_timer); | ||
| 465 | dp->dccps_xmit_timer.data = (unsigned long)sk; | ||
| 466 | dp->dccps_xmit_timer.function = dccp_write_xmit_timer; | ||
| 430 | } | 467 | } |
| 431 | 468 | ||
| 432 | int dccp_connect(struct sock *sk) | 469 | int dccp_connect(struct sock *sk) |
| @@ -561,8 +598,10 @@ void dccp_send_close(struct sock *sk, const int active) | |||
| 561 | DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ; | 598 | DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ; |
| 562 | 599 | ||
| 563 | if (active) { | 600 | if (active) { |
| 601 | dccp_write_xmit(sk, 1); | ||
| 564 | dccp_skb_entail(sk, skb); | 602 | dccp_skb_entail(sk, skb); |
| 565 | dccp_transmit_skb(sk, skb_clone(skb, prio)); | 603 | dccp_transmit_skb(sk, skb_clone(skb, prio)); |
| 604 | /* FIXME do we need a retransmit timer here? */ | ||
| 566 | } else | 605 | } else |
| 567 | dccp_transmit_skb(sk, skb); | 606 | dccp_transmit_skb(sk, skb); |
| 568 | } | 607 | } |
