Re: [dev] Suckless DNS server

From: NRK <nrk_AT_disroot.org>
Date: Thu, 20 Jul 2023 04:57:52 +0600

On Wed, Jul 19, 2023 at 03:20:21PM -0700, Jeremy wrote:
> crypto_uint16 uint16_unpack_big(const unsigned char *x)
> crypto_uint16 y;
>
> y = x[0]; y <<= 8;
> y |= x[1];
>
> return y;
> }
>
> As you're probably already aware, if there were 3 answers, and you
> were running this on a Big Endian machine, the program would attempt to
> iterate over 768 answers.

I fail to see how that'd happen. The above routine takes a 16bit big
endian encoded byte stream and places the bytes into the right place
*regardless* of what the host system's byte order is.

C standard defines shift operator as multiplication and division by
powers of 2. And the result of `x * 256` never depend on the system's
byte order and so neither does `x << 8`.

Rob Pike already has an excellent article on this, so I'll just refer to
that: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html

(Though keep in mind that the shift of 24 needs to be casted to
unsigned - i.e `(unsigned)data[3]<<24` - to avoid UB due to the result being
bigger than `INT_MAX`).

> Instead, one can use htons(byteorder.3).

If anything, those functions are precisely the source of confusion like
these and should be avoided for this reason.

As already explained in Rob's article above, the host system's byte
order is almost never relevant, what matters is what byte order is the
data stream encoded in. As long as you know that, you can simply shift
the bytes into proper place *never* needing to ask or know about the
host system's byte order.

- NRK
Received on Thu Jul 20 2023 - 00:57:52 CEST

This archive was generated by hypermail 2.3.0 : Thu Jul 20 2023 - 01:00:09 CEST