Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
dee1c26
xous: ffi: fix lend_impl() return values
xobs Dec 7, 2023
944dc21
xous: ffi: correct size of freed memory
xobs Dec 24, 2023
118e8f7
xous: std: thread_parking: fix deadlocks
bunnie Dec 22, 2023
626926f
std: xous: rework condvar to fix soundness issues
xobs Dec 24, 2023
f732d2b
std: xous: pass entire memory range to flag updater
xobs Dec 29, 2023
b5c1c47
std: xous: use blocking_scalars for mutex unlock
xobs Dec 29, 2023
eabd445
std: xous: rewrite rwlock to be more robust
xobs Dec 24, 2023
762e58a
std: once: use queue implementation on Xous
xobs Dec 24, 2023
007bf7a
std: xous: fix thread_local_key under tests
xobs Dec 24, 2023
ef4f722
std: xous: share allocator symbol in tests
xobs Dec 29, 2023
aa8acc2
xous: net: initial commit of network support
xobs Nov 7, 2023
aa73860
std: xous: mark stdio structs as `repr(C)`
xobs Dec 29, 2023
99b0659
std: xous: use constants for stdout and stderr
xobs Dec 29, 2023
50e4fed
xous: thread: mark thread_main() as divergent
xobs Dec 29, 2023
89cf177
std::net: bind update for using backlog as `-1` too.
devnexen Jan 13, 2024
a8bb418
make unsafe_op_in_unsafe_fn MachineApplicable and add it to 2024 comp…
asquared31415 Jan 13, 2024
1c77f87
add help message for `exclusive_range_pattern` error
rowan-sl Jan 19, 2024
755cfbf
core: introduce split_at{,_mut}_checked
mina86 Dec 3, 2023
9c3091e
exclude unexported macro bindings from extern crate
bvanjoi Dec 28, 2023
1afd216
use u64 to represent file size
onur-ozkan Jan 21, 2024
50cbbef
review
mina86 Jan 21, 2024
802d16c
Don't actually make bound ty/const for RTN
compiler-errors Jan 21, 2024
7ce206d
Fix -Zremap-path-scope typo
micolous Jan 22, 2024
99b4f80
Rollup merge of #118578 - mina86:c, r=dtolnay
matthiaskrgr Jan 22, 2024
c5984ca
Rollup merge of #119369 - bvanjoi:fix-119301, r=petrochenkov
matthiaskrgr Jan 22, 2024
e9c2e1b
Rollup merge of #119408 - betrusted-io:xous-fixes-add-network, r=Mark…
matthiaskrgr Jan 22, 2024
8c3c8bb
Rollup merge of #119943 - devnexen:listener_update3, r=thomcc
matthiaskrgr Jan 22, 2024
34bab29
Rollup merge of #119948 - asquared31415:unsafe_op_in_unsafe_fn_fix, r…
matthiaskrgr Jan 22, 2024
9e896f4
Rollup merge of #119999 - onur-ozkan:remote-test-tools, r=Mark-Simula…
matthiaskrgr Jan 22, 2024
2346647
Rollup merge of #120152 - rowan-sl:help-message-for-range-pattern, r=…
matthiaskrgr Jan 22, 2024
ba542c8
Rollup merge of #120213 - compiler-errors:dont-make-non-lifetime-bind…
matthiaskrgr Jan 22, 2024
44e44f4
Rollup merge of #120225 - micolous:patch-1, r=michaelwoerister
matthiaskrgr Jan 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
xous: net: initial commit of network support
This is an initial commit of network support for Xous.

On hardware, is backed by smoltcp running via a Xous server in a
separate process space.

This patch adds TCP and UDP client and server support as well as DNS
resolution support using the dns Xous server.

Signed-off-by: Sean Cross <[email protected]>
  • Loading branch information
xobs committed Jan 13, 2024
commit aa8acc2215f625db898c0f9feab3a1702f38a190
6 changes: 6 additions & 0 deletions library/std/src/os/xous/services.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
use crate::os::xous::ffi::Connection;
use core::sync::atomic::{AtomicU32, Ordering};

mod dns;
pub(crate) use dns::*;

mod log;
pub(crate) use log::*;

mod net;
pub(crate) use net::*;

mod systime;
pub(crate) use systime::*;

Expand Down
28 changes: 28 additions & 0 deletions library/std/src/os/xous/services/dns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use crate::os::xous::ffi::Connection;
use crate::os::xous::services::connect;
use core::sync::atomic::{AtomicU32, Ordering};

#[repr(usize)]
pub(crate) enum DnsLendMut {
RawLookup = 6,
}

impl Into<usize> for DnsLendMut {
fn into(self) -> usize {
self as usize
}
}

/// Return a `Connection` to the DNS lookup server. This server is used for
/// querying domain name values.
pub(crate) fn dns_server() -> Connection {
static DNS_CONNECTION: AtomicU32 = AtomicU32::new(0);
let cid = DNS_CONNECTION.load(Ordering::Relaxed);
if cid != 0 {
return cid.into();
}

let cid = connect("_DNS Resolver Middleware_").unwrap();
DNS_CONNECTION.store(cid.into(), Ordering::Relaxed);
cid
}
95 changes: 95 additions & 0 deletions library/std/src/os/xous/services/net.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use crate::os::xous::ffi::Connection;
use crate::os::xous::services::connect;
use core::sync::atomic::{AtomicU32, Ordering};

pub(crate) enum NetBlockingScalar {
StdGetTtlUdp(u16 /* fd */), /* 36 */
StdSetTtlUdp(u16 /* fd */, u32 /* ttl */), /* 37 */
StdGetTtlTcp(u16 /* fd */), /* 36 */
StdSetTtlTcp(u16 /* fd */, u32 /* ttl */), /* 37 */
StdGetNodelay(u16 /* fd */), /* 38 */
StdSetNodelay(u16 /* fd */, bool), /* 39 */
StdTcpClose(u16 /* fd */), /* 34 */
StdUdpClose(u16 /* fd */), /* 41 */
StdTcpStreamShutdown(u16 /* fd */, crate::net::Shutdown /* how */), /* 46 */
}

pub(crate) enum NetLendMut {
StdTcpConnect, /* 30 */
StdTcpTx(u16 /* fd */), /* 31 */
StdTcpPeek(u16 /* fd */, bool /* nonblocking */), /* 32 */
StdTcpRx(u16 /* fd */, bool /* nonblocking */), /* 33 */
StdGetAddress(u16 /* fd */), /* 35 */
StdUdpBind, /* 40 */
StdUdpRx(u16 /* fd */), /* 42 */
StdUdpTx(u16 /* fd */), /* 43 */
StdTcpListen, /* 44 */
StdTcpAccept(u16 /* fd */), /* 45 */
}

impl Into<usize> for NetLendMut {
fn into(self) -> usize {
match self {
NetLendMut::StdTcpConnect => 30,
NetLendMut::StdTcpTx(fd) => 31 | ((fd as usize) << 16),
NetLendMut::StdTcpPeek(fd, blocking) => {
32 | ((fd as usize) << 16) | if blocking { 0x8000 } else { 0 }
}
NetLendMut::StdTcpRx(fd, blocking) => {
33 | ((fd as usize) << 16) | if blocking { 0x8000 } else { 0 }
}
NetLendMut::StdGetAddress(fd) => 35 | ((fd as usize) << 16),
NetLendMut::StdUdpBind => 40,
NetLendMut::StdUdpRx(fd) => 42 | ((fd as usize) << 16),
NetLendMut::StdUdpTx(fd) => 43 | ((fd as usize) << 16),
NetLendMut::StdTcpListen => 44,
NetLendMut::StdTcpAccept(fd) => 45 | ((fd as usize) << 16),
}
}
}

impl<'a> Into<[usize; 5]> for NetBlockingScalar {
fn into(self) -> [usize; 5] {
match self {
NetBlockingScalar::StdGetTtlTcp(fd) => [36 | ((fd as usize) << 16), 0, 0, 0, 0],
NetBlockingScalar::StdGetTtlUdp(fd) => [36 | ((fd as usize) << 16), 0, 0, 0, 1],
NetBlockingScalar::StdSetTtlTcp(fd, ttl) => {
[37 | ((fd as usize) << 16), ttl as _, 0, 0, 0]
}
NetBlockingScalar::StdSetTtlUdp(fd, ttl) => {
[37 | ((fd as usize) << 16), ttl as _, 0, 0, 1]
}
NetBlockingScalar::StdGetNodelay(fd) => [38 | ((fd as usize) << 16), 0, 0, 0, 0],
NetBlockingScalar::StdSetNodelay(fd, enabled) => {
[39 | ((fd as usize) << 16), if enabled { 1 } else { 0 }, 0, 0, 1]
}
NetBlockingScalar::StdTcpClose(fd) => [34 | ((fd as usize) << 16), 0, 0, 0, 0],
NetBlockingScalar::StdUdpClose(fd) => [41 | ((fd as usize) << 16), 0, 0, 0, 0],
NetBlockingScalar::StdTcpStreamShutdown(fd, how) => [
46 | ((fd as usize) << 16),
match how {
crate::net::Shutdown::Read => 1,
crate::net::Shutdown::Write => 2,
crate::net::Shutdown::Both => 3,
},
0,
0,
0,
],
}
}
}

/// Return a `Connection` to the Network server. This server provides all
/// OS-level networking functions.
pub(crate) fn net_server() -> Connection {
static NET_CONNECTION: AtomicU32 = AtomicU32::new(0);
let cid = NET_CONNECTION.load(Ordering::Relaxed);
if cid != 0 {
return cid.into();
}

let cid = connect("_Middleware Network Server_").unwrap();
NET_CONNECTION.store(cid.into(), Ordering::Relaxed);
cid
}
1 change: 0 additions & 1 deletion library/std/src/sys/pal/xous/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub mod fs;
#[path = "../unsupported/io.rs"]
pub mod io;
pub mod locks;
#[path = "../unsupported/net.rs"]
pub mod net;
pub mod os;
#[path = "../unix/os_str.rs"]
Expand Down
127 changes: 127 additions & 0 deletions library/std/src/sys/pal/xous/net/dns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
use crate::io;
use crate::net::{Ipv4Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use crate::os::xous::ffi::lend_mut;
use crate::os::xous::services::{dns_server, DnsLendMut};
use core::convert::{TryFrom, TryInto};

pub struct DnsError {
pub code: u8,
}

#[repr(C, align(4096))]
struct LookupHostQuery([u8; 4096]);

pub struct LookupHost {
data: LookupHostQuery,
port: u16,
offset: usize,
count: usize,
}

impl LookupHost {
pub fn port(&self) -> u16 {
self.port
}
}

impl Iterator for LookupHost {
type Item = SocketAddr;
fn next(&mut self) -> Option<SocketAddr> {
if self.offset >= self.data.0.len() {
return None;
}
match self.data.0.get(self.offset) {
Some(&4) => {
self.offset += 1;
if self.offset + 4 > self.data.0.len() {
return None;
}
let result = Some(SocketAddr::V4(SocketAddrV4::new(
Ipv4Addr::new(
self.data.0[self.offset],
self.data.0[self.offset + 1],
self.data.0[self.offset + 2],
self.data.0[self.offset + 3],
),
self.port,
)));
self.offset += 4;
result
}
Some(&6) => {
self.offset += 1;
if self.offset + 16 > self.data.0.len() {
return None;
}
let mut new_addr = [0u8; 16];
for (src, octet) in self.data.0[(self.offset + 1)..(self.offset + 16 + 1)]
.iter()
.zip(new_addr.iter_mut())
{
*octet = *src;
}
let result =
Some(SocketAddr::V6(SocketAddrV6::new(new_addr.into(), self.port, 0, 0)));
self.offset += 16;
result
}
_ => None,
}
}
}

pub fn lookup(query: &str, port: u16) -> Result<LookupHost, DnsError> {
let mut result = LookupHost { data: LookupHostQuery([0u8; 4096]), offset: 0, count: 0, port };

// Copy the query into the message that gets sent to the DNS server
for (query_byte, result_byte) in query.as_bytes().iter().zip(result.data.0.iter_mut()) {
*result_byte = *query_byte;
}

lend_mut(
dns_server(),
DnsLendMut::RawLookup.into(),
&mut result.data.0,
0,
query.as_bytes().len(),
)
.unwrap();
if result.data.0[0] != 0 {
return Err(DnsError { code: result.data.0[1] });
}
assert_eq!(result.offset, 0);
result.count = result.data.0[1] as usize;

// Advance the offset to the first record
result.offset = 2;
Ok(result)
}

impl TryFrom<&str> for LookupHost {
type Error = io::Error;

fn try_from(s: &str) -> io::Result<LookupHost> {
macro_rules! try_opt {
($e:expr, $msg:expr) => {
match $e {
Some(r) => r,
None => return Err(io::const_io_error!(io::ErrorKind::InvalidInput, &$msg)),
}
};
}

// split the string by ':' and convert the second part to u16
let (host, port_str) = try_opt!(s.rsplit_once(':'), "invalid socket address");
let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
(host, port).try_into()
}
}

impl TryFrom<(&str, u16)> for LookupHost {
type Error = io::Error;

fn try_from(v: (&str, u16)) -> io::Result<LookupHost> {
lookup(v.0, v.1)
.map_err(|_e| io::const_io_error!(io::ErrorKind::InvalidInput, &"DNS failure"))
}
}
84 changes: 84 additions & 0 deletions library/std/src/sys/pal/xous/net/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
mod dns;

mod tcpstream;
pub use tcpstream::*;

mod tcplistener;
pub use tcplistener::*;

mod udp;
pub use udp::*;

// this structure needs to be synchronized with what's in net/src/api.rs
#[repr(C)]
#[derive(Debug)]
enum NetError {
// Ok = 0,
Unaddressable = 1,
SocketInUse = 2,
// AccessDenied = 3,
Invalid = 4,
// Finished = 5,
LibraryError = 6,
// AlreadyUsed = 7,
TimedOut = 8,
WouldBlock = 9,
}

#[repr(C, align(4096))]
struct ConnectRequest {
raw: [u8; 4096],
}

#[repr(C, align(4096))]
struct SendData {
raw: [u8; 4096],
}

#[repr(C, align(4096))]
pub struct ReceiveData {
raw: [u8; 4096],
}

#[repr(C, align(4096))]
pub struct GetAddress {
raw: [u8; 4096],
}

pub use dns::LookupHost;

#[allow(nonstandard_style)]
pub mod netc {
pub const AF_INET: u8 = 0;
pub const AF_INET6: u8 = 1;
pub type sa_family_t = u8;

#[derive(Copy, Clone)]
pub struct in_addr {
pub s_addr: u32,
}

#[derive(Copy, Clone)]
pub struct sockaddr_in {
pub sin_family: sa_family_t,
pub sin_port: u16,
pub sin_addr: in_addr,
}

#[derive(Copy, Clone)]
pub struct in6_addr {
pub s6_addr: [u8; 16],
}

#[derive(Copy, Clone)]
pub struct sockaddr_in6 {
pub sin6_family: sa_family_t,
pub sin6_port: u16,
pub sin6_addr: in6_addr,
pub sin6_flowinfo: u32,
pub sin6_scope_id: u32,
}

#[derive(Copy, Clone)]
pub struct sockaddr {}
}
Loading