summaryrefslogtreecommitdiff
path: root/test/sys/test_socket.rs
diff options
context:
space:
mode:
authorAlan Somers <asomers@gmail.com>2019-10-27 13:33:40 -0600
committerAlan Somers <asomers@gmail.com>2019-10-28 20:57:52 -0600
commite10e5373e887c96a1549e22e3dd05f448c040d1d (patch)
treecdc1b823a44dfef76fb5f7e18358e9cfad2c2368 /test/sys/test_socket.rs
parenta2bbbae3812ec5c1b591782394bcef478416b013 (diff)
downloadnix-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.rs67
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() {