diff options
Diffstat (limited to 'net/dccp/minisocks.c')
-rw-r--r-- | net/dccp/minisocks.c | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index e498e389fccc..a6a0b270fb6c 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c | |||
@@ -22,18 +22,58 @@ | |||
22 | #include "ccid.h" | 22 | #include "ccid.h" |
23 | #include "dccp.h" | 23 | #include "dccp.h" |
24 | 24 | ||
25 | struct inet_timewait_death_row dccp_death_row = { | ||
26 | .sysctl_max_tw_buckets = NR_FILE * 2, | ||
27 | .period = DCCP_TIMEWAIT_LEN / INET_TWDR_TWKILL_SLOTS, | ||
28 | .death_lock = SPIN_LOCK_UNLOCKED, | ||
29 | .hashinfo = &dccp_hashinfo, | ||
30 | .tw_timer = TIMER_INITIALIZER(inet_twdr_hangman, 0, | ||
31 | (unsigned long)&dccp_death_row), | ||
32 | .twkill_work = __WORK_INITIALIZER(dccp_death_row.twkill_work, | ||
33 | inet_twdr_twkill_work, | ||
34 | &dccp_death_row), | ||
35 | /* Short-time timewait calendar */ | ||
36 | |||
37 | .twcal_hand = -1, | ||
38 | .twcal_timer = TIMER_INITIALIZER(inet_twdr_twcal_tick, 0, | ||
39 | (unsigned long)&dccp_death_row), | ||
40 | }; | ||
41 | |||
25 | void dccp_time_wait(struct sock *sk, int state, int timeo) | 42 | void dccp_time_wait(struct sock *sk, int state, int timeo) |
26 | { | 43 | { |
27 | /* FIXME: Implement */ | 44 | struct inet_timewait_sock *tw = NULL; |
28 | dccp_pr_debug("Want to help? Start here\n"); | ||
29 | dccp_set_state(sk, state); | ||
30 | } | ||
31 | 45 | ||
32 | /* This is for handling early-kills of TIME_WAIT sockets. */ | 46 | if (dccp_death_row.tw_count < dccp_death_row.sysctl_max_tw_buckets) |
33 | void dccp_tw_deschedule(struct inet_timewait_sock *tw) | 47 | tw = inet_twsk_alloc(sk, state); |
34 | { | 48 | |
35 | dccp_pr_debug("Want to help? Start here\n"); | 49 | if (tw != NULL) { |
36 | __inet_twsk_kill(tw, &dccp_hashinfo); | 50 | const struct inet_connection_sock *icsk = inet_csk(sk); |
51 | const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1); | ||
52 | |||
53 | /* Linkage updates. */ | ||
54 | __inet_twsk_hashdance(tw, sk, &dccp_hashinfo); | ||
55 | |||
56 | /* Get the TIME_WAIT timeout firing. */ | ||
57 | if (timeo < rto) | ||
58 | timeo = rto; | ||
59 | |||
60 | tw->tw_timeout = DCCP_TIMEWAIT_LEN; | ||
61 | if (state == DCCP_TIME_WAIT) | ||
62 | timeo = DCCP_TIMEWAIT_LEN; | ||
63 | |||
64 | inet_twsk_schedule(tw, &dccp_death_row, timeo, | ||
65 | DCCP_TIMEWAIT_LEN); | ||
66 | inet_twsk_put(tw); | ||
67 | } else { | ||
68 | /* Sorry, if we're out of memory, just CLOSE this | ||
69 | * socket up. We've got bigger problems than | ||
70 | * non-graceful socket closings. | ||
71 | */ | ||
72 | if (net_ratelimit()) | ||
73 | printk(KERN_INFO "DCCP: time wait bucket table overflow\n"); | ||
74 | } | ||
75 | |||
76 | dccp_done(sk); | ||
37 | } | 77 | } |
38 | 78 | ||
39 | struct sock *dccp_create_openreq_child(struct sock *sk, | 79 | struct sock *dccp_create_openreq_child(struct sock *sk, |
@@ -55,7 +95,7 @@ struct sock *dccp_create_openreq_child(struct sock *sk, | |||
55 | 95 | ||
56 | newdp->dccps_hc_rx_ackpkts = NULL; | 96 | newdp->dccps_hc_rx_ackpkts = NULL; |
57 | newdp->dccps_role = DCCP_ROLE_SERVER; | 97 | newdp->dccps_role = DCCP_ROLE_SERVER; |
58 | newicsk->icsk_rto = TCP_TIMEOUT_INIT; | 98 | newicsk->icsk_rto = DCCP_TIMEOUT_INIT; |
59 | 99 | ||
60 | if (newdp->dccps_options.dccpo_send_ack_vector) { | 100 | if (newdp->dccps_options.dccpo_send_ack_vector) { |
61 | newdp->dccps_hc_rx_ackpkts = dccp_ackpkts_alloc(DCCP_MAX_ACK_VECTOR_LEN, | 101 | newdp->dccps_hc_rx_ackpkts = dccp_ackpkts_alloc(DCCP_MAX_ACK_VECTOR_LEN, |