diff options
Diffstat (limited to 'src/sys/windows/tcp.rs')
-rw-r--r-- | src/sys/windows/tcp.rs | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/src/sys/windows/tcp.rs b/src/sys/windows/tcp.rs index c5b0410..46ac1ac 100644 --- a/src/sys/windows/tcp.rs +++ b/src/sys/windows/tcp.rs @@ -1,11 +1,15 @@ use std::io; +use std::mem::size_of; use std::net::{self, SocketAddr}; +use std::time::Duration; use std::os::windows::io::FromRawSocket; use std::os::windows::raw::SOCKET as StdSocket; // winapi uses usize, stdlib uses u32/u64. +use winapi::ctypes::{c_char, c_int, c_ushort}; +use winapi::shared::minwindef::{BOOL, TRUE, FALSE}; use winapi::um::winsock2::{ - self, - closesocket, PF_INET, PF_INET6, SOCKET, SOCKET_ERROR, SOCK_STREAM, + self, closesocket, linger, setsockopt, PF_INET, PF_INET6, SOCKET, SOCKET_ERROR, + SOCK_STREAM, SOL_SOCKET, SO_LINGER, SO_REUSEADDR, }; use crate::sys::windows::net::{init, new_socket, socket_addr}; @@ -69,11 +73,6 @@ pub(crate) fn close(socket: TcpSocket) { } pub(crate) fn set_reuseaddr(socket: TcpSocket, reuseaddr: bool) -> io::Result<()> { - use winapi::ctypes::{c_char, c_int}; - use winapi::shared::minwindef::{BOOL, TRUE, FALSE}; - use winapi::um::winsock2::{setsockopt, SOCKET_ERROR, SO_REUSEADDR, SOL_SOCKET}; - use std::mem::size_of; - let val: BOOL = if reuseaddr { TRUE } else { FALSE }; match unsafe { setsockopt( @@ -83,9 +82,26 @@ pub(crate) fn set_reuseaddr(socket: TcpSocket, reuseaddr: bool) -> io::Result<() &val as *const _ as *const c_char, size_of::<BOOL>() as c_int, ) } { - 0 => Ok(()), SOCKET_ERROR => Err(io::Error::last_os_error()), - _ => panic!("unexpected return value"), + _ => Ok(()), + } +} + +pub(crate) fn set_linger(socket: TcpSocket, dur: Option<Duration>) -> io::Result<()> { + let val: linger = linger { + l_onoff: if dur.is_some() { 1 } else { 0 }, + l_linger: dur.map(|dur| dur.as_secs() as c_ushort).unwrap_or_default(), + }; + + match unsafe { setsockopt( + socket, + SOL_SOCKET, + SO_LINGER, + &val as *const _ as *const c_char, + size_of::<linger>() as c_int, + ) } { + SOCKET_ERROR => Err(io::Error::last_os_error()), + _ => Ok(()), } } |