summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2017-08-01 17:39:35 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2017-08-01 17:39:35 +0000
commitb39d909c87fce201df0ad796d8a92df8d63b6291 (patch)
treeb52e205678a4b72f3ba04675238b857761927ccb
parentf8768e93d8a8961b700b375d47fa3fe1ff2a346a (diff)
parentc0c8e5ee24d359e19e5a60b4299aaf707f8087a0 (diff)
downloadnix-b39d909c87fce201df0ad796d8a92df8d63b6291.zip
Merge #647
647: merge socket constants r=Susurrus > Refactor the constant declarations such that all constants are only declared once with a #[cfg] that only enables the constant on the correct platforms. Closes #637 (same PR as #646 but from another branch, to see if buildbot has a problem with PR made from master branch)
-rw-r--r--CHANGELOG.md8
-rw-r--r--nix-test/src/const.c80
-rw-r--r--src/sys/socket/addr.rs246
-rw-r--r--src/sys/socket/consts.rs437
-rw-r--r--src/sys/socket/mod.rs152
-rw-r--r--src/sys/socket/sockopt.rs79
-rw-r--r--test/sys/test_socket.rs27
-rw-r--r--test/sys/test_sockopt.rs5
8 files changed, 391 insertions, 643 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 688b0dcc..d631d462 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,8 +5,16 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
+### Added
+- Added protocol families in `AddressFamily` enum.
+ ([#647](https://github.com/nix-rust/nix/pull/647))
+
### Changed
- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692))
+- Changed function signature of `socket()` and `socketpair()`. The `protocol` argument
+ has changed type from `c_int` to `SockProtocol`.
+ It accepts a `None` value for default protocol that was specified with zero using `c_int`.
+ ([#647](https://github.com/nix-rust/nix/pull/647))
## [0.9.0] 2017-07-23
diff --git a/nix-test/src/const.c b/nix-test/src/const.c
index 60447629..b0376d48 100644
--- a/nix-test/src/const.c
+++ b/nix-test/src/const.c
@@ -238,86 +238,6 @@ get_int_const(const char* err) {
GET_CONST(ECAPMODE);
#endif
- /*
- *
- * ===== SOCKET OPTIONS =====
- *
- */
-
- GET_CONST(AF_UNIX);
- GET_CONST(AF_LOCAL);
- GET_CONST(AF_INET);
- GET_CONST(AF_INET6);
- GET_CONST(SOCK_STREAM);
- GET_CONST(SOCK_DGRAM);
- GET_CONST(SOCK_SEQPACKET);
- GET_CONST(SOCK_RAW);
- GET_CONST(SOCK_RDM);
- GET_CONST(SOL_SOCKET);
- GET_CONST(IPPROTO_IP);
- GET_CONST(IPPROTO_IPV6);
- GET_CONST(IPPROTO_TCP);
- GET_CONST(IPPROTO_UDP);
- GET_CONST(SO_ACCEPTCONN);
- GET_CONST(SO_BROADCAST);
- GET_CONST(SO_DEBUG);
- GET_CONST(SO_ERROR);
- GET_CONST(SO_DONTROUTE);
- GET_CONST(SO_KEEPALIVE);
- GET_CONST(SO_LINGER);
- GET_CONST(SO_OOBINLINE);
- GET_CONST(SO_RCVBUF);
- GET_CONST(SO_RCVLOWAT);
- GET_CONST(SO_SNDLOWAT);
- GET_CONST(SO_RCVTIMEO);
- GET_CONST(SO_SNDTIMEO);
- GET_CONST(SO_REUSEADDR);
- // GET_CONST(SO_REUSEPORT);
- GET_CONST(SO_SNDBUF);
- GET_CONST(SO_TIMESTAMP);
- GET_CONST(SO_TYPE);
- GET_CONST(TCP_NODELAY);
- GET_CONST(TCP_MAXSEG);
- GET_CONST(IP_MULTICAST_IF);
- GET_CONST(IP_MULTICAST_TTL);
- GET_CONST(IP_MULTICAST_LOOP);
- GET_CONST(IP_ADD_MEMBERSHIP);
- GET_CONST(IP_DROP_MEMBERSHIP);
- GET_CONST(INADDR_ANY);
- GET_CONST(INADDR_NONE);
- GET_CONST(INADDR_BROADCAST);
- GET_CONST(MSG_OOB);
- GET_CONST(MSG_PEEK);
- GET_CONST(MSG_DONTWAIT);
- GET_CONST(MSG_EOR);
- GET_CONST(MSG_TRUNC);
- GET_CONST(MSG_CTRUNC);
- GET_CONST(SHUT_RD);
- GET_CONST(SHUT_WR);
- GET_CONST(SHUT_RDWR);
-
-#ifdef LINUX
- GET_CONST(SOL_IP);
- GET_CONST(SOL_TCP);
- GET_CONST(SOL_IPV6);
- GET_CONST(SOL_UDP);
- GET_CONST(SO_BINDTODEVICE);
- GET_CONST(SO_BSDCOMPAT);
- // GET_CONST(SO_DOMAIN);
- // GET_CONST(SO_MARK);
- GET_CONST(TCP_CORK);
- // GET_CONST(SO_BUSY_POLL);
- // GET_CONST(SO_RXQ_OVFL);
- GET_CONST(SO_PASSCRED);
- GET_CONST(SO_PRIORITY);
- // GET_CONST(SO_PROTOCOL);
- GET_CONST(SO_RCVBUFFORCE);
- // GET_CONST(SO_PEEK_OFF);
- GET_CONST(SO_PEERCRED);
- GET_CONST(SO_SNDBUFFORCE);
- GET_CONST(MSG_ERRQUEUE);
-#endif
-
return -1;
}
diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs
index 5f8b130a..71001534 100644
--- a/src/sys/socket/addr.rs
+++ b/src/sys/socket/addr.rs
@@ -1,37 +1,204 @@
-use super::{consts, sa_family_t};
+use super::sa_family_t;
use {Errno, Error, Result, NixPath};
use libc;
use std::{fmt, hash, mem, net, ptr};
use std::ffi::OsStr;
use std::path::Path;
use std::os::unix::ffi::OsStrExt;
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(any(target_os = "android", target_os = "linux"))]
use ::sys::socket::addr::netlink::NetlinkAddr;
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(any(target_os = "ios", target_os = "macos"))]
use std::os::unix::io::RawFd;
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(any(target_os = "ios", target_os = "macos"))]
use ::sys::socket::addr::sys_control::SysControlAddr;
-// TODO: uncomment out IpAddr functions: rust-lang/rfcs#988
-
-/*
- *
- * ===== AddressFamily =====
- *
- */
-
+/// These constants specify the protocol family to be used
+/// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
#[repr(i32)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum AddressFamily {
- Unix = consts::AF_UNIX,
- Inet = consts::AF_INET,
- Inet6 = consts::AF_INET6,
- #[cfg(any(target_os = "linux", target_os = "android"))]
- Netlink = consts::AF_NETLINK,
- #[cfg(any(target_os = "linux", target_os = "android"))]
- Packet = consts::AF_PACKET,
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- System = consts::AF_SYSTEM,
+ /// Local communication (see [`unix(7)`](http://man7.org/linux/man-pages/man7/unix.7.html))
+ Unix = libc::AF_UNIX,
+ /// IPv4 Internet protocols (see [`ip(7)`](http://man7.org/linux/man-pages/man7/ip.7.html))
+ Inet = libc::AF_INET,
+ /// IPv6 Internet protocols (see [`ipv6(7)`](http://man7.org/linux/man-pages/man7/ipv6.7.html))
+ Inet6 = libc::AF_INET6,
+ /// Kernel user interface device (see [`netlink(7)`](http://man7.org/linux/man-pages/man7/netlink.7.html))
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Netlink = libc::AF_NETLINK,
+ /// Low level packet interface (see [`packet(7)`](http://man7.org/linux/man-pages/man7/packet.7.html))
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Packet = libc::AF_PACKET,
+ /// KEXT Controls and Notifications
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
+ System = libc::AF_SYSTEM,
+ /// Amateur radio AX.25 protocol
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Ax25 = libc::AF_AX25,
+ /// IPX - Novell protocols
+ Ipx = libc::AF_IPX,
+ /// AppleTalk
+ AppleTalk = libc::AF_APPLETALK,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ NetRom = libc::AF_NETROM,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Bridge = libc::AF_BRIDGE,
+ /// Access to raw ATM PVCs
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ AtmPvc = libc::AF_ATMPVC,
+ /// ITU-T X.25 / ISO-8208 protocol (see [`x25(7)`](http://man7.org/linux/man-pages/man7/x25.7.html))
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ X25 = libc::AF_X25,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Rose = libc::AF_ROSE,
+ Decnet = libc::AF_DECnet,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ NetBeui = libc::AF_NETBEUI,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Security = libc::AF_SECURITY,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Key = libc::AF_KEY,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Ash = libc::AF_ASH,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Econet = libc::AF_ECONET,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ AtmSvc = libc::AF_ATMSVC,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Rds = libc::AF_RDS,
+ Sna = libc::AF_SNA,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Irda = libc::AF_IRDA,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Pppox = libc::AF_PPPOX,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Wanpipe = libc::AF_WANPIPE,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Llc = libc::AF_LLC,
+ #[cfg(target_os = "linux")]
+ Ib = libc::AF_IB,
+ #[cfg(target_os = "linux")]
+ Mpls = libc::AF_MPLS,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Can = libc::AF_CAN,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Tipc = libc::AF_TIPC,
+ #[cfg(not(any(target_os = "ios", target_os = "macos")))]
+ Bluetooth = libc::AF_BLUETOOTH,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Iucv = libc::AF_IUCV,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ RxRpc = libc::AF_RXRPC,
+ Isdn = libc::AF_ISDN,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Phonet = libc::AF_PHONET,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Ieee802154 = libc::AF_IEEE802154,
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Caif = libc::AF_CAIF,
+ /// Interface to kernel crypto API
+ #[cfg(any(target_os = "android", target_os = "linux"))]
+ Alg = libc::AF_ALG,
+ #[cfg(target_os = "linux")]
+ Nfc = libc::AF_NFC,
+ #[cfg(target_os = "linux")]
+ Vsock = libc::AF_VSOCK,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ ImpLink = libc::AF_IMPLINK,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Pup = libc::AF_PUP,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Chaos = libc::AF_CHAOS,
+ #[cfg(any(target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Ns = libc::AF_NS,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Iso = libc::AF_ISO,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Datakit = libc::AF_DATAKIT,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Ccitt = libc::AF_CCITT,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Dli = libc::AF_DLI,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Lat = libc::AF_LAT,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Hylink = libc::AF_HYLINK,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Link = libc::AF_LINK,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Coip = libc::AF_COIP,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Cnt = libc::AF_CNT,
+ #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))]
+ Natm = libc::AF_NATM,
}
#[derive(Copy)]
@@ -252,7 +419,7 @@ impl Ipv4Addr {
}
pub fn any() -> Ipv4Addr {
- Ipv4Addr(libc::in_addr { s_addr: consts::INADDR_ANY })
+ Ipv4Addr(libc::in_addr { s_addr: libc::INADDR_ANY })
}
pub fn octets(&self) -> [u8; 4] {
@@ -480,9 +647,9 @@ impl fmt::Display for UnixAddr {
pub enum SockAddr {
Inet(InetAddr),
Unix(UnixAddr),
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
Netlink(NetlinkAddr),
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
SysControl(SysControlAddr),
}
@@ -495,12 +662,12 @@ impl SockAddr {
Ok(SockAddr::Unix(try!(UnixAddr::new(path))))
}
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
pub fn new_netlink(pid: u32, groups: u32) -> SockAddr {
SockAddr::Netlink(NetlinkAddr::new(pid, groups))
}
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
pub fn new_sys_control(sockfd: RawFd, name: &str, unit: u32) -> Result<SockAddr> {
SysControlAddr::from_name(sockfd, name, unit).map(|a| SockAddr::SysControl(a))
}
@@ -510,9 +677,9 @@ impl SockAddr {
SockAddr::Inet(InetAddr::V4(..)) => AddressFamily::Inet,
SockAddr::Inet(InetAddr::V6(..)) => AddressFamily::Inet6,
SockAddr::Unix(..) => AddressFamily::Unix,
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Netlink(..) => AddressFamily::Netlink,
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
SockAddr::SysControl(..) => AddressFamily::System,
}
}
@@ -526,9 +693,9 @@ impl SockAddr {
SockAddr::Inet(InetAddr::V4(ref addr)) => (mem::transmute(addr), mem::size_of::<libc::sockaddr_in>() as libc::socklen_t),
SockAddr::Inet(InetAddr::V6(ref addr)) => (mem::transmute(addr), mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t),
SockAddr::Unix(UnixAddr(ref addr, len)) => (mem::transmute(addr), (len + offset_of!(libc::sockaddr_un, sun_path)) as libc::socklen_t),
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Netlink(NetlinkAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<libc::sockaddr_nl>() as libc::socklen_t),
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
SockAddr::SysControl(SysControlAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<sys_control::sockaddr_ctl>() as libc::socklen_t),
}
}
@@ -543,7 +710,7 @@ impl PartialEq for SockAddr {
(SockAddr::Unix(ref a), SockAddr::Unix(ref b)) => {
a == b
}
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
(SockAddr::Netlink(ref a), SockAddr::Netlink(ref b)) => {
a == b
}
@@ -560,9 +727,9 @@ impl hash::Hash for SockAddr {
match *self {
SockAddr::Inet(ref a) => a.hash(s),
SockAddr::Unix(ref a) => a.hash(s),
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Netlink(ref a) => a.hash(s),
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
SockAddr::SysControl(ref a) => a.hash(s),
}
}
@@ -579,15 +746,15 @@ impl fmt::Display for SockAddr {
match *self {
SockAddr::Inet(ref inet) => inet.fmt(f),
SockAddr::Unix(ref unix) => unix.fmt(f),
- #[cfg(any(target_os = "linux", target_os = "android"))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Netlink(ref nl) => nl.fmt(f),
- #[cfg(any(target_os = "macos", target_os = "ios"))]
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
SockAddr::SysControl(ref sc) => sc.fmt(f),
}
}
}
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(any(target_os = "android", target_os = "linux"))]
pub mod netlink {
use ::sys::socket::addr::{AddressFamily};
use libc::{sa_family_t, sockaddr_nl};
@@ -642,11 +809,10 @@ pub mod netlink {
}
}
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(any(target_os = "ios", target_os = "macos"))]
pub mod sys_control {
- use ::sys::socket::consts;
use ::sys::socket::addr::{AddressFamily};
- use libc::{c_uchar, uint16_t, uint32_t};
+ use libc::{self, c_uchar, uint16_t, uint32_t};
use std::{fmt, mem};
use std::hash::{Hash, Hasher};
use std::os::unix::io::RawFd;
@@ -702,7 +868,7 @@ pub mod sys_control {
let addr = sockaddr_ctl {
sc_len: mem::size_of::<sockaddr_ctl>() as c_uchar,
sc_family: AddressFamily::System as c_uchar,
- ss_sysaddr: consts::AF_SYS_CONTROL as uint16_t,
+ ss_sysaddr: libc::AF_SYS_CONTROL as uint16_t,
sc_id: id,
sc_unit: unit,
sc_reserved: [0; 5]
diff --git a/src/sys/socket/consts.rs b/src/sys/socket/consts.rs
deleted file mode 100644
index ad9c522f..00000000
--- a/src/sys/socket/consts.rs
+++ /dev/null
@@ -1,437 +0,0 @@
-pub use self::os::*;
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-mod os {
- use libc::{self, c_int, uint8_t};
-
- pub const AF_UNIX: c_int = libc::AF_UNIX;
- pub const AF_LOCAL: c_int = libc::AF_LOCAL;
- pub const AF_INET: c_int = libc::AF_INET;
- pub const AF_INET6: c_int = libc::AF_INET6;
- pub const AF_NETLINK: c_int = libc::AF_NETLINK;
- pub const AF_PACKET: c_int = libc::AF_PACKET;
-
- pub const SOCK_STREAM: c_int = libc::SOCK_STREAM;
- pub const SOCK_DGRAM: c_int = libc::SOCK_DGRAM;
- pub const SOCK_SEQPACKET: c_int = libc::SOCK_SEQPACKET;
- pub const SOCK_RAW: c_int = libc::SOCK_RAW;
- pub const SOCK_RDM: c_int = 4;
-
- pub const SOL_IP: c_int = libc::SOL_IP;
- pub const SOL_SOCKET: c_int = libc::SOL_SOCKET;
- pub const SOL_TCP: c_int = libc::SOL_TCP;
- pub const SOL_UDP: c_int = 17;
- pub const SOL_IPV6: c_int = libc::SOL_IPV6;
- pub const SOL_NETLINK: c_int = libc::SOL_NETLINK;
- pub const IPPROTO_IP: c_int = libc::IPPROTO_IP;
- pub const IPPROTO_IPV6: c_int = libc::IPPROTO_IPV6;
- pub const IPPROTO_TCP: c_int = libc::IPPROTO_TCP;
- pub const IPPROTO_UDP: c_int = SOL_UDP;
-
- pub const SO_ACCEPTCONN: c_int = libc::SO_ACCEPTCONN;
- pub const SO_BINDTODEVICE: c_int = libc::SO_BINDTODEVICE;
- pub const SO_BROADCAST: c_int = libc::SO_BROADCAST;
- pub const SO_BSDCOMPAT: c_int = libc::SO_BSDCOMPAT;
- pub const SO_DEBUG: c_int = libc::SO_DEBUG;
- pub const SO_DOMAIN: c_int = libc::SO_DOMAIN;
- pub const SO_ERROR: c_int = libc::SO_ERROR;
- pub const SO_DONTROUTE: c_int = libc::SO_DONTROUTE;
- pub const SO_KEEPALIVE: c_int = libc::SO_KEEPALIVE;
- pub const SO_LINGER: c_int = libc::SO_LINGER;
- pub const SO_MARK: c_int = libc::SO_MARK;
- pub const SO_OOBINLINE: c_int = libc::SO_OOBINLINE;
- pub const SO_PASSCRED: c_int = libc::SO_PASSCRED;
- pub const SO_PEEK_OFF: c_int = libc::SO_PEEK_OFF;
- pub const SO_PEERCRED: c_int = libc::SO_PEERCRED;
- pub const SO_PRIORITY: c_int = libc::SO_PRIORITY;
- pub const SO_PROTOCOL: c_int = libc::SO_PROTOCOL;
- pub const SO_RCVBUF: c_int = libc::SO_RCVBUF;
- pub const SO_RCVBUFFORCE: c_int = 33;
- pub const SO_RCVLOWAT: c_int = libc::SO_RCVLOWAT;
- pub const SO_SNDLOWAT: c_int = libc::SO_SNDLOWAT;
- pub const SO_RCVTIMEO: c_int = libc::SO_RCVTIMEO;
- pub const SO_SNDTIMEO: c_int = libc::SO_SNDTIMEO;
- pub const SO_REUSEADDR: c_int = libc::SO_REUSEADDR;
- pub const SO_REUSEPORT: c_int = libc::SO_REUSEPORT;
- pub const SO_RXQ_OVFL: c_int = libc::SO_RXQ_OVFL;
- pub const SO_SNDBUF: c_int = libc::SO_SNDBUF;
- pub const SO_SNDBUFFORCE: c_int = libc::SO_SNDBUFFORCE;
- pub const SO_TIMESTAMP: c_int = libc::SO_TIMESTAMP;
- pub const SO_TYPE: c_int = libc::SO_TYPE;
- pub const SO_BUSY_POLL: c_int = libc::SO_BUSY_POLL;
- #[cfg(target_os = "linux")]
- pub const SO_ORIGINAL_DST: c_int = 80;
-
- // Socket options for TCP sockets
- pub const TCP_NODELAY: c_int = libc::TCP_NODELAY;
- pub const TCP_MAXSEG: c_int = libc::TCP_MAXSEG;
- pub const TCP_CORK: c_int = libc::TCP_CORK;
- pub const TCP_KEEPIDLE: c_int = libc::TCP_KEEPIDLE;
-
- // Socket options for the IP layer of the socket
- pub const IP_MULTICAST_IF: c_int = 32;
-
- pub type IpMulticastTtl = uint8_t;
-
- pub const IP_MULTICAST_TTL: c_int = libc::IP_MULTICAST_TTL;
- pub const IP_MULTICAST_LOOP: c_int = libc::IP_MULTICAST_LOOP;
- pub const IP_ADD_MEMBERSHIP: c_int = libc::IP_ADD_MEMBERSHIP;
- pub const IP_DROP_MEMBERSHIP: c_int = libc::IP_DROP_MEMBERSHIP;
-
- pub const IPV6_ADD_MEMBERSHIP: c_int = libc::IPV6_ADD_MEMBERSHIP;
- pub const IPV6_DROP_MEMBERSHIP: c_int = libc::IPV6_DROP_MEMBERSHIP;
-
- pub type InAddrT = u32;
-
- // Declarations of special addresses
- pub const INADDR_ANY: InAddrT = 0;
- pub const INADDR_NONE: InAddrT = 0xffffffff;
- pub const INADDR_BROADCAST: InAddrT = 0xffffffff;
-
- // Flags for send/recv and their relatives
- libc_bitflags!{
- pub flags MsgFlags: libc::c_int {
- MSG_OOB,
- MSG_PEEK,
- MSG_CTRUNC,
- MSG_TRUNC,
- MSG_DONTWAIT,
- MSG_EOR,
- MSG_ERRQUEUE,
- MSG_CMSG_CLOEXEC,
- }
- }
-
- // shutdown flags
- pub const SHUT_RD: c_int = libc::SHUT_RD;
- pub const SHUT_WR: c_int = libc::SHUT_WR;
- pub const SHUT_RDWR: c_int = libc::SHUT_RDWR;
-
- // Ancillary message types
- pub const SCM_RIGHTS: c_int = libc::SCM_RIGHTS;
-}
-
-// Not all of these constants exist on freebsd
-#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "ios", target_os = "openbsd", target_os = "netbsd"))]
-mod os {
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd"))]
- use libc::{self, c_int, uint8_t};
- #[cfg(any(target_os = "openbsd", target_os = "netbsd"))]
- use libc::{self, c_int, uint8_t};
-
- pub const AF_UNIX: c_int = libc::AF_UNIX;
- pub const AF_LOCAL: c_int = libc::AF_LOCAL;
- pub const AF_INET: c_int = libc::AF_INET;
- pub const AF_INET6: c_int = libc::AF_INET6;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- pub const AF_SYSTEM: c_int = libc::AF_SYSTEM;
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- pub const AF_SYS_CONTROL: c_int = 2;
-
- pub const SOCK_STREAM: c_int = libc::SOCK_STREAM;
- pub const SOCK_DGRAM: c_int = libc::SOCK_DGRAM;
- pub const SOCK_SEQPACKET: c_int = libc::SOCK_SEQPACKET;
- pub const SOCK_RAW: c_int = libc::SOCK_RAW;
- pub const SOCK_RDM: c_int = libc::SOCK_RDM;
-
- pub const SOL_SOCKET: c_int = libc::SOL_SOCKET;
- pub const IPPROTO_IP: c_int = libc::IPPROTO_IP;
- pub const IPPROTO_IPV6: c_int = libc::IPPROTO_IPV6;
- pub const IPPROTO_TCP: c_int = libc::IPPROTO_TCP;
- pub const IPPROTO_UDP: c_int = 17;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- pub const SYSPROTO_CONTROL: c_int = 2;
-
- pub const SO_ACCEPTCONN: c_int = libc::SO_ACCEPTCONN;
- pub const SO_BROADCAST: c_int = libc::SO_BROADCAST;
- pub const SO_DEBUG: c_int = libc::SO_DEBUG;
- #[cfg(not(target_os = "netbsd"))]
- pub const SO_DONTTRUNC: c_int = 0x2000;
- pub const SO_USELOOPBACK: c_int = libc::SO_USELOOPBACK;
- pub const SO_ERROR: c_int = libc::SO_ERROR;
- pub const SO_DONTROUTE: c_int = libc::SO_DONTROUTE;
- pub const SO_KEEPALIVE: c_int = libc::SO_KEEPALIVE;
- pub const SO_LABEL: c_int = 0x1010;
- pub const SO_LINGER: c_int = libc::SO_LINGER;
- pub const SO_NREAD: c_int = 0x1020;
- pub const SO_NKE: c_int = 0x1021;
- pub const SO_NOSIGPIPE: c_int = 0x1022;
- pub const SO_NOADDRERR: c_int = 0x1023;
- pub const SO_NOTIFYCONFLICT: c_int = 0x1026;
- pub const SO_NP_EXTENSIONS: c_int = 0x1083;
- pub const SO_NWRITE: c_int = 0x1024;
- pub const SO_OOBINLINE: c_int = libc::SO_OOBINLINE;
- pub const SO_PEERLABEL: c_int = 0x1011;
- pub const SO_RCVBUF: c_int = libc::SO_RCVBUF;
- pub const SO_RCVLOWAT: c_int = libc::SO_RCVLOWAT;
- pub const SO_SNDLOWAT: c_int = libc::SO_SNDLOWAT;
- pub const SO_RCVTIMEO: c_int = libc::SO_RCVTIMEO;
- pub const SO_SNDTIMEO: c_int = libc::SO_SNDTIMEO;
- pub const SO_RANDOMPORT: c_int = 0x1082;
- pub const SO_RESTRICTIONS: c_int = 0x1081;
- pub const SO_RESTRICT_DENYIN: c_int = 0x00000001;
- pub const SO_RESTRICT_DENYOUT: c_int = 0x00000002;
- pub const SO_REUSEADDR: c_int = libc::SO_REUSEADDR;
- pub const SO_REUSEPORT: c_int = libc::SO_REUSEPORT;
- pub const SO_REUSESHAREUID: c_int = 0x1025;
- pub const SO_SNDBUF: c_int = libc::SO_SNDBUF;
- pub const SO_TIMESTAMP: c_int = libc::SO_TIMESTAMP;
- #[cfg(not(target_os = "netbsd"))]
- pub const SO_TIMESTAMP_MONOTONIC: c_int = 0x0800;
- pub const SO_TYPE: c_int = libc::SO_TYPE;
- #[cfg(not(target_os = "netbsd"))]
- pub const SO_WANTMORE: c_int = 0x4000;
- pub const SO_WANTOOBFLAG: c_int = 0x8000;
- #[allow(overflowing_literals)]
- pub const SO_RESTRICT_DENYSET: c_int = 0x80000000;
-
- // Socket options for TCP sockets
- pub const TCP_NODELAY: c_int = libc::TCP_NODELAY;
- pub const TCP_MAXSEG: c_int = 2;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- pub const TCP_KEEPALIVE: c_int = libc::TCP_KEEPALIVE;
- #[cfg(target_os = "freebsd")]
- pub const TCP_KEEPIDLE: c_int = libc::TCP_KEEPIDLE;
-
- // Socket options for the IP layer of the socket
- pub const IP_MULTICAST_IF: c_int = 9;
-
- pub type IpMulticastTtl = uint8_t;
-
- pub const IP_MULTICAST_TTL: c_int = libc::IP_MULTICAST_TTL;
- pub const IP_MULTICAST_LOOP: c_int = libc::IP_MULTICAST_LOOP;
- pub const IP_ADD_MEMBERSHIP: c_int = libc::IP_ADD_MEMBERSHIP;
- pub const IP_DROP_MEMBERSHIP: c_int = libc::IP_DROP_MEMBERSHIP;
-
- pub const IPV6_JOIN_GROUP: c_int = libc::IPV6_JOIN_GROUP;
- pub const IPV6_LEAVE_GROUP: c_int = libc::IPV6_LEAVE_GROUP;
-
- pub type InAddrT = u32;
-
- // Declarations of special addresses
- pub const INADDR_ANY: InAddrT = 0;
- pub const INADDR_NONE: InAddrT = 0xffffffff;
- pub const INADDR_BROADCAST: InAddrT = 0xffffffff;
-
- // Flags for send/recv and their relatives
- libc_bitflags!{
- pub flags MsgFlags: libc::c_int {
- MSG_OOB,
- MSG_PEEK,
- MSG_EOR,
- MSG_TRUNC,
- MSG_CTRUNC,
- MSG_DONTWAIT,
- }
- }
-
- // shutdown flags
- pub const SHUT_RD: c_int = libc::SHUT_RD;
- pub const SHUT_WR: c_int = libc::SHUT_WR;
- pub const SHUT_RDWR: c_int = libc::SHUT_RDWR;
-
- // Ancillary message types
- pub const SCM_RIGHTS: c_int = 1;
-}
-
-#[cfg(target_os = "dragonfly")]
-mod os {
- use libc::{c_int, uint8_t};
-
- pub const AF_UNIX: c_int = libc::AF_UNIX;
- pub const AF_LOCAL: c_int = libc::AF_LOCAL;
- pub const AF_INET: c_int = libc::AF_INET;
- pub const AF_INET6: c_int = libc::AF_INET6;
-
- pub const SOCK_STREAM: c_int = libc::SOCK_STREAM;
- pub const SOCK_DGRAM: c_int = libc::SOCK_DGRAM;
- pub const SOCK_SEQPACKET: c_int = libc::SOCK_SEQPACKET;
- pub const SOCK_RAW: c_int = libc::SOCK_RAW;
- pub const SOCK_RDM: c_int = libc::SOCK_RDM;
-
- pub const SOL_SOCKET: c_int = libc::SOL_SOCKET;
- pub const IPPROTO_IP: c_int = libc::IPPROTO_IP;
- pub const IPPROTO_IPV6: c_int = libc::IPPROTO_IPV6;
- pub const IPPROTO_TCP: c_int = libc::IPPROTO_TCP;
- pub const IPPROTO_UDP: c_int = libc::IPPROTO_UDP;
-
- pub const SO_ACCEPTCONN: c_int = libc::SO_ACCEPTCONN;
- pub const SO_BROADCAST: c_int = libc::SO_BROADCAST;
- pub const SO_DEBUG: c_int = libc::SO_DEBUG;
- pub const SO_ERROR: c_int = libc::SO_ERROR;
- pub const SO_DONTROUTE: c_int = libc::SO_DONTROUTE;
- pub const SO_KEEPALIVE: c_int = libc::SO_KEEPALIVE;
- pub const SO_LINGER: c_int = libc::SO_LINGER;
- pub const SO_NOSIGPIPE: c_int = libc::SO_NOSIGPIPE;
- pub const SO_OOBINLINE: c_int = libc::SO_OOBINLINE;
- pub const SO_RCVBUF: c_int = libc::SO_RCVBUF;
- pub const SO_RCVLOWAT: c_int = libc::RCVLOWAT;
- pub const SO_SNDLOWAT: c_int = libc::SO_SNDLOWAT;
- pub const SO_RCVTIMEO: c_int = libc::SO_RCVTIMEO;
- pub const SO_SNDTIMEO: c_int = libc::SO_SNDTIMEO;
- pub const SO_REUSEADDR: c_int = libc::SO_REUSEADDR;
- pub const SO_REUSEPORT: c_int = libc::SO_REUSEPORT;
- pub const SO_SNDBUF: c_int = libc::SO_SNDBUF;
- pub const SO_TIMESTAMP: c_int = libc::SO_TIMESTAMP;
- pub const SO_TYPE: c_int = libc::SO_TYPE;
-
- // Socket options for TCP sockets
- pub const TCP_NODELAY: c_int = libc::TCP_NODELAY;
- pub const TCP_MAXSEG: c_int = libc::TCP_MAXSEG;
- pub const TCP_KEEPIDLE: c_int = libc::TCP_KEEPIDLE;
-
- // Socket options for the IP layer of the socket
- pub const IP_MULTICAST_IF: c_int = 9;
-
- pub type IpMulticastTtl = uint8_t;
-
- pub const IP_MULTICAST_TTL: c_int = libc::IP_MULTICAST_TTL;
- pub const IP_MULTICAST_LOOP: c_int = libc::IP_MULTICAST_LOOP;
- pub const IP_ADD_MEMBERSHIP: c_int = libc::IP_ADD_MEMBERSHIP;
- pub const IP_DROP_MEMBERSHIP: c_int = libc::IP_DROP_MEMBERSHIP;
- pub const IPV6_JOIN_GROUP: c_int = libc::IPV6_JOIN_GROUP;
- pub const IPV6_LEAVE_GROUP: c_int = libc::IPV6_LEAVE_GROUP;
-
- pub type InAddrT = u32;
-
- // Declarations of special addresses
- pub const INADDR_ANY: InAddrT = 0;
- pub const INADDR_NONE: InAddrT = 0xffffffff;
- pub const INADDR_BROADCAST: InAddrT = 0xffffffff;
-
- // Flags for send/recv and their relatives
- libc_bitflags!{
- pub flags MsgFlags: libc::c_int {
- MSG_OOB,
- MSG_PEEK,
- MSG_DONTWAIT,
- }
- }
-
- // shutdown flags
- pub const SHUT_RD: c_int = libc::SHUT_RD;
- pub const SHUT_WR: c_int = libc::SHUT_WR;
- pub const SHUT_RDWR: c_int = libc::SHUT_RDWR;
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use nixtest::{assert_const_eq,get_int_const,GetConst};
- use libc::{c_char};
- use std::fmt;
-
- impl fmt::Display for MsgFlags {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", self.bits())
- }
- }
-
- impl GetConst for MsgFlags {
- unsafe fn get_const(name: *const c_char) -> MsgFlags {
- MsgFlags::from_bits_truncate(get_int_const(name))
- }
- }
-
- macro_rules! check_const {
- ($($konst:ident),+) => {{
- $(assert_const_eq(stringify!($konst), $konst);)+
- }};
- }
-
- #[test]
- pub fn test_const_values() {
- check_const!(
- AF_UNIX,
- AF_LOCAL,
- AF_INET,
- AF_INET6,
- SOCK_STREAM,
- SOCK_DGRAM,
- SOCK_SEQPACKET,
- SOCK_RAW,
- SOCK_RDM,
- SOL_SOCKET,
- IPPROTO_IP,
- IPPROTO_IPV6,
- IPPROTO_TCP,
- IPPROTO_UDP,
- SO_ACCEPTCONN,
- SO_BROADCAST,
- SO_DEBUG,
- SO_ERROR,
- SO_DONTROUTE,
- SO_KEEPALIVE,
- SO_LINGER,
- SO_OOBINLINE,
- SO_RCVBUF,
- SO_RCVLOWAT,
- SO_SNDLOWAT,
- SO_RCVTIMEO,
- SO_SNDTIMEO,
- SO_REUSEADDR,
- // SO_REUSEPORT,
- SO_SNDBUF,
- SO_TIMESTAMP,
- SO_TYPE,
- TCP_NODELAY,
- TCP_MAXSEG,
- IP_MULTICAST_IF,
- IP_MULTICAST_TTL,
- IP_MULTICAST_LOOP,
- IP_ADD_MEMBERSHIP,
- IP_DROP_MEMBERSHIP,
- INADDR_ANY,
- INADDR_NONE,
- INADDR_BROADCAST,
- MSG_OOB,
- MSG_PEEK,
- MSG_DONTWAIT,
- MSG_EOR,
- MSG_TRUNC,
- MSG_CTRUNC,
- SHUT_RD,
- SHUT_WR,
- SHUT_RDWR
- );
-
-
- }
-
- #[cfg(target_os = "linux")]
- #[test]
- pub fn test_general_linux_consts() {
- // TODO Figure out how to test new constants
- check_const!(
- SOL_IP,
- SOL_TCP,
- SOL_UDP,
- SOL_IPV6,
- SO_BINDTODEVICE,
- SO_BSDCOMPAT,
- // SO_DOMAIN,
- // SO_MARK,
- TCP_CORK,
- // SO_BUSY_POLL,
- // SO_RXQ_OVFL,
- SO_PRIORITY,
- // SO_PROTOCOL,
- SO_RCVBUFFORCE,
- // SO_PEEK_OFF,
- MSG_ERRQUEUE);
- }
-
- #[cfg(all(target_os = "linux", not(target_arch="arm")))]
- #[test]
- pub fn test_linux_not_arm_consts() {
- // TODO Figure out how to test new constants
- check_const!(
- SO_PASSCRED,
- SO_PEERCRED,
- SO_SNDBUFFORCE);
- }
-
-}
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index c11b5367..86129fcf 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -5,13 +5,12 @@ use {Error, Errno, Result};
use features;
use fcntl::{fcntl, FD_CLOEXEC, O_NONBLOCK};
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
-use libc::{c_void, c_int, socklen_t, size_t, pid_t, uid_t, gid_t};
+use libc::{self, c_void, c_int, socklen_t, size_t, pid_t, uid_t, gid_t};
use std::{mem, ptr, slice};
use std::os::unix::io::RawFd;
use sys::uio::IoVec;
mod addr;
-mod consts;
mod ffi;
mod multicast;
pub mod sockopt;
@@ -48,28 +47,112 @@ pub use self::multicast::{
ip_mreq,
ipv6_mreq,
};
-pub use self::consts::*;
pub use libc::sockaddr_storage;
+/// These constants are used to specify the communication semantics
+/// when creating a socket with [`socket()`](fn.socket.html)
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[repr(i32)]
pub enum SockType {
- Stream = consts::SOCK_STREAM,
- Datagram = consts::SOCK_DGRAM,
- SeqPacket = consts::SOCK_SEQPACKET,
- Raw = consts::SOCK_RAW,
- Rdm = consts::SOCK_RDM,
+ /// Provides sequenced, reliable, two-way, connection-
+ /// based byte streams. An out-of-band data transmission
+ /// mechanism may be supported.
+ Stream = libc::SOCK_STREAM,
+ /// Supports datagrams (connectionless, unreliable
+ /// messages of a fixed maximum length).
+ Datagram = libc::SOCK_DGRAM,
+ /// Provides a sequenced, reliable, two-way connection-
+ /// based data transmission path for datagrams of fixed
+ /// maximum length; a consumer is required to read an
+ /// entire packet with each input system call.
+ SeqPacket = libc::SOCK_SEQPACKET,
+ /// Provides raw network protocol access.
+ Raw = libc::SOCK_RAW,
+ /// Provides a reliable datagram layer that does not
+ /// guarantee ordering.
+ Rdm = libc::SOCK_RDM,
+}
+
+/// Constants used in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
+/// to specify the protocol to use.
+#[repr(i32)]
+pub enum SockProtocol {
+ /// TCP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html))
+ Tcp = libc::IPPROTO_TCP,
+ /// UDP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html))
+ Udp = libc::IPPROTO_UDP,
+ /// Allows applications and other KEXTs to be notified when certain kernel events occur
+ /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
+ KextEvent = libc::SYSPROTO_EVENT,
+ /// Allows applications to configure and control a KEXT
+ /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
+ #[cfg(any(target_os = "ios", target_os = "macos"))]
+ KextControl = libc::SYSPROTO_CONTROL,
}
-// Extra flags - Supported by Linux 2.6.27, normalized on other platforms
bitflags!(
+ /// Extra flags - Supported by Linux 2.6.27, normalized on other platforms
pub struct SockFlag: c_int {
const SOCK_NONBLOCK = 0o0004000;
const SOCK_CLOEXEC = 0o2000000;
}
);
+libc_bitflags!{
+ /// Flags for send/recv and their relatives
+ pub flags MsgFlags: libc::c_int {
+ /// Sends or requests out-of-band data on sockets that support this notion
+ /// (e.g., of type [`Stream`](enum.SockType.html)); the underlying protocol must also
+ /// support out-of-band data.
+ MSG_OOB,
+ /// Peeks at an incoming message. The data is treated as unread and the next
+ /// [`recv()`](fn.recv.html)
+ /// or similar function shall still return this data.
+ MSG_PEEK,
+ /// Enables nonblocking operation; if the operation would block,
+ /// `EAGAIN` or `EWOULDBLOCK` is returned. This provides similar
+ /// behavior to setting the `O_NONBLOCK` flag
+ /// (via the [`fcntl`](../../fcntl/fn.fcntl.html)
+ /// `F_SETFL` operation), but differs in that `MSG_DONTWAIT` is a per-
+ /// call option, whereas `O_NONBLOCK` is a setting on the open file
+ /// description (see [open(2)](http://man7.org/linux/man-pages/man2/open.2.html)),
+ /// which will affect all threads in
+ /// the calling process and as well as other processes that hold
+ /// file descriptors referring to the same open file description.
+ MSG_DONTWAIT,
+ /// Receive flags: Control Data was discarded (buffer too small)
+ MSG_CTRUNC,
+ /// For raw ([`Packet`](addr/enum.AddressFamily.html)), Internet datagram
+ /// (since Linux 2.4.27/2.6.8),
+ /// netlink (since Linux 2.6.22) and UNIX datagram (since Linux 3.4)
+ /// sockets: return the real length of the packet or datagram, even
+ /// when it was longer than the passed buffer. Not implemented for UNIX
+ /// domain ([unix(7)](https://linux.die.net/man/7/unix)) sockets.
+ ///
+ /// For use with Internet stream sockets, see [tcp(7)](https://linux.die.net/man/7/tcp).
+ MSG_TRUNC,
+ /// Terminates a record (when this notion is supported, as for
+ /// sockets of type [`SeqPacket`](enum.SockType.html)).
+ MSG_EOR,
+ /// This flag specifies that queued errors should be received from
+ /// the socket error queue. (For more details, see
+ /// [recvfrom(2)](https://linux.die.net/man/2/recvfrom))
+ #[cfg(any(target_os = "linux", target_os = "android"))]
+ MSG_ERRQUEUE,
+ /// Set the `close-on-exec` flag for the file descriptor received via a UNIX domain
+ /// file descriptor using the `SCM_RIGHTS` operation (described in
+ /// [unix(7)](https://linux.die.net/man/7/unix)).
+ /// This flag is useful for the same reasons as the `O_CLOEXEC` flag of
+ /// [open(2)](https://linux.die.net/man/2/open).
+ ///
+ /// Only used in [`recvmsg`](fn.recvmsg.html) function.
+ #[cfg(any(target_os = "linux", target_os = "android"))]
+ MSG_CMSG_CLOEXEC,
+ }
+}
+
/// Copy the in-memory representation of src into the byte slice dst,
/// updating the slice to point to the remainder of dst only. Unsafe
/// because it exposes all bytes in src, which may be UB if some of them
@@ -157,7 +240,7 @@ impl<'a> Iterator for CmsgIterator<'a> {
self.0 = &buf[cmsg_align(cmsg_len)..];
match (cmsg.cmsg_level, cmsg.cmsg_type) {
- (SOL_SOCKET, SCM_RIGHTS) => unsafe {
+ (libc::SOL_SOCKET, libc::SCM_RIGHTS) => unsafe {
Some(ControlMessage::ScmRights(
slice::from_raw_parts(
&cmsg.cmsg_data as *const _ as *const _, 1)))
@@ -221,8 +304,8 @@ impl<'a> ControlMessage<'a> {
ControlMessage::ScmRights(fds) => {
let cmsg = cmsghdr {
cmsg_len: self.len() as type_of_cmsg_len,
- cmsg_level: SOL_SOCKET,
- cmsg_type: SCM_RIGHTS,
+ cmsg_level: libc::SOL_SOCKET,
+ cmsg_type: libc::SCM_RIGHTS,
cmsg_data: [],
};
copy_bytes(&cmsg, buf);
@@ -330,9 +413,20 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
/// Create an endpoint for communication
///
+/// The `protocol` specifies a particular protocol to be used with the
+/// socket. Normally only a single protocol exists to support a
+/// particular socket type within a given protocol family, in which case
+/// protocol can be specified as `None`. However, it is possible that many
+/// protocols may exist, in which case a particular protocol must be
+/// specified in this manner.
+///
/// [Further reading](http://man7.org/linux/man-pages/man2/socket.2.html)
-pub fn socket(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: c_int) -> Result<RawFd> {
+pub fn socket<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: T) -> Result<RawFd> {
let mut ty = ty as c_int;
+ let protocol = match protocol.into() {
+ None => 0,
+ Some(p) => p as c_int,
+ };
let feat_atomic = features::socket_atomic_cloexec();
if feat_atomic {
@@ -358,9 +452,13 @@ pub fn socket(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: c_
/// Create a pair of connected sockets
///
/// [Further reading](http://man7.org/linux/man-pages/man2/socketpair.2.html)
-pub fn socketpair(domain: AddressFamily, ty: SockType, protocol: c_int,
+pub fn socketpair<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, protocol: T,
flags: SockFlag) -> Result<(RawFd, RawFd)> {
let mut ty = ty as c_int;
+ let protocol = match protocol.into() {
+ None => 0,
+ Some(p) => p as c_int,
+ };
let feat_atomic = features::socket_atomic_cloexec();
if feat_atomic {
@@ -551,13 +649,13 @@ pub struct ucred {
/// [Further reading](http://man7.org/linux/man-pages/man2/setsockopt.2.html)
#[repr(i32)]
pub enum SockLevel {
- Socket = SOL_SOCKET,
- Tcp = IPPROTO_TCP,
- Ip = IPPROTO_IP,
- Ipv6 = IPPROTO_IPV6,
- Udp = IPPROTO_UDP,
+ Socket = libc::SOL_SOCKET,
+ Tcp = libc::IPPROTO_TCP,
+ Ip = libc::IPPROTO_IP,
+ Ipv6 = libc::IPPROTO_IPV6,
+ Udp = libc::IPPROTO_UDP,
#[cfg(any(target_os = "linux", target_os = "android"))]
- Netlink = SOL_NETLINK,
+ Netlink = libc::SOL_NETLINK,
}
/// Represents a socket option that can be accessed or set. Used as an argument
@@ -639,22 +737,22 @@ pub unsafe fn sockaddr_storage_to_addr(
}
match addr.ss_family as c_int {
- consts::AF_INET => {
+ libc::AF_INET => {
assert!(len as usize == mem::size_of::<sockaddr_in>());
let ret = *(addr as *const _ as *const sockaddr_in);
Ok(SockAddr::Inet(InetAddr::V4(ret)))
}
- consts::AF_INET6 => {
+ libc::AF_INET6 => {
assert!(len as usize == mem::size_of::<sockaddr_in6>());
Ok(SockAddr::Inet(InetAddr::V6((*(addr as *const _ as *const sockaddr_in6)))))
}
- consts::AF_UNIX => {
+ libc::AF_UNIX => {
let sun = *(addr as *const _ as *const sockaddr_un);
let pathlen = len - offset_of!(sockaddr_un, sun_path);
Ok(SockAddr::Unix(UnixAddr(sun, pathlen)))
}
#[cfg(any(target_os = "linux", target_os = "android"))]
- consts::AF_NETLINK => {
+ libc::AF_NETLINK => {
use libc::sockaddr_nl;
Ok(SockAddr::Netlink(NetlinkAddr(*(addr as *const _ as *const sockaddr_nl))))
}
@@ -681,9 +779,9 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> {
use libc::shutdown;
let how = match how {
- Shutdown::Read => consts::SHUT_RD,
- Shutdown::Write => consts::SHUT_WR,
- Shutdown::Both => consts::SHUT_RDWR,
+ Shutdown::Read => libc::SHUT_RD,
+ Shutdown::Write => libc::SHUT_WR,
+ Shutdown::Both => libc::SHUT_RDWR,
};
Errno::result(shutdown(df, how)).map(drop)
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs
index 61d85ec3..3c13c539 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -1,9 +1,7 @@
-use super::{ffi, consts, GetSockOpt, SetSockOpt};
+use super::{ffi, GetSockOpt, SetSockOpt};
use {Errno, Result};
use sys::time::TimeVal;
-use libc::{c_int, uint8_t, c_void, socklen_t};
-#[cfg(target_os = "linux")]
-use libc::sockaddr_in;
+use libc::{self, c_int, uint8_t, c_void, socklen_t};
use std::mem;
use std::os::unix::io::RawFd;
@@ -130,52 +128,49 @@ macro_rules! sockopt_impl {
*
*/
-sockopt_impl!(Both, ReuseAddr, consts::SOL_SOCKET, consts::SO_REUSEADDR, bool);
-sockopt_impl!(Both, ReusePort, consts::SOL_SOCKET, consts::SO_REUSEPORT, bool);
-sockopt_impl!(Both, TcpNoDelay, consts::IPPROTO_TCP, consts::TCP_NODELAY, bool);
-sockopt_impl!(Both, Linger, consts::SOL_SOCKET, consts::SO_LINGER, super::linger);
-sockopt_impl!(SetOnly, IpAddMembership, consts::IPPROTO_IP, consts::IP_ADD_MEMBERSHIP, super::ip_mreq);
-sockopt_impl!(SetOnly, IpDropMembership, consts::IPPROTO_IP, consts::IP_DROP_MEMBERSHIP, super::ip_mreq);
+sockopt_impl!(Both, ReuseAddr, libc::SOL_SOCKET, libc::SO_REUSEADDR, bool);
+sockopt_impl!(Both, ReusePort, libc::SOL_SOCKET, libc::SO_REUSEPORT, bool);
+sockopt_impl!(Both, TcpNoDelay, libc::IPPROTO_TCP, libc::TCP_NODELAY, bool);
+sockopt_impl!(Both, Linger, libc::SOL_SOCKET, libc::SO_LINGER, super::linger);
+sockopt_impl!(SetOnly, IpAddMembership, libc::IPPROTO_IP, libc::IP_ADD_MEMBERSHIP, super::ip_mreq);
+sockopt_impl!(SetOnly, IpDropMembership, libc::IPPROTO_IP, libc::IP_DROP_MEMBERSHIP, super::ip_mreq);
#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd")))]
-sockopt_impl!(SetOnly, Ipv6AddMembership, consts::IPPROTO_IPV6, consts::IPV6_ADD_MEMBERSHIP, super::ipv6_mreq);
+sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_ADD_MEMBERSHIP, super::ipv6_mreq);
#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd")))]
-sockopt_impl!(SetOnly, Ipv6DropMembership, consts::IPPROTO_IPV6, consts::IPV6_DROP_MEMBERSHIP, super::ipv6_mreq);
+sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::ipv6_mreq);
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd"))]
-sockopt_impl!(SetOnly, Ipv6AddMembership, consts::IPPROTO_IPV6, consts::IPV6_JOIN_GROUP, super::ipv6_mreq);
+sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_JOIN_GROUP, super::ipv6_mreq);
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd"))]
-sockopt_impl!(SetOnly, Ipv6DropMembership, consts::IPPROTO_IPV6, consts::IPV6_LEAVE_GROUP, super::ipv6_mreq);
-sockopt_impl!(Both, IpMulticastTtl, consts::IPPROTO_IP, consts::IP_MULTICAST_TTL, u8);
-sockopt_impl!(Both, IpMulticastLoop, consts::IPPROTO_IP, consts::IP_MULTICAST_LOOP, bool);
-sockopt_impl!(Both, ReceiveTimeout, consts::SOL_SOCKET, consts::SO_RCVTIMEO, TimeVal);
-sockopt_impl!(Both, SendTimeout, consts::SOL_SOCKET, consts::SO_SNDTIMEO, TimeVal);
-sockopt_impl!(Both, Broadcast, consts::SOL_SOCKET, consts::SO_BROADCAST, bool);
-sockopt_impl!(Both, OobInline, consts::SOL_SOCKET, consts::SO_OOBINLINE, bool);
-sockopt_impl!(GetOnly, SocketError, consts::SOL_SOCKET, consts::SO_ERROR, i32);
-sockopt_impl!(Both, KeepAlive, consts::SOL_SOCKET, consts::SO_KEEPALIVE, bool);
+sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_LEAVE_GROUP, super::ipv6_mreq);
+sockopt_impl!(Both, IpMulticastTtl, libc::IPPROTO_IP, libc::IP_MULTICAST_TTL, u8);
+sockopt_impl!(Both, IpMulticastLoop, libc::IPPROTO_IP, libc::IP_MULTICAST_LOOP, bool);
+sockopt_impl!(Both, ReceiveTimeout, libc::SOL_SOCKET, libc::SO_RCVTIMEO, TimeVal);
+sockopt_impl!(Both, SendTimeout, libc::SOL_SOCKET, libc::SO_SNDTIMEO, TimeVal);
+sockopt_impl!(Both, Broadcast, libc::SOL_SOCKET, libc::SO_BROADCAST, bool);
+sockopt_impl!(Both, OobInline, libc::SOL_SOCKET, libc::SO_OOBINLINE, bool);
+sockopt_impl!(GetOnly, SocketError, libc::SOL_SOCKET, libc::SO_ERROR, i32);
+sockopt_impl!(Both, KeepAlive, libc::SOL_SOCKET, libc::SO_KEEPALIVE, bool);
#[cfg(all(target_os = "linux", not(target_arch="arm")))]
-sockopt_impl!(GetOnly, PeerCredentials, consts::SOL_SOCKET, consts::SO_PEERCRED, super::ucred);
+sockopt_impl!(GetOnly, PeerCredentials, libc::SOL_SOCKET, libc::SO_PEERCRED, super::ucred);
#[cfg(any(target_os = "macos",
target_os = "ios"))]
-sockopt_impl!(Both, TcpKeepAlive, consts::IPPROTO_TCP, consts::TCP_KEEPALIVE, u32);
+sockopt_impl!(Both, TcpKeepAlive, libc::IPPROTO_TCP, libc::TCP_KEEPALIVE, u32);
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly",
target_os = "linux",
target_os = "android",
target_os = "nacl"))]
-sockopt_impl!(Both, TcpKeepIdle, consts::IPPROTO_TCP, consts::TCP_KEEPIDLE, u32);
-sockopt_impl!(Both, RcvBuf, consts::SOL_SOCKET, consts::SO_RCVBUF, usize);
-sockopt_impl!(Both, SndBuf, consts::SOL_SOCKET, consts::SO_SNDBUF, usize);
-#[cfg(target_os = "linux")]
-sockopt_impl!(SetOnly, RcvBufForce, consts::SOL_SOCKET, consts::SO_RCVBUFFORCE, usize);
-#[cfg(all(target_os = "linux", not(target_arch="arm")))]
-sockopt_impl!(SetOnly, SndBufForce, consts::SOL_SOCKET, consts::SO_SNDBUFFORCE, usize);
-sockopt_impl!(GetOnly, SockType, consts::SOL_SOCKET, consts::SO_TYPE, super::SockType);
-#[cfg(any(target_os = "freebsd",
- target_os = "linux",
- target_os = "nacl"))]
-sockopt_impl!(GetOnly, AcceptConn, consts::SOL_SOCKET, consts::SO_ACCEPTCONN, bool);
-#[cfg(target_os = "linux")]
-sockopt_impl!(GetOnly, OriginalDst, consts::SOL_IP, consts::SO_ORIGINAL_DST, sockaddr_in);
+sockopt_impl!(Both, TcpKeepIdle, libc::IPPROTO_TCP, libc::TCP_KEEPIDLE, u32);
+sockopt_impl!(Both, RcvBuf, libc::SOL_SOCKET, libc::SO_RCVBUF, usize);
+sockopt_impl!(Both, SndBuf, libc::SOL_SOCKET, libc::SO_SNDBUF, usize);
+#[cfg(any(target_os = "linux", target_os = "android"))]
+sockopt_impl!(SetOnly, RcvBufForce, libc::SOL_SOCKET, libc::SO_RCVBUFFORCE, usize);
+#[cfg(any(target_os = "linux", target_os = "android"))]
+sockopt_impl!(SetOnly, SndBufForce, libc::SOL_SOCKET, libc::SO_SNDBUFFORCE, usize);
+sockopt_impl!(GetOnly, SockType, libc::SOL_SOCKET, libc::SO_TYPE, super::SockType);
+sockopt_impl!(GetOnly, AcceptConn, libc::SOL_SOCKET, libc::SO_ACCEPTCONN, bool);
+#[cfg(any(target_os = "linux", target_os = "android"))]
+sockopt_impl!(GetOnly, OriginalDst, libc::SOL_IP, libc::SO_ORIGINAL_DST, libc::sockaddr_in);
/*
*
@@ -383,7 +378,7 @@ mod test {
fn can_get_peercred_on_unix_socket() {
use super::super::*;
- let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, 0, SockFlag::empty()).unwrap();
+ let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
let a_cred = getsockopt(a, super::PeerCredentials).unwrap();
let b_cred = getsockopt(b, super::PeerCredentials).unwrap();
assert_eq!(a_cred, b_cred);
@@ -395,7 +390,7 @@ mod test {
use super::super::*;
use ::unistd::close;
- let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, 0, SockFlag::empty()).unwrap();
+ let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
let a_type = getsockopt(a, super::SockType).unwrap();
assert!(a_type == SockType::Stream);
close(a).unwrap();
@@ -407,7 +402,7 @@ mod test {
use super::super::*;
use ::unistd::close;
- let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), 0).unwrap();
+ let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap();
let s_type = getsockopt(s, super::SockType).unwrap();
assert!(s_type == SockType::Datagram);
close(s).unwrap();
@@ -421,7 +416,7 @@ mod test {
use super::super::*;
use ::unistd::close;
- let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), 0).unwrap();
+ let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap();
let s_listening = getsockopt(s, super::AcceptConn).unwrap();
assert!(!s_listening);
listen(s, 10).unwrap();
diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs
index 9f9c9bf0..31b153dd 100644
--- a/test/sys/test_socket.rs
+++ b/test/sys/test_socket.rs
@@ -69,8 +69,8 @@ pub fn test_getsockname() {
let tempdir = TempDir::new("test_getsockname").unwrap();
let sockname = tempdir.path().join("sock");
- let sock = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(),
- 0).expect("socket failed");
+ let sock = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None)
+ .expect("socket failed");
let sockaddr = SockAddr::new_unix(&sockname).unwrap();
bind(sock, &sockaddr).expect("bind failed");
assert_eq!(sockaddr.to_str(),
@@ -82,8 +82,7 @@ pub fn test_socketpair() {
use nix::unistd::{read, write};
use nix::sys::socket::{socketpair, AddressFamily, SockType, SockFlag};
- let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
- SockFlag::empty())
+ let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
.unwrap();
write(fd1, b"hello").unwrap();
let mut buf = [0;5];
@@ -101,8 +100,7 @@ pub fn test_scm_rights() {
ControlMessage, CmsgSpace, MsgFlags,
MSG_TRUNC, MSG_CTRUNC};
- let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
- SockFlag::empty())
+ let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
.unwrap();
let (r, w) = pipe().unwrap();
let mut received_r: Option<RawFd> = None;
@@ -158,8 +156,7 @@ pub fn test_sendmsg_empty_cmsgs() {
CmsgSpace, MsgFlags,
MSG_TRUNC, MSG_CTRUNC};
- let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
- SockFlag::empty())
+ let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
.unwrap();
{
@@ -194,14 +191,14 @@ pub fn test_unixdomain() {
let tempdir = TempDir::new("test_unixdomain").unwrap();
let sockname = tempdir.path().join("sock");
let s1 = socket(AddressFamily::Unix, SockType::Stream,
- SockFlag::empty(), 0).expect("socket failed");
+ SockFlag::empty(), None).expect("socket failed");
let sockaddr = SockAddr::new_unix(&sockname).unwrap();
bind(s1, &sockaddr).expect("bind failed");
listen(s1, 10).expect("listen failed");
let thr = thread::spawn(move || {
- let s2 = socket(AddressFamily::Unix, SockType::Stream,
- SockFlag::empty(), 0).expect("socket failed");
+ let s2 = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None)
+ .expect("socket failed");
connect(s2, &sockaddr).expect("connect failed");
write(s2, b"hello").expect("write failed");
close(s2).unwrap();
@@ -223,11 +220,11 @@ pub fn test_unixdomain() {
#[test]
pub fn test_syscontrol() {
use nix::{Errno, Error};
- use nix::sys::socket::{AddressFamily, SockType, SockFlag};
- use nix::sys::socket::{socket, SockAddr};
- use nix::sys::socket::SYSPROTO_CONTROL;
+ use nix::sys::socket::{AddressFamily, socket, SockAddr, SockType, SockFlag, SockProtocol};
- let fd = socket(AddressFamily::System, SockType::Datagram, SockFlag::empty(), SYSPROTO_CONTROL).expect("socket failed");
+ let fd = socket(AddressFamily::System, SockType::Datagram,
+ SockFlag::empty(), SockProtocol::KextControl)
+ .expect("socket failed");
let _sockaddr = SockAddr::new_sys_control(fd, "com.apple.net.utun_control", 0).expect("resolving sys_control name failed");
assert_eq!(SockAddr::new_sys_control(fd, "foo.bar.lol", 0).err(), Some(Error::Sys(Errno::ENOENT)));
diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs
index 92769e52..81db8248 100644
--- a/test/sys/test_sockopt.rs
+++ b/test/sys/test_sockopt.rs
@@ -1,9 +1,10 @@
use rand::{thread_rng, Rng};
-use nix::sys::socket::{socket, sockopt, getsockopt, setsockopt, AddressFamily, SockType, SockFlag, SockLevel};
+use nix::sys::socket::{socket, sockopt, getsockopt, setsockopt, AddressFamily, SockType, SockFlag, SockProtocol};
#[test]
fn test_so_buf() {
- let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), SockLevel::Udp as i32).unwrap();
+ let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), SockProtocol::Udp)
+ .unwrap();
let bufsize: usize = thread_rng().gen_range(4096, 131072);
setsockopt(fd, sockopt::SndBuf, &bufsize).unwrap();
let actual = getsockopt(fd, sockopt::SndBuf).unwrap();