Skip to content

Commit

Permalink
Fix tests on Linux
Browse files Browse the repository at this point in the history
Linux's recvfrom(2) does not set the from address for Unix-domain
datagram sockets.
  • Loading branch information
asomers committed Oct 29, 2019
1 parent 30bb1ad commit 83d3032
Showing 1 changed file with 45 additions and 33 deletions.
78 changes: 45 additions & 33 deletions test/sys/test_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,57 +162,69 @@ pub fn test_socketpair() {
}

mod recvfrom {
use nix::Result;
use nix::sys::socket::*;
use std::thread;
use super::*;

const MSG: &'static [u8] = b"Hello, World!";

fn sendrecv<F>(rsock: RawFd, ssock: RawFd, f: F) -> Option<SockAddr>
where F: Fn(RawFd, &[u8], MsgFlags) -> Result<usize> + Send + 'static
{
let mut buf: [u8; 13] = [0u8; 13];
let mut l = 0;
let mut from = None;

#[test]
pub fn datagram() {
let msg = b"Hello, World!";
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Datagram,
None, SockFlag::empty()).unwrap();
let send_thread = thread::spawn(move || {
let mut l = 0;
while l < std::mem::size_of_val(msg) {
let flags = MsgFlags::empty();
l += send(fd1, &msg[l..], flags).unwrap();
while l < std::mem::size_of_val(MSG) {
l += f(ssock, &MSG[l..], MsgFlags::empty()).unwrap();
}
});

let mut buf: [u8; 13] = [0u8; 13];
let mut l = 0;

while l < std::mem::size_of_val(msg) {
let (len, from) = recvfrom(fd2, &mut buf[l..]).unwrap();
while l < std::mem::size_of_val(MSG) {
let (len, from_) = recvfrom(rsock, &mut buf[l..]).unwrap();
from = from_;
l += len;
assert_eq!(AddressFamily::Unix, from.unwrap().family());
}
assert_eq!(&buf, msg);
assert_eq!(&buf, MSG);
send_thread.join().unwrap();
from
}

#[test]
pub fn stream() {
let msg = b"Hello, World!";
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream,
let (fd2, fd1) = socketpair(AddressFamily::Unix, SockType::Stream,
None, SockFlag::empty()).unwrap();
let send_thread = thread::spawn(move || {
let mut l = 0;
while l < std::mem::size_of_val(msg) {
let flags = MsgFlags::empty();
l += send(fd1, &msg[l..], flags).unwrap();
}
// Ignore from for stream sockets
let _ = sendrecv(fd1, fd2, |s, m, flags| {
send(s, m, flags)
});
}

let mut buf: [u8; 13] = [0u8; 13];
let mut l = 0;

while l < std::mem::size_of_val(msg) {
let (len, _from) = recvfrom(fd2, &mut buf[l..]).unwrap();
l += len;
// Ignore _from for stream sockets
}
assert_eq!(&buf, msg);
send_thread.join().unwrap();
#[test]
pub fn udp() {
let std_sa = SocketAddr::from_str("127.0.0.1:6789").unwrap();
let inet_addr = InetAddr::from_std(&std_sa);
let sock_addr = SockAddr::new_inet(inet_addr);
let rsock = socket(AddressFamily::Inet,
SockType::Datagram,
SockFlag::empty(),
None
).unwrap();
bind(rsock, &sock_addr).unwrap();
let ssock = socket(
AddressFamily::Inet,
SockType::Datagram,
SockFlag::empty(),
None,
).expect("send socket failed");
let from = sendrecv(rsock, ssock, move |s, m, flags| {
sendto(s, m, &sock_addr, flags)
});
// UDP sockets should set the from address
assert_eq!(AddressFamily::Inet, from.unwrap().family());
}
}

Expand Down

0 comments on commit 83d3032

Please sign in to comment.