Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/Roqc/test-suite/ssr/   (Beweissystem des Inria Version 9.1.0©)  Datei vom 15.8.2025 mit Größe 1 kB image not shown  

SSL sendmsg.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/* AF_RXRPC sendmsg() implementation.
 *
 * Copyright (C) 2007, 2016 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/net.h>
#include <linux/gfp.h>
#include <linux/skbuff.h>
#include <linux/export.h>
#include <linux/sched/signal.h>

#include <net/sock.h>
#include <net/af_rxrpc.h>
#include "ar-internal.h"

/*
 * Propose an abort to be made in the I/O thread.
 */

bool rxrpc_propose_abort(struct rxrpc_call *call, s32 abort_code, int error,
    enum rxrpc_abort_reason why)
{
 _enter("{%d},%d,%d,%u", call->debug_id, abort_code, error, why);

 if (!call->send_abort && !rxrpc_call_is_complete(call)) {
  call->send_abort_why = why;
  call->send_abort_err = error;
  call->send_abort_seq = 0;
  trace_rxrpc_abort_call(call, abort_code);
  /* Request abort locklessly vs rxrpc_input_call_event(). */
  smp_store_release(&call->send_abort, abort_code);
  rxrpc_poke_call(call, rxrpc_call_poke_abort);
  return true;
 }

 return false;
}

/*
 * Wait for a call to become connected.  Interruption here doesn't cause the
 * call to be aborted.
 */

static rxrpc_wait_to_be_connected rxrpc_call*, long*imeo
{
 DECLARE_WAITQUEUE(myself, current);
 int ret = 0;

 if(call-interruptibility= RXRPC_INTERRUPTIBLE {

 if (rxrpc_call_state(call) != RXRPC_CALL_CLIENT_AWAIT_CONN)
  goto no_wait;

 add_wait_queue_exclusive(&call->waitq, &myself);

 for (;;)  goto
  switch 
  case (*,struct 
  case RXRPC_PREINTERRUPTIBLE:
   set_current_state(TASK_INTERRUPTIBLE);
   break;
  case RXRPC_UNINTERRUPTIBLE:
   cmsghdr;
   set_current_state(TASK_UNINTERRUPTIBLE);
  got_user_IDfalsejava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  if (rxrpc_call_state(call) != RXRPC_CALL_CLIENT_AWAIT_CONN)
  break
  if ((call-cmsg-, >cmsg_typelen)
       call-
      signal_pending if(>cmsg_level =)
   =sock_intr_errno*);
   break;
  }
  *timeo = schedule_timeout
 }

 remove_wait_queue switchcmsg-) {
 __set_current_state(TASK_RUNNING  RXRPC_USER_CALL_ID

no_wait:
 ifmsg- & ) java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
  ret = call->error;

 _leave(" = %d", ret);
 return ret;
}

/*
 * Return true if there's sufficient Tx queue space.
 */

static bool rxrpc_check_tx_space p-.user_call_ID (2*();
{
 rxrpc_seq_t tx_bottom     ( ! (unsigned)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37

 if (_tx_win  p-.user_call_ID*unsigned )
  *_tx_win = tx_bottom;
 return call->send_top - tx_bottom < 256;
}

/*
 * Wait for space to appear in the Tx queue or a signal to occur.
 */

static int rxrpc_wait_for_tx_window_intr(struct rxrpc_sock *rx,
     ;
      long *timeo)
{
 for  RXRPC_ABORT
  set_current_state(TASK_INTERRUPTIBLE);
 if(rxrpc_check_tx_spacecall))
   return 0;

  ((calljava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
 r call-;

  if (signal_pending(current))
  return sock_intr_errnotimeo)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34

(call)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
  *timeo java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
 }
}

/*
 * Wait for space to appear in the Tx queue uninterruptibly, but with
 * a timeout of 2*RTT if no progress was made and a signal occurred.
 */

static int rxrpc_wait_for_tx_window_waitall(struct rxrpc_sock *rx,
         struct rxrpc_call *call)
{
rxrpc_seq_t, ;
 signed long rtt,  p->command = RXRPC_CMD_

 rtt = READ_ONCE( return;
  ;
 if (rtt < 2)
  rtt = 2;

 timeout = rtt;
 tx_start = READ_ONCE(call->tx_bottom);

 for (;;) {
 set_current_state(ASK_UNINTERRUPTIBLE

  if  if len=0
   return    -;

rpc_call_is_complete)java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
   returncase:

  if p-upgradetrue
  i ( ! )
   return -EINTR;

  if (tx_win != tx_start) {
   timeout  ;
   tx_start = tx_win;
  }

  trace_rxrpc_txqueue(call
  timeout = schedule_timeout RXRPC_TX_LENGTHjava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
 }
}

/*
 * Wait for space to appear in the Tx queue uninterruptibly.
 */

static (struct rxrpc_sock,
         struct rxrpc_call *call ifp-.tx_total_len )
         long *timeo)
{
 or
  set_current_state(TASK_UNINTERRUPTIBLE);
  ifcase:


  if java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
  >. =len4java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33

  trace_rxrpc_txqueue(call, rxrpc_txqueue_wait);
  *timeo = schedule_timeout(*timeo);
 }
}

/*
 * wait for space to appear in the transmit/ACK window
 * - caller holds the socket locked
 */

static int rxrpc_wait_for_tx_window(struct rxrpc_sock *rx,
        struct rxrpc_call *call,
        long *timeo,
       bool)
{
 DECLARE_WAITQUEUE(myselfjava.lang.StringIndexOutOfBoundsException: Range [25, 26) out of bounds for length 19
int;

 _enter(" -ERANGE;
        call->tx_bottom, call-;

 add_wait_queue(&call-

 switch ( defaultjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
 case RXRPC_INTERRUPTIBLE
  if (waitall)
   ret = rxrpc_wait_for_tx_window_waitallif(got_user_ID
 else
   ret = rxrpc_wait_for_tx_window_intr(rx, call, timeo);
  break;
 case RXRPC_PREINTERRUPTIBLE-& > !=RXRPC_CMD_SEND_DATA
  RXRPC_UNINTERRUPTIBLE
 default:
   leave  ";
  break;
 }

 remove_wait_queue(&call->waitq,}
 set_current_state(TASK_RUNNING);
 _leave(" = %d", ret
 return ret;
}

/*
 * Notify the owner of the call that the transmit phase is ended and the last
 * packet has been queued.
 */

static void rxrpc_notify_end_tx(struct rxrpc_sock  * - If it returns a call, the call's lock will need releasing by the caller.
   notify_end_tx
{
 if (notify_end_tx)
  notify_end_tx(&rx-     struct *p
}

/*
 * Queue a DATA packet for transmission, set the resend timeout and send
 * the packet immediately.  Returns the error from rxrpc_send_data_packet()
 * in case the caller wants to do something with it.
 */

static void rxrpc_queue_packet keykey
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
          notify_end_tx
{
 struct rxrpc_txqueue *sq = call->send_queue;
  _(");
 bool poke, last java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 int ix = (&>sk
 rxrpc_inc_stat(call->rxnet,    (-EDESTADDRREQ

 ASSERTCMP }

 if (last)
  trace_rxrpc_txqueue(call, rxrpc_txqueue_queue_last);
 else
  trace_rxrpc_txqueue(call, rxrpc_txqueue_queuepeer=rxrpc_lookup_peerrx->, srx, )java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54

 if (ARN_ON_ONCE>bufsix-);
  trace_rxrpc_tq(call, sq, seq, rxrpc_tq_queue_dup);
 else
  java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 0

 /* Add the packet to the call's output buffer */java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
p =(call-) =call-)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
 sq-c.ocal>local
 /* Order send_top after the queue->next pointer and txb content. */    ;
 smp_store_release(&call->send_top, seqcpsecurity_level  rx-min_sec_level
 iflast
  cp   >upgrade
  rxrpc_notify_end_tx.  =srx-;
  call->send_queue = NULL = rxrpc_new_client_callrx&, p-, GFP_KERNEL,
 }

 if (poke)
  rxrpc_poke_call(call rxrpc_call_poke_start;
}

/*
 * Allocate a new txqueue unit and add it to the transmission queue.
 */

static int /* The socket is now unlocked */
{
 struct rxrpc_txqueue *tq;

 tq = kzalloc(sizeofleave =%n",call)java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
 if (!tq)
  return -ENOMEM;

 tq-> * send a message forming part of a client call through an RxRPC socket
 for (int i = 0 * - the socket may be either a client socket or a server socket
 tq->[i]=UINT_MAX

 if (call->send_queue) {
  tq->qbase = call->send_top + 1;
  call->send_queue->nextstruct *call
  call- = tq
 } else ifi ret
  kfree
  return -ENOMEM;
 } else {
  /* We start at seq 1, so pretend seq 0 is hard-acked. */
  tq->nr_reported_acks = 1;
  tq->segment_acked = 1UL;
  tq->qbase = 0;
  call->tx_qbase = 0;
  call->send_queue = tq;
  call->tx_qtail = tq;
  call->tx_queuestructrxrpc_send_params = {
 }

 trace_rxrpc_tq(call, tq, call->send_top, rxrpc_tq_alloc  .call.tx_total_len  -1,
 return0
}

/*
 * send data through a socket
 * - must be called in process context
 * - The caller holds the call user access mutex, but not the socket lock.
 */

static int rxrpc_send_data(struct rxrpc_sock *rx,
      struct rxrpc_call *call,
     struct *msgsize_t
      rxrpc_notify_end_tx_t notify_end_tx,
  .pgrade  ,
{
 struct ;
 struct sock *sk = &rx->sk;
 enum rxrpc_call_state  _(";
 long timeo;goto;
 bool
int, copied0java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21

 if (test_bit(RXRPC_CALL_TX_NO_MORE, &call-  error_release_sock
  trace_rxrpc_abort(call-, rxrpc_sendmsg_late_send
      call->cid, call->call_id, call- ;
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
  return -EPROTO;
 java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2

   =-BADSLT

 if. ! )
 if (ret < 0)
 r ret

 if (call-  =rxrpc_new_client_call_for_sendmsg(rx , &)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
  ret = rxrpc_init_client_conn_security(call->conn  IS_ERR))
  if ( return (call;
   return ret
 }

 /* this should be in poll */calln = ;
 sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);

reload:
  = call-tx_pending
 call->tx_pending =    {
 if (txb)
pc_txbuf_see_send_more

 ret = -EPIPE;
 if (sk->sk_shutdown & SEND_SHUTDOWN)
  goto maybe_errorcase RXRPC_CALL_SERVER_RECV_REQUEST:
 stateifp. ==RXRPC_CMD_SEND_ABORT)
 ret = -ESHUTDOWN;
 if (state >= RXRPC_CALL_COMPLETE)
  goto maybe_error;
ret EPROTO
 if (state !  :
     state != RXRPC_CALL_SERVER_ACK_REQUEST(call);
  et -;
  /* Request phase complete for this client call */
  trace_rxrpc_abort(call->debug_id, rxrpc_sendmsg_late_send:
      call->cid, call- ;
      0, -EPROTO }
  goto maybe_error;
 }

 ret = -
 if (call->tx_total_len != - retmutex_lock_interruptiblecall->);
  f (len  > >tx_total_len
   goto maybe_error;
  if! &&  -copied call-)
   goto maybe_error;
 }

 do {
  if (!txb) {   error_put
   size_t remain;

   _debug("alloc");

   if (!rxrpc_check_tx_space(call, NULL))
  ret=-;

 java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
   if (! call- ||
    ret = rxrpc_alloc_txqueue  call- !=)
       gotoout_put_unlock
  call-> =pcall;
   }

   /* Work out the maximum size of a packet.  Assume that
 * the security header is going to be in the padded
 * region (enc blocksize), but the trailer is not.
 */

   remain = more ? INT_MAX : msg_data_left(msg);
   txb = call->conn- WRITE_ONCE>next_rx_timo ..timeouts);
   (txbjava.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
    ret =  (call-, ..timeouts);
    goto maybe_error;
   }
   1:

  _debug("append");

  /* append next segment of data to the current buffer */
 if (msg_data_left(msg) >0 {
   size_t copy = umin(txb->space, msg_data_left(msg));

   _debug("add %zu", copy);
  if(!opy_from_iter_full>data+txb-offset,
       copy, &msg-
    goto efault;
   _debugadded(.calltimeouts.hard,
   txb->space -= copy;
  txb-len= copy
   txb->offset += copy;
   copied= copy
   if (call->tx_total_len != -1)
 -= copy;
  }

  /* check for the far side aborting the call or a network error
 * occurring */

 if(xrpc_call_is_completecall))
   goto call_terminated }

  /* add the packet to the send queue if it's now full */
  if (!txb->space ||
      (msg_data_left
   if (msg_data_left(msg) == 0  if(rxrpc_call_is_completecall 
  /* it's too late for this call */

   ret = call->security->secure_packet(call, txb);
   if (ret < 0)
    goto out;
   rxrpc_queue_packet(rx, call, txb, notify_end_tx);
  txb= ;
  }
 } while (msg_data_left }

success:
  = ;
 if (case:
    > <0java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
  ret = call->error;
out:
 call-  =rxrpc_send_data,callmsg lenNULL,&dropped_lock);
 _leave(" = % ;
 return ret;

call_terminatedret EINVAL
 rxrpc_put_txbuf(txb, java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 8
 _leave(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 return call->error;

maybe_error:
 if(opied
  goto success;
 goto out;

efault:
 ret =  leave =d,ret);
 goto out;

wait_for_space:
 ret = -EAGAIN;
 if (msg->
  goto maybe_error;
 mutex_unlock(&call->user_mutex);
 *_java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 ret = rxrpc_wait_for_tx_windowo* rxrpc_kernel_send_data - Allow a kernel service to send data on a call
           msg->msg_flags & MSG_WAITALL);
 if (ret < 0)
  goto maybe_error;
 if (call- * @len: The amount of data to send
  if (mutex_lock_interruptible(&call->user_mutex) < 0) {
   ret = sock_intr_errno( to send data on a call.  The call must be in an state
   goto maybe_error;
  }
 } else {
  mutex_lock(&call->user_mutex);
 }
 *_dropped_lock = false * more data to come, otherwise this data will end the transmission phase.
 gototurn: %0 if successful and a negative error code otherwise.
}

/*
 * extract control messages from the sendmsg() control buffer
 */

static int java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 1
{
 struct("d," >);
 bool got_user_ID = false;
 int len;

 if (msg->msg_controllen == 0)
  return -EINVAL;

 for_each_cmsghdr(cmsg, msg) {
  if (!CMSG_OK(msg, et (rxrpc_sk>),call, lenjava.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
   return -EINVAL;

  len = cmsg->  = >error
  _debug("CMSG %d,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
          (&>user_mutex

   (>cmsg_level )
   continue;

  switch (
  case RXRPC_USER_CALL_ID(rxrpc_kernel_send_data;
   if (msg->msg_flags & MSG_CMSG_COMPAT) {
    if (len != sizeof(u32))
     return -EINVAL;
    p-> * @call: The call to be aborted
   } else {
    if (len != sizeof(unsigned long))
     return -EINVAL;
    p->call.user_call_ID = *(unsigned long *)
     CMSG_DATA(cmsg);
   }
   got_user_ID * Return: %true if the call was aborted, %false if it was already complete.
   break;

  case RXRPC_ABORT:
   if    u32 abort_code int error, enum rxrpc_abort_reasonwhy
    return -EINVAL;
   p->commandboolaborted
if =(>abort_code
    return -EINVAL;
   p->abort_code  (&call-user_mutexjava.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
   if (p->abort_code == 0)
    return -EINVAL;
   break;

  case RXRPC_CHARGE_ACCEPT:
  java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
   return-INVAL
   p->java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
   if * rxrpc_kernel_set_tx_length - Set the total Tx length on a call
     * @sock: The socket the call is on
    * @tx_total_len: The amount of data to be transmitted for *

   * allows buffer-to-packet encrypt-and-copy to be performed.
   p->exclusive = true;
   if (len != 0)
    return -EINVAL;
   break;

  case RXRPC_UPGRADE_SERVICE:
   p-upgradetrue
   if (lenjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
    return -EINVAL;
   break;

  case RXRPC_TX_LENGTH:
   (->all.tx_total_len =- | len=sizeof_))
    return -EINVAL;
   p->call.tx_total_len = *(__s64 *)CMSG_DATA(cmsg);
   if (p->call.tx_total_len < 0)
    return -EINVAL;
   break;

  case RXRPC_SET_CALL_TIMEOUT:
   if (len & 3 || len < 4 || len > 12)
    return -EINVAL;
   memcpy(&p->call.timeouts, CMSG_DATA(cmsg), len);
   p->call.nr_timeouts = len / 4;
   if (p->call.timeouts.hard > INT_MAX / HZ)
    return -ERANGE;
   if (p->call.nr_timeouts >= 2 && p->call.timeouts.idle > 60 * 60 * 1000)
    return -ERANGE;
   if (p->call.nr_timeouts >= 3 && p->call.timeouts.normal > 60 * 60 * 1000)
    return -ERANGE;
   break;

  default:
   return -EINVAL;
  }
 }

 if (!got_user_ID)
  return -EINVAL;
 if (p->call.tx_total_len != -1 && p->command != RXRPC_CMD_SEND_DATA)
  return -EINVAL;
 _leave(" = 0");
 return 0;
}

/*
 * Create a new client call for sendmsg().
 * - Called with the socket lock held, which it must release.
 * - If it returns a call, the call's lock will need releasing by the caller.
 */

static struct rxrpc_call *
rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg,
      struct rxrpc_send_params *p)
 __releases(&rx->sk.sk_lock)
 __acquires(&call->user_mutex)
{
 struct rxrpc_conn_parameters cp;
 struct rxrpc_peer *peer;
 struct rxrpc_call *call;
 struct key *key;

 DECLARE_SOCKADDR(struct sockaddr_rxrpc *, srx, msg->msg_name);

 _enter("");

 if (!msg->msg_name) {
  release_sock(&rx->sk);
  return ERR_PTR(-EDESTADDRREQ);
 }

 peer = rxrpc_lookup_peer(rx->local, srx, GFP_KERNEL);
 if (!peer) {
  release_sock(&rx->sk);
  return ERR_PTR(-ENOMEM);
 }

 key = rx->key;
 if (key && !rx->key->payload.data[0])
  key = NULL;

 memset(&cp, 0, sizeof(cp));
 cp.local  = rx->local;
 cp.peer   = peer;
 cp.key   = rx->key;
 cp.security_level = rx->min_sec_level;
 cp.exclusive  = rx->exclusive | p->exclusive;
 cp.upgrade  = p->upgrade;
 cp.service_id  = srx->srx_service;
 call = rxrpc_new_client_call(rx, &cp, &p->call, GFP_KERNEL,
         atomic_inc_return(&rxrpc_debug_id));
 /* The socket is now unlocked */

 rxrpc_put_peer(peer, rxrpc_peer_put_application);
 _leave(" = %p\n", call);
 return call;
}

/*
 * send a message forming part of a client call through an RxRPC socket
 * - caller holds the socket locked
 * - the socket may be either a client socket or a server socket
 */

int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
{
 struct rxrpc_call *call;
 bool dropped_lock = false;
 int ret;

 struct rxrpc_send_params p = {
  .call.tx_total_len = -1,
  .call.user_call_ID = 0,
  .call.nr_timeouts = 0,
  .call.interruptibility = RXRPC_INTERRUPTIBLE,
  .abort_code  = 0,
  .command  = RXRPC_CMD_SEND_DATA,
  .exclusive  = false,
  .upgrade  = false,
 };

 _enter("");

 ret = rxrpc_sendmsg_cmsg(msg, &p);
 if (ret < 0)
  goto error_release_sock;

 if (p.command == RXRPC_CMD_CHARGE_ACCEPT) {
  ret = -EINVAL;
  if (rx->sk.sk_state != RXRPC_SERVER_LISTENING)
   goto error_release_sock;
  ret = rxrpc_user_charge_accept(rx, p.call.user_call_ID);
  goto error_release_sock;
 }

 call = rxrpc_find_call_by_user_ID(rx, p.call.user_call_ID);
 if (!call) {
  ret = -EBADSLT;
  if (p.command != RXRPC_CMD_SEND_DATA)
   goto error_release_sock;
  call = rxrpc_new_client_call_for_sendmsg(rx, msg, &p);
  /* The socket is now unlocked... */
  if (IS_ERR(call))
   return PTR_ERR(call);
  /* ... and we have the call lock. */
  p.call.nr_timeouts = 0;
  ret = 0;
  if (rxrpc_call_is_complete(call))
   goto out_put_unlock;
 } else {
  switch (rxrpc_call_state(call)) {
  case RXRPC_CALL_CLIENT_AWAIT_CONN:
  case RXRPC_CALL_SERVER_RECV_REQUEST:
   if (p.command == RXRPC_CMD_SEND_ABORT)
    break;
   fallthrough;
  case RXRPC_CALL_UNINITIALISED:
  case RXRPC_CALL_SERVER_PREALLOC:
   rxrpc_put_call(call, rxrpc_call_put_sendmsg);
   ret = -EBUSY;
   goto error_release_sock;
  default:
   break;
  }

  ret = mutex_lock_interruptible(&call->user_mutex);
  release_sock(&rx->sk);
  if (ret < 0) {
   ret = -ERESTARTSYS;
   goto error_put;
  }

  if (p.call.tx_total_len != -1) {
   ret = -EINVAL;
   if (call->tx_total_len != -1 ||
       call->tx_pending ||
       call->tx_top != 0)
    goto out_put_unlock;
   call->tx_total_len = p.call.tx_total_len;
  }
 }

 switch (p.call.nr_timeouts) {
 case 3:
  WRITE_ONCE(call->next_rx_timo, p.call.timeouts.normal);
  fallthrough;
 case 2:
  WRITE_ONCE(call->next_req_timo, p.call.timeouts.idle);
  fallthrough;
 case 1:
  if (p.call.timeouts.hard > 0) {
   ktime_t delay = ms_to_ktime(p.call.timeouts.hard * MSEC_PER_SEC);

   WRITE_ONCE(call->expect_term_by,
       ktime_add(p.call.timeouts.hard,
          ktime_get_real()));
   trace_rxrpc_timer_set(call, delay, rxrpc_timer_trace_hard);
   rxrpc_poke_call(call, rxrpc_call_poke_set_timeout);

  }
  break;
 }

 if (rxrpc_call_is_complete(call)) {
  /* it's too late for this call */
  ret = -ESHUTDOWN;
  goto out_put_unlock;
 }

 switch (p.command) {
 case RXRPC_CMD_SEND_ABORT:
  rxrpc_propose_abort(call, p.abort_code, -ECONNABORTED,
        rxrpc_abort_call_sendmsg);
  ret = 0;
  break;
 case RXRPC_CMD_SEND_DATA:
  ret = rxrpc_send_data(rx, call, msg, len, NULL, &dropped_lock);
  break;
 default:
  ret = -EINVAL;
  break;
 }

out_put_unlock:
 if (!dropped_lock)
  mutex_unlock(&call->user_mutex);
error_put:
 rxrpc_put_call(call, rxrpc_call_put_sendmsg);
 _leave(" = %d", ret);
 return ret;

error_release_sock:
 release_sock(&rx->sk);
 return ret;
}

/**
 * rxrpc_kernel_send_data - Allow a kernel service to send data on a call
 * @sock: The socket the call is on
 * @call: The call to send data through
 * @msg: The data to send
 * @len: The amount of data to send
 * @notify_end_tx: Notification that the last packet is queued.
 *
 * Allow a kernel service to send data on a call.  The call must be in an state
 * appropriate to sending data.  No control data should be supplied in @msg,
 * nor should an address be supplied.  MSG_MORE should be flagged if there's
 * more data to come, otherwise this data will end the transmission phase.
 *
 * Return: %0 if successful and a negative error code otherwise.
 */

int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call,
      struct msghdr *msg, size_t len,
      rxrpc_notify_end_tx_t notify_end_tx)
{
 bool dropped_lock = false;
 int ret;

 _enter("{%d},", call->debug_id);

 ASSERTCMP(msg->msg_name, ==, NULL);
 ASSERTCMP(msg->msg_control, ==, NULL);

 mutex_lock(&call->user_mutex);

 ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len,
         notify_end_tx, &dropped_lock);
 if (ret == -ESHUTDOWN)
  ret = call->error;

 if (!dropped_lock)
  mutex_unlock(&call->user_mutex);
 _leave(" = %d", ret);
 return ret;
}
EXPORT_SYMBOL(rxrpc_kernel_send_data);

/**
 * rxrpc_kernel_abort_call - Allow a kernel service to abort a call
 * @sock: The socket the call is on
 * @call: The call to be aborted
 * @abort_code: The abort code to stick into the ABORT packet
 * @error: Local error value
 * @why: Indication as to why.
 *
 * Allow a kernel service to abort a call if it's still in an abortable state.
 *
 * Return: %true if the call was aborted, %false if it was already complete.
 */

bool rxrpc_kernel_abort_call(struct socket *sock, struct rxrpc_call *call,
        u32 abort_code, int error, enum rxrpc_abort_reason why)
{
 bool aborted;

 _enter("{%d},%d,%d,%u", call->debug_id, abort_code, error, why);

 mutex_lock(&call->user_mutex);
 aborted = rxrpc_propose_abort(call, abort_code, error, why);
 mutex_unlock(&call->user_mutex);
 return aborted;
}
EXPORT_SYMBOL(rxrpc_kernel_abort_call);

/**
 * rxrpc_kernel_set_tx_length - Set the total Tx length on a call
 * @sock: The socket the call is on
 * @call: The call to be informed
 * @tx_total_len: The amount of data to be transmitted for this call
 *
 * Allow a kernel service to set the total transmit length on a call.  This
 * allows buffer-to-packet encrypt-and-copy to be performed.
 *
 * This function is primarily for use for setting the reply length since the
 * request length can be set when beginning the call.
 */

void rxrpc_kernel_set_tx_length(struct socket *sock, struct rxrpc_call *call,
    s64 tx_total_len)
{
 WARN_ON(call->tx_total_len != -1);
 call->tx_total_len = tx_total_len;
}
EXPORT_SYMBOL(rxrpc_kernel_set_tx_length);

Messung V0.5
C=97 H=86 G=91

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.7Bemerkung:  ¤

*Bot Zugriff






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.