aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp')
-rw-r--r--net/dccp/proto.c46
1 files changed, 6 insertions, 40 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 6550452d59e2..0d420790b795 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -67,6 +67,9 @@ void dccp_set_state(struct sock *sk, const int state)
67 case DCCP_OPEN: 67 case DCCP_OPEN:
68 if (oldstate != DCCP_OPEN) 68 if (oldstate != DCCP_OPEN)
69 DCCP_INC_STATS(DCCP_MIB_CURRESTAB); 69 DCCP_INC_STATS(DCCP_MIB_CURRESTAB);
70 /* Client retransmits all Confirm options until entering OPEN */
71 if (oldstate == DCCP_PARTOPEN)
72 dccp_feat_list_purge(&dccp_sk(sk)->dccps_featneg);
70 break; 73 break;
71 74
72 case DCCP_CLOSED: 75 case DCCP_CLOSED:
@@ -175,7 +178,6 @@ EXPORT_SYMBOL_GPL(dccp_state_name);
175int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) 178int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
176{ 179{
177 struct dccp_sock *dp = dccp_sk(sk); 180 struct dccp_sock *dp = dccp_sk(sk);
178 struct dccp_minisock *dmsk = dccp_msk(sk);
179 struct inet_connection_sock *icsk = inet_csk(sk); 181 struct inet_connection_sock *icsk = inet_csk(sk);
180 182
181 dccp_minisock_init(&dp->dccps_minisock); 183 dccp_minisock_init(&dp->dccps_minisock);
@@ -194,45 +196,9 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
194 dccp_init_xmit_timers(sk); 196 dccp_init_xmit_timers(sk);
195 197
196 INIT_LIST_HEAD(&dp->dccps_featneg); 198 INIT_LIST_HEAD(&dp->dccps_featneg);
197 /* 199 /* control socket doesn't need feat nego */
198 * FIXME: We're hardcoding the CCID, and doing this at this point makes 200 if (likely(ctl_sock_initialized))
199 * the listening (master) sock get CCID control blocks, which is not 201 return dccp_feat_init(sk);
200 * necessary, but for now, to not mess with the test userspace apps,
201 * lets leave it here, later the real solution is to do this in a
202 * setsockopt(CCIDs-I-want/accept). -acme
203 */
204 if (likely(ctl_sock_initialized)) {
205 int rc = dccp_feat_init(sk);
206
207 if (rc)
208 return rc;
209
210 if (dmsk->dccpms_send_ack_vector) {
211 dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(GFP_KERNEL);
212 if (dp->dccps_hc_rx_ackvec == NULL)
213 return -ENOMEM;
214 }
215 dp->dccps_hc_rx_ccid = ccid_hc_rx_new(dmsk->dccpms_rx_ccid,
216 sk, GFP_KERNEL);
217 dp->dccps_hc_tx_ccid = ccid_hc_tx_new(dmsk->dccpms_tx_ccid,
218 sk, GFP_KERNEL);
219 if (unlikely(dp->dccps_hc_rx_ccid == NULL ||
220 dp->dccps_hc_tx_ccid == NULL)) {
221 ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
222 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
223 if (dmsk->dccpms_send_ack_vector) {
224 dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
225 dp->dccps_hc_rx_ackvec = NULL;
226 }
227 dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
228 return -ENOMEM;
229 }
230 } else {
231 /* control socket doesn't need feat nego */
232 INIT_LIST_HEAD(&dmsk->dccpms_pending);
233 INIT_LIST_HEAD(&dmsk->dccpms_conf);
234 }
235
236 return 0; 202 return 0;
237} 203}
238 204