Testing a small http-client on Linux using no_std & embedded reqwless.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add RNG backends for TLS: dummy, dev-urandom, getrandom

rektide c8aacedf 3d0d65e4

+137 -3
.beads/dolt-monitor.pid.lock

This is a binary file and will not be displayed.

+1
.tool-versions
··· 1 + rust nightly
+3
Cargo.toml
··· 14 14 dns-getaddrinfo = [] 15 15 dns-ip-only = [] 16 16 https = ["reqwless/embedded-tls", "dep:der"] 17 + rng-dummy = [] 18 + rng-dev-urandom = [] 19 + rng-getrandom = [] 17 20 18 21 [dependencies] 19 22 embedded-io = { version = "0.7", default-features = false }
+2 -3
src/app/download.rs
··· 12 12 13 13 #[cfg(feature = "https")] 14 14 const TLS_BUFFER_SIZE: usize = 16 * 1024; 15 - #[cfg(feature = "https")] 16 - const TLS_DUMMY_SEED: u64 = 0xA17E_5EED_D00D_F00D; 17 15 18 16 pub async fn download_to_stdout(url: &str) -> Result<(), AppError> { 19 17 validate_url_for_mode(url)?; ··· 38 36 let dns = new_dns(); 39 37 let mut tls_read_buf = [0_u8; TLS_BUFFER_SIZE]; 40 38 let mut tls_write_buf = [0_u8; TLS_BUFFER_SIZE]; 39 + let seed = crate::rng::new_rng_seed(); 41 40 let mut client = HttpClient::new_with_tls( 42 41 &tcp, 43 42 &dns, 44 - TlsConfig::new(TLS_DUMMY_SEED, &mut tls_read_buf, &mut tls_write_buf, TlsVerify::None), 43 + TlsConfig::new(seed, &mut tls_read_buf, &mut tls_write_buf, TlsVerify::None), 45 44 ); 46 45 stream_get_to_stdout(&mut client, url).await 47 46 }
+2
src/main.rs
··· 19 19 mod dns; 20 20 mod net; 21 21 mod platform; 22 + #[cfg(feature = "https")] 23 + mod rng; 22 24 mod runtime; 23 25 24 26 use core::ffi::{c_char, c_int};
+30
src/rng/dev_urandom.rs
··· 1 + use crate::runtime::fd_io::{read_fd, write_all_fd}; 2 + 3 + const DEV_URANDOM_PATH: &[u8] = b"/dev/urandom\0"; 4 + 5 + pub fn rng_seed_impl() -> u64 { 6 + let fd = unsafe { 7 + let path_ptr = DEV_URANDOM_PATH.as_ptr() as *const core::ffi::c_char; 8 + libc::open(path_ptr, libc::O_RDONLY) 9 + }; 10 + 11 + if fd < 0 { 12 + write_all_fd(libc::STDERR_FILENO, b"failed to open /dev/urandom\n").ok(); 13 + unsafe { libc::_exit(1) }; 14 + } 15 + 16 + let mut buf = [0u8; 8]; 17 + match read_fd(fd, &mut buf) { 18 + Ok(8) => { 19 + unsafe { libc::close(fd) }; 20 + u64::from_ne_bytes(buf) 21 + } 22 + _ => { 23 + write_all_fd(libc::STDERR_FILENO, b"failed to read from /dev/urandom\n").ok(); 24 + unsafe { 25 + libc::close(fd); 26 + libc::_exit(1); 27 + } 28 + } 29 + } 30 + }
+5
src/rng/dummy.rs
··· 1 + const DUMMY_SEED: u64 = 0xA17E_5EED_D00D_F00D; 2 + 3 + pub fn rng_seed_impl() -> u64 { 4 + DUMMY_SEED 5 + }
+36
src/rng/getrandom.rs
··· 1 + use crate::runtime::fd_io::write_all_fd; 2 + 3 + const SYS_GETRANDOM: core::ffi::c_long = 318; 4 + 5 + pub fn rng_seed_impl() -> u64 { 6 + let mut buf = [0u8; 8]; 7 + let mut total_read = 0usize; 8 + 9 + while total_read < 8 { 10 + let ptr = buf.as_mut_ptr().wrapping_add(total_read); 11 + let len = 8 - total_read; 12 + let ret = unsafe { 13 + libc::syscall( 14 + SYS_GETRANDOM, 15 + ptr as *mut core::ffi::c_void, 16 + len as core::ffi::c_ulong, 17 + 0u64 as core::ffi::c_ulong, 18 + ) 19 + }; 20 + 21 + if ret < 0 { 22 + write_all_fd(libc::STDERR_FILENO, b"getrandom syscall failed\n").ok(); 23 + unsafe { libc::_exit(1) }; 24 + } 25 + 26 + let read = ret as usize; 27 + if read == 0 { 28 + write_all_fd(libc::STDERR_FILENO, b"getrandom returned 0 bytes\n").ok(); 29 + unsafe { libc::_exit(1) }; 30 + } 31 + 32 + total_read += read; 33 + } 34 + 35 + u64::from_ne_bytes(buf) 36 + }
+43
src/rng/mod.rs
··· 1 + #[cfg(feature = "rng-dev-urandom")] 2 + mod dev_urandom; 3 + #[cfg(feature = "rng-dummy")] 4 + mod dummy; 5 + #[cfg(feature = "rng-getrandom")] 6 + mod getrandom; 7 + 8 + #[cfg(all( 9 + feature = "https", 10 + not(any( 11 + feature = "rng-dummy", 12 + feature = "rng-dev-urandom", 13 + feature = "rng-getrandom" 14 + )) 15 + ))] 16 + compile_error!("https requires an RNG backend: rng-dummy, rng-dev-urandom, or rng-getrandom"); 17 + 18 + #[cfg(all( 19 + feature = "rng-dummy", 20 + any(feature = "rng-dev-urandom", feature = "rng-getrandom") 21 + ))] 22 + compile_error!("enable exactly one RNG backend: rng-dummy, rng-dev-urandom, or rng-getrandom"); 23 + 24 + #[cfg(all(feature = "rng-dev-urandom", feature = "rng-getrandom"))] 25 + compile_error!("enable exactly one RNG backend: rng-dummy, rng-dev-urandom, or rng-getrandom"); 26 + 27 + #[cfg(feature = "rng-dummy")] 28 + pub fn new_rng_seed() -> u64 { 29 + dummy::rng_seed_impl() 30 + } 31 + 32 + #[cfg(all(feature = "rng-dev-urandom", not(feature = "rng-dummy")))] 33 + pub fn new_rng_seed() -> u64 { 34 + dev_urandom::rng_seed_impl() 35 + } 36 + 37 + #[cfg(all( 38 + feature = "rng-getrandom", 39 + not(any(feature = "rng-dummy", feature = "rng-dev-urandom")) 40 + ))] 41 + pub fn new_rng_seed() -> u64 { 42 + getrandom::rng_seed_impl() 43 + }
+15
src/runtime/fd_io.rs
··· 2 2 3 3 use crate::net::errors::NetError; 4 4 5 + #[allow(dead_code)] 6 + pub fn read_fd(fd: c_int, buf: &mut [u8]) -> Result<usize, NetError> { 7 + loop { 8 + let read = unsafe { libc::read(fd, buf.as_mut_ptr().cast::<c_void>(), buf.len()) }; 9 + if read < 0 { 10 + let errno = last_errno(); 11 + if errno == libc::EINTR { 12 + continue; 13 + } 14 + return Err(NetError::Syscall(errno)); 15 + } 16 + return Ok(read as usize); 17 + } 18 + } 19 + 5 20 pub fn write_all_fd(fd: c_int, mut buf: &[u8]) -> Result<(), NetError> { 6 21 while !buf.is_empty() { 7 22 let written = unsafe { libc::write(fd, buf.as_ptr().cast::<c_void>(), buf.len()) };