pub fn write_next_segment<'a, R: ByteBuffer + ?Sized>(
        &mut self,
        buf: &'a mut [u8],
        mss_reserved: u16,
        payload_src: PayloadSource<R>,
        now: u64,
    ) -> Result<Option<Incomplete<TcpSegment<'a, &'a mut [u8]>>>, WriteNextError> {
        // TODO: like receive_segment(), this function is specific in some ways to Connections
        // created via passive open. When/if we also implement active opens, some things will
        // have to change.

        if self.is_reset() {
            return Err(WriteNextError::ConnectionReset);
        }

        if self.send_rst.is_some() {
            // A RST is pending. Try to write it, and change the state of the connection to reset
            // if successfull.
            let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
            self.set_flags(ConnStatusFlags::RESET);
            return Ok(Some(segment));
        }

        // The first thing we have to do is reply with a SYNACK if needed.
        if self.synack_pending() {
            let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
            self.set_flags(ConnStatusFlags::SYNACK_SENT);
            self.rto_start = now;
            return Ok(Some(segment));
        }

        // Resend a SYNACK if the RTO expired. Otherwise, no reason to continue until the connection
        // becomes ESTABLISHED.
        if !self.is_established() {
            if self.rto_expired(now) {
                // If we exceeded the maximum retransmission count, reset the connection and call
                // write_next_segment one more time to generate the RST.
                self.rto_count += 1;
                if self.rto_count >= self.rto_count_max {
                    self.reset();
                    return self.write_next_segment(buf, mss_reserved, payload_src, now);
                }
                let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
                self.rto_start = now;
                return Ok(Some(segment));
            }
            return Ok(None);
        }

        // First, try sending a data segment, because we can piggy back ACKs and FINs on top of it.
        if let Some((read_buf, payload_seq)) = payload_src {
            // Limit the size of read_buf so it doesn't mess up later calculations (as usual, I take
            // the easy way out).
            if read_buf.len() > MAX_WINDOW_SIZE as usize {
                return Err(WriteNextError::PayloadBufTooLarge);
            }

            let payload_end = payload_seq + Wrapping(read_buf.len() as u32);

            let mut rto_triggered = false;

            // Decide what sequence number to send next. Check out if a timeout expired first.
            let seq_to_send =
                if self.highest_ack_received != self.first_not_sent && self.rto_expired(now) {
                    self.rto_count += 1;
                    if self.rto_count >= self.rto_count_max {
                        self.reset();
                        return self.write_next_segment(buf, mss_reserved, payload_src, now);
                    }

                    if let Some(fin_seq) = self.send_fin {
                        if self.highest_ack_received == fin_seq {
                            // We're in the relatively unlikely situation where our FIN got lost.
                            // Simply calling write_control_segment() will retransmit it.
                            let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
                            self.rto_start = now;
                            return Ok(Some(segment));
                        }
                    }

                    // We have to remember this is a retransmission for later.
                    rto_triggered = true;
                    self.highest_ack_received
                } else if self.dup_ack {
                    // We retransmit an older segment if a DUPACK is recorded. We'll clear
                    // self.dup_ack after we make sure the segment has been successfully written.
                    self.highest_ack_received
                } else {
                    // Otherwise, we send some data (if possible) starting with the first byte not
                    // yet sent.
                    self.first_not_sent
                };

            // The payload buffer begins after the first sequence number we are trying to send
            // (or the payload_seq is totally off).
            if !seq_at_or_after(seq_to_send, payload_seq) {
                return Err(WriteNextError::PayloadMissingSeq);
            }

            // We can only send data if it's within both the send buffer and the remote rwnd, and
            // before the sequence number of the local FIN (if the connection is closing).
            let actual_end = if seq_at_or_after(self.remote_rwnd_edge, payload_end) {
                payload_end
            } else {
                self.remote_rwnd_edge
            };

            // Make sure we're not trying to send data past the FIN sequence we previously
            // announced.
            if let Some(fin_seq) = self.send_fin {
                if seq_after(actual_end, fin_seq) {
                    return Err(WriteNextError::DataAfterFin);
                }
            }

            // We only proceed with writing a data segment if the previously computed bounds
            // delimit a valid sequence number interval.
            if seq_after(actual_end, seq_to_send) {
                let max_payload_len = (actual_end - seq_to_send).0 as usize;

                // We always set the ACK flag for data segments.
                let tcp_flags = TcpFlags::ACK;

                let ack_to_send = self.ack_to_send;
                let mut segment = self.write_segment(
                    buf,
                    mss_reserved,
                    seq_to_send,
                    ack_to_send,
                    tcp_flags,
                    Some((read_buf, max_payload_len)),
                )?;

                // If self.dup_ack was Some(_), we've just written the retransmission segment,
                // either directly or via the RTO timer expiring.
                self.dup_ack = false;

                let payload_len = segment.inner().payload().len();
                let mut first_seq_after = seq_to_send + Wrapping(payload_len as u32);

                if let Some(fin_seq) = self.send_fin {
                    if first_seq_after == fin_seq {
                        // This segment contains the last bytes of data we're going to send, so
                        // we should also set the FIN flag.
                        segment
                            .inner_mut()
                            .set_flags_after_ns(tcp_flags | TcpFlags::FIN);

                        // The FIN takes up 1 sequence number.
                        first_seq_after += Wrapping(1);
                        // The main purpose of knowing we sent at least one FIN is to signal that
                        // we already added 1 to self.first_not_sent, to account for its sequence
                        // number.
                        self.set_flags(ConnStatusFlags::FIN_SENT);
                    }
                }

                if rto_triggered || self.first_not_sent == self.highest_ack_received {
                    // Reset the RTO "timer" after each retransmission, or after sending the first
                    // unacknowledged segment in the current window.
                    self.rto_start = now;
                }

                if seq_after(first_seq_after, self.first_not_sent) {
                    self.first_not_sent = first_seq_after;
                }

                return Ok(Some(segment));
            }
        }

        // At this point, we only send a control segment if there's a pending ACK, or we didn't send
        // a FIN segment before and we would be sending the first one.

        // The FIN flag will be automatically added to the segment when necessary by the
        // write_control_segment() method.
        let send_first_fin = self.can_send_first_fin();
        if self.pending_ack || send_first_fin {
            let segment = self.write_control_segment::<R>(buf, mss_reserved)?;

            if send_first_fin {
                self.first_not_sent += Wrapping(1);
                self.set_flags(ConnStatusFlags::FIN_SENT);
            }

            return Ok(Some(segment));
        }

        Ok(None)
    }
/// Writes a new segment (if available) to the specified buffer.
///
/// The `payload_src` argument is required because the `Connection` does not have an internal
/// send buffer. If the payload source is present, the data referenced therein must not amount
/// to more than [`MAX_WINDOW_SIZE`].
///
/// # Arguments
///
/// * `buf` - The buffer where the segment is written.
/// * `mss_reserved` - How much (if anything) of the MSS value has been already used at the
///   lower layers (by IP options, for example). This will be zero most of the time.
/// * `payload_src` - References a buffer which contains data to send, and also specifies
///   the sequence number associated with the first byte from that that buffer.
/// * `now` - An opaque timestamp representing the current moment in time.
///
/// [`MAX_WINDOW_SIZE`]: ../constant.MAX_WINDOW_SIZE.html
Writes a new segment (if available) to the specified buffer.
The `payload_src` argument is required because the `Connection` does not have an internal
send buffer. If the payload source is present, the data referenced therein must not amount
to more than [`MAX_WINDOW_SIZE`].
Writes a new segment ( if available ) to the specified buffer . The ` payload_src ` argument is required because the ` Connection ` does not have an internal send buffer . If the payload source is present the data referenced therein must not amount to more than [ ` MAX_WINDOW_SIZE ` ] .
pub fn write_next_segment<'a, R: ByteBuffer + ?Sized>(
        &mut self,
        buf: &'a mut [u8],
        mss_reserved: u16,
        payload_src: PayloadSource<R>,
        now: u64,
    ) -> Result<Option<Incomplete<TcpSegment<'a, &'a mut [u8]>>>, WriteNextError> {
        // TODO: like receive_segment(), this function is specific in some ways to Connections
        // created via passive open. When/if we also implement active opens, some things will
        // have to change.
        if self.is_reset() {
            return Err(WriteNextError::ConnectionReset);
        }
        if self.send_rst.is_some() {
            // A RST is pending. Try to write it, and change the state of the connection to reset
            // if successfull.
            let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
            self.set_flags(ConnStatusFlags::RESET);
            return Ok(Some(segment));
        }
        // The first thing we have to do is reply with a SYNACK if needed.
        if self.synack_pending() {
            let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
            self.set_flags(ConnStatusFlags::SYNACK_SENT);
            self.rto_start = now;
            return Ok(Some(segment));
        }
        // Resend a SYNACK if the RTO expired. Otherwise, no reason to continue until the connection
        // becomes ESTABLISHED.
        if !self.is_established() {
            if self.rto_expired(now) {
                // If we exceeded the maximum retransmission count, reset the connection and call
                // write_next_segment one more time to generate the RST.
                self.rto_count += 1;
                if self.rto_count >= self.rto_count_max {
                    self.reset();
                    return self.write_next_segment(buf, mss_reserved, payload_src, now);
                }
                let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
                self.rto_start = now;
                return Ok(Some(segment));
            }
            return Ok(None);
        }
        // First, try sending a data segment, because we can piggy back ACKs and FINs on top of it.
        if let Some((read_buf, payload_seq)) = payload_src {
            // Limit the size of read_buf so it doesn't mess up later calculations (as usual, I take
            // the easy way out).
            if read_buf.len() > MAX_WINDOW_SIZE as usize {
                return Err(WriteNextError::PayloadBufTooLarge);
            }
            let payload_end = payload_seq + Wrapping(read_buf.len() as u32);
            let mut rto_triggered = false;
            // Decide what sequence number to send next. Check out if a timeout expired first.
            let seq_to_send =
                if self.highest_ack_received != self.first_not_sent && self.rto_expired(now) {
                    self.rto_count += 1;
                    if self.rto_count >= self.rto_count_max {
                        self.reset();
                        return self.write_next_segment(buf, mss_reserved, payload_src, now);
                    }
                    if let Some(fin_seq) = self.send_fin {
                        if self.highest_ack_received == fin_seq {
                            // We're in the relatively unlikely situation where our FIN got lost.
                            // Simply calling write_control_segment() will retransmit it.
                            let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
                            self.rto_start = now;
                            return Ok(Some(segment));
                        }
                    }
                    // We have to remember this is a retransmission for later.
                    rto_triggered = true;
                    self.highest_ack_received
                } else if self.dup_ack {
                    // We retransmit an older segment if a DUPACK is recorded. We'll clear
                    // self.dup_ack after we make sure the segment has been successfully written.
                    self.highest_ack_received
                } else {
                    // Otherwise, we send some data (if possible) starting with the first byte not
                    // yet sent.
                    self.first_not_sent
                };
            // The payload buffer begins after the first sequence number we are trying to send
            // (or the payload_seq is totally off).
            if !seq_at_or_after(seq_to_send, payload_seq) {
                return Err(WriteNextError::PayloadMissingSeq);
            }
            // We can only send data if it's within both the send buffer and the remote rwnd, and
            // before the sequence number of the local FIN (if the connection is closing).
            let actual_end = if seq_at_or_after(self.remote_rwnd_edge, payload_end) {
                payload_end
            } else {
                self.remote_rwnd_edge
            };
            // Make sure we're not trying to send data past the FIN sequence we previously
            // announced.
            if let Some(fin_seq) = self.send_fin {
                if seq_after(actual_end, fin_seq) {
                    return Err(WriteNextError::DataAfterFin);
                }
            }
            // We only proceed with writing a data segment if the previously computed bounds
            // delimit a valid sequence number interval.
            if seq_after(actual_end, seq_to_send) {
                let max_payload_len = (actual_end - seq_to_send).0 as usize;
                // We always set the ACK flag for data segments.
                let tcp_flags = TcpFlags::ACK;
                let ack_to_send = self.ack_to_send;
                let mut segment = self.write_segment(
                    buf,
                    mss_reserved,
                    seq_to_send,
                    ack_to_send,
                    tcp_flags,
                    Some((read_buf, max_payload_len)),
                )?;
                // If self.dup_ack was Some(_), we've just written the retransmission segment,
                // either directly or via the RTO timer expiring.
                self.dup_ack = false;
                let payload_len = segment.inner().payload().len();
                let mut first_seq_after = seq_to_send + Wrapping(payload_len as u32);
                if let Some(fin_seq) = self.send_fin {
                    if first_seq_after == fin_seq {
                        // This segment contains the last bytes of data we're going to send, so
                        // we should also set the FIN flag.
                        segment
                            .inner_mut()
                            .set_flags_after_ns(tcp_flags | TcpFlags::FIN);
                        // The FIN takes up 1 sequence number.
                        first_seq_after += Wrapping(1);
                        // The main purpose of knowing we sent at least one FIN is to signal that
                        // we already added 1 to self.first_not_sent, to account for its sequence
                        // number.
                        self.set_flags(ConnStatusFlags::FIN_SENT);
                    }
                }
                if rto_triggered || self.first_not_sent == self.highest_ack_received {
                    // Reset the RTO "timer" after each retransmission, or after sending the first
                    // unacknowledged segment in the current window.
                    self.rto_start = now;
                }
                if seq_after(first_seq_after, self.first_not_sent) {
                    self.first_not_sent = first_seq_after;
                }
                return Ok(Some(segment));
            }
        }
        // At this point, we only send a control segment if there's a pending ACK, or we didn't send
        // a FIN segment before and we would be sending the first one.
        // The FIN flag will be automatically added to the segment when necessary by the
        // write_control_segment() method.
        let send_first_fin = self.can_send_first_fin();
        if self.pending_ack || send_first_fin {
            let segment = self.write_control_segment::<R>(buf, mss_reserved)?;
            if send_first_fin {
                self.first_not_sent += Wrapping(1);
                self.set_flags(ConnStatusFlags::FIN_SENT);
            }
            return Ok(Some(segment));
        }
        Ok(None)
    }
pub fn write_next_segment < ' a , R : ByteBuffer + ? Sized > ( & mut self , buf : & ' a mut [ u8 ] , mss_reserved : u16 , payload_src : PayloadSource < R > , now : u64 , ) -> Result < Option < Incomplete < TcpSegment < ' a , & ' a mut [ u8 ] > > > , WriteNextError > { // TODO: like receive_segment(), this function is specific in some ways to Connections // created via passive open. When/if we also implement active opens, some things will // have to change. if self . is_reset ( ) { return Err ( WriteNextError :: ConnectionReset ) ; } if self . send_rst . is_some ( ) { // A RST is pending. Try to write it, and change the state of the connection to reset // if successfull. let segment = self . write_control_segment :: < R > ( buf , mss_reserved ) ? ; self . set_flags ( ConnStatusFlags :: RESET ) ; return Ok ( Some ( segment ) ) ; } // The first thing we have to do is reply with a SYNACK if needed. if self . synack_pending ( ) { let segment = self . write_control_segment :: < R > ( buf , mss_reserved ) ? ; self . set_flags ( ConnStatusFlags :: SYNACK_SENT ) ; self . rto_start = now ; return Ok ( Some ( segment ) ) ; } // Resend a SYNACK if the RTO expired. Otherwise, no reason to continue until the connection // becomes ESTABLISHED. if ! self . is_established ( ) { if self . rto_expired ( now ) { // If we exceeded the maximum retransmission count, reset the connection and call // write_next_segment one more time to generate the RST. self . rto_count += 1 ; if self . rto_count >= self . rto_count_max { self . reset ( ) ; return self . write_next_segment ( buf , mss_reserved , payload_src , now ) ; } let segment = self . write_control_segment :: < R > ( buf , mss_reserved ) ? ; self . rto_start = now ; return Ok ( Some ( segment ) ) ; } return Ok ( None ) ; } // First, try sending a data segment, because we can piggy back ACKs and FINs on top of it. if let Some ( ( read_buf , payload_seq ) ) = payload_src { // Limit the size of read_buf so it doesn't mess up later calculations (as usual, I take // the easy way out). if read_buf . len ( ) > MAX_WINDOW_SIZE as usize { return Err ( WriteNextError :: PayloadBufTooLarge ) ; } let payload_end = payload_seq + Wrapping ( read_buf . len ( ) as u32 ) ; let mut rto_triggered = false ; // Decide what sequence number to send next. Check out if a timeout expired first. let seq_to_send = if self . highest_ack_received != self . first_not_sent && self . rto_expired ( now ) { self . rto_count += 1 ; if self . rto_count >= self . rto_count_max { self . reset ( ) ; return self . write_next_segment ( buf , mss_reserved , payload_src , now ) ; } if let Some ( fin_seq ) = self . send_fin { if self . highest_ack_received == fin_seq { // We're in the relatively unlikely situation where our FIN got lost. // Simply calling write_control_segment() will retransmit it. let segment = self . write_control_segment :: < R > ( buf , mss_reserved ) ? ; self . rto_start = now ; return Ok ( Some ( segment ) ) ; } } // We have to remember this is a retransmission for later. rto_triggered = true ; self . highest_ack_received } else if self . dup_ack { // We retransmit an older segment if a DUPACK is recorded. We'll clear // self.dup_ack after we make sure the segment has been successfully written. self . highest_ack_received } else { // Otherwise, we send some data (if possible) starting with the first byte not // yet sent. self . first_not_sent } ; // The payload buffer begins after the first sequence number we are trying to send // (or the payload_seq is totally off). if ! seq_at_or_after ( seq_to_send , payload_seq ) { return Err ( WriteNextError :: PayloadMissingSeq ) ; } // We can only send data if it's within both the send buffer and the remote rwnd, and // before the sequence number of the local FIN (if the connection is closing). let actual_end = if seq_at_or_after ( self . remote_rwnd_edge , payload_end ) { payload_end } else { self . remote_rwnd_edge } ; // Make sure we're not trying to send data past the FIN sequence we previously // announced. if let Some ( fin_seq ) = self . send_fin { if seq_after ( actual_end , fin_seq ) { return Err ( WriteNextError :: DataAfterFin ) ; } } // We only proceed with writing a data segment if the previously computed bounds // delimit a valid sequence number interval. if seq_after ( actual_end , seq_to_send ) { let max_payload_len = ( actual_end - seq_to_send ) . 0 as usize ; // We always set the ACK flag for data segments. let tcp_flags = TcpFlags :: ACK ; let ack_to_send = self . ack_to_send ; let mut segment = self . write_segment ( buf , mss_reserved , seq_to_send , ack_to_send , tcp_flags , Some ( ( read_buf , max_payload_len ) ) , ) ? ; // If self.dup_ack was Some(_), we've just written the retransmission segment, // either directly or via the RTO timer expiring. self . dup_ack = false ; let payload_len = segment . inner ( ) . payload ( ) . len ( ) ; let mut first_seq_after = seq_to_send + Wrapping ( payload_len as u32 ) ; if let Some ( fin_seq ) = self . send_fin { if first_seq_after == fin_seq { // This segment contains the last bytes of data we're going to send, so // we should also set the FIN flag. segment . inner_mut ( ) . set_flags_after_ns ( tcp_flags | TcpFlags :: FIN ) ; // The FIN takes up 1 sequence number. first_seq_after += Wrapping ( 1 ) ; // The main purpose of knowing we sent at least one FIN is to signal that // we already added 1 to self.first_not_sent, to account for its sequence // number. self . set_flags ( ConnStatusFlags :: FIN_SENT ) ; } } if rto_triggered || self . first_not_sent == self . highest_ack_received { // Reset the RTO "timer" after each retransmission, or after sending the first // unacknowledged segment in the current window. self . rto_start = now ; } if seq_after ( first_seq_after , self . first_not_sent ) { self . first_not_sent = first_seq_after ; } return Ok ( Some ( segment ) ) ; } } // At this point, we only send a control segment if there's a pending ACK, or we didn't send // a FIN segment before and we would be sending the first one. // The FIN flag will be automatically added to the segment when necessary by the // write_control_segment() method. let send_first_fin = self . can_send_first_fin ( ) ; if self . pending_ack || send_first_fin { let segment = self . write_control_segment :: < R > ( buf , mss_reserved ) ? ; if send_first_fin { self . first_not_sent += Wrapping ( 1 ) ; self . set_flags ( ConnStatusFlags :: FIN_SENT ) ; } return Ok ( Some ( segment ) ) ; } Ok ( None ) }
Writes a new segment (if available) to the specified buffer.
Writes a new segment ( if available ) to the specified buffer .
&mut self
buf
&'a mut [u8]
mss_reserved
u16
payload_src
PayloadSource<R>
now
u64
&mut self
buf
&'a mut [u8]
mss_reserved
u16
payload_src
PayloadSource<R>
now
u64