Skip to content

#487 Add ways to set Path Discovery MTU for Linux on a Socket. - #515

Open
darnuria wants to merge 5 commits into
rust-lang:masterfrom
darnuria:socket_opt_mtu
Open

darnuria wants to merge 5 commits into
rust-lang:masterfrom
darnuria:socket_opt_mtu

Conversation

@darnuria

@darnuria darnuria commented Jun 9, 2024 •

Copy link
Copy Markdown

Hello first contribution here! It may need some careful review since MTU management is a bit complicated and not so portable.

Add ways to set Path Discovery MTU for Linux on a Socket. (it may not work on freebsd EDIT: CI confirmed it! but may work on Windows subsystem and winsock: https://learn.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options.

This contribution use setsocketops to configure Dont Fragment (DF) bit and OS
behavior related to PMTU.

It introduce PathMtuDiscoveringMode enum to manage it rust-way and 4 functions
respectively for ipv4/v6 and set/get.

Omit and Interface exist but are not widely documented.

Initially It started by preparing a PR for the patch purposed here: #487

Context: Why it can be needed in a rust library? Some protocols such as DNS in UDP or traceroute needs to manage the MTU on a socket level.

Exemples:

This contribution use setsocketops to configure Dont Fragment (DF) bit and OS
behavior related to PMTU.

It introduce PathMtuDiscoveringMode enum to manage it rust-way and 4 functions
respectively for ipv4/v6 and set/get.

Omit and Interface exist but are not widely documented.
Comment thread src/sys/unix.rs Outdated
#[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))]
#[repr(C)]
#[derive(Debug)]
pub enum PathMtuDiscoveringMode {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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 in.h/in6.h

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

I reused the pattern used for Type and Protocol code tell me if wasn't the best move. :)

Comment thread src/sys/unix.rs Outdated
@darnuria

Copy link
Copy Markdown
Author

Hello, thanks for the review, will do the changes today.

darnuria and others added 4 commits June 19, 2024 14:28
Co-authored-by: Thomas de Zeeuw <thomasdezeeuw@gmail.com>
I reused the pattern used elsewhere to have handful short hands documented,
while yet permiting futur constant not exposed in the lib.

Also expose MtuDiscovering Mode types..
Comment thread src/sys/unix.rs

#[cfg(all(feature = "all", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_os = "linux"))))]
impl PathMtuDiscoveringModeV6 {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It involve some code duplication alas but it's code that... never change except for adding new mode since API don't change for Linux.

@darnuria
darnuria marked this pull request as ready for review June 19, 2024 19:21
@Thomasdezeeuw

Copy link
Copy Markdown
Collaborator

Sorry @darnuria I didn't have time to review this last weekend and I don't think I'll have time the next two weeks either, so it's going to take a little while.

@larseggert

Copy link
Copy Markdown

It would be great if this PR would also allow setting IP_DONTFRAG for UDP sockets.

@pederbe

pederbe commented Sep 25, 2026

Copy link
Copy Markdown

+1 for this, and a request to extend it to Windows (and macOS) so DF can be set and read back portably.

Use case: I'm implementing RFC 9946 (UDPSTP), a UDP capacity-measurement protocol. RFC 9946 §5 says the IPv4 DF bit SHOULD be set on test traffic, and operators must be able to clear it when fragmentation is what they're measuring. Today socket2 covers my other per-socket IP options (TTL, hop limit, TOS/Traffic Class, buffers), but not DF.

  • Linux: I use rustix (IP_MTU_DISCOVER / IPV6_MTU_DISCOVER, IP_PMTUDISC_PROBE or DONT), which this PR would cover.
  • macOS: nix (IP_DONTFRAG / IPV6_DONTFRAG), which is Apple-only in nix.
  • Windows: no safe crate sets IP_DONTFRAGMENT / IPV6_DONTFRAG (IPPROTO_IP and IPPROTO_IPV6 options documented for UDP), so without unsafe our Windows builds can't set DF at all.

What would cover it on every platform:

  1. A setter and getter for "don't fragment", in both families: IP_DONTFRAGMENT / IPV6_DONTFRAG on Windows, IP_DONTFRAG / IPV6_DONTFRAG on Apple and the BSDs, and on Linux the IP_MTU_DISCOVER modes this PR adds (or IPV6_DONTFRAG).
  2. The getter matters as much as the setter: we check the option by reading it back in tests.

I'd be glad to contribute the Windows and Apple parts myself, either as a follow-up PR or as commits on this branch if @darnuria prefers. Just say which you'd rather have. I can test on Windows and Linux locally, CI covers mac.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants