[libos] Implement inner-defined sockopt with ioctl api
This commit is contained in:
		
							parent
							
								
									92ec7c334b
								
							
						
					
					
						commit
						9d4dcc2b21
					
				| @ -1,7 +1,7 @@ | ||||
| use atomic::Atomic; | ||||
| use std::any::Any; | ||||
| use std::io::{Read, Seek, SeekFrom, Write}; | ||||
| use std::mem; | ||||
| use atomic::Atomic; | ||||
| 
 | ||||
| use super::*; | ||||
| use crate::fs::{ | ||||
|  | ||||
| @ -1,14 +1,15 @@ | ||||
| use std::any::Any; | ||||
| use std::io::{Read, Seek, SeekFrom, Write}; | ||||
| 
 | ||||
| use atomic::{Atomic, Ordering}; | ||||
| 
 | ||||
| use super::*; | ||||
| use crate::fs::{AccessMode, File, HostFd, IoEvents, StatusFlags, STATUS_FLAGS_MASK}; | ||||
| use crate::fs::{ | ||||
|     AccessMode, AtomicIoEvents, File, HostFd, IoEvents, StatusFlags, STATUS_FLAGS_MASK, | ||||
| }; | ||||
| use crate::fs::{ | ||||
|     GetIfConf, GetIfReqWithRawCmd, GetReadBufLen, IoctlCmd, NonBuiltinIoctlCmd, SetNonBlocking, | ||||
| }; | ||||
| use crate::net::socket::sockopt::{GetSockOptRawCmd, SetSockOptRawCmd}; | ||||
| use atomic::{Atomic, Ordering}; | ||||
| 
 | ||||
| //TODO: refactor write syscall to allow zero length with non-zero buffer
 | ||||
| impl File for HostSocket { | ||||
|  | ||||
							
								
								
									
										64
									
								
								src/libos/src/net/socket/sockopt/get.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										64
									
								
								src/libos/src/net/socket/sockopt/get.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| use crate::{fs::IoctlCmd, prelude::*}; | ||||
| use libc::ocall::getsockopt as do_getsockopt; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct GetSockOptRawCmd { | ||||
|     level: i32, | ||||
|     optname: i32, | ||||
|     optval: Box<[u8]>, | ||||
|     optlen: Option<u32>, | ||||
| } | ||||
| 
 | ||||
| impl GetSockOptRawCmd { | ||||
|     pub fn new(level: i32, optname: i32, max_optlen: u32) -> Self { | ||||
|         // Using uninit slice is safe, since the buffer in rust SDK ocall is [out] type.
 | ||||
|         let optval = unsafe { Box::new_uninit_slice(max_optlen as usize).assume_init() }; | ||||
|         Self { | ||||
|             level, | ||||
|             optname, | ||||
|             optval, | ||||
|             optlen: None, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn execute(&mut self, fd: FileDesc) -> Result<()> { | ||||
|         if self.optlen.is_some() { | ||||
|             return_errno!(EINVAL, "can not execute twice"); | ||||
|         } | ||||
|         self.optlen = Some(getsockopt_by_host( | ||||
|             fd, | ||||
|             self.level, | ||||
|             self.optname, | ||||
|             &mut self.optval, | ||||
|         )?); | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     pub fn output(&self) -> Option<&[u8]> { | ||||
|         self.optlen.map(|_| self.optval.as_ref()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl IoctlCmd for GetSockOptRawCmd {} | ||||
| 
 | ||||
| pub fn getsockopt_by_host( | ||||
|     fd: FileDesc, | ||||
|     level: i32, | ||||
|     optname: i32, | ||||
|     optval: &mut [u8], | ||||
| ) -> Result<u32> { | ||||
|     let max_optlen = optval.len() as u32; | ||||
|     let mut optlen = max_optlen; | ||||
|     try_libc!(do_getsockopt( | ||||
|         fd as _, | ||||
|         level as _, | ||||
|         optname as _, | ||||
|         optval.as_mut_ptr() as _, | ||||
|         &mut optlen as *mut u32 | ||||
|     )); | ||||
|     // Defence Iago attack
 | ||||
|     if optlen > max_optlen { | ||||
|         return_errno!(EINVAL, "host returns a invalid optlen"); | ||||
|     } | ||||
|     Ok(optlen) | ||||
| } | ||||
							
								
								
									
										3
									
								
								src/libos/src/net/socket/sockopt/get_acceptconn.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								src/libos/src/net/socket/sockopt/get_acceptconn.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| crate::impl_ioctl_cmd! { | ||||
|     pub struct GetAcceptConnCmd<Input=(), Output=i32> {} | ||||
| } | ||||
							
								
								
									
										3
									
								
								src/libos/src/net/socket/sockopt/get_domain.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								src/libos/src/net/socket/sockopt/get_domain.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| crate::impl_ioctl_cmd! { | ||||
|     pub struct GetDomainCmd<Input=(), Output=i32> {} | ||||
| } | ||||
							
								
								
									
										3
									
								
								src/libos/src/net/socket/sockopt/get_error.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								src/libos/src/net/socket/sockopt/get_error.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| crate::impl_ioctl_cmd! { | ||||
|     pub struct GetErrorCmd<Input=(), Output=i32> {} | ||||
| } | ||||
							
								
								
									
										105
									
								
								src/libos/src/net/socket/sockopt/get_output.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										105
									
								
								src/libos/src/net/socket/sockopt/get_output.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | ||||
| use super::{GetRecvTimeoutCmd, GetSendTimeoutCmd}; | ||||
| 
 | ||||
| use super::{ | ||||
|     GetAcceptConnCmd, GetDomainCmd, GetErrorCmd, GetPeerNameCmd, GetRcvBufSizeCmd, | ||||
|     GetSndBufSizeCmd, GetSockOptRawCmd, GetTypeCmd, | ||||
| }; | ||||
| 
 | ||||
| use libc::timeval; | ||||
| use std::time::Duration; | ||||
| 
 | ||||
| use crate::prelude::*; | ||||
| 
 | ||||
| pub trait GetOutputAsBytes { | ||||
|     fn get_output_as_bytes(&self) -> Option<&[u8]>; | ||||
| } | ||||
| 
 | ||||
| impl GetOutputAsBytes for GetSockOptRawCmd { | ||||
|     fn get_output_as_bytes(&self) -> Option<&[u8]> { | ||||
|         self.output() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl GetOutputAsBytes for GetDomainCmd { | ||||
|     fn get_output_as_bytes(&self) -> Option<&[u8]> { | ||||
|         self.output().map(|val_ref| unsafe { | ||||
|             std::slice::from_raw_parts(val_ref as *const _ as *const u8, std::mem::size_of::<i32>()) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl GetOutputAsBytes for GetErrorCmd { | ||||
|     fn get_output_as_bytes(&self) -> Option<&[u8]> { | ||||
|         self.output().map(|val_ref| unsafe { | ||||
|             std::slice::from_raw_parts(val_ref as *const _ as *const u8, std::mem::size_of::<i32>()) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl GetOutputAsBytes for GetAcceptConnCmd { | ||||
|     fn get_output_as_bytes(&self) -> Option<&[u8]> { | ||||
|         self.output().map(|val_ref| unsafe { | ||||
|             std::slice::from_raw_parts(val_ref as *const _ as *const u8, std::mem::size_of::<i32>()) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl GetOutputAsBytes for GetPeerNameCmd { | ||||
|     fn get_output_as_bytes(&self) -> Option<&[u8]> { | ||||
|         self.output().map(|val_ref| unsafe { | ||||
|             std::slice::from_raw_parts(&(val_ref.0).0 as *const _ as *const u8, (val_ref.0).1) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl GetOutputAsBytes for GetTypeCmd { | ||||
|     fn get_output_as_bytes(&self) -> Option<&[u8]> { | ||||
|         self.output().map(|val_ref| unsafe { | ||||
|             std::slice::from_raw_parts(val_ref as *const _ as *const u8, std::mem::size_of::<i32>()) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl GetOutputAsBytes for GetSndBufSizeCmd { | ||||
|     fn get_output_as_bytes(&self) -> Option<&[u8]> { | ||||
|         self.output().map(|val_ref| unsafe { | ||||
|             std::slice::from_raw_parts( | ||||
|                 val_ref as *const _ as *const u8, | ||||
|                 std::mem::size_of::<usize>(), | ||||
|             ) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl GetOutputAsBytes for GetRcvBufSizeCmd { | ||||
|     fn get_output_as_bytes(&self) -> Option<&[u8]> { | ||||
|         self.output().map(|val_ref| unsafe { | ||||
|             std::slice::from_raw_parts( | ||||
|                 val_ref as *const _ as *const u8, | ||||
|                 std::mem::size_of::<usize>(), | ||||
|             ) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl GetOutputAsBytes for GetRecvTimeoutCmd { | ||||
|     fn get_output_as_bytes(&self) -> Option<&[u8]> { | ||||
|         self.output().map(|val_ref| unsafe { | ||||
|             std::slice::from_raw_parts( | ||||
|                 val_ref as *const _ as *const u8, | ||||
|                 std::mem::size_of::<timeval>(), | ||||
|             ) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl GetOutputAsBytes for GetSendTimeoutCmd { | ||||
|     fn get_output_as_bytes(&self) -> Option<&[u8]> { | ||||
|         self.output().map(|val_ref| unsafe { | ||||
|             std::slice::from_raw_parts( | ||||
|                 val_ref as *const _ as *const u8, | ||||
|                 std::mem::size_of::<timeval>(), | ||||
|             ) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										15
									
								
								src/libos/src/net/socket/sockopt/get_peername.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										15
									
								
								src/libos/src/net/socket/sockopt/get_peername.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| use sgx_trts::libc; | ||||
| 
 | ||||
| pub struct AddrStorage(pub (libc::sockaddr_storage, usize)); | ||||
| impl std::fmt::Debug for AddrStorage { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         f.debug_tuple("AddrStorage") | ||||
|             .field(&"sockaddr_storage") | ||||
|             .field(&(self.0).1) | ||||
|             .finish() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| crate::impl_ioctl_cmd! { | ||||
|     pub struct GetPeerNameCmd<Input=(), Output=AddrStorage> {} | ||||
| } | ||||
							
								
								
									
										7
									
								
								src/libos/src/net/socket/sockopt/get_sockbuf.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										7
									
								
								src/libos/src/net/socket/sockopt/get_sockbuf.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| crate::impl_ioctl_cmd! { | ||||
|     pub struct GetSndBufSizeCmd<Input=(), Output=usize> {} | ||||
| } | ||||
| 
 | ||||
| crate::impl_ioctl_cmd! { | ||||
|     pub struct GetRcvBufSizeCmd<Input=(), Output=usize> {} | ||||
| } | ||||
							
								
								
									
										3
									
								
								src/libos/src/net/socket/sockopt/get_type.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								src/libos/src/net/socket/sockopt/get_type.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| crate::impl_ioctl_cmd! { | ||||
|     pub struct GetTypeCmd<Input=(), Output=i32> {} | ||||
| } | ||||
							
								
								
									
										105
									
								
								src/libos/src/net/socket/sockopt/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										105
									
								
								src/libos/src/net/socket/sockopt/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | ||||
| mod get; | ||||
| mod get_acceptconn; | ||||
| mod get_domain; | ||||
| mod get_error; | ||||
| mod get_output; | ||||
| mod get_peername; | ||||
| mod get_sockbuf; | ||||
| mod get_type; | ||||
| mod set; | ||||
| mod set_sockbuf; | ||||
| mod timeout; | ||||
| 
 | ||||
| pub use get::{getsockopt_by_host, GetSockOptRawCmd}; | ||||
| pub use get_acceptconn::GetAcceptConnCmd; | ||||
| pub use get_domain::GetDomainCmd; | ||||
| pub use get_error::GetErrorCmd; | ||||
| pub use get_output::*; | ||||
| pub use get_peername::{AddrStorage, GetPeerNameCmd}; | ||||
| pub use get_sockbuf::{GetRcvBufSizeCmd, GetSndBufSizeCmd}; | ||||
| pub use get_type::GetTypeCmd; | ||||
| pub use set::{setsockopt_by_host, SetSockOptRawCmd}; | ||||
| pub use set_sockbuf::{SetRcvBufSizeCmd, SetSndBufSizeCmd}; | ||||
| pub use timeout::{ | ||||
|     timeout_to_timeval, GetRecvTimeoutCmd, GetSendTimeoutCmd, SetRecvTimeoutCmd, SetSendTimeoutCmd, | ||||
| }; | ||||
| 
 | ||||
| use num_enum::{IntoPrimitive, TryFromPrimitive}; | ||||
| 
 | ||||
| #[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)] | ||||
| #[repr(i32)] | ||||
| #[allow(non_camel_case_types)] | ||||
| pub enum SockOptName { | ||||
|     SO_DEBUG = 1,      // i32, bool, 0 or 1
 | ||||
|     SO_REUSEADDR = 2,  // i32, bool, 0 or 1
 | ||||
|     SO_TYPE = 3,       // [builtin] read-only, i32
 | ||||
|     SO_ERROR = 4,      // read-only, i32
 | ||||
|     SO_DONTROUTE = 5,  // i32, bool, 0 or 1, Equal to: send with MSG_DONTROUTE flag.
 | ||||
|     SO_BROADCAST = 6,  // i32, bool, 0 or 1
 | ||||
|     SO_SNDBUF = 7,     // i32
 | ||||
|     SO_RCVBUF = 8,     // i32
 | ||||
|     SO_KEEPALIVE = 9,  // i32, bool, 0 or 1
 | ||||
|     SO_OOBINLINE = 10, // i32, bool, 0 or 1, Might equal to: recv with MSG_OOB flag.
 | ||||
|     SO_NO_CHECK = 11,  // i32, bool, 0 or 1
 | ||||
|     SO_PRIORITY = 12,  // i32, >= 0, <= 6
 | ||||
|     SO_LINGER = 13,    // linger structure
 | ||||
|     SO_BSDCOMPAT = 14, // removed in linux 2.2
 | ||||
|     SO_REUSEPORT = 15, // i32, bool, 0 or 1
 | ||||
|     SO_PASSCRED = 16,  // i32, bool, 0 or 1
 | ||||
|     SO_PEERCRED = 17,  // read-only, ucred structure
 | ||||
|     // TODO: there may be a bug.
 | ||||
|     // select(2), poll(2), and epoll(7) indicate a socket as readable
 | ||||
|     // only if at least SO_RCVLOWAT bytes are available.
 | ||||
|     SO_RCVLOWAT = 18,                      // i32
 | ||||
|     SO_SNDLOWAT = 19,                      // read-only, i32
 | ||||
|     SO_RCVTIMEO_OLD = 20,                  // struct timeval
 | ||||
|     SO_SNDTIMEO_OLD = 21,                  // struct timeval
 | ||||
|     SO_SECURITY_AUTHENTICATION = 22,       // no doc / code
 | ||||
|     SO_SECURITY_ENCRYPTION_TRANSPORT = 23, // no doc / code
 | ||||
|     SO_SECURITY_ENCRYPTION_NETWORK = 24,   // no doc / code
 | ||||
|     SO_BINDTODEVICE = 25,                  // array
 | ||||
|     SO_ATTACH_FILTER = 26,                 // SO_GET_FILTER, BPF-related
 | ||||
|     SO_DETACH_FILTER = 27,                 // SO_DETACH_BPF, BPF-related
 | ||||
|     SO_PEERNAME = 28,                      // [builtin] read-only, peer name
 | ||||
|     SO_TIMESTAMP_OLD = 29,                 // i32, bool, 0 or 1, cmsg-related
 | ||||
|     SO_ACCEPTCONN = 30,                    // [builtin] read-only, i32, bool, 0 or 1
 | ||||
|     SO_PEERSEC = 31,                       // read-only, array
 | ||||
|     SO_SNDBUFFORCE = 32,                   // i32
 | ||||
|     SO_RCVBUFFORCE = 33,                   // i32
 | ||||
|     SO_PASSSEC = 34,                       // i32, bool, 0 or 1, cmsg-related
 | ||||
|     SO_TIMESTAMPNS_OLD = 35,               // i32, bool, 0 or 1, cmsg-related
 | ||||
|     SO_MARK = 36,                          // i32
 | ||||
|     SO_TIMESTAMPING_OLD = 37,              // i32, bool, 0 or 1, cmsg-related
 | ||||
|     SO_PROTOCOL = 38,                      // read-only, i32
 | ||||
|     SO_DOMAIN = 39,                        // [builtin] read-only, i32
 | ||||
|     SO_RXQ_OVFL = 40,                      // i32, bool, 0 or 1, cmsg-related
 | ||||
|     SO_WIFI_STATUS = 41,                   // i32, bool, 0 or 1
 | ||||
|     // TODO: there may be a bug when specify SO_PEEK_OFF and MSG_PEEK
 | ||||
|     SO_PEEK_OFF = 42,                // i32
 | ||||
|     SO_NOFCS = 43,                   // i32, bool, 0 or 1
 | ||||
|     SO_LOCK_FILTER = 44,             // i32, bool, 0 or 1
 | ||||
|     SO_SELECT_ERR_QUEUE = 45,        // i32, bool, 0 or 1
 | ||||
|     SO_BUSY_POLL = 46,               // i32
 | ||||
|     SO_MAX_PACING_RATE = 47,         // u64
 | ||||
|     SO_BPF_EXTENSIONS = 48,          // BPF-related
 | ||||
|     SO_INCOMING_CPU = 49,            // i32
 | ||||
|     SO_ATTACH_BPF = 50,              // BPF-related
 | ||||
|     SO_ATTACH_REUSEPORT_CBPF = 51,   // BPF-related
 | ||||
|     SO_ATTACH_REUSEPORT_EBPF = 52,   // BPF-related
 | ||||
|     SO_CNX_ADVICE = 53,              // write-only, i32
 | ||||
|     SCM_TIMESTAMPING_OPT_STATS = 54, // no doc / code
 | ||||
|     SO_MEMINFO = 55,                 // read-only, array
 | ||||
|     SO_INCOMING_NAPI_ID = 56,        // read-only, i32
 | ||||
|     SO_COOKIE = 57,                  // read-only, u64
 | ||||
|     SCM_TIMESTAMPING_PKTINFO = 58,   // no doc / code
 | ||||
|     SO_PEERGROUPS = 59,              // read-only, array
 | ||||
|     SO_ZEROCOPY = 60,                // i32, bool, 0 or 1
 | ||||
|     SO_TXTIME = 61,                  // SCM_TXTIME, struct sock_txtime
 | ||||
|     SO_BINDTOIFINDEX = 62,           // i32
 | ||||
|     SO_TIMESTAMP_NEW = 63,           // i32, bool, 0 or 1, cmsg-related
 | ||||
|     SO_TIMESTAMPNS_NEW = 64,         // i32, bool, 0 or 1, cmsg-related
 | ||||
|     SO_TIMESTAMPING_NEW = 65,        // i32, bool, 0 or 1, cmsg-related
 | ||||
|     SO_RCVTIMEO_NEW = 66,            // struct timeval
 | ||||
|     SO_SNDTIMEO_NEW = 67,            // struct timeval
 | ||||
|     SO_DETACH_REUSEPORT_BPF = 68,    // BPF-related
 | ||||
| } | ||||
							
								
								
									
										38
									
								
								src/libos/src/net/socket/sockopt/set.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										38
									
								
								src/libos/src/net/socket/sockopt/set.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| use crate::{fs::IoctlCmd, prelude::*}; | ||||
| use libc::ocall::setsockopt as do_setsockopt; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct SetSockOptRawCmd { | ||||
|     level: i32, | ||||
|     optname: i32, | ||||
|     optval: Box<[u8]>, | ||||
| } | ||||
| 
 | ||||
| impl SetSockOptRawCmd { | ||||
|     pub fn new(level: i32, optname: i32, optval: &[u8]) -> Self { | ||||
|         let optval = Box::from(optval); | ||||
|         Self { | ||||
|             level, | ||||
|             optname, | ||||
|             optval, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn execute(&mut self, fd: FileDesc) -> Result<()> { | ||||
|         setsockopt_by_host(fd, self.level, self.optname, &self.optval)?; | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl IoctlCmd for SetSockOptRawCmd {} | ||||
| 
 | ||||
| pub fn setsockopt_by_host(fd: FileDesc, level: i32, optname: i32, optval: &[u8]) -> Result<()> { | ||||
|     try_libc!(do_setsockopt( | ||||
|         fd as _, | ||||
|         level as _, | ||||
|         optname as _, | ||||
|         optval.as_ptr() as _, | ||||
|         optval.len() as _ | ||||
|     )); | ||||
|     Ok(()) | ||||
| } | ||||
							
								
								
									
										62
									
								
								src/libos/src/net/socket/sockopt/set_sockbuf.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										62
									
								
								src/libos/src/net/socket/sockopt/set_sockbuf.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | ||||
| use super::set::setsockopt_by_host; | ||||
| use crate::{fs::IoctlCmd, prelude::*}; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct SetSndBufSizeCmd { | ||||
|     buf_size: usize, | ||||
| } | ||||
| 
 | ||||
| impl SetSndBufSizeCmd { | ||||
|     pub fn new(buf_size: usize) -> Self { | ||||
|         Self { buf_size } | ||||
|     } | ||||
| 
 | ||||
|     pub fn buf_size(&self) -> usize { | ||||
|         self.buf_size | ||||
|     } | ||||
| 
 | ||||
|     pub fn update_host(&self, fd: FileDesc) -> Result<()> { | ||||
|         // The buf size for host call should be divided by 2 because the value will be doubled by host kernel.
 | ||||
|         let host_call_buf_size = (self.buf_size / 2).to_ne_bytes(); | ||||
| 
 | ||||
|         // Setting SO_SNDBUF for host socket needs to respect /proc/sys/net/core/wmem_max. Thus, the value might be different on host, but it is fine.
 | ||||
|         setsockopt_by_host( | ||||
|             fd, | ||||
|             libc::SOL_SOCKET, | ||||
|             super::SockOptName::SO_SNDBUF.into(), | ||||
|             &host_call_buf_size, | ||||
|         ) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl IoctlCmd for SetSndBufSizeCmd {} | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct SetRcvBufSizeCmd { | ||||
|     buf_size: usize, | ||||
| } | ||||
| 
 | ||||
| impl SetRcvBufSizeCmd { | ||||
|     pub fn new(buf_size: usize) -> Self { | ||||
|         Self { buf_size } | ||||
|     } | ||||
| 
 | ||||
|     pub fn buf_size(&self) -> usize { | ||||
|         self.buf_size | ||||
|     } | ||||
| 
 | ||||
|     pub fn update_host(&self, fd: FileDesc) -> Result<()> { | ||||
|         // The buf size for host call should be divided by 2 because the value will be doubled by host kernel.
 | ||||
|         let host_call_buf_size = (self.buf_size / 2).to_ne_bytes(); | ||||
| 
 | ||||
|         // Setting SO_RCVBUF for host socket needs to respect /proc/sys/net/core/rmem_max. Thus, the value might be different on host, but it is fine.
 | ||||
|         setsockopt_by_host( | ||||
|             fd, | ||||
|             libc::SOL_SOCKET, | ||||
|             super::SockOptName::SO_RCVBUF.into(), | ||||
|             &host_call_buf_size, | ||||
|         ) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl IoctlCmd for SetRcvBufSizeCmd {} | ||||
							
								
								
									
										65
									
								
								src/libos/src/net/socket/sockopt/timeout.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										65
									
								
								src/libos/src/net/socket/sockopt/timeout.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | ||||
| use crate::fs::IoctlCmd; | ||||
| use crate::prelude::*; | ||||
| use libc::{suseconds_t, time_t}; | ||||
| use std::time::Duration; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct SetSendTimeoutCmd(Duration); | ||||
| 
 | ||||
| impl IoctlCmd for SetSendTimeoutCmd {} | ||||
| 
 | ||||
| impl SetSendTimeoutCmd { | ||||
|     pub fn new(timeout: Duration) -> Self { | ||||
|         Self(timeout) | ||||
|     } | ||||
| 
 | ||||
|     pub fn timeout(&self) -> &Duration { | ||||
|         &self.0 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct SetRecvTimeoutCmd(Duration); | ||||
| 
 | ||||
| impl IoctlCmd for SetRecvTimeoutCmd {} | ||||
| 
 | ||||
| impl SetRecvTimeoutCmd { | ||||
|     pub fn new(timeout: Duration) -> Self { | ||||
|         Self(timeout) | ||||
|     } | ||||
| 
 | ||||
|     pub fn timeout(&self) -> &Duration { | ||||
|         &self.0 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| crate::impl_ioctl_cmd! { | ||||
|     pub struct GetSendTimeoutCmd<Input=(), Output=timeval> {} | ||||
| } | ||||
| 
 | ||||
| crate::impl_ioctl_cmd! { | ||||
|     pub struct GetRecvTimeoutCmd<Input=(), Output=timeval> {} | ||||
| } | ||||
| 
 | ||||
| pub fn timeout_to_timeval(timeout: Option<Duration>) -> timeval { | ||||
|     match timeout { | ||||
|         Some(duration) => { | ||||
|             let sec = duration.as_secs(); | ||||
|             let usec = duration.subsec_micros(); | ||||
|             timeval { | ||||
|                 sec: sec as time_t, | ||||
|                 usec: usec as suseconds_t, | ||||
|             } | ||||
|         } | ||||
|         None => timeval { sec: 0, usec: 0 }, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Same as libc::timeval
 | ||||
| #[repr(C)] | ||||
| #[derive(Debug, Copy, Clone)] | ||||
| #[allow(non_camel_case_types)] | ||||
| pub struct timeval { | ||||
|     sec: time_t, | ||||
|     usec: suseconds_t, | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user