Skip to content

Commit c54e43d

Browse files
committed
rxrpc: Fix missing start of call timeout
The expect_rx_by call timeout is supposed to be set when a call is started to indicate that we need to receive a packet by that point. This is currently put back every time we receive a packet, but it isn't started when we first send a packet. Without this, the call may wait forever if the server doesn't deign to reply. Fix this by setting the timeout upon a successful UDP sendmsg call for the first DATA packet. The timeout is initiated only for initial transmission and not for subsequent retries as we don't want the retry mechanism to extend the timeout indefinitely. Fixes: a158bdd ("rxrpc: Fix call timeouts") Reported-by: Marc Dionne <[email protected]> Signed-off-by: David Howells <[email protected]>
1 parent 4a026da commit c54e43d

File tree

4 files changed

+23
-1
lines changed

4 files changed

+23
-1
lines changed

net/rxrpc/ar-internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ enum rxrpc_call_flag {
476476
RXRPC_CALL_SEND_PING, /* A ping will need to be sent */
477477
RXRPC_CALL_PINGING, /* Ping in process */
478478
RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */
479+
RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */
479480
};
480481

481482
/*

net/rxrpc/input.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call,
971971
if (timo) {
972972
unsigned long now = jiffies, expect_rx_by;
973973

974-
expect_rx_by = jiffies + timo;
974+
expect_rx_by = now + timo;
975975
WRITE_ONCE(call->expect_rx_by, expect_rx_by);
976976
rxrpc_reduce_call_timer(call, expect_rx_by, now,
977977
rxrpc_timer_set_for_normal);

net/rxrpc/output.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,17 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
414414
rxrpc_timer_set_for_lost_ack);
415415
}
416416
}
417+
418+
if (sp->hdr.seq == 1 &&
419+
!test_and_set_bit(RXRPC_CALL_BEGAN_RX_TIMER,
420+
&call->flags)) {
421+
unsigned long nowj = jiffies, expect_rx_by;
422+
423+
expect_rx_by = nowj + call->next_rx_timo;
424+
WRITE_ONCE(call->expect_rx_by, expect_rx_by);
425+
rxrpc_reduce_call_timer(call, expect_rx_by, nowj,
426+
rxrpc_timer_set_for_normal);
427+
}
417428
}
418429

419430
rxrpc_set_keepalive(call);

net/rxrpc/sendmsg.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,15 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
223223

224224
ret = rxrpc_send_data_packet(call, skb, false);
225225
if (ret < 0) {
226+
switch (ret) {
227+
case -ENETUNREACH:
228+
case -EHOSTUNREACH:
229+
case -ECONNREFUSED:
230+
rxrpc_set_call_completion(call,
231+
RXRPC_CALL_LOCAL_ERROR,
232+
0, ret);
233+
goto out;
234+
}
226235
_debug("need instant resend %d", ret);
227236
rxrpc_instant_resend(call, ix);
228237
} else {
@@ -241,6 +250,7 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
241250
rxrpc_timer_set_for_send);
242251
}
243252

253+
out:
244254
rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
245255
_leave("");
246256
}

0 commit comments

Comments
 (0)