-
Notifications
You must be signed in to change notification settings - Fork 258
#487 Add ways to set Path Discovery MTU for Linux on a Socket. #515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
f24c12d
4286134
06ceefb
e95a481
d35c931
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1391,6 +1391,39 @@ pub(crate) const fn to_mreqn( | |
} | ||
} | ||
|
||
/// Possibles state for Path Maximum Transmission Unit (PMTU) Discovering of packets received on a socket. | ||
/// | ||
/// It set in the IP packet Header the flag DF also known as "do not fragment". | ||
/// | ||
/// For UDP it's particullary important to note that during Path MTU discovery is done by the OS, | ||
/// incomming datagram may be dropped. | ||
/// | ||
/// ## Portability | ||
/// | ||
/// It's Linux only way of managing the Path MTU. | ||
#[cfg(all(feature = "all", target_os = "linux"))] | ||
#[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] | ||
#[repr(C)] | ||
#[derive(Debug)] | ||
pub enum PathMtuDiscoveringMode { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure about this enum. Maybe it's better as a type alias with constants for the options? This way we don't have to do the conversion and we don't have to deal with the case where the kernel returns a value we don't support yet. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok I agree, I may do a patch to the linux man page since some are not explicitly documented outside of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I reused the pattern used for |
||
/// Path MTU discovery is not done. | ||
Dont = 0, | ||
/// Path MTU discovery is done according to route setting. | ||
Want = 1, | ||
/// Path MTU discovery | ||
Do = 2, | ||
/// Set DF bit but ignore Path MTDU | ||
Probe = 3, | ||
/// Use interface MTU. | ||
/// It ignore destination PMTU and does not set DF flag. | ||
/// Incomming ICMP frag_needed notifications on this socket will be ignored in | ||
/// order to prevent accepting spoofed ones. | ||
Interface = 4, | ||
/// Almost like [MtuDiscoveringMode::Interface] but authorize fragmented packet | ||
/// if they do not saturate the interface MTU. | ||
Omit = 5, | ||
} | ||
|
||
/// Unix only API. | ||
impl crate::Socket { | ||
/// Accept a new incoming connection from this listener. | ||
|
@@ -3063,6 +3096,94 @@ impl crate::Socket { | |
) | ||
} | ||
} | ||
|
||
/// Get the value of the `IP_MTU_DISCOVER` of this socket for IPv4. | ||
#[cfg(all(feature = "all", target_os = "linux"))] | ||
#[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] | ||
pub fn mtu_discover(&self) -> io::Result<PathMtuDiscoveringMode> { | ||
unsafe { | ||
use PathMtuDiscoveringMode as MTU; | ||
let mtu_discovering = | ||
getsockopt::<c_int>(self.as_raw(), libc::SOL_IP, libc::IP_MTU_DISCOVER)?; | ||
|
||
Ok(match mtu_discovering { | ||
libc::IP_PMTUDISC_DONT => MTU::Dont, | ||
libc::IP_PMTUDISC_WANT => MTU::Want, | ||
libc::IP_PMTUDISC_DO => MTU::Do, | ||
libc::IP_PMTUDISC_PROBE => MTU::Probe, | ||
#[cfg(all(feature = "all", target_os = "linux"))] | ||
libc::IP_PMTUDISC_INTERFACE => MTU::Interface, | ||
#[cfg(all(feature = "all", target_os = "linux"))] | ||
libc::IP_PMTUDISC_OMIT => MTU::Omit, | ||
_ => { | ||
return Err(std::io::Error::new( | ||
std::io::ErrorKind::Other, | ||
"IP_PMTUDISC value not yet implemented by socket2", | ||
)); | ||
} | ||
}) | ||
} | ||
} | ||
|
||
/// Set value for the `IP_MTU_DISCOVER` of this socket for IPv4. | ||
/// Used to configure Dont fragment DF bit and OS behaviour related to Path MTU discovery. | ||
/// See [PathMtuDiscoveringMode] for details. | ||
#[cfg(all(feature = "all", target_os = "linux"))] | ||
#[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] | ||
pub fn set_mtu_discover(&self, mtu_discovery: PathMtuDiscoveringMode) -> io::Result<()> { | ||
unsafe { | ||
setsockopt( | ||
self.as_raw(), | ||
libc::SOL_IP, | ||
libc::IP_MTU_DISCOVER, | ||
mtu_discovery as c_int, | ||
) | ||
} | ||
} | ||
|
||
/// Get the value of the `IP_MTU_DISCOVER` of this socket for IPv6. | ||
#[cfg(all(feature = "all", target_os = "linux"))] | ||
#[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] | ||
pub fn mtu_discover_ipv6(&self) -> io::Result<PathMtuDiscoveringMode> { | ||
unsafe { | ||
use PathMtuDiscoveringMode as MTU; | ||
let mtu_discovering = | ||
getsockopt::<c_int>(self.as_raw(), libc::SOL_IPV6, libc::IPV6_MTU_DISCOVER)?; | ||
|
||
Ok(match mtu_discovering { | ||
libc::IPV6_PMTUDISC_DONT => MTU::Dont, | ||
libc::IPV6_PMTUDISC_WANT => MTU::Want, | ||
libc::IPV6_PMTUDISC_DO => MTU::Do, | ||
libc::IPV6_PMTUDISC_PROBE => MTU::Probe, | ||
#[cfg(all(feature = "all", target_os = "linux"))] | ||
libc::IPV6_PMTUDISC_INTERFACE => MTU::Interface, | ||
#[cfg(all(feature = "all", target_os = "linux"))] | ||
libc::IPV6_PMTUDISC_OMIT => MTU::Omit, | ||
_ => { | ||
return Err(std::io::Error::new( | ||
std::io::ErrorKind::Other, | ||
"IP_PMTUDISC value not yet implemented by socket2", | ||
)); | ||
} | ||
}) | ||
} | ||
} | ||
|
||
/// Set value for the `IP_MTU_DISCOVER` of this socket for IPv6. | ||
/// Used to configure Dont fragment DF bit and OS behaviour related to Path MTU discovery. | ||
/// See [PathMtuDiscoveringMode] for details. | ||
#[cfg(all(feature = "all", target_os = "linux"))] | ||
#[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))] | ||
pub fn set_mtu_discover_ipv6(&self, mtu_discovery: PathMtuDiscoveringMode) -> io::Result<()> { | ||
unsafe { | ||
setsockopt( | ||
self.as_raw(), | ||
libc::SOL_IPV6, | ||
libc::IPV6_MTU_DISCOVER, | ||
mtu_discovery as c_int, | ||
) | ||
} | ||
} | ||
} | ||
|
||
/// See [`Socket::dccp_available_ccids`]. | ||
|
Uh oh!
There was an error while loading. Please reload this page.