diff options
Diffstat (limited to 'net/ipv4/tcp_fastopen.c')
-rw-r--r-- | net/ipv4/tcp_fastopen.c | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index ea82fd492c1b..e3d87aca6be8 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c | |||
@@ -141,7 +141,7 @@ static bool tcp_fastopen_create_child(struct sock *sk, | |||
141 | req->sk = NULL; | 141 | req->sk = NULL; |
142 | 142 | ||
143 | child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL); | 143 | child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL); |
144 | if (child == NULL) | 144 | if (!child) |
145 | return false; | 145 | return false; |
146 | 146 | ||
147 | spin_lock(&queue->fastopenq->lock); | 147 | spin_lock(&queue->fastopenq->lock); |
@@ -155,12 +155,7 @@ static bool tcp_fastopen_create_child(struct sock *sk, | |||
155 | tp = tcp_sk(child); | 155 | tp = tcp_sk(child); |
156 | 156 | ||
157 | tp->fastopen_rsk = req; | 157 | tp->fastopen_rsk = req; |
158 | /* Do a hold on the listner sk so that if the listener is being | 158 | tcp_rsk(req)->tfo_listener = true; |
159 | * closed, the child that has been accepted can live on and still | ||
160 | * access listen_lock. | ||
161 | */ | ||
162 | sock_hold(sk); | ||
163 | tcp_rsk(req)->listener = sk; | ||
164 | 159 | ||
165 | /* RFC1323: The window in SYN & SYN/ACK segments is never | 160 | /* RFC1323: The window in SYN & SYN/ACK segments is never |
166 | * scaled. So correct it appropriately. | 161 | * scaled. So correct it appropriately. |
@@ -174,6 +169,7 @@ static bool tcp_fastopen_create_child(struct sock *sk, | |||
174 | inet_csk_reset_xmit_timer(child, ICSK_TIME_RETRANS, | 169 | inet_csk_reset_xmit_timer(child, ICSK_TIME_RETRANS, |
175 | TCP_TIMEOUT_INIT, TCP_RTO_MAX); | 170 | TCP_TIMEOUT_INIT, TCP_RTO_MAX); |
176 | 171 | ||
172 | atomic_set(&req->rsk_refcnt, 1); | ||
177 | /* Add the child socket directly into the accept queue */ | 173 | /* Add the child socket directly into the accept queue */ |
178 | inet_csk_reqsk_queue_add(sk, req, child); | 174 | inet_csk_reqsk_queue_add(sk, req, child); |
179 | 175 | ||
@@ -218,10 +214,9 @@ static bool tcp_fastopen_create_child(struct sock *sk, | |||
218 | sk->sk_data_ready(sk); | 214 | sk->sk_data_ready(sk); |
219 | bh_unlock_sock(child); | 215 | bh_unlock_sock(child); |
220 | sock_put(child); | 216 | sock_put(child); |
221 | WARN_ON(req->sk == NULL); | 217 | WARN_ON(!req->sk); |
222 | return true; | 218 | return true; |
223 | } | 219 | } |
224 | EXPORT_SYMBOL(tcp_fastopen_create_child); | ||
225 | 220 | ||
226 | static bool tcp_fastopen_queue_check(struct sock *sk) | 221 | static bool tcp_fastopen_queue_check(struct sock *sk) |
227 | { | 222 | { |
@@ -238,14 +233,14 @@ static bool tcp_fastopen_queue_check(struct sock *sk) | |||
238 | * temporarily vs a server not supporting Fast Open at all. | 233 | * temporarily vs a server not supporting Fast Open at all. |
239 | */ | 234 | */ |
240 | fastopenq = inet_csk(sk)->icsk_accept_queue.fastopenq; | 235 | fastopenq = inet_csk(sk)->icsk_accept_queue.fastopenq; |
241 | if (fastopenq == NULL || fastopenq->max_qlen == 0) | 236 | if (!fastopenq || fastopenq->max_qlen == 0) |
242 | return false; | 237 | return false; |
243 | 238 | ||
244 | if (fastopenq->qlen >= fastopenq->max_qlen) { | 239 | if (fastopenq->qlen >= fastopenq->max_qlen) { |
245 | struct request_sock *req1; | 240 | struct request_sock *req1; |
246 | spin_lock(&fastopenq->lock); | 241 | spin_lock(&fastopenq->lock); |
247 | req1 = fastopenq->rskq_rst_head; | 242 | req1 = fastopenq->rskq_rst_head; |
248 | if ((req1 == NULL) || time_after(req1->expires, jiffies)) { | 243 | if (!req1 || time_after(req1->rsk_timer.expires, jiffies)) { |
249 | spin_unlock(&fastopenq->lock); | 244 | spin_unlock(&fastopenq->lock); |
250 | NET_INC_STATS_BH(sock_net(sk), | 245 | NET_INC_STATS_BH(sock_net(sk), |
251 | LINUX_MIB_TCPFASTOPENLISTENOVERFLOW); | 246 | LINUX_MIB_TCPFASTOPENLISTENOVERFLOW); |
@@ -254,7 +249,7 @@ static bool tcp_fastopen_queue_check(struct sock *sk) | |||
254 | fastopenq->rskq_rst_head = req1->dl_next; | 249 | fastopenq->rskq_rst_head = req1->dl_next; |
255 | fastopenq->qlen--; | 250 | fastopenq->qlen--; |
256 | spin_unlock(&fastopenq->lock); | 251 | spin_unlock(&fastopenq->lock); |
257 | reqsk_free(req1); | 252 | reqsk_put(req1); |
258 | } | 253 | } |
259 | return true; | 254 | return true; |
260 | } | 255 | } |
@@ -308,6 +303,7 @@ fastopen: | |||
308 | } else if (foc->len > 0) /* Client presents an invalid cookie */ | 303 | } else if (foc->len > 0) /* Client presents an invalid cookie */ |
309 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENPASSIVEFAIL); | 304 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENPASSIVEFAIL); |
310 | 305 | ||
306 | valid_foc.exp = foc->exp; | ||
311 | *foc = valid_foc; | 307 | *foc = valid_foc; |
312 | return false; | 308 | return false; |
313 | } | 309 | } |