kellerkindt / w5500

W5500 ethernet module driver written in rust
Apache License 2.0
40 stars 18 forks source link

TcpFullStack is not implemented for TCP #49

Open andresv opened 1 year ago

andresv commented 1 year ago

UdpFullStack is implemented for UDP: https://github.com/kellerkindt/w5500/blob/master/src/udp.rs#L292. But TcpFullStack is missing for TCP, only TcpClientStack is available: https://github.com/kellerkindt/w5500/blob/master/src/tcp.rs#L263.

andresv commented 1 year ago

Here is TcpFullStack in full glory:

/// This trait is implemented by TCP/IP stacks that expose TCP server functionality. TCP servers
/// may listen for connection requests to establish multiple unique TCP connections with various
/// clients.
pub trait TcpFullStack: TcpClientStack {
    /// Create a new TCP socket and bind it to the specified local port.
    ///
    /// Returns `Ok` when a socket is successfully bound to the specified local port. Otherwise, an
    /// `Err(e)` variant is returned.
    fn bind(&mut self, socket: &mut Self::TcpSocket, local_port: u16) -> Result<(), Self::Error>;

    /// Begin listening for connection requests on a previously-bound socket.
    ///
    /// Returns `Ok` if the socket was successfully transitioned to the listening state. Otherwise,
    /// an `Err(e)` variant is returned.
    fn listen(&mut self, socket: &mut Self::TcpSocket) -> Result<(), Self::Error>;

    /// Accept an active connection request on a listening socket.
    ///
    /// Returns `Ok(connection)` if a new connection was created. If no pending connections are
    /// available, this function should return [`nb::Error::WouldBlock`].
    fn accept(
        &mut self,
        socket: &mut Self::TcpSocket,
    ) -> nb::Result<(Self::TcpSocket, SocketAddr), Self::Error>;
}

How accept should be handled, what to actually return as a socket there?

ryan-summers commented 1 year ago

accept would need to return a different, newly-allocated socket. That's why it hasn't been implemented - TCP servers are way more complex and aren't generally implemented on embedded targets because of the limited resources available. The server would have a limited number of connections that it can give out.

andresv commented 1 year ago

Makes sense. I have an app that uses all 8 available sockets and 4 of them are used as server sockets. Server sockets only handled 1 connection per socket which was OK in my use case. Essentially it was just connected to RPi like device which just made single connection.

I was using some old W5500 fork https://github.com/andresv/w5500/blob/master/src/lib.rs for this. I hacked W6100 support on top of the latest W5500 version and tried to port my app over. That is when I realized that server support is actually not implemented anymore. I consider switching from TCP to UDP.