[1/1] inet: add support for 64-bit network byte order
Checks
Context |
Check |
Description |
redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
redhat-pt-bot/TryBot-32bit |
success
|
Build for i686
|
linaro-tcwg-bot/tcwg_glibc_build--master-arm |
fail
|
Patch failed to apply
|
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
fail
|
Patch failed to apply
|
Commit Message
From: Philip Prindeville <philipp@redfish-solutions.com>
As 32-bit machines become increasingly supplanted by 64-bit
architectures, network protocols likewise leverage those
larger word capabilities. A good example is POSIX supporting
64-bit time_t's to avoid the 2038 problem, or timestamps that
include micro- or nanosecond precision.
---
conform/data/arpa/inet.h-data | 2 ++
conform/data/netinet/in.h-data | 2 ++
inet/Makefile | 1 +
inet/htonll.c | 35 +++++++++++++++++++
inet/htontest.c | 11 ++++++
inet/netinet/in.h | 11 ++++++
inet/test-hnto-types.c | 4 +++
manual/socket.texi | 15 ++++++++
sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 ++
sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 ++
.../sysv/linux/loongarch/lp64/libc.abilist | 2 ++
.../sysv/linux/m68k/coldfire/libc.abilist | 2 ++
.../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 ++
.../sysv/linux/microblaze/be/libc.abilist | 2 ++
.../sysv/linux/microblaze/le/libc.abilist | 2 ++
.../unix/sysv/linux/riscv/rv32/libc.abilist | 2 ++
.../unix/sysv/linux/riscv/rv64/libc.abilist | 2 ++
.../unix/sysv/linux/s390/s390-32/libc.abilist | 2 ++
.../unix/sysv/linux/s390/s390-64/libc.abilist | 2 ++
sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 ++
sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 ++
.../sysv/linux/sparc/sparc32/libc.abilist | 2 ++
.../sysv/linux/sparc/sparc64/libc.abilist | 2 ++
.../unix/sysv/linux/x86_64/64/libc.abilist | 2 ++
.../unix/sysv/linux/x86_64/x32/libc.abilist | 2 ++
25 files changed, 115 insertions(+)
Comments
* Philip Prindeville:
> From: Philip Prindeville <philipp@redfish-solutions.com>
>
> As 32-bit machines become increasingly supplanted by 64-bit
> architectures, network protocols likewise leverage those
> larger word capabilities. A good example is POSIX supporting
> 64-bit time_t's to avoid the 2038 problem, or timestamps that
> include micro- or nanosecond precision.
> ---
> conform/data/arpa/inet.h-data | 2 ++
> conform/data/netinet/in.h-data | 2 ++
> inet/Makefile | 1 +
> inet/htonll.c | 35 +++++++++++++++++++
> inet/htontest.c | 11 ++++++
> inet/netinet/in.h | 11 ++++++
> inet/test-hnto-types.c | 4 +++
> manual/socket.texi | 15 ++++++++
> sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 ++
> sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 ++
> .../sysv/linux/loongarch/lp64/libc.abilist | 2 ++
> .../sysv/linux/m68k/coldfire/libc.abilist | 2 ++
> .../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 ++
> .../sysv/linux/microblaze/be/libc.abilist | 2 ++
> .../sysv/linux/microblaze/le/libc.abilist | 2 ++
> .../unix/sysv/linux/riscv/rv32/libc.abilist | 2 ++
> .../unix/sysv/linux/riscv/rv64/libc.abilist | 2 ++
> .../unix/sysv/linux/s390/s390-32/libc.abilist | 2 ++
> .../unix/sysv/linux/s390/s390-64/libc.abilist | 2 ++
> sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 ++
> sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 ++
> .../sysv/linux/sparc/sparc32/libc.abilist | 2 ++
> .../sysv/linux/sparc/sparc64/libc.abilist | 2 ++
> .../unix/sysv/linux/x86_64/64/libc.abilist | 2 ++
> .../unix/sysv/linux/x86_64/x32/libc.abilist | 2 ++
> 25 files changed, 115 insertions(+)
I think Hurd abilist updates are missing.
Please also add a NEWS entry mentioning the function.
Do you have a copyright assignment with the FSF? If not, please
consider obtaining one, or submit the patch under DCO
<https://developercertificate.org/>, by including a Signed-off-by: line
in the commit message.
> diff --git a/conform/data/arpa/inet.h-data b/conform/data/arpa/inet.h-data
> index 040b8212c73778d2e1272a2841424fdb098ddde2..c80912ffde59e1d6da1c548f3a0e072f4b4ab5f6 100644
> --- a/conform/data/arpa/inet.h-data
> +++ b/conform/data/arpa/inet.h-data
> @@ -11,8 +11,10 @@ macro INET_ADDRSTRLEN
> macro INET6_ADDRSTRLEN
>
> // The following can be declared as functions, defined as macros or both:
> +function uint64_t htonll (uint64_t)
> function uint32_t htonl (uint32_t)
> function uint16_t htons (uint16_t)
> +function uint64_t ntohll (uint64_t)
> function uint32_t ntohl (uint32_t)
> function uint16_t htons (uint16_t)
This looks premature because these functions are not yet part of POSIX
or any other standard.
> diff --git a/conform/data/netinet/in.h-data b/conform/data/netinet/in.h-data
> index ccc74db608727200161d2713a2f7fb171d8b8138..27a8628a99f749e69c0b6456fb875da5cd8da367 100644
> --- a/conform/data/netinet/in.h-data
> +++ b/conform/data/netinet/in.h-data
> @@ -53,8 +53,10 @@ macro INADDR_BROADCAST
>
> constant INET_ADDRSTRLEN == 16
>
> +function uint64_t htonll (uint64_t)
> function uint32_t htonl (uint32_t)
> function uint16_t htons (uint16_t)
> +function uint64_t ntohll (uint64_t)
> function uint32_t ntohl (uint32_t)
> function uint16_t ntohs (uint16_t)
Likewise.
> diff --git a/inet/netinet/in.h b/inet/netinet/in.h
> index fa796be406a7120fd6b85d7851b94fe5938bebc0..4fe19b9ee5181a43cb42b86bae603b1f47cb1c3e 100644
> --- a/inet/netinet/in.h
> +++ b/inet/netinet/in.h
> @@ -406,6 +406,13 @@ extern uint32_t htonl (uint32_t __hostlong)
> extern uint16_t htons (uint16_t __hostshort)
> __THROW __attribute__ ((__const__));
>
> +/* Address the following shortcoming by including unsigned long long,
> + which is useful for things such as nanosecond timestamps, etc. */
> +
> +extern uint64_t ntohll (uint64_t __netlonglong) __THROW __attribute__ ((__const__));
> +extern uint64_t htonll (uint64_t __hostlonglong)
> + __THROW __attribute__ ((__const__));
> +
> #include <endian.h>
I think the comment is unnecessary here.
The actual implementation and the manual update look okay.
Thanks,
Florian
On Sun, 9 Mar 2025, Philip Prindeville wrote:
> diff --git a/conform/data/arpa/inet.h-data b/conform/data/arpa/inet.h-data
> index 040b8212c73778d2e1272a2841424fdb098ddde2..c80912ffde59e1d6da1c548f3a0e072f4b4ab5f6 100644
> --- a/conform/data/arpa/inet.h-data
> +++ b/conform/data/arpa/inet.h-data
> @@ -11,8 +11,10 @@ macro INET_ADDRSTRLEN
> macro INET6_ADDRSTRLEN
>
> // The following can be declared as functions, defined as macros or both:
> +function uint64_t htonll (uint64_t)
> function uint32_t htonl (uint32_t)
> function uint16_t htons (uint16_t)
> +function uint64_t ntohll (uint64_t)
> function uint32_t ntohl (uint32_t)
> function uint16_t htons (uint16_t)
>
> diff --git a/conform/data/netinet/in.h-data b/conform/data/netinet/in.h-data
> index ccc74db608727200161d2713a2f7fb171d8b8138..27a8628a99f749e69c0b6456fb875da5cd8da367 100644
> --- a/conform/data/netinet/in.h-data
> +++ b/conform/data/netinet/in.h-data
> @@ -53,8 +53,10 @@ macro INADDR_BROADCAST
>
> constant INET_ADDRSTRLEN == 16
>
> +function uint64_t htonll (uint64_t)
> function uint32_t htonl (uint32_t)
> function uint16_t htons (uint16_t)
> +function uint64_t ntohll (uint64_t)
> function uint32_t ntohl (uint32_t)
> function uint16_t ntohs (uint16_t)
conform/ is only for things that are actually in one of the supported
versions of standards, not for GNU extensions and not possible future
standard features. Adding things to this section of these files is
asserting that those features were in UNIX98, in POSIX.1-2001 with X/Open
extensions, and in POSIX.1-2008 both with and without X/Open extensions.
Unless you've verified the interfaces were in all those standards, they
don't belong in that place in those files.
Similarly, the declarations need to be conditional on __USE_GNU in the
headers unless in all standards that support those headers.
I'd argue that the "network" byte order naming is not particularly
user-friendly (and nor, for that matter, is the "ll"/"l"/"s" naming).
Rather, we already have names such as htobe64 in <endian.h> as extensions
under __USE_MISC and those ought to suffice, without adding less-friendly
names such as these, unless some actual standard has those names.
Note that POSIX.1-2024 added <endian.h> with the functions such as
htobe64, which is further evidence against adding these extensions using
an older naming convention. (glibc hasn't yet been systematically updated
for POSIX.1-2024, nor have conform/ tests had support for that standard
added.)
> +@deftypefun {uint64_t} htonll (uint64_t @var{hostlonglong})
> +@standards{BSD, netinet/in.h}
Saying "BSD" is only appropriate for things that actually came from BSD
(which I think in this context means 4.4 BSD not anything more recent).
Did 4.4 BSD have the functions you are adding?
Hi all,
Joseph Myers <josmyers@redhat.com> writes:
> I'd argue that the "network" byte order naming is not particularly
> user-friendly (and nor, for that matter, is the "ll"/"l"/"s" naming).
> Rather, we already have names such as htobe64 in <endian.h> as extensions
> under __USE_MISC and those ought to suffice, without adding less-friendly
> names such as these, unless some actual standard has those names.
I agree that the endian.h functions are more clear.
>> +@deftypefun {uint64_t} htonll (uint64_t @var{hostlonglong})
>> +@standards{BSD, netinet/in.h}
>
> Saying "BSD" is only appropriate for things that actually came from BSD
> (which I think in this context means 4.4 BSD not anything more recent).
> Did 4.4 BSD have the functions you are adding?
These functions did not exist in 4.4BSD-Lite 2. However, these functions
do exist in some places. In Gnulib maintainer tools [1]:
./show-portability ntohll
ntohll
libc aix-5.1.0
libc aix-5.2.0
libc aix-5.3.0a
libc aix-6.1.0
libc aix-7.1.0
libc aix-7.2.0
libc aix-7.3.1
libc solaris-2.11-openindiana-20171031
libc solaris-2.11.0
libc solaris-2.11.3
libc solaris-2.11.4
libc solaris-2.11_2010_11
It also exists on Windows [2].
[1] https://git.savannah.gnu.org/cgit/gnulib/maint-tools.git
[2] https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-ntohll
@@ -11,8 +11,10 @@ macro INET_ADDRSTRLEN
macro INET6_ADDRSTRLEN
// The following can be declared as functions, defined as macros or both:
+function uint64_t htonll (uint64_t)
function uint32_t htonl (uint32_t)
function uint16_t htons (uint16_t)
+function uint64_t ntohll (uint64_t)
function uint32_t ntohl (uint32_t)
function uint16_t htons (uint16_t)
@@ -53,8 +53,10 @@ macro INADDR_BROADCAST
constant INET_ADDRSTRLEN == 16
+function uint64_t htonll (uint64_t)
function uint32_t htonl (uint32_t)
function uint16_t htons (uint16_t)
+function uint64_t ntohll (uint64_t)
function uint32_t ntohl (uint32_t)
function uint16_t ntohs (uint16_t)
@@ -51,6 +51,7 @@ routines := \
herrno \
herrno-loc \
htonl \
+ htonll \
htons \
idna \
idna_name_classify \
new file mode 100644
@@ -0,0 +1,35 @@
+/* Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdint.h>
+#include <netinet/in.h>
+
+#undef htonll
+#undef ntohll
+
+uint64_t
+htonll (uint64_t x)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+ return x;
+#elif BYTE_ORDER == LITTLE_ENDIAN
+ return __bswap_64 (x);
+#else
+# error "What kind of system is this?"
+#endif
+}
+weak_alias (htonll, ntohll)
@@ -37,6 +37,7 @@
# error "Bah, what kind of system do you use?"
#endif
+uint64_t lots = 0xefcdab8967452301;
uint32_t lo = 0x67452301;
uint16_t foo = 0x1234;
@@ -45,6 +46,16 @@ main (void)
{
int result = 0;
+ TEST (0xefcdab8967452301, 0x0123456789abcdef, htonll);
+ TEST (0xefcdab8967452301, 0x0123456789abcdef, (htonll));
+ TEST (0xefcdab8967452301, 0x0123456789abcdef, ntohll);
+ TEST (0xefcdab8967452301, 0x0123456789abcdef, (ntohll));
+
+ TEST (lots, 0x0123456789abcdef, htonl);
+ TEST (lots, 0x0123456789abcdef, (htonl));
+ TEST (lots, 0x0123456789abcdef, ntohl);
+ TEST (lots, 0x0123456789abcdef, (ntohl));
+
TEST (0x67452301, 0x01234567, htonl);
TEST (0x67452301, 0x01234567, (htonl));
TEST (0x67452301, 0x01234567, ntohl);
@@ -406,6 +406,13 @@ extern uint32_t htonl (uint32_t __hostlong)
extern uint16_t htons (uint16_t __hostshort)
__THROW __attribute__ ((__const__));
+/* Address the following shortcoming by including unsigned long long,
+ which is useful for things such as nanosecond timestamps, etc. */
+
+extern uint64_t ntohll (uint64_t __netlonglong) __THROW __attribute__ ((__const__));
+extern uint64_t htonll (uint64_t __hostlonglong)
+ __THROW __attribute__ ((__const__));
+
#include <endian.h>
/* Get machine dependent optimized versions of byte swapping functions. */
@@ -419,14 +426,18 @@ extern uint16_t htons (uint16_t __hostshort)
# if __BYTE_ORDER == __BIG_ENDIAN
/* The host byte order is the same as network byte order,
so these functions are all just identity. */
+# define ntohll(x) __uint64_identity (x)
# define ntohl(x) __uint32_identity (x)
# define ntohs(x) __uint16_identity (x)
+# define htonll(x) __uint64_identity (x)
# define htonl(x) __uint32_identity (x)
# define htons(x) __uint16_identity (x)
# else
# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define ntohll(x) __bswap_64 (x)
# define ntohl(x) __bswap_32 (x)
# define ntohs(x) __bswap_16 (x)
+# define htonll(x) __bswap_64 (x)
# define htonl(x) __bswap_32 (x)
# define htons(x) __bswap_16 (x)
# endif
@@ -22,6 +22,7 @@
int i;
uint16_t u16;
uint32_t u32;
+uint64_t u64;
int
do_test (void)
@@ -31,8 +32,11 @@ do_test (void)
extern __typeof (ntohs (i)) u16;
extern __typeof (htonl (i)) u32;
extern __typeof (ntohl (i)) u32;
+ extern __typeof (htonll (i)) u64;
+ extern __typeof (ntohll (i)) u64;
(void) u16;
(void) u32;
+ (void) u64;
return 0;
}
@@ -1957,6 +1957,14 @@ host byte order to network byte order.
This is used for IPv4 Internet addresses.
@end deftypefun
+@deftypefun {uint64_t} htonll (uint64_t @var{hostlonglong})
+@standards{BSD, netinet/in.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c htonll ok
+@c bswap_64 dup ok
+This function converts the @code{uint64_t} integer @var{hostlonglong} from
+host byte order to network byte order.
+
@deftypefun {uint32_t} ntohl (uint32_t @var{netlong})
@standards{BSD, netinet/in.h}
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@@ -1967,6 +1975,13 @@ network byte order to host byte order.
This is used for IPv4 Internet addresses.
@end deftypefun
+@deftypefun {uint64_t} ntohll (uint64_t @var{netlonglong})
+@standards{BSD, netinet/in.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Alias to htonll.
+This function converts the @code{uint64_t} integer @var{netlonglong} from
+network byte order to host byte order.
+
@node Protocols Database
@subsection Protocols Database
@cindex protocols database
@@ -2876,3 +2876,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2873,3 +2873,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2271,3 +2271,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2855,3 +2855,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -3022,3 +3022,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2836,3 +2836,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2833,3 +2833,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2514,3 +2514,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.40 __riscv_hwprobe F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2714,3 +2714,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.40 __riscv_hwprobe F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -3244,3 +3244,5 @@ GLIBC_2.9 pututline F
GLIBC_2.9 pututxline F
GLIBC_2.9 updwtmp F
GLIBC_2.9 updwtmpx F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -3021,3 +3021,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2902,3 +2902,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2899,3 +2899,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -3249,3 +3249,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2867,3 +2867,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2818,3 +2818,5 @@ GLIBC_2.9 ns_name_skip F
GLIBC_2.9 ns_name_uncompress F
GLIBC_2.9 ns_name_unpack F
GLIBC_2.9 pipe2 F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F
@@ -2765,3 +2765,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 htonll F
+GLIBC_2.42 ntohll F