Reputation: 252
I have a Client/Server application written in C++. The client sends a structure (proxy_header) containing three int 32. This triggers the server to send information back. Problem is that the server doesn't reply if the client runs on OS X (El Capitan). Tcpdump reveals different values of the structure sent.
The C++ code is as follows:
Initialising the message to the server:
struct { int m:32; int x:32; int y:32; } proxy_header;
proxy_header.m = 0x02212102;
proxy_header.x = 1;
proxy_header.y = 1;
... Sending:
{ int r;
if ((r = send(t->fd, (void*)&proxy_header, sizeof(proxy_header), 0)) != sizeof(proxy_header)) {
error("Failed to send proxy header (%d != %d)", r, sizeof(proxy_header));
goto error;
}
... Waiting for answer - recv():
if ((r = recv(t->fd, (void*)&(proxy_answer), sizeof(proxy_answer), MSG_WAITALL)) != sizeof(proxy_answer)) {
printf("Failed to receive ...")
}
else {
printf("Successfully received...");
}
The program compiles and works well on Linux. On MacOS I get "Failed to receive...".
tcpdumping the packages, I discovered the following:
On Ubuntu, I can see a SYN/ACK, then PSH from Client to Server which responds ACK, then PSH from Server to client which responds ACK.
The first push (from client) contains this:
char peer0_0[] = { /* Packet 4 */
0x02, 0x21, 0x21, 0x02, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00 };
On MacOS, the same happens up to the first PSH from the client which is ACK by the server. The server then just sends a FIN.
This is what the push contains:
char peer0_0[] = {
0x02, 0x21, 0x21, 0x02, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01 };
Apparently it is different... Why?
Upvotes: 1
Views: 407
Reputation: 4501
It looks like a problem of endianness (reversed data bytes).
Considering what you get when sending from the MAC OS client, data format seams to be "big-endian", while the server likely uses "little-endian" format. (Is the computer running MAC OS a PowerPC ?)
https://en.wikipedia.org/wiki/Endianness
One way to fix this is to use, on both sides (client & server), data buffers independant of the platform endianness. You may use, for example, boost endian_buffers:
http://www.boost.org/doc/libs/1_58_0/libs/endian/doc/buffers.html
Your data structure may look like this:
struct {
little_int32_buf_t m;
little_int32_buf_t x;
little_int32_buf_t y;
} proxy_header;
Upvotes: 2