diff options
Diffstat (limited to 'net/tls/tls_main.c')
-rw-r--r-- | net/tls/tls_main.c | 54 |
1 files changed, 21 insertions, 33 deletions
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index 523622dc74f8..06094de7a3d9 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c | |||
@@ -141,7 +141,6 @@ retry: | |||
141 | size = sg->length; | 141 | size = sg->length; |
142 | } | 142 | } |
143 | 143 | ||
144 | clear_bit(TLS_PENDING_CLOSED_RECORD, &ctx->flags); | ||
145 | ctx->in_tcp_sendpages = false; | 144 | ctx->in_tcp_sendpages = false; |
146 | ctx->sk_write_space(sk); | 145 | ctx->sk_write_space(sk); |
147 | 146 | ||
@@ -193,15 +192,12 @@ int tls_proccess_cmsg(struct sock *sk, struct msghdr *msg, | |||
193 | return rc; | 192 | return rc; |
194 | } | 193 | } |
195 | 194 | ||
196 | int tls_push_pending_closed_record(struct sock *sk, struct tls_context *ctx, | 195 | int tls_push_partial_record(struct sock *sk, struct tls_context *ctx, |
197 | int flags, long *timeo) | 196 | int flags) |
198 | { | 197 | { |
199 | struct scatterlist *sg; | 198 | struct scatterlist *sg; |
200 | u16 offset; | 199 | u16 offset; |
201 | 200 | ||
202 | if (!tls_is_partially_sent_record(ctx)) | ||
203 | return ctx->push_pending_record(sk, flags); | ||
204 | |||
205 | sg = ctx->partially_sent_record; | 201 | sg = ctx->partially_sent_record; |
206 | offset = ctx->partially_sent_offset; | 202 | offset = ctx->partially_sent_offset; |
207 | 203 | ||
@@ -209,9 +205,23 @@ int tls_push_pending_closed_record(struct sock *sk, struct tls_context *ctx, | |||
209 | return tls_push_sg(sk, ctx, sg, offset, flags); | 205 | return tls_push_sg(sk, ctx, sg, offset, flags); |
210 | } | 206 | } |
211 | 207 | ||
208 | int tls_push_pending_closed_record(struct sock *sk, | ||
209 | struct tls_context *tls_ctx, | ||
210 | int flags, long *timeo) | ||
211 | { | ||
212 | struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); | ||
213 | |||
214 | if (tls_is_partially_sent_record(tls_ctx) || | ||
215 | !list_empty(&ctx->tx_ready_list)) | ||
216 | return tls_tx_records(sk, flags); | ||
217 | else | ||
218 | return tls_ctx->push_pending_record(sk, flags); | ||
219 | } | ||
220 | |||
212 | static void tls_write_space(struct sock *sk) | 221 | static void tls_write_space(struct sock *sk) |
213 | { | 222 | { |
214 | struct tls_context *ctx = tls_get_ctx(sk); | 223 | struct tls_context *ctx = tls_get_ctx(sk); |
224 | struct tls_sw_context_tx *tx_ctx = tls_sw_ctx_tx(ctx); | ||
215 | 225 | ||
216 | /* If in_tcp_sendpages call lower protocol write space handler | 226 | /* If in_tcp_sendpages call lower protocol write space handler |
217 | * to ensure we wake up any waiting operations there. For example | 227 | * to ensure we wake up any waiting operations there. For example |
@@ -222,20 +232,11 @@ static void tls_write_space(struct sock *sk) | |||
222 | return; | 232 | return; |
223 | } | 233 | } |
224 | 234 | ||
225 | if (!sk->sk_write_pending && tls_is_pending_closed_record(ctx)) { | 235 | /* Schedule the transmission if tx list is ready */ |
226 | gfp_t sk_allocation = sk->sk_allocation; | 236 | if (is_tx_ready(ctx, tx_ctx) && !sk->sk_write_pending) { |
227 | int rc; | 237 | /* Schedule the transmission */ |
228 | long timeo = 0; | 238 | if (!test_and_set_bit(BIT_TX_SCHEDULED, &tx_ctx->tx_bitmask)) |
229 | 239 | schedule_delayed_work(&tx_ctx->tx_work.work, 0); | |
230 | sk->sk_allocation = GFP_ATOMIC; | ||
231 | rc = tls_push_pending_closed_record(sk, ctx, | ||
232 | MSG_DONTWAIT | | ||
233 | MSG_NOSIGNAL, | ||
234 | &timeo); | ||
235 | sk->sk_allocation = sk_allocation; | ||
236 | |||
237 | if (rc < 0) | ||
238 | return; | ||
239 | } | 240 | } |
240 | 241 | ||
241 | ctx->sk_write_space(sk); | 242 | ctx->sk_write_space(sk); |
@@ -270,19 +271,6 @@ static void tls_sk_proto_close(struct sock *sk, long timeout) | |||
270 | if (!tls_complete_pending_work(sk, ctx, 0, &timeo)) | 271 | if (!tls_complete_pending_work(sk, ctx, 0, &timeo)) |
271 | tls_handle_open_record(sk, 0); | 272 | tls_handle_open_record(sk, 0); |
272 | 273 | ||
273 | if (ctx->partially_sent_record) { | ||
274 | struct scatterlist *sg = ctx->partially_sent_record; | ||
275 | |||
276 | while (1) { | ||
277 | put_page(sg_page(sg)); | ||
278 | sk_mem_uncharge(sk, sg->length); | ||
279 | |||
280 | if (sg_is_last(sg)) | ||
281 | break; | ||
282 | sg++; | ||
283 | } | ||
284 | } | ||
285 | |||
286 | /* We need these for tls_sw_fallback handling of other packets */ | 274 | /* We need these for tls_sw_fallback handling of other packets */ |
287 | if (ctx->tx_conf == TLS_SW) { | 275 | if (ctx->tx_conf == TLS_SW) { |
288 | kfree(ctx->tx.rec_seq); | 276 | kfree(ctx->tx.rec_seq); |