Skip to content

Commit 862ddb1

Browse files
committed
fix(connchan): improved portability of byte-order helpers
- Refactor be*toh/htobe* handling in connchan.c for Linux, *BSD, macOS, Windows, and other compilers. - On Darwin, include <libkern/OSByteOrder.h> and map htobe*/be*toh to OSSwapHostToBigInt*/OSSwapBigToHostInt* when not already defined. - On Windows, define be16toh/htobe16 and be32toh/htobe32 via ntohs/htons and ntohl/htonl, and implement htobe64/be64toh using a portable 64-bit swap built from 32-bit htonl/ntohl. - Add a final fallback that derives htobe64/be64toh (and related helpers) from **BYTE_ORDER** and __builtin_bswap64 when available. The change fixes build/link issues on macOS and other non-Linux platforms where xhtonll/ntohll or be*toh macros are missing, ensuring connchan (e.g., WebSocket masking) compiles and runs consistently across supported OSes.
1 parent 3798d11 commit 862ddb1

File tree

1 file changed

+42
-18
lines changed

1 file changed

+42
-18
lines changed

nsd/connchan.c

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,56 @@
2323
*/
2424
#if defined(__linux__)
2525
# include <endian.h>
26+
2627
#elif defined(__FreeBSD__) || defined(__NetBSD__)
27-
# include <sys/endian.h>
28+
# include <sys/endian.h>
29+
2830
#elif defined(__OpenBSD__)
2931
# include <sys/types.h>
3032
# ifndef be16toh
3133
# define be16toh(x) betoh16(x)
3234
# define be32toh(x) betoh32(x)
3335
# define be64toh(x) betoh64(x)
3436
# endif
35-
#elif defined(__APPLE__) || defined(_WIN32)
36-
# define be16toh(x) ntohs(x)
37-
# define htobe16(x) htons(x)
38-
# define be32toh(x) ntonl(x)
39-
# define htobe32(x) htonl(x)
40-
# if defined(_WIN32)
41-
/*
42-
* Not sure, why htonll() and ntohll() are undefined in Visual Studio 2019:
43-
*
44-
*# define be64toh(x) ntohll(x)
45-
*# define htobe64(x) htonll(x)
46-
*/
47-
# define htobe64(x) ((1==htonl(1)) ? (x) : (((uint64_t)htonl((x) & 0xFFFFFFFFUL)) << 32) | htonl((uint32_t)((x) >> 32)))
48-
# define be64toh(x) ((1==ntohl(1)) ? (x) : (((uint64_t)ntohl((x) & 0xFFFFFFFFUL)) << 32) | ntohl((uint32_t)((x) >> 32)))
49-
# else
50-
# define be64toh(x) ntohll(x)
51-
# define htobe64(x) htonll(x)
37+
38+
#elif defined(__APPLE__)
39+
/* Darwin does NOT have a native htonll/ntohll. Use OSByteOrder helpers. */
40+
# include <libkern/OSByteOrder.h>
41+
# ifndef htobe16
42+
# define htobe16(x) OSSwapHostToBigInt16((uint16_t)(x))
43+
# define be16toh(x) OSSwapBigToHostInt16((uint16_t)(x))
44+
# define htobe32(x) OSSwapHostToBigInt32((uint32_t)(x))
45+
# define be32toh(x) OSSwapBigToHostInt32((uint32_t)(x))
46+
# define htobe64(x) OSSwapHostToBigInt64((uint64_t)(x))
47+
# define be64toh(x) OSSwapBigToHostInt64((uint64_t)(x))
48+
# endif
49+
50+
#elif defined(_WIN32)
51+
/* Windows lacks be*toh; build from htonl/ntohl or use byte-swap intrinsics. */
52+
# define be16toh(x) ntohs((uint16_t)(x))
53+
# define htobe16(x) htons((uint16_t)(x))
54+
# define be32toh(x) ntohl((uint32_t)(x))
55+
# define htobe32(x) htonl((uint32_t)(x))
56+
/* Portable 64-bit swap using two 32-bit ops */
57+
# define htobe64(x) ((1==htonl(1)) ? (uint64_t)(x) : (((uint64_t)htonl((uint32_t)((x) & 0xFFFFFFFFu))) << 32) | htonl((uint32_t)((x) >> 32)))
58+
# define be64toh(x) ((1==ntohl(1)) ? (uint64_t)(x) : (((uint64_t)ntohl((uint32_t)((x) & 0xFFFFFFFFu))) << 32) | ntohl((uint32_t)((x) >> 32)))
59+
#endif
60+
61+
/* As a final fallback attempt, derive from compiler endianness macros */
62+
#ifndef htobe64
63+
# if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__)
64+
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
65+
# define __ns_bswap64(v) __builtin_bswap64((uint64_t)(v))
66+
# define htobe64(x) __ns_bswap64(x)
67+
# define be64toh(x) __ns_bswap64(x)
68+
# define htobe32(x) htonl((uint32_t)(x))
69+
# define be32toh(x) ntohl((uint32_t)(x))
70+
# define htobe16(x) htons((uint16_t)(x))
71+
# define be16toh(x) ntohs((uint16_t)(x))
72+
# else
73+
# define htobe64(x) (uint64_t)(x)
74+
# define be64toh(x) (uint64_t)(x)
75+
# endif
5276
# endif
5377
#endif
5478

0 commit comments

Comments
 (0)