diff options
Diffstat (limited to 'net/dccp/minisocks.c')
-rw-r--r-- | net/dccp/minisocks.c | 87 |
1 files changed, 23 insertions, 64 deletions
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index b2804e2d1b8c..f4d9c8f60ede 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c | |||
@@ -42,16 +42,6 @@ struct inet_timewait_death_row dccp_death_row = { | |||
42 | 42 | ||
43 | EXPORT_SYMBOL_GPL(dccp_death_row); | 43 | EXPORT_SYMBOL_GPL(dccp_death_row); |
44 | 44 | ||
45 | void dccp_minisock_init(struct dccp_minisock *dmsk) | ||
46 | { | ||
47 | dmsk->dccpms_sequence_window = sysctl_dccp_feat_sequence_window; | ||
48 | dmsk->dccpms_rx_ccid = sysctl_dccp_feat_rx_ccid; | ||
49 | dmsk->dccpms_tx_ccid = sysctl_dccp_feat_tx_ccid; | ||
50 | dmsk->dccpms_ack_ratio = sysctl_dccp_feat_ack_ratio; | ||
51 | dmsk->dccpms_send_ack_vector = sysctl_dccp_feat_send_ack_vector; | ||
52 | dmsk->dccpms_send_ndp_count = sysctl_dccp_feat_send_ndp_count; | ||
53 | } | ||
54 | |||
55 | void dccp_time_wait(struct sock *sk, int state, int timeo) | 45 | void dccp_time_wait(struct sock *sk, int state, int timeo) |
56 | { | 46 | { |
57 | struct inet_timewait_sock *tw = NULL; | 47 | struct inet_timewait_sock *tw = NULL; |
@@ -112,10 +102,9 @@ struct sock *dccp_create_openreq_child(struct sock *sk, | |||
112 | struct sock *newsk = inet_csk_clone(sk, req, GFP_ATOMIC); | 102 | struct sock *newsk = inet_csk_clone(sk, req, GFP_ATOMIC); |
113 | 103 | ||
114 | if (newsk != NULL) { | 104 | if (newsk != NULL) { |
115 | const struct dccp_request_sock *dreq = dccp_rsk(req); | 105 | struct dccp_request_sock *dreq = dccp_rsk(req); |
116 | struct inet_connection_sock *newicsk = inet_csk(newsk); | 106 | struct inet_connection_sock *newicsk = inet_csk(newsk); |
117 | struct dccp_sock *newdp = dccp_sk(newsk); | 107 | struct dccp_sock *newdp = dccp_sk(newsk); |
118 | struct dccp_minisock *newdmsk = dccp_msk(newsk); | ||
119 | 108 | ||
120 | newdp->dccps_role = DCCP_ROLE_SERVER; | 109 | newdp->dccps_role = DCCP_ROLE_SERVER; |
121 | newdp->dccps_hc_rx_ackvec = NULL; | 110 | newdp->dccps_hc_rx_ackvec = NULL; |
@@ -125,65 +114,32 @@ struct sock *dccp_create_openreq_child(struct sock *sk, | |||
125 | newdp->dccps_timestamp_time = dreq->dreq_timestamp_time; | 114 | newdp->dccps_timestamp_time = dreq->dreq_timestamp_time; |
126 | newicsk->icsk_rto = DCCP_TIMEOUT_INIT; | 115 | newicsk->icsk_rto = DCCP_TIMEOUT_INIT; |
127 | 116 | ||
128 | if (dccp_feat_clone(sk, newsk)) | 117 | INIT_LIST_HEAD(&newdp->dccps_featneg); |
129 | goto out_free; | ||
130 | |||
131 | if (newdmsk->dccpms_send_ack_vector) { | ||
132 | newdp->dccps_hc_rx_ackvec = | ||
133 | dccp_ackvec_alloc(GFP_ATOMIC); | ||
134 | if (unlikely(newdp->dccps_hc_rx_ackvec == NULL)) | ||
135 | goto out_free; | ||
136 | } | ||
137 | |||
138 | newdp->dccps_hc_rx_ccid = | ||
139 | ccid_hc_rx_new(newdmsk->dccpms_rx_ccid, | ||
140 | newsk, GFP_ATOMIC); | ||
141 | newdp->dccps_hc_tx_ccid = | ||
142 | ccid_hc_tx_new(newdmsk->dccpms_tx_ccid, | ||
143 | newsk, GFP_ATOMIC); | ||
144 | if (unlikely(newdp->dccps_hc_rx_ccid == NULL || | ||
145 | newdp->dccps_hc_tx_ccid == NULL)) { | ||
146 | dccp_ackvec_free(newdp->dccps_hc_rx_ackvec); | ||
147 | ccid_hc_rx_delete(newdp->dccps_hc_rx_ccid, newsk); | ||
148 | ccid_hc_tx_delete(newdp->dccps_hc_tx_ccid, newsk); | ||
149 | out_free: | ||
150 | /* It is still raw copy of parent, so invalidate | ||
151 | * destructor and make plain sk_free() */ | ||
152 | newsk->sk_destruct = NULL; | ||
153 | sk_free(newsk); | ||
154 | return NULL; | ||
155 | } | ||
156 | |||
157 | /* | 118 | /* |
158 | * Step 3: Process LISTEN state | 119 | * Step 3: Process LISTEN state |
159 | * | 120 | * |
160 | * Choose S.ISS (initial seqno) or set from Init Cookies | 121 | * Choose S.ISS (initial seqno) or set from Init Cookies |
161 | * Initialize S.GAR := S.ISS | 122 | * Initialize S.GAR := S.ISS |
162 | * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies | 123 | * Set S.ISR, S.GSR from packet (or Init Cookies) |
124 | * | ||
125 | * Setting AWL/AWH and SWL/SWH happens as part of the feature | ||
126 | * activation below, as these windows all depend on the local | ||
127 | * and remote Sequence Window feature values (7.5.2). | ||
163 | */ | 128 | */ |
164 | 129 | newdp->dccps_gss = newdp->dccps_iss = dreq->dreq_iss; | |
165 | /* See dccp_v4_conn_request */ | 130 | newdp->dccps_gar = newdp->dccps_iss; |
166 | newdmsk->dccpms_sequence_window = req->rcv_wnd; | 131 | newdp->dccps_gsr = newdp->dccps_isr = dreq->dreq_isr; |
167 | |||
168 | newdp->dccps_gar = newdp->dccps_iss = dreq->dreq_iss; | ||
169 | dccp_update_gss(newsk, dreq->dreq_iss); | ||
170 | |||
171 | newdp->dccps_isr = dreq->dreq_isr; | ||
172 | dccp_update_gsr(newsk, dreq->dreq_isr); | ||
173 | 132 | ||
174 | /* | 133 | /* |
175 | * SWL and AWL are initially adjusted so that they are not less than | 134 | * Activate features: initialise CCIDs, sequence windows etc. |
176 | * the initial Sequence Numbers received and sent, respectively: | ||
177 | * SWL := max(GSR + 1 - floor(W/4), ISR), | ||
178 | * AWL := max(GSS - W' + 1, ISS). | ||
179 | * These adjustments MUST be applied only at the beginning of the | ||
180 | * connection. | ||
181 | */ | 135 | */ |
182 | dccp_set_seqno(&newdp->dccps_swl, | 136 | if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) { |
183 | max48(newdp->dccps_swl, newdp->dccps_isr)); | 137 | /* It is still raw copy of parent, so invalidate |
184 | dccp_set_seqno(&newdp->dccps_awl, | 138 | * destructor and make plain sk_free() */ |
185 | max48(newdp->dccps_awl, newdp->dccps_iss)); | 139 | newsk->sk_destruct = NULL; |
186 | 140 | sk_free(newsk); | |
141 | return NULL; | ||
142 | } | ||
187 | dccp_init_xmit_timers(newsk); | 143 | dccp_init_xmit_timers(newsk); |
188 | 144 | ||
189 | DCCP_INC_STATS_BH(DCCP_MIB_PASSIVEOPENS); | 145 | DCCP_INC_STATS_BH(DCCP_MIB_PASSIVEOPENS); |
@@ -304,14 +260,17 @@ void dccp_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, | |||
304 | 260 | ||
305 | EXPORT_SYMBOL_GPL(dccp_reqsk_send_ack); | 261 | EXPORT_SYMBOL_GPL(dccp_reqsk_send_ack); |
306 | 262 | ||
307 | void dccp_reqsk_init(struct request_sock *req, struct sk_buff *skb) | 263 | int dccp_reqsk_init(struct request_sock *req, |
264 | struct dccp_sock const *dp, struct sk_buff const *skb) | ||
308 | { | 265 | { |
309 | struct dccp_request_sock *dreq = dccp_rsk(req); | 266 | struct dccp_request_sock *dreq = dccp_rsk(req); |
310 | 267 | ||
311 | inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport; | 268 | inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport; |
312 | inet_rsk(req)->acked = 0; | 269 | inet_rsk(req)->acked = 0; |
313 | req->rcv_wnd = sysctl_dccp_feat_sequence_window; | ||
314 | dreq->dreq_timestamp_echo = 0; | 270 | dreq->dreq_timestamp_echo = 0; |
271 | |||
272 | /* inherit feature negotiation options from listening socket */ | ||
273 | return dccp_feat_clone_list(&dp->dccps_featneg, &dreq->dreq_featneg); | ||
315 | } | 274 | } |
316 | 275 | ||
317 | EXPORT_SYMBOL_GPL(dccp_reqsk_init); | 276 | EXPORT_SYMBOL_GPL(dccp_reqsk_init); |