Skip to content
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

Fallback to 256 w/ no host name max on unix #16

Closed
wants to merge 1 commit into from
Closed

Fallback to 256 w/ no host name max on unix #16

wants to merge 1 commit into from

Conversation

pinotree
Copy link

@pinotree pinotree commented Jul 3, 2024

POSIX allows sysconf(_SC_HOST_NAME_MAX) to return -1 in case no limit is set; in such cases, fallback to an hardcoded 256 as limit for the buffer used for libc::gethostname(), which should be more than good enough in most/all the cases.

This fixes gethostname() on GNU/Hurd, where there is no limit defined by sysconf(_SC_HOST_NAME_MAX).

POSIX allows sysconf(_SC_HOST_NAME_MAX) to return -1 in case no limit
is set; in such cases, fallback to an hardcoded 256 as limit for the
buffer used for libc::gethostname(), which should be more than good
enough in most/all the cases.

This fixes gethostname() on GNU/Hurd, where there is no limit defined
by sysconf(_SC_HOST_NAME_MAX).
@swsnr
Copy link
Owner

swsnr commented Jul 3, 2024

How do you know that 256 is "enough in most cases"? If we're into POSIX, what does POSIX say about the size of a hostname? What does POSIX say how one's supposed to determine the size of a hostname if sysconf returns -1 for the size of a hostname?

@swsnr swsnr self-assigned this Jul 3, 2024
@pinotree
Copy link
Author

pinotree commented Jul 3, 2024

If we're into POSIX, what does POSIX say about the size of a hostname? What does POSIX say how one's supposed to determine the size of a hostname if sysconf returns -1 for the size of a hostname?

The gethostname() POSIX documentation [1] does not document any failure, mentioning that it truncates to fit into the provided buffer, and also that

Host names are limited to {HOST_NAME_MAX} bytes.

HOST_NAME_MAX may be defined in <limits.h> [2]:

A definition of one of the symbolic constants in the following list shall be omitted from <limits.h> on specific implementations where the corresponding value is equal to or greater than the stated minimum, but is unspecified.

So it cannot be relied on, and it is not exposed by the libc crate.

_POSIX_HOST_NAME_MAX, which is defined in POSIX as 255, seems not exposed either (except on Hurd).

Looking at the gethostname() Linux man page [3], there are a couple of additional details:

  • GNU libc errors out with ENAMETOOLONG if the provided buffer is too short
  • on Linux HOST_NAME_MAX is limited to 64:
    $ grep -rnw HOST_NAME_MAX /usr/include/
    [...]
    /usr/include/x86_64-linux-gnu/bits/local_lim.h:93:#define HOST_NAME_MAX         64
    [...]
    $ getconf HOST_NAME_MAX
    64
    

Hence, the value I hardcoded generally fits the general situation.

A non-hardcoding way for this would be:

  1. allocate a buffer of a certain length
  2. call gethostname()
  3. if the buffer is not null-terminated, extend the length for the buffer with some logic, go back to point (1) above

[1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html
[2] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html
[3] https://linux.die.net/man/2/gethostname

@swsnr
Copy link
Owner

swsnr commented Jul 3, 2024

So POSIX says in absence of a sysconf value we should fall back to #defines from limit.h? Does libc (or any other crate) expose this? Or alternatively, how does rustix handle this?

If this turns out to be a proper mess, I'd rather just go for rustix (see #10), which abstracts the whole thing for us 🙂

@pinotree
Copy link
Author

pinotree commented Jul 3, 2024

So POSIX says in absence of a sysconf value we should fall back to #defines from limit.h?

In practice, yes.

Does libc (or any other crate) expose this?

See my comment above: it seems not.

Or alternatively, how does rustix handle this?

It seems that it does not provide gethostname() specifically, and it points people to use Uname::nodename instead, whose source is C uname() (and the fields in the C struct utsname have static lengths).

If this turns out to be a proper mess, I'd rather just go for rustix (see #10), which abstracts the whole thing for us 🙂

IMHO my simple fallback is a good enough solution for corner cases; otherwise, switching this crate to Uname::nodename from rustix seems another good solution as well.

@pinotree
Copy link
Author

pinotree commented Jul 3, 2024

Another possibility could be to use uname() from the libc crate directly here, on platforms where it is available, falling back to the current gethostname() solution otherwise.

@swsnr swsnr mentioned this pull request Jul 6, 2024
@swsnr
Copy link
Owner

swsnr commented Jul 6, 2024

See #17 for rustix.

@swsnr swsnr closed this in #17 Jul 6, 2024
@swsnr swsnr closed this in 0d2bd4e Jul 6, 2024
@pinotree pinotree deleted the unix-no-host_name_max branch July 7, 2024 04:35
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.

2 participants