pub fn write_next_packet(
        &mut self,
        buf: &mut [u8],
    ) -> Result<(Option<NonZeroUsize>, WriteEvent), WriteNextError> {
        let mut len = None;
        let mut writer_status = None;
        let mut event = WriteEvent::Nothing;

        // Write an incomplete Ipv4 packet and complete it afterwards with missing information.
        let mut packet =
            IPv4Packet::write_header(buf, PROTOCOL_TCP, Ipv4Addr::LOCALHOST, Ipv4Addr::LOCALHOST)
                .map_err(WriteNextError::IPv4Packet)?;

        // We set mss_used to 0, because we don't add any IP options.
        // TODO: Maybe get this nicely from packet at some point.
        let mss_reserved = 0;

        // We prioritize sending RSTs for now. The 10000 value for window size is just an arbitrary
        // number, and using mss_remaining = 0 is perfectly fine in this case, because we don't add
        // any TCP options, or a payload.
        if let Some((tuple, rst_cfg)) = self.rst_queue.pop() {
            let (seq, ack, flags_after_ns) = rst_cfg.seq_ack_tcp_flags();
            let segment_len = TcpSegment::write_incomplete_segment::<[u8]>(
                packet.inner_mut().payload_mut(),
                seq,
                ack,
                flags_after_ns,
                10000,
                None,
                0,
                None,
            )
            .map_err(WriteNextError::TcpSegment)?
            .finalize(
                self.local_port,
                tuple.remote_port,
                Some((self.local_ipv4_addr, tuple.remote_addr)),
            )
            .len();

            packet
                .inner_mut()
                .set_source_address(self.local_ipv4_addr)
                .set_destination_address(tuple.remote_addr);

            let packet_len = packet.with_payload_len_unchecked(segment_len, true).len();
            // The unwrap() is safe because packet_len > 0.
            return Ok((
                Some(NonZeroUsize::new(packet_len).unwrap()),
                WriteEvent::Nothing,
            ));
        }

        for tuple in self
            .active_connections
            .iter()
            .chain(self.next_timeout.as_ref().map(|(_, x)| x))
        {
            // Tuples in self.active_connection or self.next_timeout should also appear as keys
            // in self.connections.
            let endpoint = self.connections.get_mut(tuple).unwrap();
            // We need this block to clearly delimit the lifetime of the mutable borrow started by
            // the following packet.inner_mut().
            let segment_len = {
                let maybe_segment =
                    endpoint.write_next_segment(packet.inner_mut().payload_mut(), mss_reserved);

                match maybe_segment {
                    Some(segment) => segment
                        .finalize(
                            self.local_port,
                            tuple.remote_port,
                            Some((self.local_ipv4_addr, tuple.remote_addr)),
                        )
                        .len(),
                    None => continue,
                }
            };

            packet
                .inner_mut()
                .set_source_address(self.local_ipv4_addr)
                .set_destination_address(tuple.remote_addr);

            let ip_len = packet.with_payload_len_unchecked(segment_len, true).len();

            // The unwrap is safe because ip_len > 0.
            len = Some(NonZeroUsize::new(ip_len).unwrap());
            writer_status = Some((*tuple, endpoint.is_done()));

            break;
        }

        if let Some((tuple, is_done)) = writer_status {
            if is_done {
                self.remove_connection(tuple);
                event = WriteEvent::EndpointDone;
            } else {
                // The unwrap is safe because tuple is present as a key in self.connections if we
                // got here.
                let status = self.connections[&tuple].next_segment_status();
                if !self.check_next_segment_status(tuple, status) {
                    self.active_connections.remove(&tuple);
                }
            }
        }

        Ok((len, event))
    }
/// Attempts to write one packet, from either the `RST` queue or one of the existing endpoints,
/// to `buf`.
///
/// On success, the function returns a pair containing an `Option<NonZeroUsize>` and a
/// `WriteEvent`. The options represents how many bytes have been written to `buf`, or
/// that no packet can be send presently (when equal to `None`). The `WriteEvent` describes
/// whether any noteworthy state changes are associated with the write.
Attempts to write one packet, from either the `RST` queue or one of the existing endpoints,
to `buf`.

On success, the function returns a pair containing an `Option` and a
`WriteEvent`. The options represents how many bytes have been written to `buf`, or
that no packet can be send presently (when equal to `None`). The `WriteEvent` describes
whether any noteworthy state changes are associated with the write.
Attempts to write one packet from either the ` RST ` queue or one of the existing endpoints to ` buf ` . On success the function returns a pair containing an ` Option ` and a ` WriteEvent ` . The options represents how many bytes have been written to ` buf ` or that no packet can be send presently ( when equal to ` None ` ) . The ` WriteEvent ` describes whether any noteworthy state changes are associated with the write .
pub fn write_next_packet(
        &mut self,
        buf: &mut [u8],
    ) -> Result<(Option<NonZeroUsize>, WriteEvent), WriteNextError> {
        let mut len = None;
        let mut writer_status = None;
        let mut event = WriteEvent::Nothing;
        // Write an incomplete Ipv4 packet and complete it afterwards with missing information.
        let mut packet =
            IPv4Packet::write_header(buf, PROTOCOL_TCP, Ipv4Addr::LOCALHOST, Ipv4Addr::LOCALHOST)
                .map_err(WriteNextError::IPv4Packet)?;
        // We set mss_used to 0, because we don't add any IP options.
        // TODO: Maybe get this nicely from packet at some point.
        let mss_reserved = 0;
        // We prioritize sending RSTs for now. The 10000 value for window size is just an arbitrary
        // number, and using mss_remaining = 0 is perfectly fine in this case, because we don't add
        // any TCP options, or a payload.
        if let Some((tuple, rst_cfg)) = self.rst_queue.pop() {
            let (seq, ack, flags_after_ns) = rst_cfg.seq_ack_tcp_flags();
            let segment_len = TcpSegment::write_incomplete_segment::<[u8]>(
                packet.inner_mut().payload_mut(),
                seq,
                ack,
                flags_after_ns,
                10000,
                None,
                0,
                None,
            )
            .map_err(WriteNextError::TcpSegment)?
            .finalize(
                self.local_port,
                tuple.remote_port,
                Some((self.local_ipv4_addr, tuple.remote_addr)),
            )
            .len();
            packet
                .inner_mut()
                .set_source_address(self.local_ipv4_addr)
                .set_destination_address(tuple.remote_addr);
            let packet_len = packet.with_payload_len_unchecked(segment_len, true).len();
            // The unwrap() is safe because packet_len > 0.
            return Ok((
                Some(NonZeroUsize::new(packet_len).unwrap()),
                WriteEvent::Nothing,
            ));
        }
        for tuple in self
            .active_connections
            .iter()
            .chain(self.next_timeout.as_ref().map(|(_, x)| x))
        {
            // Tuples in self.active_connection or self.next_timeout should also appear as keys
            // in self.connections.
            let endpoint = self.connections.get_mut(tuple).unwrap();
            // We need this block to clearly delimit the lifetime of the mutable borrow started by
            // the following packet.inner_mut().
            let segment_len = {
                let maybe_segment =
                    endpoint.write_next_segment(packet.inner_mut().payload_mut(), mss_reserved);
                match maybe_segment {
                    Some(segment) => segment
                        .finalize(
                            self.local_port,
                            tuple.remote_port,
                            Some((self.local_ipv4_addr, tuple.remote_addr)),
                        )
                        .len(),
                    None => continue,
                }
            };
            packet
                .inner_mut()
                .set_source_address(self.local_ipv4_addr)
                .set_destination_address(tuple.remote_addr);
            let ip_len = packet.with_payload_len_unchecked(segment_len, true).len();
            // The unwrap is safe because ip_len > 0.
            len = Some(NonZeroUsize::new(ip_len).unwrap());
            writer_status = Some((*tuple, endpoint.is_done()));
            break;
        }
        if let Some((tuple, is_done)) = writer_status {
            if is_done {
                self.remove_connection(tuple);
                event = WriteEvent::EndpointDone;
            } else {
                // The unwrap is safe because tuple is present as a key in self.connections if we
                // got here.
                let status = self.connections[&tuple].next_segment_status();
                if !self.check_next_segment_status(tuple, status) {
                    self.active_connections.remove(&tuple);
                }
            }
        }
        Ok((len, event))
    }
pub fn write_next_packet ( & mut self , buf : & mut [ u8 ] , ) -> Result < ( Option < NonZeroUsize > , WriteEvent ) , WriteNextError > { let mut len = None ; let mut writer_status = None ; let mut event = WriteEvent :: Nothing ; // Write an incomplete Ipv4 packet and complete it afterwards with missing information. let mut packet = IPv4Packet :: write_header ( buf , PROTOCOL_TCP , Ipv4Addr :: LOCALHOST , Ipv4Addr :: LOCALHOST ) . map_err ( WriteNextError :: IPv4Packet ) ? ; // We set mss_used to 0, because we don't add any IP options. // TODO: Maybe get this nicely from packet at some point. let mss_reserved = 0 ; // We prioritize sending RSTs for now. The 10000 value for window size is just an arbitrary // number, and using mss_remaining = 0 is perfectly fine in this case, because we don't add // any TCP options, or a payload. if let Some ( ( tuple , rst_cfg ) ) = self . rst_queue . pop ( ) { let ( seq , ack , flags_after_ns ) = rst_cfg . seq_ack_tcp_flags ( ) ; let segment_len = TcpSegment :: write_incomplete_segment :: < [ u8 ] > ( packet . inner_mut ( ) . payload_mut ( ) , seq , ack , flags_after_ns , 10000 , None , 0 , None , ) . map_err ( WriteNextError :: TcpSegment ) ? . finalize ( self . local_port , tuple . remote_port , Some ( ( self . local_ipv4_addr , tuple . remote_addr ) ) , ) . len ( ) ; packet . inner_mut ( ) . set_source_address ( self . local_ipv4_addr ) . set_destination_address ( tuple . remote_addr ) ; let packet_len = packet . with_payload_len_unchecked ( segment_len , true ) . len ( ) ; // The unwrap() is safe because packet_len > 0. return Ok ( ( Some ( NonZeroUsize :: new ( packet_len ) . unwrap ( ) ) , WriteEvent :: Nothing , ) ) ; } for tuple in self . active_connections . iter ( ) . chain ( self . next_timeout . as_ref ( ) . map ( | ( _ , x ) | x ) ) { // Tuples in self.active_connection or self.next_timeout should also appear as keys // in self.connections. let endpoint = self . connections . get_mut ( tuple ) . unwrap ( ) ; // We need this block to clearly delimit the lifetime of the mutable borrow started by // the following packet.inner_mut(). let segment_len = { let maybe_segment = endpoint . write_next_segment ( packet . inner_mut ( ) . payload_mut ( ) , mss_reserved ) ; match maybe_segment { Some ( segment ) => segment . finalize ( self . local_port , tuple . remote_port , Some ( ( self . local_ipv4_addr , tuple . remote_addr ) ) , ) . len ( ) , None => continue , } } ; packet . inner_mut ( ) . set_source_address ( self . local_ipv4_addr ) . set_destination_address ( tuple . remote_addr ) ; let ip_len = packet . with_payload_len_unchecked ( segment_len , true ) . len ( ) ; // The unwrap is safe because ip_len > 0. len = Some ( NonZeroUsize :: new ( ip_len ) . unwrap ( ) ) ; writer_status = Some ( ( * tuple , endpoint . is_done ( ) ) ) ; break ; } if let Some ( ( tuple , is_done ) ) = writer_status { if is_done { self . remove_connection ( tuple ) ; event = WriteEvent :: EndpointDone ; } else { // The unwrap is safe because tuple is present as a key in self.connections if we // got here. let status = self . connections [ & tuple ] . next_segment_status ( ) ; if ! self . check_next_segment_status ( tuple , status ) { self . active_connections . remove ( & tuple ) ; } } } Ok ( ( len , event ) ) }
Attempts to write one packet, from either the `RST` queue or one of the existing endpoints,
to `buf`.
Attempts to write one packet from either the ` RST ` queue or one of the existing endpoints to ` buf ` .
&mut self
buf
&mut [u8]
&mut self
buf
&mut [u8]