@@ -32,6 +32,8 @@ struct rxrpc_abort_buffer {
3232 __be32 abort_code ;
3333};
3434
35+ static const char rxrpc_keepalive_string [] = "" ;
36+
3537/*
3638 * Arrange for a keepalive ping a certain time after we last transmitted. This
3739 * lets the far side know we're still interested in this call and helps keep
@@ -122,6 +124,7 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
122124 struct kvec iov [2 ];
123125 rxrpc_serial_t serial ;
124126 rxrpc_seq_t hard_ack , top ;
127+ ktime_t now ;
125128 size_t len , n ;
126129 int ret ;
127130 u8 reason ;
@@ -203,8 +206,10 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
203206 }
204207
205208 ret = kernel_sendmsg (conn -> params .local -> socket , & msg , iov , 2 , len );
209+ now = ktime_get_real ();
206210 if (ping )
207- call -> ping_time = ktime_get_real ();
211+ call -> ping_time = now ;
212+ conn -> params .peer -> last_tx_at = ktime_get_real ();
208213
209214 if (call -> state < RXRPC_CALL_COMPLETE ) {
210215 if (ret < 0 ) {
@@ -288,6 +293,7 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call)
288293
289294 ret = kernel_sendmsg (conn -> params .local -> socket ,
290295 & msg , iov , 1 , sizeof (pkt ));
296+ conn -> params .peer -> last_tx_at = ktime_get_real ();
291297
292298 rxrpc_put_connection (conn );
293299 return ret ;
@@ -378,6 +384,7 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
378384 * message and update the peer record
379385 */
380386 ret = kernel_sendmsg (conn -> params .local -> socket , & msg , iov , 2 , len );
387+ conn -> params .peer -> last_tx_at = ktime_get_real ();
381388
382389 up_read (& conn -> params .local -> defrag_sem );
383390 if (ret == - EMSGSIZE )
@@ -429,6 +436,7 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
429436 if (ret == 0 ) {
430437 ret = kernel_sendmsg (conn -> params .local -> socket , & msg ,
431438 iov , 2 , len );
439+ conn -> params .peer -> last_tx_at = ktime_get_real ();
432440
433441 opt = IP_PMTUDISC_DO ;
434442 kernel_setsockopt (conn -> params .local -> socket , SOL_IP ,
@@ -446,6 +454,7 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
446454 if (ret == 0 ) {
447455 ret = kernel_sendmsg (conn -> params .local -> socket , & msg ,
448456 iov , 2 , len );
457+ conn -> params .peer -> last_tx_at = ktime_get_real ();
449458
450459 opt = IPV6_PMTUDISC_DO ;
451460 kernel_setsockopt (conn -> params .local -> socket ,
@@ -515,3 +524,51 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
515524
516525 _leave ("" );
517526}
527+
528+ /*
529+ * Send a VERSION reply to a peer as a keepalive.
530+ */
531+ void rxrpc_send_keepalive (struct rxrpc_peer * peer )
532+ {
533+ struct rxrpc_wire_header whdr ;
534+ struct msghdr msg ;
535+ struct kvec iov [2 ];
536+ size_t len ;
537+ int ret ;
538+
539+ _enter ("" );
540+
541+ msg .msg_name = & peer -> srx .transport ;
542+ msg .msg_namelen = peer -> srx .transport_len ;
543+ msg .msg_control = NULL ;
544+ msg .msg_controllen = 0 ;
545+ msg .msg_flags = 0 ;
546+
547+ whdr .epoch = htonl (peer -> local -> rxnet -> epoch );
548+ whdr .cid = 0 ;
549+ whdr .callNumber = 0 ;
550+ whdr .seq = 0 ;
551+ whdr .serial = 0 ;
552+ whdr .type = RXRPC_PACKET_TYPE_VERSION ; /* Not client-initiated */
553+ whdr .flags = RXRPC_LAST_PACKET ;
554+ whdr .userStatus = 0 ;
555+ whdr .securityIndex = 0 ;
556+ whdr ._rsvd = 0 ;
557+ whdr .serviceId = 0 ;
558+
559+ iov [0 ].iov_base = & whdr ;
560+ iov [0 ].iov_len = sizeof (whdr );
561+ iov [1 ].iov_base = (char * )rxrpc_keepalive_string ;
562+ iov [1 ].iov_len = sizeof (rxrpc_keepalive_string );
563+
564+ len = iov [0 ].iov_len + iov [1 ].iov_len ;
565+
566+ _proto ("Tx VERSION (keepalive)" );
567+
568+ ret = kernel_sendmsg (peer -> local -> socket , & msg , iov , 2 , len );
569+ if (ret < 0 )
570+ _debug ("sendmsg failed: %d" , ret );
571+
572+ peer -> last_tx_at = ktime_get_real ();
573+ _leave ("" );
574+ }
0 commit comments