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 db225f93cd5a..0941f8fe1675 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -61,6 +61,9 @@ void dccp_set_state(struct sock *sk, const int state)
61 case DCCP_OPEN: 61 case DCCP_OPEN:
62 if (oldstate != DCCP_OPEN) 62 if (oldstate != DCCP_OPEN)
63 DCCP_INC_STATS(DCCP_MIB_CURRESTAB); 63 DCCP_INC_STATS(DCCP_MIB_CURRESTAB);
64 /* Client retransmits all Confirm options until entering OPEN */
65 if (oldstate == DCCP_PARTOPEN)
66 dccp_feat_list_purge(&dccp_sk(sk)->dccps_featneg);
64 break; 67 break;
65 68
66 case DCCP_CLOSED: 69 case DCCP_CLOSED:
@@ -169,7 +172,6 @@ EXPORT_SYMBOL_GPL(dccp_state_name);
169int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) 172int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
170{ 173{
171 struct dccp_sock *dp = dccp_sk(sk); 174 struct dccp_sock *dp = dccp_sk(sk);
172 struct dccp_minisock *dmsk = dccp_msk(sk);
173 struct inet_connection_sock *icsk = inet_csk(sk); 175 struct inet_connection_sock *icsk = inet_csk(sk);
174 176
175 dccp_minisock_init(&dp->dccps_minisock); 177 dccp_minisock_init(&dp->dccps_minisock);
@@ -188,45 +190,9 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
188 dccp_init_xmit_timers(sk); 190 dccp_init_xmit_timers(sk);
189 191
190 INIT_LIST_HEAD(&dp->dccps_featneg); 192 INIT_LIST_HEAD(&dp->dccps_featneg);
191 /* 193 /* control socket doesn't need feat nego */
192 * FIXME: We're hardcoding the CCID, and doing this at this point makes 194 if (likely(ctl_sock_initialized))
193 * the listening (master) sock get CCID control blocks, which is not 195 return dccp_feat_init(sk);
194 * necessary, but for now, to not mess with the test userspace apps,
195 * lets leave it here, later the real solution is to do this in a
196 * setsockopt(CCIDs-I-want/accept). -acme
197 */
198 if (likely(ctl_sock_initialized)) {
199 int rc = dccp_feat_init(sk);
200
201 if (rc)
202 return rc;
203
204 if (dmsk->dccpms_send_ack_vector) {
205 dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(GFP_KERNEL);
206 if (dp->dccps_hc_rx_ackvec == NULL)
207 return -ENOMEM;
208 }
209 dp->dccps_hc_rx_ccid = ccid_hc_rx_new(dmsk->dccpms_rx_ccid,
210 sk, GFP_KERNEL);
211 dp->dccps_hc_tx_ccid = ccid_hc_tx_new(dmsk->dccpms_tx_ccid,
212 sk, GFP_KERNEL);
213 if (unlikely(dp->dccps_hc_rx_ccid == NULL ||
214 dp->dccps_hc_tx_ccid == NULL)) {
215 ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
216 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
217 if (dmsk->dccpms_send_ack_vector) {
218 dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
219 dp->dccps_hc_rx_ackvec = NULL;
220 }
221 dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
222 return -ENOMEM;
223 }
224 } else {
225 /* control socket doesn't need feat nego */
226 INIT_LIST_HEAD(&dmsk->dccpms_pending);
227 INIT_LIST_HEAD(&dmsk->dccpms_conf);
228 }
229
230 return 0; 196 return 0;
231} 197}
232 198