msg/msg_types: fix the dencoder of entity_addr_t

improve the interoperability between freebsd/osx and GNU/Linux, because
the their layouts of sockaddr_storage are different, and we use the
one of linux as the wire format. so need to convert it on freebsd/osx
side.

Signed-off-by: Kefu Chai <kchai@redhat.com>
This commit is contained in:
Kefu Chai 2017-09-13 17:21:38 +08:00
parent cea9f1e3da
commit 9099ca599d

View File

@ -444,7 +444,14 @@ struct entity_addr_t {
__u32 elen = get_sockaddr_len();
::encode(elen, bl);
if (elen) {
#if (__FreeBSD__) || defined(__APPLE__)
__le16 ss_family = u.sa.sa_family;
::encode(ss_family, bl);
bl.append(u.sa.sa_data,
elen - sizeof(u.sa.sa_len) - sizeof(u.sa.sa_family));
#else
bl.append((char*)get_sockaddr(), elen);
#endif
}
ENCODE_FINISH(bl);
}
@ -463,6 +470,20 @@ struct entity_addr_t {
__u32 elen;
::decode(elen, bl);
if (elen) {
#if defined(__FreeBSD__) || defined(__APPLE__)
u.sa.sa_len = 0;
__le16 ss_family;
if (elen < sizeof(ss_family)) {
throw buffer::malformed_input("elen smaller than family len");
}
::decode(ss_family, bl);
u.sa.sa_family = ss_family;
elen -= sizeof(ss_family);
if (elen > get_sockaddr_len() - sizeof(u.sa.sa_family)) {
throw buffer::malformed_input("elen exceeds sockaddr len");
}
bl.copy(elen, u.sa.sa_data);
#else
if (elen < sizeof(u.sa.sa_family)) {
throw buffer::malformed_input("elen smaller than family len");
}
@ -472,6 +493,7 @@ struct entity_addr_t {
}
elen -= sizeof(u.sa.sa_family);
bl.copy(elen, u.sa.sa_data);
#endif
}
DECODE_FINISH(bl);
}