| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* connection-level event handling |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. |
|---|
| 4 | 5 | * Written by David Howells (dhowells@redhat.com) |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of the GNU General Public License |
|---|
| 8 | | - * as published by the Free Software Foundation; either version |
|---|
| 9 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 10 | 6 | */ |
|---|
| 11 | 7 | |
|---|
| 12 | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| .. | .. |
|---|
| 153 | 149 | * pass a connection-level abort onto all calls on that connection |
|---|
| 154 | 150 | */ |
|---|
| 155 | 151 | static void rxrpc_abort_calls(struct rxrpc_connection *conn, |
|---|
| 156 | | - enum rxrpc_call_completion compl) |
|---|
| 152 | + enum rxrpc_call_completion compl, |
|---|
| 153 | + rxrpc_serial_t serial) |
|---|
| 157 | 154 | { |
|---|
| 158 | 155 | struct rxrpc_call *call; |
|---|
| 159 | 156 | int i; |
|---|
| 160 | 157 | |
|---|
| 161 | 158 | _enter("{%d},%x", conn->debug_id, conn->abort_code); |
|---|
| 162 | 159 | |
|---|
| 163 | | - spin_lock(&conn->channel_lock); |
|---|
| 160 | + spin_lock(&conn->bundle->channel_lock); |
|---|
| 164 | 161 | |
|---|
| 165 | 162 | for (i = 0; i < RXRPC_MAXCALLS; i++) { |
|---|
| 166 | 163 | call = rcu_dereference_protected( |
|---|
| 167 | 164 | conn->channels[i].call, |
|---|
| 168 | | - lockdep_is_held(&conn->channel_lock)); |
|---|
| 165 | + lockdep_is_held(&conn->bundle->channel_lock)); |
|---|
| 169 | 166 | if (call) { |
|---|
| 170 | 167 | if (compl == RXRPC_CALL_LOCALLY_ABORTED) |
|---|
| 171 | 168 | trace_rxrpc_abort(call->debug_id, |
|---|
| .. | .. |
|---|
| 173 | 170 | call->call_id, 0, |
|---|
| 174 | 171 | conn->abort_code, |
|---|
| 175 | 172 | conn->error); |
|---|
| 176 | | - if (rxrpc_set_call_completion(call, compl, |
|---|
| 177 | | - conn->abort_code, |
|---|
| 178 | | - conn->error)) |
|---|
| 179 | | - rxrpc_notify_socket(call); |
|---|
| 173 | + else |
|---|
| 174 | + trace_rxrpc_rx_abort(call, serial, |
|---|
| 175 | + conn->abort_code); |
|---|
| 176 | + rxrpc_set_call_completion(call, compl, |
|---|
| 177 | + conn->abort_code, |
|---|
| 178 | + conn->error); |
|---|
| 180 | 179 | } |
|---|
| 181 | 180 | } |
|---|
| 182 | 181 | |
|---|
| 183 | | - spin_unlock(&conn->channel_lock); |
|---|
| 182 | + spin_unlock(&conn->bundle->channel_lock); |
|---|
| 184 | 183 | _leave(""); |
|---|
| 185 | 184 | } |
|---|
| 186 | 185 | |
|---|
| .. | .. |
|---|
| 211 | 210 | conn->error = error; |
|---|
| 212 | 211 | conn->abort_code = abort_code; |
|---|
| 213 | 212 | conn->state = RXRPC_CONN_LOCALLY_ABORTED; |
|---|
| 213 | + set_bit(RXRPC_CONN_DONT_REUSE, &conn->flags); |
|---|
| 214 | 214 | spin_unlock_bh(&conn->state_lock); |
|---|
| 215 | | - |
|---|
| 216 | | - rxrpc_abort_calls(conn, RXRPC_CALL_LOCALLY_ABORTED); |
|---|
| 217 | 215 | |
|---|
| 218 | 216 | msg.msg_name = &conn->params.peer->srx.transport; |
|---|
| 219 | 217 | msg.msg_namelen = conn->params.peer->srx.transport_len; |
|---|
| .. | .. |
|---|
| 242 | 240 | len = iov[0].iov_len + iov[1].iov_len; |
|---|
| 243 | 241 | |
|---|
| 244 | 242 | serial = atomic_inc_return(&conn->serial); |
|---|
| 243 | + rxrpc_abort_calls(conn, RXRPC_CALL_LOCALLY_ABORTED, serial); |
|---|
| 245 | 244 | whdr.serial = htonl(serial); |
|---|
| 246 | 245 | _proto("Tx CONN ABORT %%%u { %d }", serial, conn->abort_code); |
|---|
| 247 | 246 | |
|---|
| .. | .. |
|---|
| 271 | 270 | if (call) { |
|---|
| 272 | 271 | write_lock_bh(&call->state_lock); |
|---|
| 273 | 272 | if (call->state == RXRPC_CALL_SERVER_SECURING) { |
|---|
| 274 | | - call->state = RXRPC_CALL_SERVER_ACCEPTING; |
|---|
| 273 | + call->state = RXRPC_CALL_SERVER_RECV_REQUEST; |
|---|
| 275 | 274 | rxrpc_notify_socket(call); |
|---|
| 276 | 275 | } |
|---|
| 277 | 276 | write_unlock_bh(&call->state_lock); |
|---|
| .. | .. |
|---|
| 321 | 320 | conn->error = -ECONNABORTED; |
|---|
| 322 | 321 | conn->abort_code = abort_code; |
|---|
| 323 | 322 | conn->state = RXRPC_CONN_REMOTELY_ABORTED; |
|---|
| 324 | | - rxrpc_abort_calls(conn, RXRPC_CALL_REMOTELY_ABORTED); |
|---|
| 323 | + set_bit(RXRPC_CONN_DONT_REUSE, &conn->flags); |
|---|
| 324 | + rxrpc_abort_calls(conn, RXRPC_CALL_REMOTELY_ABORTED, sp->hdr.serial); |
|---|
| 325 | 325 | return -ECONNABORTED; |
|---|
| 326 | 326 | |
|---|
| 327 | 327 | case RXRPC_PACKET_TYPE_CHALLENGE: |
|---|
| .. | .. |
|---|
| 341 | 341 | if (ret < 0) |
|---|
| 342 | 342 | return ret; |
|---|
| 343 | 343 | |
|---|
| 344 | | - spin_lock(&conn->channel_lock); |
|---|
| 344 | + spin_lock(&conn->bundle->channel_lock); |
|---|
| 345 | 345 | spin_lock_bh(&conn->state_lock); |
|---|
| 346 | 346 | |
|---|
| 347 | 347 | if (conn->state == RXRPC_CONN_SERVICE_CHALLENGING) { |
|---|
| .. | .. |
|---|
| 351 | 351 | rxrpc_call_is_secure( |
|---|
| 352 | 352 | rcu_dereference_protected( |
|---|
| 353 | 353 | conn->channels[loop].call, |
|---|
| 354 | | - lockdep_is_held(&conn->channel_lock))); |
|---|
| 354 | + lockdep_is_held(&conn->bundle->channel_lock))); |
|---|
| 355 | 355 | } else { |
|---|
| 356 | 356 | spin_unlock_bh(&conn->state_lock); |
|---|
| 357 | 357 | } |
|---|
| 358 | 358 | |
|---|
| 359 | | - spin_unlock(&conn->channel_lock); |
|---|
| 359 | + spin_unlock(&conn->bundle->channel_lock); |
|---|
| 360 | 360 | return 0; |
|---|
| 361 | 361 | |
|---|
| 362 | 362 | default: |
|---|
| .. | .. |
|---|
| 377 | 377 | _enter("{%d}", conn->debug_id); |
|---|
| 378 | 378 | |
|---|
| 379 | 379 | ASSERT(conn->security_ix != 0); |
|---|
| 380 | | - |
|---|
| 381 | | - if (!conn->params.key) { |
|---|
| 382 | | - _debug("set up security"); |
|---|
| 383 | | - ret = rxrpc_init_server_conn_security(conn); |
|---|
| 384 | | - switch (ret) { |
|---|
| 385 | | - case 0: |
|---|
| 386 | | - break; |
|---|
| 387 | | - case -ENOENT: |
|---|
| 388 | | - abort_code = RX_CALL_DEAD; |
|---|
| 389 | | - goto abort; |
|---|
| 390 | | - default: |
|---|
| 391 | | - abort_code = RXKADNOAUTH; |
|---|
| 392 | | - goto abort; |
|---|
| 393 | | - } |
|---|
| 394 | | - } |
|---|
| 380 | + ASSERT(conn->server_key); |
|---|
| 395 | 381 | |
|---|
| 396 | 382 | if (conn->security->issue_challenge(conn) < 0) { |
|---|
| 397 | 383 | abort_code = RX_CALL_DEAD; |
|---|
| .. | .. |
|---|
| 411 | 397 | /* |
|---|
| 412 | 398 | * Process delayed final ACKs that we haven't subsumed into a subsequent call. |
|---|
| 413 | 399 | */ |
|---|
| 414 | | -static void rxrpc_process_delayed_final_acks(struct rxrpc_connection *conn) |
|---|
| 400 | +void rxrpc_process_delayed_final_acks(struct rxrpc_connection *conn, bool force) |
|---|
| 415 | 401 | { |
|---|
| 416 | 402 | unsigned long j = jiffies, next_j; |
|---|
| 417 | 403 | unsigned int channel; |
|---|
| .. | .. |
|---|
| 430 | 416 | smp_rmb(); /* vs rxrpc_disconnect_client_call */ |
|---|
| 431 | 417 | ack_at = READ_ONCE(chan->final_ack_at); |
|---|
| 432 | 418 | |
|---|
| 433 | | - if (time_before(j, ack_at)) { |
|---|
| 419 | + if (time_before(j, ack_at) && !force) { |
|---|
| 434 | 420 | if (time_before(ack_at, next_j)) { |
|---|
| 435 | 421 | next_j = ack_at; |
|---|
| 436 | 422 | set = true; |
|---|
| .. | .. |
|---|
| 464 | 450 | |
|---|
| 465 | 451 | /* Process delayed ACKs whose time has come. */ |
|---|
| 466 | 452 | if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK) |
|---|
| 467 | | - rxrpc_process_delayed_final_acks(conn); |
|---|
| 453 | + rxrpc_process_delayed_final_acks(conn, false); |
|---|
| 468 | 454 | |
|---|
| 469 | 455 | /* go through the conn-level event packets, releasing the ref on this |
|---|
| 470 | 456 | * connection that each one has when we've finished with it */ |
|---|
| 471 | 457 | while ((skb = skb_dequeue(&conn->rx_queue))) { |
|---|
| 472 | | - rxrpc_see_skb(skb, rxrpc_skb_rx_seen); |
|---|
| 458 | + rxrpc_see_skb(skb, rxrpc_skb_seen); |
|---|
| 473 | 459 | ret = rxrpc_process_event(conn, skb, &abort_code); |
|---|
| 474 | 460 | switch (ret) { |
|---|
| 475 | 461 | case -EPROTO: |
|---|
| .. | .. |
|---|
| 481 | 467 | goto requeue_and_leave; |
|---|
| 482 | 468 | case -ECONNABORTED: |
|---|
| 483 | 469 | default: |
|---|
| 484 | | - rxrpc_free_skb(skb, rxrpc_skb_rx_freed); |
|---|
| 470 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
|---|
| 485 | 471 | break; |
|---|
| 486 | 472 | } |
|---|
| 487 | 473 | } |
|---|
| .. | .. |
|---|
| 495 | 481 | protocol_error: |
|---|
| 496 | 482 | if (rxrpc_abort_connection(conn, ret, abort_code) < 0) |
|---|
| 497 | 483 | goto requeue_and_leave; |
|---|
| 498 | | - rxrpc_free_skb(skb, rxrpc_skb_rx_freed); |
|---|
| 484 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
|---|
| 499 | 485 | return; |
|---|
| 500 | 486 | } |
|---|
| 501 | 487 | |
|---|
| .. | .. |
|---|
| 515 | 501 | _leave(""); |
|---|
| 516 | 502 | return; |
|---|
| 517 | 503 | } |
|---|
| 518 | | - |
|---|