aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/proto.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/proto.c')
-rw-r--r--net/dccp/proto.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 8b613c3017c5..a3f8a8095f81 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -402,12 +402,15 @@ void dccp_close(struct sock *sk, long timeout)
402 /* Check zero linger _after_ checking for unread data. */ 402 /* Check zero linger _after_ checking for unread data. */
403 sk->sk_prot->disconnect(sk, 0); 403 sk->sk_prot->disconnect(sk, 0);
404 } else if (dccp_close_state(sk)) { 404 } else if (dccp_close_state(sk)) {
405 dccp_send_close(sk); 405 dccp_send_close(sk, 1);
406 } 406 }
407 407
408 sk_stream_wait_close(sk, timeout); 408 sk_stream_wait_close(sk, timeout);
409 409
410adjudge_to_death: 410adjudge_to_death:
411 /*
412 * It is the last release_sock in its life. It will remove backlog.
413 */
411 release_sock(sk); 414 release_sock(sk);
412 /* 415 /*
413 * Now socket is owned by kernel and we acquire BH lock 416 * Now socket is owned by kernel and we acquire BH lock
@@ -419,11 +422,26 @@ adjudge_to_death:
419 422
420 sock_hold(sk); 423 sock_hold(sk);
421 sock_orphan(sk); 424 sock_orphan(sk);
422 425
423 if (sk->sk_state != DCCP_CLOSED) 426 /*
427 * The last release_sock may have processed the CLOSE or RESET
428 * packet moving sock to CLOSED state, if not we have to fire
429 * the CLOSE/CLOSEREQ retransmission timer, see "8.3. Termination"
430 * in draft-ietf-dccp-spec-11. -acme
431 */
432 if (sk->sk_state == DCCP_CLOSING) {
433 /* FIXME: should start at 2 * RTT */
434 /* Timer for repeating the CLOSE/CLOSEREQ until an answer. */
435 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
436 inet_csk(sk)->icsk_rto,
437 DCCP_RTO_MAX);
438#if 0
439 /* Yeah, we should use sk->sk_prot->orphan_count, etc */
424 dccp_set_state(sk, DCCP_CLOSED); 440 dccp_set_state(sk, DCCP_CLOSED);
441#endif
442 }
425 443
426 atomic_inc(&dccp_orphan_count); 444 atomic_inc(sk->sk_prot->orphan_count);
427 if (sk->sk_state == DCCP_CLOSED) 445 if (sk->sk_state == DCCP_CLOSED)
428 inet_csk_destroy_sock(sk); 446 inet_csk_destroy_sock(sk);
429 447