summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFensteer <fensteer@protonmail.com>2018-11-16 16:06:12 +0100
committernobody <nomaill@domain.org>2018-12-06 16:29:29 +0100
commitb75d31d2f5b84a3ac5c0d59809dba918dd9c53d8 (patch)
tree02b018b6e5e266b4c2baa439bd02f56f8b989df9 /src
parentf2780946875817c41b8de1dadb1904652b697e60 (diff)
downloadnix-b75d31d2f5b84a3ac5c0d59809dba918dd9c53d8.zip
Add support of TCP_CONGESTION for setsockopt
Diffstat (limited to 'src')
-rw-r--r--src/sys/socket/sockopt.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs
index 494de4f5..17119384 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -5,6 +5,14 @@ use sys::time::TimeVal;
use libc::{self, c_int, uint8_t, c_void, socklen_t};
use std::mem;
use std::os::unix::io::RawFd;
+use std::ffi::{OsStr, OsString};
+#[cfg(target_family = "unix")]
+use std::os::unix::ffi::OsStrExt;
+
+// Constants
+// TCP_CA_NAME_MAX isn't defined in user space include files
+#[cfg(any(target_os = "freebsd", target_os = "linux"))]
+const TCP_CA_NAME_MAX: usize = 16;
/// Helper for implementing `SetSockOpt` for a given socket option. See
/// [`::sys::socket::SetSockOpt`](sys/socket/trait.SetSockOpt.html).
@@ -152,6 +160,10 @@ macro_rules! sockopt_impl {
sockopt_impl!(Both, $name, $level, $flag, usize, GetUsize, SetUsize);
};
+ (Both, $name:ident, $level:path, $flag:path, OsString<$array:ty>) => {
+ sockopt_impl!(Both, $name, $level, $flag, OsString, GetOsString<$array>, SetOsString);
+ };
+
/*
* Matchers with generic getter types must be placed at the end, so
* they'll only match _after_ specialized matchers fail
@@ -257,6 +269,8 @@ sockopt_impl!(Both, BindAny, libc::IPPROTO_IP, libc::IP_BINDANY, bool);
sockopt_impl!(Both, Mark, libc::SOL_SOCKET, libc::SO_MARK, u32);
#[cfg(any(target_os = "android", target_os = "linux"))]
sockopt_impl!(Both, PassCred, libc::SOL_SOCKET, libc::SO_PASSCRED, bool);
+#[cfg(any(target_os = "freebsd", target_os = "linux"))]
+sockopt_impl!(Both, TcpCongestion, libc::IPPROTO_TCP, libc::TCP_CONGESTION, OsString<[u8; TCP_CA_NAME_MAX]>);
/*
*
@@ -478,6 +492,53 @@ unsafe impl<'a> Set<'a, usize> for SetUsize {
}
}
+/// Getter for a `OsString` value.
+struct GetOsString<T: AsMut<[u8]>> {
+ len: socklen_t,
+ val: T,
+}
+
+unsafe impl<T: AsMut<[u8]>> Get<OsString> for GetOsString<T> {
+ unsafe fn blank() -> Self {
+ GetOsString {
+ len: mem::size_of::<T>() as socklen_t,
+ val: mem::zeroed(),
+ }
+ }
+
+ fn ffi_ptr(&mut self) -> *mut c_void {
+ &mut self.val as *mut T as *mut c_void
+ }
+
+ fn ffi_len(&mut self) -> *mut socklen_t {
+ &mut self.len
+ }
+
+ unsafe fn unwrap(mut self) -> OsString {
+ OsStr::from_bytes(self.val.as_mut()).to_owned()
+ }
+}
+
+/// Setter for a `OsString` value.
+struct SetOsString<'a> {
+ val: &'a OsStr,
+}
+
+unsafe impl<'a> Set<'a, OsString> for SetOsString<'a> {
+ fn new(val: &'a OsString) -> SetOsString {
+ SetOsString { val: val.as_os_str() }
+ }
+
+ fn ffi_ptr(&self) -> *const c_void {
+ self.val.as_bytes().as_ptr() as *const c_void
+ }
+
+ fn ffi_len(&self) -> socklen_t {
+ self.val.len() as socklen_t
+ }
+}
+
+
#[cfg(test)]
mod test {
#[cfg(any(target_os = "android", target_os = "linux"))]