diff --git a/README.md b/README.md index 406a4d2..66c532b 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Tested boards: QEMU, HiFive Unleashed, x86_64 PC (i5/i7), Raspberry Pi 3B+ * [RISCV64 GNU toolchain](https://www.sifive.com/boards) (for riscv32/64) * [AArch64 GNU toolchain](https://cs140e.sergio.bz/assignments/0-blinky/) (for aarch64) * [musl-cross-make](https://github.com/richfelker/musl-cross-make) (for userland musl) +* [libfuse-dev](https://github.com/libfuse/libfuse) (for userland image generation) See [Travis script](./.travis.yml) for details. diff --git a/kernel/src/arch/aarch64/mod.rs b/kernel/src/arch/aarch64/mod.rs index ae54ba9..39e25cc 100644 --- a/kernel/src/arch/aarch64/mod.rs +++ b/kernel/src/arch/aarch64/mod.rs @@ -9,6 +9,7 @@ pub mod cpu; pub mod driver; pub mod timer; pub mod syscall; +pub mod rand; #[cfg(feature = "board_raspi3")] #[path = "board/raspi3/mod.rs"] diff --git a/kernel/src/arch/aarch64/rand.rs b/kernel/src/arch/aarch64/rand.rs new file mode 100644 index 0000000..7395793 --- /dev/null +++ b/kernel/src/arch/aarch64/rand.rs @@ -0,0 +1,3 @@ +pub fn rand() -> u64 { + return 0; +} \ No newline at end of file diff --git a/kernel/src/arch/riscv32/mod.rs b/kernel/src/arch/riscv32/mod.rs index 4b42ad0..85014d0 100644 --- a/kernel/src/arch/riscv32/mod.rs +++ b/kernel/src/arch/riscv32/mod.rs @@ -7,6 +7,7 @@ pub mod compiler_rt; pub mod consts; pub mod cpu; pub mod syscall; +pub mod rand; #[cfg(feature = "board_u540")] #[path = "board/u540/mod.rs"] mod board; diff --git a/kernel/src/arch/riscv32/rand.rs b/kernel/src/arch/riscv32/rand.rs new file mode 100644 index 0000000..7395793 --- /dev/null +++ b/kernel/src/arch/riscv32/rand.rs @@ -0,0 +1,3 @@ +pub fn rand() -> u64 { + return 0; +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/mod.rs b/kernel/src/arch/x86_64/mod.rs index 9c8c812..2aef93c 100644 --- a/kernel/src/arch/x86_64/mod.rs +++ b/kernel/src/arch/x86_64/mod.rs @@ -13,6 +13,7 @@ pub mod io; pub mod consts; pub mod timer; pub mod syscall; +pub mod rand; static AP_CAN_INIT: AtomicBool = ATOMIC_BOOL_INIT; diff --git a/kernel/src/arch/x86_64/rand.rs b/kernel/src/arch/x86_64/rand.rs new file mode 100644 index 0000000..c870679 --- /dev/null +++ b/kernel/src/arch/x86_64/rand.rs @@ -0,0 +1,7 @@ +use core::arch::x86_64::_rdtsc; + +pub fn rand() -> u64 { + // rdrand is not implemented in QEMU + // so use rdtsc instead + unsafe { _rdtsc() as u64 } +} diff --git a/kernel/src/drivers/net/ixgbe.rs b/kernel/src/drivers/net/ixgbe.rs index 351187c..032e9b8 100644 --- a/kernel/src/drivers/net/ixgbe.rs +++ b/kernel/src/drivers/net/ixgbe.rs @@ -32,6 +32,7 @@ struct IXGBEDriver { inner: ixgbe::IXGBEDriver, header: usize, size: usize, + mtu: usize, } impl Drop for IXGBEDriver { @@ -177,7 +178,9 @@ impl<'a> phy::Device<'a> for IXGBEDriver { fn capabilities(&self) -> DeviceCapabilities { let mut caps = DeviceCapabilities::default(); - caps.max_transmission_unit = ixgbe::IXGBEDriver::get_mtu(); // max MTU + // do not use max MTU by default + //caps.max_transmission_unit = ixgbe::IXGBEDriver::get_mtu(); // max MTU + caps.max_transmission_unit = self.mtu; caps.max_burst_size = Some(256); // IP Rx checksum is offloaded with RXCSUM caps.checksum.ipv4 = Checksum::Tx; @@ -241,14 +244,20 @@ pub fn ixgbe_init( inner: ixgbe, header, size, + mtu: 1500, }; let ip_addrs = [IpCidr::new(IpAddress::v4(10, 0, 0, 2), 24)]; let neighbor_cache = NeighborCache::new(BTreeMap::new()); - let iface = EthernetInterfaceBuilder::new(net_driver.clone()) + let mut routes = Routes::new(BTreeMap::new()); + routes + .add_default_ipv4_route(Ipv4Address::new(10, 0, 0, 1)) + .unwrap(); + let mut iface = EthernetInterfaceBuilder::new(net_driver.clone()) .ethernet_addr(ethernet_addr) .ip_addrs(ip_addrs) .neighbor_cache(neighbor_cache) + .routes(routes) .finalize(); info!("ixgbe: interface {} up", &name); diff --git a/kernel/src/net/structs.rs b/kernel/src/net/structs.rs index 5779600..bc88361 100644 --- a/kernel/src/net/structs.rs +++ b/kernel/src/net/structs.rs @@ -1,6 +1,7 @@ use alloc::sync::Arc; use core::fmt; +use crate::arch::rand; use crate::drivers::{NET_DRIVERS, SOCKET_ACTIVITY}; use crate::process::structs::Process; use crate::sync::SpinNoIrqLock as Mutex; @@ -41,8 +42,11 @@ pub struct SocketWrapper { pub fn get_ephemeral_port() -> u16 { // TODO selects non-conflict high port - static mut EPHEMERAL_PORT: u16 = 49152; + static mut EPHEMERAL_PORT: u16 = 0; unsafe { + if EPHEMERAL_PORT == 0 { + EPHEMERAL_PORT = (49152 + rand::rand() % (65536 - 49152)) as u16; + } if EPHEMERAL_PORT == 65535 { EPHEMERAL_PORT = 49152; } else { diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index 312411a..326985c 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -26,6 +26,9 @@ const IPPROTO_TCP: usize = 6; const TCP_SENDBUF: usize = 512 * 1024; // 512K const TCP_RECVBUF: usize = 512 * 1024; // 512K +const UDP_SENDBUF: usize = 64 * 1024; // 64K +const UDP_RECVBUF: usize = 64 * 1024; // 64K + pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResult { info!( "socket: domain: {}, socket_type: {}, protocol: {}", @@ -58,10 +61,14 @@ pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResu SOCK_DGRAM => { let fd = proc.get_free_fd(); - let udp_rx_buffer = - UdpSocketBuffer::new(vec![UdpPacketMetadata::EMPTY], vec![0; 2048]); - let udp_tx_buffer = - UdpSocketBuffer::new(vec![UdpPacketMetadata::EMPTY], vec![0; 2048]); + let udp_rx_buffer = UdpSocketBuffer::new( + vec![UdpPacketMetadata::EMPTY; 1024], + vec![0; UDP_RECVBUF], + ); + let udp_tx_buffer = UdpSocketBuffer::new( + vec![UdpPacketMetadata::EMPTY; 1024], + vec![0; UDP_SENDBUF], + ); let udp_socket = UdpSocket::new(udp_rx_buffer, udp_tx_buffer); let udp_handle = SOCKETS.lock().add(udp_socket); @@ -272,9 +279,14 @@ pub fn sys_sendto( proc.vm.check_read_array(base, len)?; let wrapper = proc.get_socket(fd)?; - let endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?; let slice = unsafe { slice::from_raw_parts(base, len) }; - wrapper.write(&slice, Some(endpoint)) + if addr.is_null() { + wrapper.write(&slice, None) + } else { + let endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?; + info!("sys_sendto: sending to endpoint {:?}", endpoint); + wrapper.write(&slice, Some(endpoint)) + } } pub fn sys_recvfrom( diff --git a/user b/user index 835568e..bf9d296 160000 --- a/user +++ b/user @@ -1 +1 @@ -Subproject commit 835568e2059ef872320e41517e826ced0768e357 +Subproject commit bf9d296331fd160849abd45faf361941b533c08d