Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0dedbaf597c9
Choose a base ref
...
head repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1cd88421b46c
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Jan 14, 2017

  1. Copy the full SHA
    830f9d9 View commit details
  2. Copy the full SHA
    1cd8842 View commit details
Showing with 63 additions and 25 deletions.
  1. +2 −2 examples/server.rs
  2. +56 −18 src/socket/tcp.rs
  3. +5 −5 src/socket/udp.rs
4 changes: 2 additions & 2 deletions examples/server.rs
Original file line number Diff line number Diff line change
@@ -146,7 +146,7 @@ fn main() {
}
tcp_6969_connected = socket.is_connected();

if socket.can_recv() {
if socket.may_recv() {
let data = {
let mut data = socket.recv(128).unwrap().to_owned();
if data.len() > 0 {
@@ -163,7 +163,7 @@ fn main() {
str::from_utf8(data.as_ref()).unwrap_or("(invalid utf8)"));
socket.send_slice(&data[..]).unwrap();
}
} else if socket.can_send() {
} else if socket.may_send() {
debug!("tcp:6970 close");
socket.close();
}
74 changes: 56 additions & 18 deletions src/socket/tcp.rs
Original file line number Diff line number Diff line change
@@ -37,6 +37,14 @@ impl<'a> SocketBuffer<'a> {
self.capacity() - self.len()
}

fn empty(&self) -> bool {
self.length != 0
}

fn full(&self) -> bool {
self.window() == 0
}

fn clamp_writer(&self, mut size: usize) -> (usize, usize) {
let write_at = (self.read_at + self.length) % self.storage.len();
// We can't enqueue more than there is free space.
@@ -360,7 +368,7 @@ impl<'a> TcpSocket<'a> {
/// to the remote endpoint. However, it does not make any guarantees about the state
/// of the transmit buffer, and even if it returns true, [send](#method.send) may
/// not be able to enqueue any octets.
pub fn can_send(&self) -> bool {
pub fn may_send(&self) -> bool {
match self.state {
State::Established => true,
// In CLOSE-WAIT, the remote endpoint has closed our receive half of the connection
@@ -375,7 +383,7 @@ impl<'a> TcpSocket<'a> {
/// This function returns true if it's possible to receive data from the remote endpoint.
/// It will return true while there is data in the receive buffer, and if there isn't,
/// as long as the remote endpoint has not closed the connection.
pub fn can_recv(&self) -> bool {
pub fn may_recv(&self) -> bool {
match self.state {
State::Established => true,
// In FIN-WAIT-1/2, we have closed our transmit half of the connection but
@@ -387,6 +395,22 @@ impl<'a> TcpSocket<'a> {
}
}

/// Check whether the transmit half of the full-duplex connection is open, and
/// the transmit buffer is not full.
pub fn can_send(&self) -> bool {
if !self.may_send() { return false }

!self.tx_buffer.full()
}

/// Check whether the receive half of the full-duplex connection buffer is open,
/// and the receive buffer is not empty.
pub fn can_recv(&self) -> bool {
if !self.may_recv() { return false }

!self.rx_buffer.empty()
}

/// Enqueue a sequence of octets to be sent, and return a pointer to it.
///
/// This function may return a slice smaller than the requested size in case
@@ -396,7 +420,7 @@ impl<'a> TcpSocket<'a> {
/// This function returns an error if the transmit half of the connection is not open;
/// see [can_send](#method.can_send).
pub fn send(&mut self, size: usize) -> Result<&mut [u8], ()> {
if !self.can_send() { return Err(()) }
if !self.may_send() { return Err(()) }

let old_length = self.tx_buffer.len();
let buffer = self.tx_buffer.enqueue(size);
@@ -430,7 +454,7 @@ impl<'a> TcpSocket<'a> {
pub fn recv(&mut self, size: usize) -> Result<&[u8], ()> {
// We may have received some data inside the initial SYN ("TCP Fast Open"),
// but until the connection is fully open we refuse to dequeue any data.
if !self.can_recv() { return Err(()) }
if !self.may_recv() { return Err(()) }

let old_length = self.rx_buffer.len();
let buffer = self.rx_buffer.dequeue(size);
@@ -785,21 +809,21 @@ impl<'a> TcpSocket<'a> {
// in case it's not possible to extract a contiguous slice.
let offset = self.remote_last_seq - self.local_seq_no;
let data = self.tx_buffer.peek(offset, size);
if data.len() > 0 {
// Send the extracted data.
net_trace!("tcp:{}:{}: tx buffer: peeking at {} octets (from {})",
self.local_endpoint, self.remote_endpoint,
data.len(), offset);
repr.seq_number += offset;
repr.payload = data;
// Speculatively shrink the remote window. This will get updated
// the next time we receive a packet.
self.remote_win_len -= data.len();
// Advance the in-flight sequence number.
self.remote_last_seq += data.len();
should_send = true;
}
match self.state {
_ if data.len() > 0 => {
// Send the extracted data.
net_trace!("tcp:{}:{}: tx buffer: peeking at {} octets (from {})",
self.local_endpoint, self.remote_endpoint,
data.len(), offset);
repr.seq_number += offset;
repr.payload = data;
// Speculatively shrink the remote window. This will get updated
// the next time we receive a packet.
self.remote_win_len -= data.len();
// Advance the in-flight sequence number.
self.remote_last_seq += data.len();
should_send = true;
}
State::FinWait1 | State::LastAck => {
// We should notify the other side that we've closed the transmit half
// of the connection.
@@ -1782,4 +1806,18 @@ mod test {
..RECV_TEMPL
}));
}

#[test]
fn test_fin_with_data() {
let mut s = socket_established();
s.send_slice(b"abcdef").unwrap();
s.close();
recv!(s, [TcpRepr {
control: TcpControl::Fin,
seq_number: LOCAL_SEQ + 1,
ack_number: Some(REMOTE_SEQ + 1),
payload: &b"abcdef"[..],
..RECV_TEMPL
}])
}
}
10 changes: 5 additions & 5 deletions src/socket/udp.rs
Original file line number Diff line number Diff line change
@@ -141,6 +141,11 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
!self.tx_buffer.full()
}

/// Check whether the receive buffer is not empty.
pub fn can_recv(&self) -> bool {
!self.rx_buffer.empty()
}

/// Enqueue a packet to be sent to a given remote endpoint, and return a pointer
/// to its payload.
///
@@ -165,11 +170,6 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
Ok(data.len())
}

/// Check whether the receive buffer is full.
pub fn can_recv(&self) -> bool {
!self.rx_buffer.empty()
}

/// Dequeue a packet received from a remote endpoint, and return the endpoint as well
/// as a pointer to the payload.
///