fn send_pkt(&mut self, pkt: &VsockPacket, mem: &GuestMemoryMmap) -> VsockResult<()> {
        // Update the peer credit information.
        self.peer_buf_alloc = pkt.buf_alloc();
        self.peer_fwd_cnt = Wrapping(pkt.fwd_cnt());
        METRICS.vsock.tx_packets_count.inc();

        match self.state {
            // Most frequent case: this is an established connection that needs to forward some
            // data to the host stream. Also works for a connection that has begun shutting
            // down, but the peer still has some data to send.
            ConnState::Established | ConnState::PeerClosed(_, false)
                if pkt.op() == uapi::VSOCK_OP_RW =>
            {
                if pkt.buf_size() == 0 {
                    info!(
                        "vsock: dropping empty data packet from guest (lp={}, pp={}",
                        self.local_port, self.peer_port
                    );
                    return Ok(());
                }

                // Unwrapping here is safe, since we just checked `pkt.buf()` above.
                if let Err(err) = self.send_bytes(mem, &pkt) {
                    // If we can't write to the host stream, that's an unrecoverable error, so
                    // we'll terminate this connection.
                    warn!(
                        "vsock: error writing to local stream (lp={}, pp={}): {:?}",
                        self.local_port, self.peer_port, err
                    );
                    self.kill();
                    return Ok(());
                }

                // We might've just consumed some data. If that's the case, we might need to
                // update the peer on our buffer space situation, so that it can keep sending
                // data packets our way.
                if self.peer_needs_credit_update() {
                    self.pending_rx.insert(PendingRx::CreditUpdate);
                }
            }

            // Next up: receiving a response / confirmation for a host-initiated connection.
            // We'll move to an Established state, and pass on the good news through the host
            // stream.
            ConnState::LocalInit if pkt.op() == uapi::VSOCK_OP_RESPONSE => {
                self.expiry = None;
                self.state = ConnState::Established;
            }

            // The peer wants to shut down an established connection.  If they have nothing
            // more to send nor receive, and we don't have to wait to drain our TX buffer, we
            // can schedule an RST packet (to terminate the connection on the next recv call).
            // Otherwise, we'll arm the kill timer.
            ConnState::Established if pkt.op() == uapi::VSOCK_OP_SHUTDOWN => {
                let recv_off = pkt.flags() & uapi::VSOCK_FLAGS_SHUTDOWN_RCV != 0;
                let send_off = pkt.flags() & uapi::VSOCK_FLAGS_SHUTDOWN_SEND != 0;
                self.state = ConnState::PeerClosed(recv_off, send_off);
                if recv_off && send_off {
                    if self.tx_buf.is_empty() {
                        self.pending_rx.insert(PendingRx::Rst);
                    } else {
                        self.expiry = Some(
                            Instant::now() + Duration::from_millis(defs::CONN_SHUTDOWN_TIMEOUT_MS),
                        );
                    }
                }
            }

            // The peer wants to update a shutdown request, with more receive/send indications.
            // The same logic as above applies.
            ConnState::PeerClosed(ref mut recv_off, ref mut send_off)
                if pkt.op() == uapi::VSOCK_OP_SHUTDOWN =>
            {
                *recv_off = *recv_off || (pkt.flags() & uapi::VSOCK_FLAGS_SHUTDOWN_RCV != 0);
                *send_off = *send_off || (pkt.flags() & uapi::VSOCK_FLAGS_SHUTDOWN_SEND != 0);
                if *recv_off && *send_off && self.tx_buf.is_empty() {
                    self.pending_rx.insert(PendingRx::Rst);
                }
            }

            // A credit update from our peer is valid only in a state which allows data
            // transfer towards the peer.
            ConnState::Established | ConnState::PeerInit | ConnState::PeerClosed(false, _)
                if pkt.op() == uapi::VSOCK_OP_CREDIT_UPDATE =>
            {
                // Nothing to do here; we've already updated peer credit.
            }

            // A credit request from our peer is valid only in a state which allows data
            // transfer from the peer. We'll respond with a credit update packet.
            ConnState::Established | ConnState::PeerInit | ConnState::PeerClosed(_, false)
                if pkt.op() == uapi::VSOCK_OP_CREDIT_REQUEST =>
            {
                self.pending_rx.insert(PendingRx::CreditUpdate);
            }

            _ => {
                debug!(
                    "vsock: dropping invalid TX pkt for connection: state={:?}, pkt.hdr={:?}",
                    self.state,
                    pkt.hdr()
                );
            }
        };

        Ok(())
    }
/// Deliver a guest-generated packet to this connection.
///
/// This forwards the data in RW packets to the host stream, and absorbs control packets,
/// using them to manage the internal connection state.
///
/// Returns:
/// always `Ok(())`: the packet has been consumed;
Deliver a guest-generated packet to this connection.
This forwards the data in RW packets to the host stream, and absorbs control packets,
using them to manage the internal connection state.

always `Ok(())`: the packet has been consumed.
Deliver a guest - generated packet to this connection . This forwards the data in RW packets to the host stream and absorbs control packets using them to manage the internal connection state . always ` Ok (( )) ` : the packet has been consumed .
fn send_pkt(&mut self, pkt: &VsockPacket, mem: &GuestMemoryMmap) -> VsockResult<()> {
        // Update the peer credit information.
        self.peer_buf_alloc = pkt.buf_alloc();
        self.peer_fwd_cnt = Wrapping(pkt.fwd_cnt());
        METRICS.vsock.tx_packets_count.inc();
        match self.state {
            // Most frequent case: this is an established connection that needs to forward some
            // data to the host stream. Also works for a connection that has begun shutting
            // down, but the peer still has some data to send.
            ConnState::Established | ConnState::PeerClosed(_, false)
                if pkt.op() == uapi::VSOCK_OP_RW =>
            {
                if pkt.buf_size() == 0 {
                    info!(
                        "vsock: dropping empty data packet from guest (lp={}, pp={}",
                        self.local_port, self.peer_port
                    );
                    return Ok(());
                }
                // Unwrapping here is safe, since we just checked `pkt.buf()` above.
                if let Err(err) = self.send_bytes(mem, &pkt) {
                    // If we can't write to the host stream, that's an unrecoverable error, so
                    // we'll terminate this connection.
                    warn!(
                        "vsock: error writing to local stream (lp={}, pp={}): {:?}",
                        self.local_port, self.peer_port, err
                    );
                    self.kill();
                    return Ok(());
                }
                // We might've just consumed some data. If that's the case, we might need to
                // update the peer on our buffer space situation, so that it can keep sending
                // data packets our way.
                if self.peer_needs_credit_update() {
                    self.pending_rx.insert(PendingRx::CreditUpdate);
                }
            }
            // Next up: receiving a response / confirmation for a host-initiated connection.
            // We'll move to an Established state, and pass on the good news through the host
            // stream.
            ConnState::LocalInit if pkt.op() == uapi::VSOCK_OP_RESPONSE => {
                self.expiry = None;
                self.state = ConnState::Established;
            }
            // The peer wants to shut down an established connection.  If they have nothing
            // more to send nor receive, and we don't have to wait to drain our TX buffer, we
            // can schedule an RST packet (to terminate the connection on the next recv call).
            // Otherwise, we'll arm the kill timer.
            ConnState::Established if pkt.op() == uapi::VSOCK_OP_SHUTDOWN => {
                let recv_off = pkt.flags() & uapi::VSOCK_FLAGS_SHUTDOWN_RCV != 0;
                let send_off = pkt.flags() & uapi::VSOCK_FLAGS_SHUTDOWN_SEND != 0;
                self.state = ConnState::PeerClosed(recv_off, send_off);
                if recv_off && send_off {
                    if self.tx_buf.is_empty() {
                        self.pending_rx.insert(PendingRx::Rst);
                    } else {
                        self.expiry = Some(
                            Instant::now() + Duration::from_millis(defs::CONN_SHUTDOWN_TIMEOUT_MS),
                        );
                    }
                }
            }
            // The peer wants to update a shutdown request, with more receive/send indications.
            // The same logic as above applies.
            ConnState::PeerClosed(ref mut recv_off, ref mut send_off)
                if pkt.op() == uapi::VSOCK_OP_SHUTDOWN =>
            {
                *recv_off = *recv_off || (pkt.flags() & uapi::VSOCK_FLAGS_SHUTDOWN_RCV != 0);
                *send_off = *send_off || (pkt.flags() & uapi::VSOCK_FLAGS_SHUTDOWN_SEND != 0);
                if *recv_off && *send_off && self.tx_buf.is_empty() {
                    self.pending_rx.insert(PendingRx::Rst);
                }
            }
            // A credit update from our peer is valid only in a state which allows data
            // transfer towards the peer.
            ConnState::Established | ConnState::PeerInit | ConnState::PeerClosed(false, _)
                if pkt.op() == uapi::VSOCK_OP_CREDIT_UPDATE =>
            {
                // Nothing to do here; we've already updated peer credit.
            }
            // A credit request from our peer is valid only in a state which allows data
            // transfer from the peer. We'll respond with a credit update packet.
            ConnState::Established | ConnState::PeerInit | ConnState::PeerClosed(_, false)
                if pkt.op() == uapi::VSOCK_OP_CREDIT_REQUEST =>
            {
                self.pending_rx.insert(PendingRx::CreditUpdate);
            }
            _ => {
                debug!(
                    "vsock: dropping invalid TX pkt for connection: state={:?}, pkt.hdr={:?}",
                    self.state,
                    pkt.hdr()
                );
            }
        };
        Ok(())
    }
fn send_pkt ( & mut self , pkt : & VsockPacket , mem : & GuestMemoryMmap ) -> VsockResult < ( ) > { // Update the peer credit information. self . peer_buf_alloc = pkt . buf_alloc ( ) ; self . peer_fwd_cnt = Wrapping ( pkt . fwd_cnt ( ) ) ; METRICS . vsock . tx_packets_count . inc ( ) ; match self . state { // Most frequent case: this is an established connection that needs to forward some // data to the host stream. Also works for a connection that has begun shutting // down, but the peer still has some data to send. ConnState :: Established | ConnState :: PeerClosed ( _ , false ) if pkt . op ( ) == uapi :: VSOCK_OP_RW => { if pkt . buf_size ( ) == 0 { info ! ( " " self local_port self peer_port ) ; return Ok ( ( ) ) ; } // Unwrapping here is safe, since we just checked `pkt.buf()` above. if let Err ( err ) = self . send_bytes ( mem , & pkt ) { // If we can't write to the host stream, that's an unrecoverable error, so // we'll terminate this connection. warn ! ( " " self local_port self peer_port err ) ; self . kill ( ) ; return Ok ( ( ) ) ; } // We might've just consumed some data. If that's the case, we might need to // update the peer on our buffer space situation, so that it can keep sending // data packets our way. if self . peer_needs_credit_update ( ) { self . pending_rx . insert ( PendingRx :: CreditUpdate ) ; } } // Next up: receiving a response / confirmation for a host-initiated connection. // We'll move to an Established state, and pass on the good news through the host // stream. ConnState :: LocalInit if pkt . op ( ) == uapi :: VSOCK_OP_RESPONSE => { self . expiry = None ; self . state = ConnState :: Established ; } // The peer wants to shut down an established connection.  If they have nothing // more to send nor receive, and we don't have to wait to drain our TX buffer, we // can schedule an RST packet (to terminate the connection on the next recv call). // Otherwise, we'll arm the kill timer. ConnState :: Established if pkt . op ( ) == uapi :: VSOCK_OP_SHUTDOWN => { let recv_off = pkt . flags ( ) & uapi :: VSOCK_FLAGS_SHUTDOWN_RCV != 0 ; let send_off = pkt . flags ( ) & uapi :: VSOCK_FLAGS_SHUTDOWN_SEND != 0 ; self . state = ConnState :: PeerClosed ( recv_off , send_off ) ; if recv_off && send_off { if self . tx_buf . is_empty ( ) { self . pending_rx . insert ( PendingRx :: Rst ) ; } else { self . expiry = Some ( Instant :: now ( ) + Duration :: from_millis ( defs :: CONN_SHUTDOWN_TIMEOUT_MS ) , ) ; } } } // The peer wants to update a shutdown request, with more receive/send indications. // The same logic as above applies. ConnState :: PeerClosed ( ref mut recv_off , ref mut send_off ) if pkt . op ( ) == uapi :: VSOCK_OP_SHUTDOWN => { * recv_off = * recv_off || ( pkt . flags ( ) & uapi :: VSOCK_FLAGS_SHUTDOWN_RCV != 0 ) ; * send_off = * send_off || ( pkt . flags ( ) & uapi :: VSOCK_FLAGS_SHUTDOWN_SEND != 0 ) ; if * recv_off && * send_off && self . tx_buf . is_empty ( ) { self . pending_rx . insert ( PendingRx :: Rst ) ; } } // A credit update from our peer is valid only in a state which allows data // transfer towards the peer. ConnState :: Established | ConnState :: PeerInit | ConnState :: PeerClosed ( false , _ ) if pkt . op ( ) == uapi :: VSOCK_OP_CREDIT_UPDATE => { // Nothing to do here; we've already updated peer credit. } // A credit request from our peer is valid only in a state which allows data // transfer from the peer. We'll respond with a credit update packet. ConnState :: Established | ConnState :: PeerInit | ConnState :: PeerClosed ( _ , false ) if pkt . op ( ) == uapi :: VSOCK_OP_CREDIT_REQUEST => { self . pending_rx . insert ( PendingRx :: CreditUpdate ) ; } _ => { debug ! ( " " self state pkt hdr ( ) ) ; } } ; Ok ( ( ) ) }
Deliver a guest-generated packet to this connection.
Deliver a guest - generated packet to this connection .
&mut self
pkt
&VsockPacket
mem
&GuestMemoryMmap
&mut self
pkt
&VsockPacket
mem
&GuestMemoryMmap