When decoding an entity_addrvec_t with marker 1, we just have
a single (non-legacy) entity_addr_t. This should be decoded
exactly the same as done by entity_addr_t::decode, but it
currently is not. Specifically, the sa_family member of
the sockaddr is not converted from the on-wire little-endian
format to host byte order (as done by entity_addr_t::decode).
Fixed by using the same code as in entity_addr_t::decode.
Signed-off-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
(cherry picked from commit
31da17378b712542e915adbf4084e0212b8bb615)
__u32 elen;
decode(elen, bl);
if (elen) {
- bl.copy(elen, (char*)addr.get_sockaddr());
+ struct sockaddr *sa = (struct sockaddr *)addr.get_sockaddr();
+#if defined(__FreeBSD__) || defined(__APPLE__)
+ sa->sa_len = 0;
+#endif
+ uint16_t ss_family;
+ if (elen < sizeof(ss_family)) {
+ throw ceph::buffer::malformed_input("elen smaller than family len");
+ }
+ decode(ss_family, bl);
+ sa->sa_family = ss_family;
+ elen -= sizeof(ss_family);
+ if (elen > addr.get_sockaddr_len() - sizeof(sa->sa_family)) {
+ throw ceph::buffer::malformed_input("elen exceeds sockaddr len");
+ }
+ bl.copy(elen, sa->sa_data);
}
DECODE_FINISH(bl);
v.clear();