-
Notifications
You must be signed in to change notification settings - Fork 4
Protobuf → IPC debugging
When including strings in protobufs sent over IPC messages (sending from client to server), I began to encounter a strange bug in which I would receive the message successfully, but attempting to unpack the protobuf object from the message body would yield NULL. After some experimentation I realized that the issue seems to only manifest itself when there are strings of specific lengths in the message.
These examples involve sending the RegisterClientMessage over a pipe managed by NNG. Note the string length, the message length (as given by nng_msg_len
), and the return value of the protobuf unpack.
string (length) | message size | effect |
---|---|---|
/tmp/te (7) |
22 | null |
/tmp/tes (8) |
24 | success |
/tmp/test (9) |
26 | null |
/tmp/testx (10) |
28 | success |
An apparent behavior of the protobuf is that adding a byte to the string increases the size of the message by two bytes. This is probably normal behavior from the library, though.
There is pretty obvious pattern in that table: if the size of the message divided by two is odd, the unpacking fails. This explains why the bug only manifests with strings -- the only other data type we have been using is int32
and oneof
(which is just a union with an int32
designating the member). Those data types add 4 bytes to the message, so the length/2 was always even.
When I have time I will try to make a minimal example of this to show to protobuf-c or NNG devs. For the time being, though, an easy fix is as follows. This is the fix as performed in the sunneed server; for the client-side, SunneedRequest
would be replaced by SunneedResponse
.
nng_msg *msg;
// ...receive message over IPC
size_t msg_len = nng_msg_len(msg);
if ((msg_len / 2) % 2 == 1)
msg_len++;
SunneedRequest *request = sunneed_request__unpack(NULL, msg_len, nng_msg_body(msg));
There's definitely more to this issue (why does adding specifically 1 solve it) but I've tested this a bunch and never got NULL.