aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/minisocks.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/minisocks.c')
-rw-r--r--net/dccp/minisocks.c37
1 files changed, 18 insertions, 19 deletions
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index 29261fc198e7..c0349e5b0551 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -22,6 +22,7 @@
22#include "ackvec.h" 22#include "ackvec.h"
23#include "ccid.h" 23#include "ccid.h"
24#include "dccp.h" 24#include "dccp.h"
25#include "feat.h"
25 26
26struct inet_timewait_death_row dccp_death_row = { 27struct inet_timewait_death_row dccp_death_row = {
27 .sysctl_max_tw_buckets = NR_FILE * 2, 28 .sysctl_max_tw_buckets = NR_FILE * 2,
@@ -106,6 +107,7 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
106 const struct dccp_request_sock *dreq = dccp_rsk(req); 107 const struct dccp_request_sock *dreq = dccp_rsk(req);
107 struct inet_connection_sock *newicsk = inet_csk(sk); 108 struct inet_connection_sock *newicsk = inet_csk(sk);
108 struct dccp_sock *newdp = dccp_sk(newsk); 109 struct dccp_sock *newdp = dccp_sk(newsk);
110 struct dccp_minisock *newdmsk = dccp_msk(newsk);
109 111
110 newdp->dccps_role = DCCP_ROLE_SERVER; 112 newdp->dccps_role = DCCP_ROLE_SERVER;
111 newdp->dccps_hc_rx_ackvec = NULL; 113 newdp->dccps_hc_rx_ackvec = NULL;
@@ -114,27 +116,27 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
114 newicsk->icsk_rto = DCCP_TIMEOUT_INIT; 116 newicsk->icsk_rto = DCCP_TIMEOUT_INIT;
115 do_gettimeofday(&newdp->dccps_epoch); 117 do_gettimeofday(&newdp->dccps_epoch);
116 118
117 if (newdp->dccps_options.dccpo_send_ack_vector) { 119 if (dccp_feat_clone(sk, newsk))
120 goto out_free;
121
122 if (newdmsk->dccpms_send_ack_vector) {
118 newdp->dccps_hc_rx_ackvec = 123 newdp->dccps_hc_rx_ackvec =
119 dccp_ackvec_alloc(DCCP_MAX_ACKVEC_LEN, 124 dccp_ackvec_alloc(GFP_ATOMIC);
120 GFP_ATOMIC);
121 /*
122 * XXX: We're using the same CCIDs set on the parent,
123 * i.e. sk_clone copied the master sock and left the
124 * CCID pointers for this child, that is why we do the
125 * __ccid_get calls.
126 */
127 if (unlikely(newdp->dccps_hc_rx_ackvec == NULL)) 125 if (unlikely(newdp->dccps_hc_rx_ackvec == NULL))
128 goto out_free; 126 goto out_free;
129 } 127 }
130 128
131 if (unlikely(ccid_hc_rx_init(newdp->dccps_hc_rx_ccid, 129 newdp->dccps_hc_rx_ccid =
132 newsk) != 0 || 130 ccid_hc_rx_new(newdmsk->dccpms_rx_ccid,
133 ccid_hc_tx_init(newdp->dccps_hc_tx_ccid, 131 newsk, GFP_ATOMIC);
134 newsk) != 0)) { 132 newdp->dccps_hc_tx_ccid =
133 ccid_hc_tx_new(newdmsk->dccpms_tx_ccid,
134 newsk, GFP_ATOMIC);
135 if (unlikely(newdp->dccps_hc_rx_ccid == NULL ||
136 newdp->dccps_hc_tx_ccid == NULL)) {
135 dccp_ackvec_free(newdp->dccps_hc_rx_ackvec); 137 dccp_ackvec_free(newdp->dccps_hc_rx_ackvec);
136 ccid_hc_rx_exit(newdp->dccps_hc_rx_ccid, newsk); 138 ccid_hc_rx_delete(newdp->dccps_hc_rx_ccid, newsk);
137 ccid_hc_tx_exit(newdp->dccps_hc_tx_ccid, newsk); 139 ccid_hc_tx_delete(newdp->dccps_hc_tx_ccid, newsk);
138out_free: 140out_free:
139 /* It is still raw copy of parent, so invalidate 141 /* It is still raw copy of parent, so invalidate
140 * destructor and make plain sk_free() */ 142 * destructor and make plain sk_free() */
@@ -143,9 +145,6 @@ out_free:
143 return NULL; 145 return NULL;
144 } 146 }
145 147
146 __ccid_get(newdp->dccps_hc_rx_ccid);
147 __ccid_get(newdp->dccps_hc_tx_ccid);
148
149 /* 148 /*
150 * Step 3: Process LISTEN state 149 * Step 3: Process LISTEN state
151 * 150 *
@@ -155,7 +154,7 @@ out_free:
155 */ 154 */
156 155
157 /* See dccp_v4_conn_request */ 156 /* See dccp_v4_conn_request */
158 newdp->dccps_options.dccpo_sequence_window = req->rcv_wnd; 157 newdmsk->dccpms_sequence_window = req->rcv_wnd;
159 158
160 newdp->dccps_gar = newdp->dccps_isr = dreq->dreq_isr; 159 newdp->dccps_gar = newdp->dccps_isr = dreq->dreq_isr;
161 dccp_update_gsr(newsk, dreq->dreq_isr); 160 dccp_update_gsr(newsk, dreq->dreq_isr);