| 166 | * encode sockaddr.ss_family as network byte order |
| 167 | */ |
| 168 | static inline void encode(const sockaddr_storage& a, ceph::buffer::list& bl) { |
| 169 | #if defined(__linux__) |
| 170 | struct sockaddr_storage ss = a; |
| 171 | ss.ss_family = htons(ss.ss_family); |
| 172 | ceph::encode_raw(ss, bl); |
| 173 | #elif defined(__FreeBSD__) || defined(__APPLE__) |
| 174 | ceph_sockaddr_storage ss{}; |
| 175 | auto src = (unsigned char const *)&a; |
| 176 | auto dst = (unsigned char *)&ss; |
| 177 | src += sizeof(a.ss_len); |
| 178 | ss.ss_family = a.ss_family; |
| 179 | src += sizeof(a.ss_family); |
| 180 | dst += sizeof(ss.ss_family); |
| 181 | const auto copy_size = std::min((unsigned char*)(&a + 1) - src, |
| 182 | (unsigned char*)(&ss + 1) - dst); |
| 183 | ::memcpy(dst, src, copy_size); |
| 184 | encode(ss, bl); |
| 185 | #elif defined(_WIN32) |
| 186 | ceph_sockaddr_storage ss{}; |
| 187 | ::memcpy(&ss, &a, std::min(sizeof(ss), sizeof(a))); |
| 188 | // The Windows AF_INET6 definition doesn't match the Linux one. |
| 189 | if (a.ss_family == AF_INET6) { |
| 190 | ss.ss_family = AF_INET6_LINUX; |
| 191 | } |
| 192 | encode(ss, bl); |
| 193 | #else |
| 194 | ceph_sockaddr_storage ss; |
| 195 | ::memset(&ss, '\0', sizeof(ss)); |
| 196 | ::memcpy(&ss, &a, std::min(sizeof(ss), sizeof(a))); |
| 197 | encode(ss, bl); |
| 198 | #endif |
| 199 | } |
| 200 | static inline void decode(sockaddr_storage& a, |
| 201 | ceph::buffer::list::const_iterator& bl) { |
| 202 | #if defined(__linux__) |
no test coverage detected