|
@@ -67,6 +67,9 @@ void dccp_set_state(struct sock *sk, const int state)
|
|
case DCCP_OPEN:
|
|
case DCCP_OPEN:
|
|
if (oldstate != DCCP_OPEN)
|
|
if (oldstate != DCCP_OPEN)
|
|
DCCP_INC_STATS(DCCP_MIB_CURRESTAB);
|
|
DCCP_INC_STATS(DCCP_MIB_CURRESTAB);
|
|
|
|
+ /* Client retransmits all Confirm options until entering OPEN */
|
|
|
|
+ if (oldstate == DCCP_PARTOPEN)
|
|
|
|
+ dccp_feat_list_purge(&dccp_sk(sk)->dccps_featneg);
|
|
break;
|
|
break;
|
|
|
|
|
|
case DCCP_CLOSED:
|
|
case DCCP_CLOSED:
|
|
@@ -175,7 +178,6 @@ EXPORT_SYMBOL_GPL(dccp_state_name);
|
|
int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
|
|
int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
|
|
{
|
|
{
|
|
struct dccp_sock *dp = dccp_sk(sk);
|
|
struct dccp_sock *dp = dccp_sk(sk);
|
|
- struct dccp_minisock *dmsk = dccp_msk(sk);
|
|
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
|
|
|
|
dccp_minisock_init(&dp->dccps_minisock);
|
|
dccp_minisock_init(&dp->dccps_minisock);
|
|
@@ -194,45 +196,9 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
|
|
dccp_init_xmit_timers(sk);
|
|
dccp_init_xmit_timers(sk);
|
|
|
|
|
|
INIT_LIST_HEAD(&dp->dccps_featneg);
|
|
INIT_LIST_HEAD(&dp->dccps_featneg);
|
|
- /*
|
|
|
|
- * FIXME: We're hardcoding the CCID, and doing this at this point makes
|
|
|
|
- * the listening (master) sock get CCID control blocks, which is not
|
|
|
|
- * necessary, but for now, to not mess with the test userspace apps,
|
|
|
|
- * lets leave it here, later the real solution is to do this in a
|
|
|
|
- * setsockopt(CCIDs-I-want/accept). -acme
|
|
|
|
- */
|
|
|
|
- if (likely(ctl_sock_initialized)) {
|
|
|
|
- int rc = dccp_feat_init(sk);
|
|
|
|
-
|
|
|
|
- if (rc)
|
|
|
|
- return rc;
|
|
|
|
-
|
|
|
|
- if (dmsk->dccpms_send_ack_vector) {
|
|
|
|
- dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(GFP_KERNEL);
|
|
|
|
- if (dp->dccps_hc_rx_ackvec == NULL)
|
|
|
|
- return -ENOMEM;
|
|
|
|
- }
|
|
|
|
- dp->dccps_hc_rx_ccid = ccid_hc_rx_new(dmsk->dccpms_rx_ccid,
|
|
|
|
- sk, GFP_KERNEL);
|
|
|
|
- dp->dccps_hc_tx_ccid = ccid_hc_tx_new(dmsk->dccpms_tx_ccid,
|
|
|
|
- sk, GFP_KERNEL);
|
|
|
|
- if (unlikely(dp->dccps_hc_rx_ccid == NULL ||
|
|
|
|
- dp->dccps_hc_tx_ccid == NULL)) {
|
|
|
|
- ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
|
|
|
|
- ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
|
|
|
|
- if (dmsk->dccpms_send_ack_vector) {
|
|
|
|
- dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
|
|
|
|
- dp->dccps_hc_rx_ackvec = NULL;
|
|
|
|
- }
|
|
|
|
- dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
|
|
|
|
- return -ENOMEM;
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- /* control socket doesn't need feat nego */
|
|
|
|
- INIT_LIST_HEAD(&dmsk->dccpms_pending);
|
|
|
|
- INIT_LIST_HEAD(&dmsk->dccpms_conf);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ /* control socket doesn't need feat nego */
|
|
|
|
+ if (likely(ctl_sock_initialized))
|
|
|
|
+ return dccp_feat_init(sk);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|