3

I am using existing code, that passes data - union ibv_gid through TCP connection without converting the endianness. There is a comment inside: "The gid will be transfer byte by byte so no need to do "hton". The code is correct and works, but I don't understand why the data is passed byte by byte (actually they pass the entire struct) and why there is no need in endianess convertion. The data type they pass is:

union ibv_gid {
        uint8_t                 raw[16];
        struct {
                uint64_t        subnet_prefix;
                uint64_t        interface_id;
        } global;
};

** For other data types (as int etc.) they do convert the data before and after

//VL_sock_sync_data function synchronizes between the two sides 
//by exchanging data between the two sides.
//size bytes are being copied from out_buf to the other side, and being saved in in_buf.
rc = VL_sock_sync_data(sock_p, sizeof(union ibv_gid), &local_gid, &tmp_gid);

Can you please explain why there is no need in endianness conversion? Thank you for any help

Halona
  • 1,475
  • 1
  • 15
  • 26
  • If both peer hosts have the same endian-ness, structure member alignment rules, inter-member padding! member sizes, and overall structure sizes, a bitwise copy is sufficient. As many of these parameters are dependent on the compiler, compiler version, compiler flags used, and surrounding #pragmas, you can see it is very risky indeed to use structs as network protocols. – user207421 Jun 02 '14 at 13:08

1 Answers1

4

The reasoning here seems to be that there's no need to do endianness conversion here because the GID (in its canonical representation) is not two 64-bit integers. It is 16 bytes.

The complication is that two systems with different endianness will see different values in the subnet_prefix and interface_id fields. So if they were to write those values to strings, send the strings back and forth, and compare them, that would be a problem. If they were to compare GIDs based on which one had a greater subnet_prefix, and expected the comparison to be the same between systems, that would be a problem. If one generated only consecutive interface_ids, and the other expected them to be consecutive, that would be a problem. But as long as they're only being used as opaque arrays of bytes, there's no problem.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • My thoughts exactly, and it seems really questionable to add these `int` types to the `union` at all, seeing as their interpretation can vary depending on endianess. – Felix Frank Jun 02 '14 at 13:17
  • @FelixFrank agreed. I suspect it was simply to break the GID into two fields, and allow for function-less equality comparison within each field, but it's a bad tradeoff. – Sneftel Jun 02 '14 at 13:26