Coder Social home page Coder Social logo

tokio-smoltcp's Introduction

Hi there 👋

Github stats

Twitter: https://twitter.com/spacemeowx2

关于我

  • 天天写前端, 很喜欢 TypeScript 和 Rust

  • 舞萌(maimai)刚入门(2023-7)

  • Splatoon(2017-7-21), Apex Legends (2022-6) 玩家(玩的不是特别好, 不过也不菜)

  • 会一点逆向, 一点点PWN, 一点点点Web(已经好几年没打CTF了). 打过DEF CON CTF

  • 平时会写一些玩的游戏/主机的工具, 还有代理相关的东西

项目简介

  • switch-lan-play: 给 Switch 模拟局域网和应用 SOCKS 5 代理的工具

  • ldn_mitm: 把 CFW Switch 的本地联机改成局域网联机的 sysmodule

  • rabbit-digger-pro: 用 Rust 写的兼容 Clash 订阅文件的代理工具

  • s3si.ts: 将 鱿鱼圈3(Splatoon3) 战绩导出到 stat.ink 的工具

  • LiveHelper: 浏览器插件, 将多个平台的关注主播整合到一个界面(很久没更新了)

tokio-smoltcp's People

Contributors

apatrushev avatar spacemeowx2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

tokio-smoltcp's Issues

ACK problems?

Hi, I've been looking at this repo and I was wondering if you thought of my question about the way you poll each socket. I'd love to use this instead of mine because it does not do a second copy of the rx buffer. But it looks to me that this copy is needed. Look:

impl AsyncRead for TcpSocket {
    fn poll_read(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &mut ReadBuf<'_>,
    ) -> Poll<io::Result<()>> {
        let mut set = self.reactor.socket_alloctor().lock();
        let mut socket = set.get::<socket::TcpSocket>(*self.handle);
        if !socket.may_recv() {
            return Poll::Ready(Ok(()));
        }
        if socket.can_recv() {
            let read = socket
                .recv_slice(buf.initialize_unfilled())
                .map_err(map_err)?;
            buf.advance(read);
            return Poll::Ready(Ok(()));
        }
        socket.register_recv_waker(cx.waker());
        Poll::Pending
    }
}

you are saying that there's no chance the socket will be overwritten before a new poll is made. It looks like smoltcp uses arbitrary socket sizes, so if the socket size is of half a TCP packet size, then I thought it could be that half a packet must be taken out of the socket before a new part emerges and then the ACK is sent. However, I think there's no sense in what I said because smoltcp will always analyze the entire packet before delivering to me. So a ACK will only be sent after the entire packet is received.

But is the ACK sent when socket.recv_slice is called? I researched a bit and it looks like not. I think the ACK is sent right after the packet is received in smoltcp and put available to socket.recv_slice. So if I don't call recv_slice fast enough it would be overwritten by the next packet, because ACK is already sent before I call socket.rect_slice. The socket.recv_slice end up calling this:

    pub fn dequeue_many_with<'b, R, F>(&'b mut self, f: F) -> (usize, R)
            where F: FnOnce(&'b mut [T]) -> (usize, R) {
        let capacity = self.capacity();
        let max_size = cmp::min(self.len(), capacity - self.read_at);
        let (size, result) = f(&mut self.storage[self.read_at..self.read_at + max_size]);
        assert!(size <= max_size);
        self.read_at = if capacity > 0 {
            (self.read_at + size) % capacity
        } else {
            0
        };
        self.length -= size;
        (size, result)
    }

which does not look like it triggers an ACK response. So it looks like ACK is sent before this.

I'm still not convinced for the TCP case, but what about UDP?

    pub fn poll_recv_from(
        &self,
        cx: &mut Context<'_>,
        buf: &mut [u8],
    ) -> Poll<io::Result<(usize, SocketAddr)>> {
        let mut set = self.reactor.socket_alloctor().lock();
        let mut socket = set.get::<socket::UdpSocket>(*self.handle);

        match socket.recv_slice(buf) {
            // the buffer is empty
            Err(smoltcp::Error::Exhausted) => {}
            r => {
                let (size, endpoint) = r.map_err(map_err)?;
                return Poll::Ready(Ok((size, ep2sa(&endpoint))));
            }
        }

        socket.register_recv_waker(cx.waker());
        Poll::Pending
    }

UDP has no ACK, so there's no way that the server would know that I already received a packet, so there's the chance that poll does not occur fast enough to grab a packet before it's overwritten. Same for RawSocket.

By the way, will you support the most recent version of smoltcp? I needed it because of some things from there, mostly to do a virtual interface.

Thanks

TCP Connection unfairness

When using iperf for benchmarking, increasing the number of concurrent connections will result in only one connection having speed.

Reproduction steps

Requires rabbit-digger-pro and iperf3.

  1. Start rabbit-digger-pro with the following config, the raw type depends on this crate:
net:
  raw:
    type: raw
    device:
      type: tun
      host_addr: 10.0.0.2
    mtu: 1400
    ip_addr: 10.0.0.1/24
server:
  forward:
    type: forward
    listen: raw
    bind: 0.0.0.0:5201
    net: local
    target: 127.0.0.1:5201
  1. Start iperf server iperf -s
  2. Run iperf3 -c 10.0.0.1 -P 2 on the other terminal

image

You will see that one of the connections has almost 0 speed.

[Question] Performance issue in multi-thread runtime

I couldn't find another use cases in Github with tokio except yours.

I am working on a Project with also using smoltcp as an user space network stack and provide wrappers for interpolate with existed Tokio IO structs (TcpStream, ...), but I found some problems:

  1. Since Interface::poll requires to call frequently in a very short interval, it have to be put in a separated task (the Reactor in this Project).
  2. In the latest version of smoltcp, SocketSet is now managed by Interface, so if you want to call Interface::poll, and also AsyncRead::poll_read and AsyncRead::poll_write on TcpStream (wrapper of TcpSocket), you will have to take a lock on the Interface. (which is the same in this Project, the SocketAllocator).

I don't know if you have any benchmark data about the current design of tokio-smoltcp. I made a simple test with iperf3, which showed that the interface is relatively slower than system's network stack.

Here I open an issue and hoping you can share any informations about this with me.

Question: How do you interact with the echo server in the pcap example

In the pcap example, an echo server is created on the last step, but I can't seem to interact with it at all... My invocation:

$ cargo build --example pcap && sudo RUST_BACKTRACE=1 ./target/debug/examples/pcap eth0 --gateway 192.168.0.1 --ip-addr 192.168.0.240/24
$ telnet 192.168.0.240 12345
Trying 192.168.0.240...
telnet: Unable to connect to remote host: No route to host

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.