diff options
author | Alan Somers <asomers@gmail.com> | 2019-10-27 13:33:40 -0600 |
---|---|---|
committer | Alan Somers <asomers@gmail.com> | 2019-10-28 20:57:52 -0600 |
commit | e10e5373e887c96a1549e22e3dd05f448c040d1d (patch) | |
tree | cdc1b823a44dfef76fb5f7e18358e9cfad2c2368 /test/sys/test_socket.rs | |
parent | a2bbbae3812ec5c1b591782394bcef478416b013 (diff) | |
download | nix-e10e5373e887c96a1549e22e3dd05f448c040d1d.zip |
Fix sys::socket::recvfrom for TCP sockets
recvfrom(2) only returns the sender's address for protocols that provide
it. Usually, that means it returns the sender's address for datagram
sockets but not for stream sockets.
Fixes #1144
Diffstat (limited to 'test/sys/test_socket.rs')
-rw-r--r-- | test/sys/test_socket.rs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 106428b9..13d7b6b0 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -161,6 +161,73 @@ pub fn test_socketpair() { assert_eq!(&buf[..], b"hello"); } +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; + + let send_thread = thread::spawn(move || { + let mut l = 0; + while l < std::mem::size_of_val(MSG) { + l += f(ssock, &MSG[l..], MsgFlags::empty()).unwrap(); + } + }); + + while l < std::mem::size_of_val(MSG) { + let (len, from_) = recvfrom(rsock, &mut buf[l..]).unwrap(); + from = from_; + l += len; + } + assert_eq!(&buf, MSG); + send_thread.join().unwrap(); + from + } + + #[test] + pub fn stream() { + let (fd2, fd1) = socketpair(AddressFamily::Unix, SockType::Stream, + None, SockFlag::empty()).unwrap(); + // Ignore from for stream sockets + let _ = sendrecv(fd1, fd2, |s, m, flags| { + send(s, m, flags) + }); + } + + #[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()); + } +} + // Test error handling of our recvmsg wrapper #[test] pub fn test_recvmsg_ebadf() { |