diff options
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/proto.c | 46 |
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); | |||
175 | int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) | 178 | int 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 | ||