!RxaQWWMYJTsVdHEKmL:matrix.org

smoltcp

164 Members
smoltcp discussion and help - https://github.com/smoltcp-rs/smoltcp13 Servers

Load older messages


SenderMessageTime
4 Feb 2024
@embassy-bot:matrix.orgsmoltcp-bot

New PR: Update DHCP example

03:40:14
7 Feb 2024
@jamwaffles:matrix.orgjamwaffles Hey all, is there a reason smoltcp couldn't work on FreeBSD? NetBSD and OpenBSD are supported (e.g. here) but not freebsd. I'm less than a day old in the *BSD universe so I could be missing an obvious reason 14:07:39
@jamwaffles:matrix.orgjamwaffles

Actually I'm getting the same compile error when compiling with --target x86_64-unknown-netbsd:

error[E0425]: cannot find value `BIOCSETIF` in this scope
  --> /home/james/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/phy/sys/bpf.rs:82:29
   |
82 |         try_ioctl!(self.fd, BIOCSETIF, &mut self.ifreq);
   |                             ^^^^^^^^^ not found in this scope
   |
help: consider importing one of these items
   |
1  + use crate::phy::sys::bpf::libc::BIOCSETIF;
   |
1  + use libc::BIOCSETIF;
   |

error[E0425]: cannot find value `BIOCIMMEDIATE` in this scope
   --> /home/james/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/phy/sys/bpf.rs:110:29
    |
110 |         try_ioctl!(self.fd, BIOCIMMEDIATE, &mut bufsize as *mut libc::c_int);
    |                             ^^^^^^^^^^^^^ not found in this scope
    |
help: consider importing one of these items
    |
1   + use crate::phy::sys::bpf::libc::BIOCIMMEDIATE;
    |
1   + use libc::BIOCIMMEDIATE;
    |

error[E0425]: cannot find value `BIOCGBLEN` in this scope
   --> /home/james/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/phy/sys/bpf.rs:111:29
    |
111 |         try_ioctl!(self.fd, BIOCGBLEN, &mut bufsize as *mut libc::c_int);
    |                             ^^^^^^^^^ not found in this scope
    |
help: consider importing one of these items
    |
1   + use crate::phy::sys::bpf::libc::BIOCGBLEN;
    |
1   + use libc::BIOCGBLEN;
    |

error[E0425]: cannot find value `BPF_HDRLEN` in this scope
   --> /home/james/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/phy/sys/bpf.rs:124:35
    |
124 |             if len == -1 || len < BPF_HDRLEN as isize {
    |                                   ^^^^^^^^^^ not found in this scope

error[E0425]: cannot find value `BPF_HDRLEN` in this scope
   --> /home/james/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/phy/sys/bpf.rs:132:25
    |
132 |                 &buffer[BPF_HDRLEN] as *const u8 as *const libc::c_void,
    |                         ^^^^^^^^^^ not found in this scope

error[E0425]: cannot find value `BPF_HDRLEN` in this scope
   --> /home/james/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/phy/sys/bpf.rs:133:23
    |
133 |                 len - BPF_HDRLEN,
    |                       ^^^^^^^^^^ not found in this scope
14:17:10
@jamwaffles:matrix.orgjamwaffles Oh, NetBSD support hasn't been released yet. Those errors above happen when I compile smoltcp itself at v0.11.0 but don't happen at the latest commit. 14:19:04
@embassy-bot:matrix.orgsmoltcp-bot

New PR: Add BPF support for FreeBSD

19:54:38
@jamwaffles:matrix.orgjamwaffles If anyone is interested, my above issues were caused by the SIZEOF_BPF_HDR constant in my fork of smoltcp being incorrectly defined as 18 bytes instead of 24. The error I was getting was a red herring it seems 19:55:43
@embassy-bot:matrix.orgsmoltcp-bot

PR merged: Add BPF support for FreeBSD

20:29:18
10 Feb 2024
@embassy-bot:matrix.orgsmoltcp-bot

PR merged: Update DHCP example

02:03:50
11 Feb 2024
@bowiedough:matrix.org@bowiedough:matrix.org left the room.00:52:37
16 Feb 2024
@talizkahn:matrix.orgtalizkahn joined the room.09:08:55
@voidedgin:matrix.orgAndo “Thor” Nando joined the room.09:34:44
@azraanimating:matrix.orgTobi changed their profile picture.10:02:19
@talizkahn:matrix.orgtalizkahn

Hi all, wondering if I might be able to as some advice. Im trying to implement a TCP server based heavily on the example here (https://github.com/smoltcp-rs/smoltcp/blob/main/examples/server.rs). What Im seeing is that the server receives the SYN from the client and processes it:
(https://github.com/smoltcp-rs/smoltcp/blob/main/src/socket/tcp.rs#L1365)

  • Finds the appropriate socket
  • Sets the socket to the SYN-RECEIVED state (https://github.com/smoltcp-rs/smoltcp/blob/main/src/socket/tcp.rs#L1632)

It then checks if the payload len is 0 and returns None. I cant find a code path that actually sends a SYN|ACK. As a result, the client retries the SYN over and over. The server, having put the socket in SYN-RECEIVED state, reports "Expected an ACK" https://github.com/smoltcp-rs/smoltcp/blob/main/src/socket/tcp.rs#L1407.

I modified that function and removed the if payload.len == 0 { return None' } and also the final bit of the function so that it always did an ack_reply(...). Which resulted in it sending an ACK (visable in wireshark) but only ACK is set, not SYN.

The other thing, sorta unrelated, is that after making the changes above, initially the ACK would not send because the neighbour was unknown. It would trigger an ARP, which would result in the neighbour being filled, but the sending of the ACK had been abandoned at that point. The client would resend SYNs, which would be RST, because now the socket is in SYN-RECIEVED and not dealing anymore with SYNs.

I was able to mitigate that by pre-populating the neighbour cache with the MAC of the incommning packet and the route IP for the incomming src IP address.

So i guess my questions boil down to:

  • Where/how is the SYN|ACK generated and sent
  • Is there a way for the arp process to be done without abandoning the packet to be sent
19:35:11
@dirbaio:matrix.orgdirbaiothe syn+ack is triggered here https://github.com/smoltcp-rs/smoltcp/blob/main/src/socket/tcp.rs#L1983 https://github.com/smoltcp-rs/smoltcp/blob/main/src/socket/tcp.rs#L216819:50:11
@dirbaio:matrix.orgdirbaioplus there's plenty of tests for it, so it's impossible that it's broken19:50:20
@talizkahn:matrix.orgtalizkahn
In reply to @dirbaio:matrix.org
plus there's plenty of tests for it, so it's impossible that it's broken
thats sort of what I was also thinking
19:50:45
@dirbaio:matrix.orgdirbaioif ARP is pending, sending fails (so the socket knows it wasn't sent and doesn't change state) and the socket is "slienced" until ARP is done. when unsilenced, the socket tries sending it again.19:51:56
@dirbaio:matrix.orgdirbaioso it must be some other issue19:52:21
@dirbaio:matrix.orgdirbaioplease post your code and trace-level logs19:52:31
@talizkahn:matrix.orgtalizkahn

here are some logs... the SENDING and RECIEVING logs are emitted from the relevant token consume functions:

[2024-02-16T19:57:11Z TRACE smoltcp::iface::socket_set] [0]: adding
[2024-02-16T19:57:11Z INFO  rsbec] listening
[2024-02-16T19:57:11Z TRACE smoltcp::socket::tcp] state=CLOSED=>LISTEN
[2024-02-16T19:57:11Z DEBUG rsbec] polling...
[2024-02-16T19:57:13Z DEBUG rsbec] RECEIVED: EthernetII src=fe-54-00-ca-d0-df dst=01-80-c2-00-00-00 type=0x0026
[2024-02-16T19:57:15Z DEBUG rsbec] RECEIVED: EthernetII src=fe-54-00-ca-d0-df dst=01-80-c2-00-00-00 type=0x0026
[2024-02-16T19:57:16Z DEBUG rsbec] RECEIVED: EthernetII src=52-54-00-4a-2d-08 dst=52-54-00-ca-d0-df type=IPv4
              \ IPv4 src=192.168.122.1 dst=192.168.122.129 proto=TCP
               \ TCP src=33606 dst=8080 syn seq=2156941596 win=32120 len=0 mss=1460 (checksum incorrect)
[2024-02-16T19:57:16Z TRACE smoltcp::socket::tcp] received SYN
[2024-02-16T19:57:16Z TRACE smoltcp::socket::tcp] state=LISTEN=>SYN-RECEIVED
[2024-02-16T19:57:17Z DEBUG rsbec] RECEIVED: EthernetII src=fe-54-00-ca-d0-df dst=01-80-c2-00-00-00 type=0x0026
[2024-02-16T19:57:17Z DEBUG rsbec] RECEIVED: EthernetII src=52-54-00-4a-2d-08 dst=52-54-00-ca-d0-df type=IPv4
              \ IPv4 src=192.168.122.1 dst=192.168.122.129 proto=TCP
               \ TCP src=33606 dst=8080 syn seq=2156941596 win=32120 len=0 mss=1460 (checksum incorrect)
[2024-02-16T19:57:17Z DEBUG smoltcp::socket::tcp] expecting an ACK
[2024-02-16T19:57:18Z DEBUG rsbec] RECEIVED: EthernetII src=52-54-00-4a-2d-08 dst=52-54-00-ca-d0-df type=IPv4
              \ IPv4 src=192.168.122.1 dst=192.168.122.129 proto=TCP
               \ TCP src=33606 dst=8080 syn seq=2156941596 win=32120 len=0 mss=1460 (checksum incorrect)
[2024-02-16T19:57:18Z DEBUG smoltcp::socket::tcp] expecting an ACK
[2024-02-16T19:57:19Z DEBUG rsbec] RECEIVED: EthernetII src=fe-54-00-ca-d0-df dst=01-80-c2-00-00-00 type=0x0026
[2024-02-16T19:57:19Z DEBUG rsbec] RECEIVED: EthernetII src=52-54-00-4a-2d-08 dst=52-54-00-ca-d0-df type=IPv4
              \ IPv4 src=192.168.122.1 dst=192.168.122.129 proto=TCP
               \ TCP src=33606 dst=8080 syn seq=2156941596 win=32120 len=0 mss=1460 (checksum incorrect)
[2024-02-16T19:57:19Z DEBUG smoltcp::socket::tcp] expecting an ACK
[2024-02-16T19:57:20Z DEBUG rsbec] RECEIVED: EthernetII src=52-54-00-4a-2d-08 dst=52-54-00-ca-d0-df type=IPv4
              \ IPv4 src=192.168.122.1 dst=192.168.122.129 proto=TCP
               \ TCP src=33606 dst=8080 syn seq=2156941596 win=32120 len=0 mss=1460 (checksum incorrect)
[2024-02-16T19:57:20Z DEBUG smoltcp::socket::tcp] expecting an ACK

19:59:51
@talizkahn:matrix.orgtalizkahn

this is the code where I create a TCP socket and attemt a basic data reverse service (copied from the server.rs example). It doesnt actually get past the iface.poll:

fn tcp_service(device: &mut MyDevice) {
    // Create interface
    let mut config = match device.capabilities().medium {
        Medium::Ethernet => {
            // 52:54:00:ca:d0:df
            Config::new(EthernetAddress([0x52, 0x54, 0x00, 0xca, 0xd0, 0xdf]).into())
        }
        _ => return,
    };

    config.random_seed = rand::random();

    let mut iface = Interface::new(config, device, Instant::now());
    iface.update_ip_addrs(|ip_addrs| {
        ip_addrs
            .push(IpCidr::new(IpAddress::v4(192, 168, 122, 129), 24))
            .unwrap();
    });
    iface
        .routes_mut()
        .add_default_ipv4_route(Ipv4Address::new(192, 168, 122, 1))
        .unwrap();

    let mut sockets = SocketSet::new(vec![]);
    let tcp1_rx_buffer = tcp::SocketBuffer::new(vec![0; 64]);
    let tcp1_tx_buffer = tcp::SocketBuffer::new(vec![0; 128]);
    let tcp1_socket = tcp::Socket::new(tcp1_rx_buffer, tcp1_tx_buffer);
    let tcp1_handle = sockets.add(tcp1_socket);

    let mut connected = false;
    let socket = sockets.get_mut::<tcp::Socket>(tcp1_handle);
    if !socket.is_open() {
        info!("listening");
        socket.listen(8080).unwrap();
    }

    loop {
        let timestamp = Instant::now();
        debug!("polling...");
        iface.poll(timestamp, device, &mut sockets);
        debug!("polled...");

        let socket = sockets.get_mut::<tcp::Socket>(tcp1_handle);
        if socket.is_active() && !connected {
            info!("connected");
        }
        connected = socket.is_active();

        if socket.may_recv() {
            let data = socket
                .recv(|buffer| {
                    let recvd_len = buffer.len();
                    let mut data = buffer.to_owned();
                    if !data.is_empty() {
                        data = data.split(|&b| b == b'\n').collect::<Vec<_>>().concat();
                        data.reverse();
                        data.extend(b"\n");
                    }
                    (recvd_len, data)
                })
                .unwrap();
            if socket.can_send() && !data.is_empty() {
                socket.send_slice(&data[..]).unwrap();
            }
        }
    }
}
20:02:35
@dirbaio:matrix.orgdirbaioseems your Device implementation is blocking on receive, instead of returning None20:04:10
@talizkahn:matrix.orgtalizkahnshould the Device::recieve() function actually poll the underlying subsystem for data or should that be done in the consume for the token?20:07:21
@dirbaio:matrix.orgdirbaioread the Device trait docs20:07:36
@talizkahn:matrix.orgtalizkahn

"* The receive and transmit functions only construct such tokens, the real sending/receiving operation are performed when the tokens are consumed.*"

This indicates that the actual work should be done in the token consume, which is what im doing... under what circumstances would you return None from receive()?

20:10:05
@dirbaio:matrix.orgdirbaio receive must return None if there's no packet received right now, Some if there is. it must not block
and then RxToken::consume must consume that received packet immediately. it must not block either.
20:11:10
@dirbaio:matrix.orgdirbaio * receive must return None if there's no packet received right now, Some if there is. it must not block.
and then RxToken::consume must consume that received packet immediately. it must not block either.
20:11:19
@talizkahn:matrix.orgtalizkahnRight, so the receive will read the data into the token if it exists, and the consume will process it?20:12:06
@dirbaio:matrix.orgdirbaioit's up to you when you read the data20:12:30
@dirbaio:matrix.orgdirbaiobut you must not block20:12:32

Show newer messages


Back to Room ListRoom Version: 6