Commit | Line | Data |
---|---|---|
b4d0d230 | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
0b58b8a1 DH |
2 | /* AF_RXRPC sendmsg() implementation. |
3 | * | |
4 | * Copyright (C) 2007, 2016 Red Hat, Inc. All Rights Reserved. | |
5 | * Written by David Howells (dhowells@redhat.com) | |
0b58b8a1 DH |
6 | */ |
7 | ||
8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
9 | ||
10 | #include <linux/net.h> | |
11 | #include <linux/gfp.h> | |
12 | #include <linux/skbuff.h> | |
13 | #include <linux/export.h> | |
174cd4b1 IM |
14 | #include <linux/sched/signal.h> |
15 | ||
0b58b8a1 DH |
16 | #include <net/sock.h> |
17 | #include <net/af_rxrpc.h> | |
18 | #include "ar-internal.h" | |
19 | ||
158fe666 DH |
20 | /* |
21 | * Return true if there's sufficient Tx queue space. | |
22 | */ | |
23 | static bool rxrpc_check_tx_space(struct rxrpc_call *call, rxrpc_seq_t *_tx_win) | |
24 | { | |
158fe666 | 25 | if (_tx_win) |
cf37b598 DH |
26 | *_tx_win = call->tx_bottom; |
27 | return call->tx_prepared - call->tx_bottom < 256; | |
158fe666 DH |
28 | } |
29 | ||
bc5e3a54 DH |
30 | /* |
31 | * Wait for space to appear in the Tx queue or a signal to occur. | |
32 | */ | |
33 | static int rxrpc_wait_for_tx_window_intr(struct rxrpc_sock *rx, | |
34 | struct rxrpc_call *call, | |
35 | long *timeo) | |
36 | { | |
37 | for (;;) { | |
38 | set_current_state(TASK_INTERRUPTIBLE); | |
158fe666 | 39 | if (rxrpc_check_tx_space(call, NULL)) |
bc5e3a54 DH |
40 | return 0; |
41 | ||
42 | if (call->state >= RXRPC_CALL_COMPLETE) | |
43 | return call->error; | |
44 | ||
45 | if (signal_pending(current)) | |
46 | return sock_intr_errno(*timeo); | |
47 | ||
a4ea4c47 | 48 | trace_rxrpc_txqueue(call, rxrpc_txqueue_wait); |
bc5e3a54 | 49 | *timeo = schedule_timeout(*timeo); |
bc5e3a54 DH |
50 | } |
51 | } | |
52 | ||
53 | /* | |
54 | * Wait for space to appear in the Tx queue uninterruptibly, but with | |
55 | * a timeout of 2*RTT if no progress was made and a signal occurred. | |
56 | */ | |
e138aa7d | 57 | static int rxrpc_wait_for_tx_window_waitall(struct rxrpc_sock *rx, |
bc5e3a54 DH |
58 | struct rxrpc_call *call) |
59 | { | |
60 | rxrpc_seq_t tx_start, tx_win; | |
c410bf01 | 61 | signed long rtt, timeout; |
bc5e3a54 | 62 | |
c410bf01 DH |
63 | rtt = READ_ONCE(call->peer->srtt_us) >> 3; |
64 | rtt = usecs_to_jiffies(rtt) * 2; | |
65 | if (rtt < 2) | |
66 | rtt = 2; | |
bc5e3a54 | 67 | |
c410bf01 | 68 | timeout = rtt; |
a4ea4c47 | 69 | tx_start = smp_load_acquire(&call->acks_hard_ack); |
bc5e3a54 DH |
70 | |
71 | for (;;) { | |
72 | set_current_state(TASK_UNINTERRUPTIBLE); | |
73 | ||
158fe666 | 74 | if (rxrpc_check_tx_space(call, &tx_win)) |
bc5e3a54 DH |
75 | return 0; |
76 | ||
77 | if (call->state >= RXRPC_CALL_COMPLETE) | |
78 | return call->error; | |
79 | ||
e138aa7d | 80 | if (timeout == 0 && |
bc5e3a54 DH |
81 | tx_win == tx_start && signal_pending(current)) |
82 | return -EINTR; | |
83 | ||
84 | if (tx_win != tx_start) { | |
c410bf01 | 85 | timeout = rtt; |
bc5e3a54 DH |
86 | tx_start = tx_win; |
87 | } | |
88 | ||
a4ea4c47 | 89 | trace_rxrpc_txqueue(call, rxrpc_txqueue_wait); |
bc5e3a54 DH |
90 | timeout = schedule_timeout(timeout); |
91 | } | |
92 | } | |
93 | ||
e138aa7d DH |
94 | /* |
95 | * Wait for space to appear in the Tx queue uninterruptibly. | |
96 | */ | |
97 | static int rxrpc_wait_for_tx_window_nonintr(struct rxrpc_sock *rx, | |
98 | struct rxrpc_call *call, | |
99 | long *timeo) | |
100 | { | |
101 | for (;;) { | |
102 | set_current_state(TASK_UNINTERRUPTIBLE); | |
103 | if (rxrpc_check_tx_space(call, NULL)) | |
104 | return 0; | |
105 | ||
106 | if (call->state >= RXRPC_CALL_COMPLETE) | |
107 | return call->error; | |
108 | ||
a4ea4c47 | 109 | trace_rxrpc_txqueue(call, rxrpc_txqueue_wait); |
e138aa7d DH |
110 | *timeo = schedule_timeout(*timeo); |
111 | } | |
112 | } | |
113 | ||
0b58b8a1 | 114 | /* |
df423a4a DH |
115 | * wait for space to appear in the transmit/ACK window |
116 | * - caller holds the socket locked | |
0b58b8a1 | 117 | */ |
df423a4a DH |
118 | static int rxrpc_wait_for_tx_window(struct rxrpc_sock *rx, |
119 | struct rxrpc_call *call, | |
bc5e3a54 DH |
120 | long *timeo, |
121 | bool waitall) | |
0b58b8a1 | 122 | { |
df423a4a DH |
123 | DECLARE_WAITQUEUE(myself, current); |
124 | int ret; | |
0b58b8a1 | 125 | |
a4ea4c47 DH |
126 | _enter(",{%u,%u,%u,%u}", |
127 | call->tx_bottom, call->acks_hard_ack, call->tx_top, call->tx_winsize); | |
0b58b8a1 | 128 | |
df423a4a | 129 | add_wait_queue(&call->waitq, &myself); |
0b58b8a1 | 130 | |
e138aa7d DH |
131 | switch (call->interruptibility) { |
132 | case RXRPC_INTERRUPTIBLE: | |
133 | if (waitall) | |
134 | ret = rxrpc_wait_for_tx_window_waitall(rx, call); | |
135 | else | |
136 | ret = rxrpc_wait_for_tx_window_intr(rx, call, timeo); | |
137 | break; | |
138 | case RXRPC_PREINTERRUPTIBLE: | |
139 | case RXRPC_UNINTERRUPTIBLE: | |
140 | default: | |
141 | ret = rxrpc_wait_for_tx_window_nonintr(rx, call, timeo); | |
142 | break; | |
143 | } | |
0b58b8a1 | 144 | |
df423a4a DH |
145 | remove_wait_queue(&call->waitq, &myself); |
146 | set_current_state(TASK_RUNNING); | |
147 | _leave(" = %d", ret); | |
148 | return ret; | |
0b58b8a1 DH |
149 | } |
150 | ||
e833251a DH |
151 | /* |
152 | * Notify the owner of the call that the transmit phase is ended and the last | |
153 | * packet has been queued. | |
154 | */ | |
155 | static void rxrpc_notify_end_tx(struct rxrpc_sock *rx, struct rxrpc_call *call, | |
156 | rxrpc_notify_end_tx_t notify_end_tx) | |
157 | { | |
158 | if (notify_end_tx) | |
159 | notify_end_tx(&rx->sk, call, call->user_call_ID); | |
160 | } | |
161 | ||
0b58b8a1 | 162 | /* |
8e8715aa MD |
163 | * Queue a DATA packet for transmission, set the resend timeout and send |
164 | * the packet immediately. Returns the error from rxrpc_send_data_packet() | |
165 | * in case the caller wants to do something with it. | |
0b58b8a1 | 166 | */ |
a4ea4c47 DH |
167 | static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, |
168 | struct rxrpc_txbuf *txb, | |
169 | rxrpc_notify_end_tx_t notify_end_tx) | |
0b58b8a1 | 170 | { |
a158bdd3 | 171 | unsigned long now; |
a4ea4c47 | 172 | rxrpc_seq_t seq = txb->seq; |
5e6ef4f1 | 173 | bool last = test_bit(RXRPC_TXBUF_LAST, &txb->flags), poke; |
0b58b8a1 | 174 | |
b0154246 DH |
175 | rxrpc_inc_stat(call->rxnet, stat_tx_data); |
176 | ||
cf37b598 | 177 | ASSERTCMP(txb->seq, ==, call->tx_prepared + 1); |
0b58b8a1 | 178 | |
b24d2891 DH |
179 | /* We have to set the timestamp before queueing as the retransmit |
180 | * algorithm can see the packet as soon as we queue it. | |
181 | */ | |
a4ea4c47 | 182 | txb->last_sent = ktime_get_real(); |
b24d2891 | 183 | |
70790dbe | 184 | if (last) |
a4ea4c47 | 185 | trace_rxrpc_txqueue(call, rxrpc_txqueue_queue_last); |
70790dbe | 186 | else |
a4ea4c47 | 187 | trace_rxrpc_txqueue(call, rxrpc_txqueue_queue); |
0b58b8a1 | 188 | |
cf37b598 DH |
189 | /* Add the packet to the call's output buffer */ |
190 | spin_lock(&call->tx_lock); | |
5e6ef4f1 | 191 | poke = list_empty(&call->tx_sendmsg); |
cf37b598 DH |
192 | list_add_tail(&txb->call_link, &call->tx_sendmsg); |
193 | call->tx_prepared = seq; | |
194 | spin_unlock(&call->tx_lock); | |
195 | ||
df423a4a DH |
196 | if (last || call->state == RXRPC_CALL_SERVER_ACK_REQUEST) { |
197 | _debug("________awaiting reply/ACK__________"); | |
3dd9c8b5 | 198 | write_lock(&call->state_lock); |
df423a4a DH |
199 | switch (call->state) { |
200 | case RXRPC_CALL_CLIENT_SEND_REQUEST: | |
201 | call->state = RXRPC_CALL_CLIENT_AWAIT_REPLY; | |
e833251a | 202 | rxrpc_notify_end_tx(rx, call, notify_end_tx); |
df423a4a DH |
203 | break; |
204 | case RXRPC_CALL_SERVER_ACK_REQUEST: | |
205 | call->state = RXRPC_CALL_SERVER_SEND_REPLY; | |
a158bdd3 | 206 | now = jiffies; |
530403d9 | 207 | WRITE_ONCE(call->delay_ack_at, now + MAX_JIFFY_OFFSET); |
9749fd2b DH |
208 | if (call->ackr_reason == RXRPC_ACK_DELAY) |
209 | call->ackr_reason = 0; | |
a158bdd3 | 210 | trace_rxrpc_timer(call, rxrpc_timer_init_for_send_reply, now); |
df423a4a DH |
211 | if (!last) |
212 | break; | |
df561f66 | 213 | fallthrough; |
df423a4a DH |
214 | case RXRPC_CALL_SERVER_SEND_REPLY: |
215 | call->state = RXRPC_CALL_SERVER_AWAIT_ACK; | |
e833251a | 216 | rxrpc_notify_end_tx(rx, call, notify_end_tx); |
df423a4a DH |
217 | break; |
218 | default: | |
219 | break; | |
220 | } | |
3dd9c8b5 | 221 | write_unlock(&call->state_lock); |
df423a4a | 222 | } |
0b58b8a1 | 223 | |
5e6ef4f1 DH |
224 | if (poke) |
225 | rxrpc_poke_call(call, rxrpc_call_poke_start); | |
0b58b8a1 DH |
226 | } |
227 | ||
df423a4a DH |
228 | /* |
229 | * send data through a socket | |
230 | * - must be called in process context | |
540b1c48 | 231 | * - The caller holds the call user access mutex, but not the socket lock. |
0b58b8a1 | 232 | */ |
df423a4a DH |
233 | static int rxrpc_send_data(struct rxrpc_sock *rx, |
234 | struct rxrpc_call *call, | |
e833251a | 235 | struct msghdr *msg, size_t len, |
b0f571ec DH |
236 | rxrpc_notify_end_tx_t notify_end_tx, |
237 | bool *_dropped_lock) | |
0b58b8a1 | 238 | { |
a4ea4c47 | 239 | struct rxrpc_txbuf *txb; |
df423a4a | 240 | struct sock *sk = &rx->sk; |
b0f571ec | 241 | enum rxrpc_call_state state; |
df423a4a | 242 | long timeo; |
b0f571ec DH |
243 | bool more = msg->msg_flags & MSG_MORE; |
244 | int ret, copied = 0; | |
0b58b8a1 | 245 | |
df423a4a | 246 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); |
0b58b8a1 | 247 | |
df423a4a DH |
248 | /* this should be in poll */ |
249 | sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); | |
0b58b8a1 | 250 | |
b0f571ec DH |
251 | reload: |
252 | ret = -EPIPE; | |
639f181f | 253 | if (sk->sk_shutdown & SEND_SHUTDOWN) |
b0f571ec DH |
254 | goto maybe_error; |
255 | state = READ_ONCE(call->state); | |
256 | ret = -ESHUTDOWN; | |
257 | if (state >= RXRPC_CALL_COMPLETE) | |
258 | goto maybe_error; | |
259 | ret = -EPROTO; | |
260 | if (state != RXRPC_CALL_CLIENT_SEND_REQUEST && | |
261 | state != RXRPC_CALL_SERVER_ACK_REQUEST && | |
262 | state != RXRPC_CALL_SERVER_SEND_REPLY) | |
263 | goto maybe_error; | |
264 | ||
265 | ret = -EMSGSIZE; | |
e754eba6 | 266 | if (call->tx_total_len != -1) { |
b0f571ec DH |
267 | if (len - copied > call->tx_total_len) |
268 | goto maybe_error; | |
269 | if (!more && len - copied != call->tx_total_len) | |
270 | goto maybe_error; | |
e754eba6 DH |
271 | } |
272 | ||
a4ea4c47 | 273 | txb = call->tx_pending; |
df423a4a | 274 | call->tx_pending = NULL; |
a4ea4c47 DH |
275 | if (txb) |
276 | rxrpc_see_txbuf(txb, rxrpc_txbuf_see_send_more); | |
0b58b8a1 | 277 | |
df423a4a | 278 | do { |
a4ea4c47 | 279 | if (!txb) { |
d7d775b1 | 280 | size_t remain, bufsize, chunk, offset; |
0b58b8a1 | 281 | |
df423a4a | 282 | _debug("alloc"); |
0b58b8a1 | 283 | |
b0f571ec DH |
284 | if (!rxrpc_check_tx_space(call, NULL)) |
285 | goto wait_for_space; | |
0b58b8a1 | 286 | |
d7d775b1 DH |
287 | /* Work out the maximum size of a packet. Assume that |
288 | * the security header is going to be in the padded | |
289 | * region (enc blocksize), but the trailer is not. | |
290 | */ | |
291 | remain = more ? INT_MAX : msg_data_left(msg); | |
292 | ret = call->conn->security->how_much_data(call, remain, | |
293 | &bufsize, &chunk, &offset); | |
294 | if (ret < 0) | |
295 | goto maybe_error; | |
0b58b8a1 | 296 | |
d7d775b1 | 297 | _debug("SIZE: %zu/%zu @%zu", chunk, bufsize, offset); |
0b58b8a1 | 298 | |
df423a4a | 299 | /* create a buffer that we can retain until it's ACK'd */ |
a4ea4c47 DH |
300 | ret = -ENOMEM; |
301 | txb = rxrpc_alloc_txbuf(call, RXRPC_PACKET_TYPE_DATA, | |
302 | GFP_KERNEL); | |
303 | if (!txb) | |
df423a4a | 304 | goto maybe_error; |
0b58b8a1 | 305 | |
a4ea4c47 DH |
306 | txb->offset = offset; |
307 | txb->space -= offset; | |
308 | txb->space = min_t(size_t, chunk, txb->space); | |
df423a4a | 309 | } |
0b58b8a1 | 310 | |
df423a4a | 311 | _debug("append"); |
0b58b8a1 | 312 | |
df423a4a DH |
313 | /* append next segment of data to the current buffer */ |
314 | if (msg_data_left(msg) > 0) { | |
a4ea4c47 DH |
315 | size_t copy = min_t(size_t, txb->space, msg_data_left(msg)); |
316 | ||
317 | _debug("add %zu", copy); | |
318 | if (!copy_from_iter_full(txb->data + txb->offset, copy, | |
319 | &msg->msg_iter)) | |
df423a4a | 320 | goto efault; |
a4ea4c47 DH |
321 | _debug("added"); |
322 | txb->space -= copy; | |
323 | txb->len += copy; | |
324 | txb->offset += copy; | |
df423a4a | 325 | copied += copy; |
e754eba6 DH |
326 | if (call->tx_total_len != -1) |
327 | call->tx_total_len -= copy; | |
0b58b8a1 DH |
328 | } |
329 | ||
e122d845 DH |
330 | /* check for the far side aborting the call or a network error |
331 | * occurring */ | |
332 | if (call->state == RXRPC_CALL_COMPLETE) | |
333 | goto call_terminated; | |
334 | ||
df423a4a | 335 | /* add the packet to the send queue if it's now full */ |
a4ea4c47 | 336 | if (!txb->space || |
df423a4a | 337 | (msg_data_left(msg) == 0 && !more)) { |
a4ea4c47 DH |
338 | if (msg_data_left(msg) == 0 && !more) { |
339 | txb->wire.flags |= RXRPC_LAST_PACKET; | |
340 | __set_bit(RXRPC_TXBUF_LAST, &txb->flags); | |
341 | } | |
342 | else if (call->tx_top - call->acks_hard_ack < | |
248f219c | 343 | call->tx_winsize) |
a4ea4c47 | 344 | txb->wire.flags |= RXRPC_MORE_PACKETS; |
0b58b8a1 | 345 | |
a4ea4c47 | 346 | ret = call->security->secure_packet(call, txb); |
df423a4a DH |
347 | if (ret < 0) |
348 | goto out; | |
0b58b8a1 | 349 | |
a4ea4c47 DH |
350 | rxrpc_queue_packet(rx, call, txb, notify_end_tx); |
351 | txb = NULL; | |
df423a4a DH |
352 | } |
353 | } while (msg_data_left(msg) > 0); | |
0b58b8a1 | 354 | |
df423a4a DH |
355 | success: |
356 | ret = copied; | |
4ba68c51 | 357 | if (READ_ONCE(call->state) == RXRPC_CALL_COMPLETE) { |
3dd9c8b5 | 358 | read_lock(&call->state_lock); |
4ba68c51 DH |
359 | if (call->error < 0) |
360 | ret = call->error; | |
3dd9c8b5 | 361 | read_unlock(&call->state_lock); |
4ba68c51 | 362 | } |
df423a4a | 363 | out: |
a4ea4c47 | 364 | call->tx_pending = txb; |
df423a4a DH |
365 | _leave(" = %d", ret); |
366 | return ret; | |
0b58b8a1 | 367 | |
e122d845 | 368 | call_terminated: |
a4ea4c47 | 369 | rxrpc_put_txbuf(txb, rxrpc_txbuf_put_send_aborted); |
e122d845 DH |
370 | _leave(" = %d", call->error); |
371 | return call->error; | |
372 | ||
df423a4a DH |
373 | maybe_error: |
374 | if (copied) | |
375 | goto success; | |
376 | goto out; | |
0b58b8a1 | 377 | |
df423a4a DH |
378 | efault: |
379 | ret = -EFAULT; | |
380 | goto out; | |
b0f571ec DH |
381 | |
382 | wait_for_space: | |
383 | ret = -EAGAIN; | |
384 | if (msg->msg_flags & MSG_DONTWAIT) | |
385 | goto maybe_error; | |
386 | mutex_unlock(&call->user_mutex); | |
387 | *_dropped_lock = true; | |
388 | ret = rxrpc_wait_for_tx_window(rx, call, &timeo, | |
389 | msg->msg_flags & MSG_WAITALL); | |
390 | if (ret < 0) | |
391 | goto maybe_error; | |
392 | if (call->interruptibility == RXRPC_INTERRUPTIBLE) { | |
393 | if (mutex_lock_interruptible(&call->user_mutex) < 0) { | |
394 | ret = sock_intr_errno(timeo); | |
395 | goto maybe_error; | |
396 | } | |
397 | } else { | |
398 | mutex_lock(&call->user_mutex); | |
399 | } | |
400 | *_dropped_lock = false; | |
401 | goto reload; | |
0b58b8a1 DH |
402 | } |
403 | ||
404 | /* | |
df423a4a | 405 | * extract control messages from the sendmsg() control buffer |
0b58b8a1 | 406 | */ |
3ab26a6f | 407 | static int rxrpc_sendmsg_cmsg(struct msghdr *msg, struct rxrpc_send_params *p) |
0b58b8a1 | 408 | { |
df423a4a DH |
409 | struct cmsghdr *cmsg; |
410 | bool got_user_ID = false; | |
411 | int len; | |
0b58b8a1 | 412 | |
df423a4a DH |
413 | if (msg->msg_controllen == 0) |
414 | return -EINVAL; | |
0b58b8a1 | 415 | |
df423a4a DH |
416 | for_each_cmsghdr(cmsg, msg) { |
417 | if (!CMSG_OK(msg, cmsg)) | |
418 | return -EINVAL; | |
0b58b8a1 | 419 | |
1ff8cebf | 420 | len = cmsg->cmsg_len - sizeof(struct cmsghdr); |
df423a4a DH |
421 | _debug("CMSG %d, %d, %d", |
422 | cmsg->cmsg_level, cmsg->cmsg_type, len); | |
0b58b8a1 | 423 | |
df423a4a DH |
424 | if (cmsg->cmsg_level != SOL_RXRPC) |
425 | continue; | |
0b58b8a1 | 426 | |
df423a4a DH |
427 | switch (cmsg->cmsg_type) { |
428 | case RXRPC_USER_CALL_ID: | |
429 | if (msg->msg_flags & MSG_CMSG_COMPAT) { | |
430 | if (len != sizeof(u32)) | |
431 | return -EINVAL; | |
48124178 | 432 | p->call.user_call_ID = *(u32 *)CMSG_DATA(cmsg); |
df423a4a DH |
433 | } else { |
434 | if (len != sizeof(unsigned long)) | |
435 | return -EINVAL; | |
48124178 | 436 | p->call.user_call_ID = *(unsigned long *) |
df423a4a DH |
437 | CMSG_DATA(cmsg); |
438 | } | |
df423a4a DH |
439 | got_user_ID = true; |
440 | break; | |
0b58b8a1 | 441 | |
df423a4a | 442 | case RXRPC_ABORT: |
3ab26a6f | 443 | if (p->command != RXRPC_CMD_SEND_DATA) |
df423a4a | 444 | return -EINVAL; |
3ab26a6f DH |
445 | p->command = RXRPC_CMD_SEND_ABORT; |
446 | if (len != sizeof(p->abort_code)) | |
df423a4a | 447 | return -EINVAL; |
3ab26a6f DH |
448 | p->abort_code = *(unsigned int *)CMSG_DATA(cmsg); |
449 | if (p->abort_code == 0) | |
df423a4a DH |
450 | return -EINVAL; |
451 | break; | |
0b58b8a1 | 452 | |
2d914c1b | 453 | case RXRPC_CHARGE_ACCEPT: |
3ab26a6f | 454 | if (p->command != RXRPC_CMD_SEND_DATA) |
df423a4a | 455 | return -EINVAL; |
2d914c1b | 456 | p->command = RXRPC_CMD_CHARGE_ACCEPT; |
df423a4a DH |
457 | if (len != 0) |
458 | return -EINVAL; | |
459 | break; | |
0b58b8a1 | 460 | |
df423a4a | 461 | case RXRPC_EXCLUSIVE_CALL: |
3ab26a6f | 462 | p->exclusive = true; |
df423a4a DH |
463 | if (len != 0) |
464 | return -EINVAL; | |
465 | break; | |
4e255721 DH |
466 | |
467 | case RXRPC_UPGRADE_SERVICE: | |
3ab26a6f | 468 | p->upgrade = true; |
4e255721 DH |
469 | if (len != 0) |
470 | return -EINVAL; | |
471 | break; | |
472 | ||
e754eba6 | 473 | case RXRPC_TX_LENGTH: |
48124178 | 474 | if (p->call.tx_total_len != -1 || len != sizeof(__s64)) |
e754eba6 | 475 | return -EINVAL; |
48124178 DH |
476 | p->call.tx_total_len = *(__s64 *)CMSG_DATA(cmsg); |
477 | if (p->call.tx_total_len < 0) | |
e754eba6 DH |
478 | return -EINVAL; |
479 | break; | |
480 | ||
a158bdd3 DH |
481 | case RXRPC_SET_CALL_TIMEOUT: |
482 | if (len & 3 || len < 4 || len > 12) | |
483 | return -EINVAL; | |
484 | memcpy(&p->call.timeouts, CMSG_DATA(cmsg), len); | |
485 | p->call.nr_timeouts = len / 4; | |
486 | if (p->call.timeouts.hard > INT_MAX / HZ) | |
487 | return -ERANGE; | |
488 | if (p->call.nr_timeouts >= 2 && p->call.timeouts.idle > 60 * 60 * 1000) | |
489 | return -ERANGE; | |
490 | if (p->call.nr_timeouts >= 3 && p->call.timeouts.normal > 60 * 60 * 1000) | |
491 | return -ERANGE; | |
492 | break; | |
493 | ||
df423a4a DH |
494 | default: |
495 | return -EINVAL; | |
496 | } | |
497 | } | |
0b58b8a1 | 498 | |
df423a4a DH |
499 | if (!got_user_ID) |
500 | return -EINVAL; | |
48124178 | 501 | if (p->call.tx_total_len != -1 && p->command != RXRPC_CMD_SEND_DATA) |
e754eba6 | 502 | return -EINVAL; |
df423a4a DH |
503 | _leave(" = 0"); |
504 | return 0; | |
505 | } | |
0b58b8a1 | 506 | |
df423a4a DH |
507 | /* |
508 | * Create a new client call for sendmsg(). | |
540b1c48 DH |
509 | * - Called with the socket lock held, which it must release. |
510 | * - If it returns a call, the call's lock will need releasing by the caller. | |
df423a4a DH |
511 | */ |
512 | static struct rxrpc_call * | |
513 | rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, | |
3ab26a6f | 514 | struct rxrpc_send_params *p) |
540b1c48 | 515 | __releases(&rx->sk.sk_lock.slock) |
88f2a825 | 516 | __acquires(&call->user_mutex) |
df423a4a DH |
517 | { |
518 | struct rxrpc_conn_parameters cp; | |
519 | struct rxrpc_call *call; | |
520 | struct key *key; | |
0b58b8a1 | 521 | |
df423a4a | 522 | DECLARE_SOCKADDR(struct sockaddr_rxrpc *, srx, msg->msg_name); |
0b58b8a1 | 523 | |
df423a4a | 524 | _enter(""); |
0b58b8a1 | 525 | |
540b1c48 DH |
526 | if (!msg->msg_name) { |
527 | release_sock(&rx->sk); | |
df423a4a | 528 | return ERR_PTR(-EDESTADDRREQ); |
540b1c48 | 529 | } |
0b58b8a1 | 530 | |
df423a4a DH |
531 | key = rx->key; |
532 | if (key && !rx->key->payload.data[0]) | |
533 | key = NULL; | |
0b58b8a1 | 534 | |
df423a4a DH |
535 | memset(&cp, 0, sizeof(cp)); |
536 | cp.local = rx->local; | |
537 | cp.key = rx->key; | |
538 | cp.security_level = rx->min_sec_level; | |
3ab26a6f DH |
539 | cp.exclusive = rx->exclusive | p->exclusive; |
540 | cp.upgrade = p->upgrade; | |
df423a4a | 541 | cp.service_id = srx->srx_service; |
a25e21f0 DH |
542 | call = rxrpc_new_client_call(rx, &cp, srx, &p->call, GFP_KERNEL, |
543 | atomic_inc_return(&rxrpc_debug_id)); | |
540b1c48 | 544 | /* The socket is now unlocked */ |
0b58b8a1 | 545 | |
47c810a7 | 546 | rxrpc_put_peer(cp.peer, rxrpc_peer_put_discard_tmp); |
df423a4a DH |
547 | _leave(" = %p\n", call); |
548 | return call; | |
549 | } | |
0b58b8a1 | 550 | |
df423a4a DH |
551 | /* |
552 | * send a message forming part of a client call through an RxRPC socket | |
553 | * - caller holds the socket locked | |
554 | * - the socket may be either a client socket or a server socket | |
555 | */ | |
556 | int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) | |
540b1c48 | 557 | __releases(&rx->sk.sk_lock.slock) |
df423a4a | 558 | { |
146d8fef | 559 | enum rxrpc_call_state state; |
df423a4a | 560 | struct rxrpc_call *call; |
a158bdd3 | 561 | unsigned long now, j; |
b0f571ec | 562 | bool dropped_lock = false; |
df423a4a | 563 | int ret; |
0b58b8a1 | 564 | |
3ab26a6f | 565 | struct rxrpc_send_params p = { |
48124178 DH |
566 | .call.tx_total_len = -1, |
567 | .call.user_call_ID = 0, | |
a158bdd3 | 568 | .call.nr_timeouts = 0, |
e138aa7d | 569 | .call.interruptibility = RXRPC_INTERRUPTIBLE, |
48124178 DH |
570 | .abort_code = 0, |
571 | .command = RXRPC_CMD_SEND_DATA, | |
572 | .exclusive = false, | |
573 | .upgrade = false, | |
3ab26a6f DH |
574 | }; |
575 | ||
df423a4a | 576 | _enter(""); |
0b58b8a1 | 577 | |
3ab26a6f | 578 | ret = rxrpc_sendmsg_cmsg(msg, &p); |
df423a4a | 579 | if (ret < 0) |
540b1c48 | 580 | goto error_release_sock; |
0b58b8a1 | 581 | |
2d914c1b | 582 | if (p.command == RXRPC_CMD_CHARGE_ACCEPT) { |
540b1c48 | 583 | ret = -EINVAL; |
df423a4a | 584 | if (rx->sk.sk_state != RXRPC_SERVER_LISTENING) |
540b1c48 | 585 | goto error_release_sock; |
2d914c1b DH |
586 | ret = rxrpc_user_charge_accept(rx, p.call.user_call_ID); |
587 | goto error_release_sock; | |
df423a4a | 588 | } |
0b58b8a1 | 589 | |
48124178 | 590 | call = rxrpc_find_call_by_user_ID(rx, p.call.user_call_ID); |
df423a4a | 591 | if (!call) { |
540b1c48 | 592 | ret = -EBADSLT; |
3ab26a6f | 593 | if (p.command != RXRPC_CMD_SEND_DATA) |
540b1c48 | 594 | goto error_release_sock; |
3ab26a6f | 595 | call = rxrpc_new_client_call_for_sendmsg(rx, msg, &p); |
540b1c48 | 596 | /* The socket is now unlocked... */ |
df423a4a DH |
597 | if (IS_ERR(call)) |
598 | return PTR_ERR(call); | |
540b1c48 | 599 | /* ... and we have the call lock. */ |
65550098 DH |
600 | ret = 0; |
601 | if (READ_ONCE(call->state) == RXRPC_CALL_COMPLETE) | |
602 | goto out_put_unlock; | |
540b1c48 | 603 | } else { |
146d8fef DH |
604 | switch (READ_ONCE(call->state)) { |
605 | case RXRPC_CALL_UNINITIALISED: | |
606 | case RXRPC_CALL_CLIENT_AWAIT_CONN: | |
607 | case RXRPC_CALL_SERVER_PREALLOC: | |
608 | case RXRPC_CALL_SERVER_SECURING: | |
cb0fc0c9 | 609 | rxrpc_put_call(call, rxrpc_call_put_sendmsg); |
146d8fef | 610 | ret = -EBUSY; |
37411cad | 611 | goto error_release_sock; |
146d8fef DH |
612 | default: |
613 | break; | |
614 | } | |
37411cad | 615 | |
540b1c48 DH |
616 | ret = mutex_lock_interruptible(&call->user_mutex); |
617 | release_sock(&rx->sk); | |
618 | if (ret < 0) { | |
619 | ret = -ERESTARTSYS; | |
620 | goto error_put; | |
621 | } | |
e754eba6 | 622 | |
48124178 | 623 | if (p.call.tx_total_len != -1) { |
e754eba6 DH |
624 | ret = -EINVAL; |
625 | if (call->tx_total_len != -1 || | |
626 | call->tx_pending || | |
627 | call->tx_top != 0) | |
628 | goto error_put; | |
48124178 | 629 | call->tx_total_len = p.call.tx_total_len; |
e754eba6 | 630 | } |
df423a4a | 631 | } |
0b58b8a1 | 632 | |
a158bdd3 DH |
633 | switch (p.call.nr_timeouts) { |
634 | case 3: | |
635 | j = msecs_to_jiffies(p.call.timeouts.normal); | |
636 | if (p.call.timeouts.normal > 0 && j == 0) | |
637 | j = 1; | |
638 | WRITE_ONCE(call->next_rx_timo, j); | |
df561f66 | 639 | fallthrough; |
a158bdd3 DH |
640 | case 2: |
641 | j = msecs_to_jiffies(p.call.timeouts.idle); | |
642 | if (p.call.timeouts.idle > 0 && j == 0) | |
643 | j = 1; | |
644 | WRITE_ONCE(call->next_req_timo, j); | |
df561f66 | 645 | fallthrough; |
a158bdd3 DH |
646 | case 1: |
647 | if (p.call.timeouts.hard > 0) { | |
648 | j = msecs_to_jiffies(p.call.timeouts.hard); | |
649 | now = jiffies; | |
650 | j += now; | |
651 | WRITE_ONCE(call->expect_term_by, j); | |
652 | rxrpc_reduce_call_timer(call, j, now, | |
653 | rxrpc_timer_set_for_hard); | |
654 | } | |
655 | break; | |
656 | } | |
657 | ||
146d8fef | 658 | state = READ_ONCE(call->state); |
df423a4a | 659 | _debug("CALL %d USR %lx ST %d on CONN %p", |
146d8fef | 660 | call->debug_id, call->user_call_ID, state, call->conn); |
0b58b8a1 | 661 | |
146d8fef | 662 | if (state >= RXRPC_CALL_COMPLETE) { |
df423a4a DH |
663 | /* it's too late for this call */ |
664 | ret = -ESHUTDOWN; | |
3ab26a6f | 665 | } else if (p.command == RXRPC_CMD_SEND_ABORT) { |
df423a4a | 666 | ret = 0; |
3ab26a6f | 667 | if (rxrpc_abort_call("CMD", call, 0, p.abort_code, -ECONNABORTED)) |
26cb02aa | 668 | ret = rxrpc_send_abort_packet(call); |
3ab26a6f | 669 | } else if (p.command != RXRPC_CMD_SEND_DATA) { |
df423a4a | 670 | ret = -EINVAL; |
df423a4a | 671 | } else { |
b0f571ec | 672 | ret = rxrpc_send_data(rx, call, msg, len, NULL, &dropped_lock); |
df423a4a | 673 | } |
0b58b8a1 | 674 | |
03a6c822 | 675 | out_put_unlock: |
b0f571ec DH |
676 | if (!dropped_lock) |
677 | mutex_unlock(&call->user_mutex); | |
540b1c48 | 678 | error_put: |
cb0fc0c9 | 679 | rxrpc_put_call(call, rxrpc_call_put_sendmsg); |
df423a4a DH |
680 | _leave(" = %d", ret); |
681 | return ret; | |
540b1c48 DH |
682 | |
683 | error_release_sock: | |
684 | release_sock(&rx->sk); | |
685 | return ret; | |
df423a4a | 686 | } |
0b58b8a1 | 687 | |
df423a4a DH |
688 | /** |
689 | * rxrpc_kernel_send_data - Allow a kernel service to send data on a call | |
690 | * @sock: The socket the call is on | |
691 | * @call: The call to send data through | |
692 | * @msg: The data to send | |
693 | * @len: The amount of data to send | |
e833251a | 694 | * @notify_end_tx: Notification that the last packet is queued. |
df423a4a DH |
695 | * |
696 | * Allow a kernel service to send data on a call. The call must be in an state | |
697 | * appropriate to sending data. No control data should be supplied in @msg, | |
698 | * nor should an address be supplied. MSG_MORE should be flagged if there's | |
699 | * more data to come, otherwise this data will end the transmission phase. | |
700 | */ | |
701 | int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, | |
e833251a DH |
702 | struct msghdr *msg, size_t len, |
703 | rxrpc_notify_end_tx_t notify_end_tx) | |
df423a4a | 704 | { |
b0f571ec | 705 | bool dropped_lock = false; |
df423a4a | 706 | int ret; |
0b58b8a1 | 707 | |
df423a4a | 708 | _enter("{%d,%s},", call->debug_id, rxrpc_call_states[call->state]); |
0b58b8a1 | 709 | |
df423a4a DH |
710 | ASSERTCMP(msg->msg_name, ==, NULL); |
711 | ASSERTCMP(msg->msg_control, ==, NULL); | |
0b58b8a1 | 712 | |
540b1c48 | 713 | mutex_lock(&call->user_mutex); |
0b58b8a1 | 714 | |
df423a4a DH |
715 | _debug("CALL %d USR %lx ST %d on CONN %p", |
716 | call->debug_id, call->user_call_ID, call->state, call->conn); | |
0b58b8a1 | 717 | |
146d8fef DH |
718 | switch (READ_ONCE(call->state)) { |
719 | case RXRPC_CALL_CLIENT_SEND_REQUEST: | |
720 | case RXRPC_CALL_SERVER_ACK_REQUEST: | |
721 | case RXRPC_CALL_SERVER_SEND_REPLY: | |
e833251a | 722 | ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len, |
b0f571ec | 723 | notify_end_tx, &dropped_lock); |
146d8fef DH |
724 | break; |
725 | case RXRPC_CALL_COMPLETE: | |
3dd9c8b5 | 726 | read_lock(&call->state_lock); |
bd2db2d2 | 727 | ret = call->error; |
3dd9c8b5 | 728 | read_unlock(&call->state_lock); |
146d8fef DH |
729 | break; |
730 | default: | |
fb46f6ee DH |
731 | /* Request phase complete for this client call */ |
732 | trace_rxrpc_rx_eproto(call, 0, tracepoint_string("late_send")); | |
146d8fef DH |
733 | ret = -EPROTO; |
734 | break; | |
df423a4a DH |
735 | } |
736 | ||
b0f571ec DH |
737 | if (!dropped_lock) |
738 | mutex_unlock(&call->user_mutex); | |
0b58b8a1 DH |
739 | _leave(" = %d", ret); |
740 | return ret; | |
df423a4a DH |
741 | } |
742 | EXPORT_SYMBOL(rxrpc_kernel_send_data); | |
0b58b8a1 | 743 | |
df423a4a DH |
744 | /** |
745 | * rxrpc_kernel_abort_call - Allow a kernel service to abort a call | |
746 | * @sock: The socket the call is on | |
747 | * @call: The call to be aborted | |
748 | * @abort_code: The abort code to stick into the ABORT packet | |
5a42976d DH |
749 | * @error: Local error value |
750 | * @why: 3-char string indicating why. | |
df423a4a | 751 | * |
84a4c09c DH |
752 | * Allow a kernel service to abort a call, if it's still in an abortable state |
753 | * and return true if the call was aborted, false if it was already complete. | |
df423a4a | 754 | */ |
84a4c09c | 755 | bool rxrpc_kernel_abort_call(struct socket *sock, struct rxrpc_call *call, |
5a42976d | 756 | u32 abort_code, int error, const char *why) |
df423a4a | 757 | { |
84a4c09c DH |
758 | bool aborted; |
759 | ||
5a42976d | 760 | _enter("{%d},%d,%d,%s", call->debug_id, abort_code, error, why); |
0b58b8a1 | 761 | |
540b1c48 | 762 | mutex_lock(&call->user_mutex); |
0b58b8a1 | 763 | |
84a4c09c DH |
764 | aborted = rxrpc_abort_call(why, call, 0, abort_code, error); |
765 | if (aborted) | |
26cb02aa | 766 | rxrpc_send_abort_packet(call); |
df423a4a | 767 | |
540b1c48 | 768 | mutex_unlock(&call->user_mutex); |
84a4c09c | 769 | return aborted; |
0b58b8a1 | 770 | } |
df423a4a | 771 | EXPORT_SYMBOL(rxrpc_kernel_abort_call); |
e754eba6 DH |
772 | |
773 | /** | |
774 | * rxrpc_kernel_set_tx_length - Set the total Tx length on a call | |
775 | * @sock: The socket the call is on | |
776 | * @call: The call to be informed | |
777 | * @tx_total_len: The amount of data to be transmitted for this call | |
778 | * | |
779 | * Allow a kernel service to set the total transmit length on a call. This | |
780 | * allows buffer-to-packet encrypt-and-copy to be performed. | |
781 | * | |
782 | * This function is primarily for use for setting the reply length since the | |
783 | * request length can be set when beginning the call. | |
784 | */ | |
785 | void rxrpc_kernel_set_tx_length(struct socket *sock, struct rxrpc_call *call, | |
786 | s64 tx_total_len) | |
787 | { | |
788 | WARN_ON(call->tx_total_len != -1); | |
789 | call->tx_total_len = tx_total_len; | |
790 | } | |
791 | EXPORT_SYMBOL(rxrpc_kernel_set_tx_length); |