fn recv_pkt(&mut self, pkt: &mut VsockPacket, mem: &GuestMemoryMmap) -> VsockResult<()> {
        // We'll look for instructions on how to build the RX packet in the RX queue. If the
        // queue is empty, that doesn't necessarily mean we don't have any pending RX, since
        // the queue might be out-of-sync. If that's the case, we'll attempt to sync it first,
        // and then try to pop something out again.
        if self.rxq.is_empty() && !self.rxq.is_synced() {
            self.rxq = MuxerRxQ::from_conn_map(&self.conn_map);
        }

        while let Some(rx) = self.rxq.peek() {
            let res = match rx {
                // We need to build an RST packet, going from `local_port` to `peer_port`.
                MuxerRx::RstPkt {
                    local_port,
                    peer_port,
                } => {
                    pkt.set_op(uapi::VSOCK_OP_RST)
                        .set_src_cid(uapi::VSOCK_HOST_CID)
                        .set_dst_cid(self.cid)
                        .set_src_port(local_port)
                        .set_dst_port(peer_port)
                        .set_len(0)
                        .set_type(uapi::VSOCK_TYPE_STREAM)
                        .set_flags(0)
                        .set_buf_alloc(0)
                        .set_fwd_cnt(0);
                    self.rxq.pop().unwrap();
                    return Ok(());
                }

                // We'll defer building the packet to this connection, since it has something
                // to say.
                MuxerRx::ConnRx(key) => {
                    let mut conn_res = Err(VsockError::NoData);
                    let mut do_pop = true;
                    self.apply_conn_mutation(key, |conn| {
                        conn_res = conn.recv_pkt(pkt, mem);
                        do_pop = !conn.has_pending_rx();
                    });
                    if do_pop {
                        self.rxq.pop().unwrap();
                    }
                    conn_res
                }
            };

            if res.is_ok() {
                // Inspect traffic, looking for RST packets, since that means we have to
                // terminate and remove this connection from the active connection pool.
                //
                if pkt.op() == uapi::VSOCK_OP_RST {
                    self.remove_connection(ConnMapKey {
                        local_port: pkt.src_port(),
                        peer_port: pkt.dst_port(),
                    });
                }

                debug!("vsock muxer: RX pkt: {:?}", pkt.hdr());
                return Ok(());
            }
        }

        Err(VsockError::NoData)
    }
/// Deliver a vsock packet to the guest vsock driver.
///
/// Retuns:
/// - `Ok(())`: `pkt` has been successfully filled in; or
/// - `Err(VsockError::NoData)`: there was no available data with which to fill in the
///   packet.
Deliver a vsock packet to the guest vsock driver.
Deliver a vsock packet to the guest vsock driver .
fn recv_pkt(&mut self, pkt: &mut VsockPacket, mem: &GuestMemoryMmap) -> VsockResult<()> {
        // We'll look for instructions on how to build the RX packet in the RX queue. If the
        // queue is empty, that doesn't necessarily mean we don't have any pending RX, since
        // the queue might be out-of-sync. If that's the case, we'll attempt to sync it first,
        // and then try to pop something out again.
        if self.rxq.is_empty() && !self.rxq.is_synced() {
            self.rxq = MuxerRxQ::from_conn_map(&self.conn_map);
        }
        while let Some(rx) = self.rxq.peek() {
            let res = match rx {
                // We need to build an RST packet, going from `local_port` to `peer_port`.
                MuxerRx::RstPkt {
                    local_port,
                    peer_port,
                } => {
                    pkt.set_op(uapi::VSOCK_OP_RST)
                        .set_src_cid(uapi::VSOCK_HOST_CID)
                        .set_dst_cid(self.cid)
                        .set_src_port(local_port)
                        .set_dst_port(peer_port)
                        .set_len(0)
                        .set_type(uapi::VSOCK_TYPE_STREAM)
                        .set_flags(0)
                        .set_buf_alloc(0)
                        .set_fwd_cnt(0);
                    self.rxq.pop().unwrap();
                    return Ok(());
                }
                // We'll defer building the packet to this connection, since it has something
                // to say.
                MuxerRx::ConnRx(key) => {
                    let mut conn_res = Err(VsockError::NoData);
                    let mut do_pop = true;
                    self.apply_conn_mutation(key, |conn| {
                        conn_res = conn.recv_pkt(pkt, mem);
                        do_pop = !conn.has_pending_rx();
                    });
                    if do_pop {
                        self.rxq.pop().unwrap();
                    }
                    conn_res
                }
            };
            if res.is_ok() {
                // Inspect traffic, looking for RST packets, since that means we have to
                // terminate and remove this connection from the active connection pool.
                //
                if pkt.op() == uapi::VSOCK_OP_RST {
                    self.remove_connection(ConnMapKey {
                        local_port: pkt.src_port(),
                        peer_port: pkt.dst_port(),
                    });
                }
                debug!("vsock muxer: RX pkt: {:?}", pkt.hdr());
                return Ok(());
            }
        }
        Err(VsockError::NoData)
    }
fn recv_pkt ( & mut self , pkt : & mut VsockPacket , mem : & GuestMemoryMmap ) -> VsockResult < ( ) > { // We'll look for instructions on how to build the RX packet in the RX queue. If the // queue is empty, that doesn't necessarily mean we don't have any pending RX, since // the queue might be out-of-sync. If that's the case, we'll attempt to sync it first, // and then try to pop something out again. if self . rxq . is_empty ( ) && ! self . rxq . is_synced ( ) { self . rxq = MuxerRxQ :: from_conn_map ( & self . conn_map ) ; } while let Some ( rx ) = self . rxq . peek ( ) { let res = match rx { // We need to build an RST packet, going from `local_port` to `peer_port`. MuxerRx :: RstPkt { local_port , peer_port , } => { pkt . set_op ( uapi :: VSOCK_OP_RST ) . set_src_cid ( uapi :: VSOCK_HOST_CID ) . set_dst_cid ( self . cid ) . set_src_port ( local_port ) . set_dst_port ( peer_port ) . set_len ( 0 ) . set_type ( uapi :: VSOCK_TYPE_STREAM ) . set_flags ( 0 ) . set_buf_alloc ( 0 ) . set_fwd_cnt ( 0 ) ; self . rxq . pop ( ) . unwrap ( ) ; return Ok ( ( ) ) ; } // We'll defer building the packet to this connection, since it has something // to say. MuxerRx :: ConnRx ( key ) => { let mut conn_res = Err ( VsockError :: NoData ) ; let mut do_pop = true ; self . apply_conn_mutation ( key , | conn | { conn_res = conn . recv_pkt ( pkt , mem ) ; do_pop = ! conn . has_pending_rx ( ) ; } ) ; if do_pop { self . rxq . pop ( ) . unwrap ( ) ; } conn_res } } ; if res . is_ok ( ) { // Inspect traffic, looking for RST packets, since that means we have to // terminate and remove this connection from the active connection pool. // if pkt . op ( ) == uapi :: VSOCK_OP_RST { self . remove_connection ( ConnMapKey { local_port : pkt . src_port ( ) , peer_port : pkt . dst_port ( ) , } ) ; } debug ! ( " " pkt hdr ( ) ) ; return Ok ( ( ) ) ; } } Err ( VsockError :: NoData ) }
Deliver a vsock packet to the guest vsock driver.
Deliver a vsock packet to the guest vsock driver .
&mut self
pkt
&mut VsockPacket
mem
&GuestMemoryMmap
&mut self
pkt
&mut VsockPacket
mem
&GuestMemoryMmap