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: 3ff0ca277b87
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: 553d640057e1
Choose a head ref
  • 4 commits
  • 4 files changed
  • 1 contributor

Commits on Dec 28, 2016

  1. Copy the full SHA
    a058996 View commit details
  2. Copy the full SHA
    a475925 View commit details
  3. Copy the full SHA
    40be830 View commit details
  4. Copy the full SHA
    553d640 View commit details
Showing with 299 additions and 55 deletions.
  1. +6 −3 README.md
  2. +37 −14 examples/server.rs
  3. +243 −38 src/socket/tcp.rs
  4. +13 −0 src/wire/ip.rs
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -52,11 +52,12 @@ The TCP protocol is supported over IPv4.

* TCP header checksum is supported.
* Multiple packets will be transmitted without waiting for an acknowledgement.
* TCP urgent pointer is **not** supported; any urgent octets will be received alongside data.
* TCP urgent pointer is **not** supported; any urgent octets will be received alongside
data octets.
* Reassembly of out-of-order segments is **not** supported.
* TCP options are **not** supported, in particular:
* Maximum segment size is hardcoded at the default value, 536.
* Window scaling is **not** supported.
* Window scaling is **not** supported, and the maximum buffer size is 65536.
* Keepalive is **not** supported.

Installation
@@ -143,7 +144,9 @@ It responds to:
* pings (`ping 192.168.69.1`);
* UDP packets on port 6969 (`socat stdio udp4-connect:192.168.69.1:6969 <<<"abcdefg"`),
where it will respond "yo dawg" to any incoming packet;
* TCP packets on port 6969 (`socat stdio tcp4-connect:192.168.69.1:6969 <<<"abcdefg"`),
* TCP packets on port 6969 (`socat stdio tcp4-connect:192.168.69.1:6969`),
where it will respond "yo dawg" to any incoming connection and immediately close it;
* TCP packets on port 6970 (`socat stdio tcp4-connect:192.168.69.1:6970 <<<"abcdefg"`),
where it will respond with reversed chunks of the input indefinitely.

The buffers are only 64 bytes long, for convenience of testing resource exhaustion conditions.
51 changes: 37 additions & 14 deletions examples/server.rs
Original file line number Diff line number Diff line change
@@ -53,60 +53,83 @@ fn main() {
let udp_tx_buffer = UdpSocketBuffer::new(vec![UdpPacketBuffer::new(vec![0; 128])]);
let udp_socket = UdpSocket::new(endpoint, udp_rx_buffer, udp_tx_buffer);

let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; 64]);
let tcp_tx_buffer = TcpSocketBuffer::new(vec![0; 128]);
let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
let tcp1_rx_buffer = TcpSocketBuffer::new(vec![0; 64]);
let tcp1_tx_buffer = TcpSocketBuffer::new(vec![0; 128]);
let tcp1_socket = TcpSocket::new(tcp1_rx_buffer, tcp1_tx_buffer);

let tcp2_rx_buffer = TcpSocketBuffer::new(vec![0; 64]);
let tcp2_tx_buffer = TcpSocketBuffer::new(vec![0; 128]);
let tcp2_socket = TcpSocket::new(tcp2_rx_buffer, tcp2_tx_buffer);

let hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
let protocol_addrs = [IpAddress::v4(192, 168, 69, 1)];
let sockets = vec![udp_socket, tcp_socket];
let sockets = vec![udp_socket, tcp1_socket, tcp2_socket];
let mut iface = EthernetInterface::new(device, arp_cache,
hardware_addr, protocol_addrs, sockets);

let mut tcp_6969_connected = false;
loop {
// udp:6969: respond "yo dawg"
{
let socket: &mut UdpSocket = iface.sockets()[0].as_socket();
let client = match socket.recv() {
Ok((endpoint, data)) => {
debug!("udp recv data: {:?} from {}",
debug!("udp:6969 recv data: {:?} from {}",
str::from_utf8(data.as_ref()).unwrap(), endpoint);
Some(endpoint)
}
Err(Error::Exhausted) => {
None
}
Err(e) => {
debug!("udp recv error: {}", e);
debug!("udp:6969 recv error: {}", e);
None
}
};
if let Some(endpoint) = client {
let data = b"yo dawg";
debug!("udp send data: {:?}",
let data = b"yo dawg\n";
debug!("udp:6969 send data: {:?}",
str::from_utf8(data.as_ref()).unwrap());
socket.send_slice(endpoint, data).unwrap()
}
}

// tcp:6969: respond "yo dawg"
{
let socket: &mut TcpSocket = iface.sockets()[1].as_socket();
if !socket.is_open() {
socket.listen(endpoint).unwrap()
socket.listen(6969).unwrap();
}

if socket.can_send() {
let data = b"yo dawg\n";
debug!("tcp:6969 send data: {:?}",
str::from_utf8(data.as_ref()).unwrap());
socket.send_slice(data).unwrap();
debug!("tcp:6969 close");
socket.close();
}
}

// tcp:6970: echo with reverse
{
let socket: &mut TcpSocket = iface.sockets()[2].as_socket();
if !socket.is_open() {
socket.listen(6970).unwrap()
}

if socket.is_connected() && !tcp_6969_connected {
debug!("tcp connected");
debug!("tcp:6970 connected");
} else if !socket.is_connected() && tcp_6969_connected {
debug!("tcp disconnected");
debug!("tcp:6970 disconnected");
}
tcp_6969_connected = socket.is_connected();

if socket.can_recv() {
let data = {
let mut data = socket.recv(128).unwrap().to_owned();
if data.len() > 0 {
debug!("tcp recv data: {:?}",
debug!("tcp:6970 recv data: {:?}",
str::from_utf8(data.as_ref()).unwrap_or("(invalid utf8)"));
data = data.split(|&b| b == b'\n').collect::<Vec<_>>().concat();
data.reverse();
@@ -115,13 +138,13 @@ fn main() {
data
};
if socket.can_send() && data.len() > 0 {
debug!("tcp send data: {:?}",
debug!("tcp:6970 send data: {:?}",
str::from_utf8(data.as_ref()).unwrap_or("(invalid utf8)"));
socket.send_slice(&data[..]).unwrap();
}
} else if socket.can_send() {
debug!("tcp:6970 close");
socket.close();
debug!("tcp closed")
}
}

Loading