Skip to content

Commit e7d4720

Browse files
committed
add SockProtocol type for third argument of socket and socketpair
1 parent 64ae507 commit e7d4720

File tree

4 files changed

+54
-23
lines changed

4 files changed

+54
-23
lines changed

src/sys/socket/mod.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,24 @@ pub enum SockType {
6161
Rdm = libc::SOCK_RDM,
6262
}
6363

64+
/// Constants used in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
65+
/// to specify the protocol to use.
66+
#[repr(i32)]
67+
pub enum SockProtocol {
68+
/// TCP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html))
69+
Tcp = libc::IPPROTO_TCP,
70+
/// UDP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html))
71+
Udp = libc::IPPROTO_UDP,
72+
/// Allows applications and other KEXTs to be notified when certain kernel events occur
73+
/// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
74+
#[cfg(any(target_os = "ios", target_os = "macos"))]
75+
KextEvent = SYSPROTO_EVENT,
76+
/// Allows applications to configure and control a KEXT
77+
/// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
78+
#[cfg(any(target_os = "ios", target_os = "macos"))]
79+
KextControl = SYSPROTO_CONTROL,
80+
}
81+
6482
// Extra flags - Supported by Linux 2.6.27, normalized on other platforms
6583
bitflags!(
6684
pub struct SockFlag: c_int {
@@ -382,9 +400,20 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
382400

383401
/// Create an endpoint for communication
384402
///
403+
/// The `protocol` specifies a particular protocol to be used with the
404+
/// socket. Normally only a single protocol exists to support a
405+
/// particular socket type within a given protocol family, in which case
406+
/// protocol can be specified as `None`. However, it is possible that many
407+
/// protocols may exist, in which case a particular protocol must be
408+
/// specified in this manner.
409+
///
385410
/// [Further reading](http://man7.org/linux/man-pages/man2/socket.2.html)
386-
pub fn socket(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: c_int) -> Result<RawFd> {
411+
pub fn socket<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: T) -> Result<RawFd> {
387412
let mut ty = ty as c_int;
413+
let protocol = match protocol.into() {
414+
None => 0,
415+
Some(p) => p as c_int,
416+
};
388417
let feat_atomic = features::socket_atomic_cloexec();
389418

390419
if feat_atomic {
@@ -410,9 +439,13 @@ pub fn socket(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: c_
410439
/// Create a pair of connected sockets
411440
///
412441
/// [Further reading](http://man7.org/linux/man-pages/man2/socketpair.2.html)
413-
pub fn socketpair(domain: AddressFamily, ty: SockType, protocol: c_int,
442+
pub fn socketpair<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, protocol: T,
414443
flags: SockFlag) -> Result<(RawFd, RawFd)> {
415444
let mut ty = ty as c_int;
445+
let protocol = match protocol.into() {
446+
None => 0,
447+
Some(p) => p as c_int,
448+
};
416449
let feat_atomic = features::socket_atomic_cloexec();
417450

418451
if feat_atomic {

src/sys/socket/sockopt.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ mod test {
379379
fn can_get_peercred_on_unix_socket() {
380380
use super::super::*;
381381

382-
let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, 0, SockFlag::empty()).unwrap();
382+
let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
383383
let a_cred = getsockopt(a, super::PeerCredentials).unwrap();
384384
let b_cred = getsockopt(b, super::PeerCredentials).unwrap();
385385
assert_eq!(a_cred, b_cred);
@@ -391,7 +391,7 @@ mod test {
391391
use super::super::*;
392392
use ::unistd::close;
393393

394-
let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, 0, SockFlag::empty()).unwrap();
394+
let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
395395
let a_type = getsockopt(a, super::SockType).unwrap();
396396
assert!(a_type == SockType::Stream);
397397
close(a).unwrap();
@@ -403,7 +403,7 @@ mod test {
403403
use super::super::*;
404404
use ::unistd::close;
405405

406-
let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), 0).unwrap();
406+
let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap();
407407
let s_type = getsockopt(s, super::SockType).unwrap();
408408
assert!(s_type == SockType::Datagram);
409409
close(s).unwrap();
@@ -417,7 +417,7 @@ mod test {
417417
use super::super::*;
418418
use ::unistd::close;
419419

420-
let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), 0).unwrap();
420+
let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap();
421421
let s_listening = getsockopt(s, super::AcceptConn).unwrap();
422422
assert!(!s_listening);
423423
listen(s, 10).unwrap();

test/sys/test_socket.rs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ pub fn test_getsockname() {
6969

7070
let tempdir = TempDir::new("test_getsockname").unwrap();
7171
let sockname = tempdir.path().join("sock");
72-
let sock = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(),
73-
0).expect("socket failed");
72+
let sock = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None)
73+
.expect("socket failed");
7474
let sockaddr = SockAddr::new_unix(&sockname).unwrap();
7575
bind(sock, &sockaddr).expect("bind failed");
7676
assert_eq!(sockaddr.to_str(),
@@ -82,8 +82,7 @@ pub fn test_socketpair() {
8282
use nix::unistd::{read, write};
8383
use nix::sys::socket::{socketpair, AddressFamily, SockType, SockFlag};
8484

85-
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
86-
SockFlag::empty())
85+
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
8786
.unwrap();
8887
write(fd1, b"hello").unwrap();
8988
let mut buf = [0;5];
@@ -101,8 +100,7 @@ pub fn test_scm_rights() {
101100
ControlMessage, CmsgSpace, MsgFlags,
102101
MSG_TRUNC, MSG_CTRUNC};
103102

104-
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
105-
SockFlag::empty())
103+
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
106104
.unwrap();
107105
let (r, w) = pipe().unwrap();
108106
let mut received_r: Option<RawFd> = None;
@@ -158,8 +156,7 @@ pub fn test_sendmsg_empty_cmsgs() {
158156
CmsgSpace, MsgFlags,
159157
MSG_TRUNC, MSG_CTRUNC};
160158

161-
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
162-
SockFlag::empty())
159+
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
163160
.unwrap();
164161

165162
{
@@ -194,14 +191,14 @@ pub fn test_unixdomain() {
194191
let tempdir = TempDir::new("test_unixdomain").unwrap();
195192
let sockname = tempdir.path().join("sock");
196193
let s1 = socket(AddressFamily::Unix, SockType::Stream,
197-
SockFlag::empty(), 0).expect("socket failed");
194+
SockFlag::empty(), None).expect("socket failed");
198195
let sockaddr = SockAddr::new_unix(&sockname).unwrap();
199196
bind(s1, &sockaddr).expect("bind failed");
200197
listen(s1, 10).expect("listen failed");
201198

202199
let thr = thread::spawn(move || {
203-
let s2 = socket(AddressFamily::Unix, SockType::Stream,
204-
SockFlag::empty(), 0).expect("socket failed");
200+
let s2 = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None)
201+
.expect("socket failed");
205202
connect(s2, &sockaddr).expect("connect failed");
206203
write(s2, b"hello").expect("write failed");
207204
close(s2).unwrap();
@@ -223,11 +220,11 @@ pub fn test_unixdomain() {
223220
#[test]
224221
pub fn test_syscontrol() {
225222
use nix::{Errno, Error};
226-
use nix::sys::socket::{AddressFamily, SockType, SockFlag};
227-
use nix::sys::socket::{socket, SockAddr};
228-
use nix::sys::socket::SYSPROTO_CONTROL;
223+
use nix::sys::socket::{AddressFamily, socket, SockAddr, SockType, SockFlag, SockProtocol};
229224

230-
let fd = socket(AddressFamily::System, SockType::Datagram, SockFlag::empty(), SYSPROTO_CONTROL).expect("socket failed");
225+
let fd = socket(AddressFamily::System, SockType::Datagram,
226+
SockFlag::empty(), SockProtocol::KextControl)
227+
.expect("socket failed");
231228
let _sockaddr = SockAddr::new_sys_control(fd, "com.apple.net.utun_control", 0).expect("resolving sys_control name failed");
232229
assert_eq!(SockAddr::new_sys_control(fd, "foo.bar.lol", 0).err(), Some(Error::Sys(Errno::ENOENT)));
233230

test/sys/test_sockopt.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use rand::{thread_rng, Rng};
2-
use nix::sys::socket::{socket, sockopt, getsockopt, setsockopt, AddressFamily, SockType, SockFlag, SockLevel};
2+
use nix::sys::socket::{socket, sockopt, getsockopt, setsockopt, AddressFamily, SockType, SockFlag, SockProtocol};
33

44
#[test]
55
fn test_so_buf() {
6-
let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), SockLevel::Udp as i32).unwrap();
6+
let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), SockProtocol::Udp)
7+
.unwrap();
78
let bufsize: usize = thread_rng().gen_range(4096, 131072);
89
setsockopt(fd, sockopt::SndBuf, &bufsize).unwrap();
910
let actual = getsockopt(fd, sockopt::SndBuf).unwrap();

0 commit comments

Comments
 (0)