|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
| 2 | + |
| 3 | +//! Rust echo server sample. |
| 4 | +
|
| 5 | +use kernel::{ |
| 6 | + kasync::executor::{workqueue::Executor as WqExecutor, AutoStopHandle, Executor}, |
| 7 | + kasync::net::{TcpListener, TcpStream}, |
| 8 | + net::{self, Ipv4Addr, SocketAddr, SocketAddrV4}, |
| 9 | + prelude::*, |
| 10 | + spawn_task, |
| 11 | + sync::{Ref, RefBorrow}, |
| 12 | +}; |
| 13 | + |
| 14 | +async fn echo_server(stream: TcpStream) -> Result { |
| 15 | + let mut buf = [0u8; 1024]; |
| 16 | + loop { |
| 17 | + let n = stream.read(&mut buf).await?; |
| 18 | + if n == 0 { |
| 19 | + return Ok(()); |
| 20 | + } |
| 21 | + stream.write_all(&buf[..n]).await?; |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +async fn accept_loop(listener: TcpListener, executor: Ref<impl Executor>) { |
| 26 | + loop { |
| 27 | + if let Ok(stream) = listener.accept().await { |
| 28 | + let _ = spawn_task!(executor.as_ref_borrow(), echo_server(stream)); |
| 29 | + } |
| 30 | + } |
| 31 | +} |
| 32 | + |
| 33 | +fn start_listener(ex: RefBorrow<'_, impl Executor + Send + Sync + 'static>) -> Result { |
| 34 | + let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::ANY, 8080)); |
| 35 | + let listener = TcpListener::try_new(net::init_ns(), &addr)?; |
| 36 | + spawn_task!(ex, accept_loop(listener, ex.into()))?; |
| 37 | + Ok(()) |
| 38 | +} |
| 39 | + |
| 40 | +struct RustEchoServer { |
| 41 | + _handle: AutoStopHandle<dyn Executor>, |
| 42 | +} |
| 43 | + |
| 44 | +impl kernel::Module for RustEchoServer { |
| 45 | + fn init(_name: &'static CStr, _module: &'static ThisModule) -> Result<Self> { |
| 46 | + let handle = WqExecutor::try_new(kernel::workqueue::system())?; |
| 47 | + start_listener(handle.executor())?; |
| 48 | + Ok(Self { |
| 49 | + _handle: handle.into(), |
| 50 | + }) |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +module! { |
| 55 | + type: RustEchoServer, |
| 56 | + name: b"rust_echo_server", |
| 57 | + author: b"Rust for Linux Contributors", |
| 58 | + description: b"Rust tcp echo sample", |
| 59 | + license: b"GPL v2", |
| 60 | +} |
0 commit comments