3232
3333namespace tcp_in {
3434
35+ /* * Constexpr implementation of std::max for 3 size_t values. */
36+ constexpr size_t max (size_t a, size_t b, size_t c) {
37+ return a > b ? (a > c ? a : c) : (b > c ? b : c);
38+ }
39+
3540Acceptor::Acceptor (ClientManager &clients, ipx_ctx_t *ctx) :
3641 m_epoll (),
3742 m_sockets (),
@@ -74,9 +79,11 @@ void Acceptor::add_address(IpAddress &adr, uint16_t port, bool ipv6_only) {
7479}
7580
7681UniqueFd Acceptor::bind_address (IpAddress &addr, uint16_t port, bool ipv6_only) {
77- sockaddr saddr{};
78- auto v4 = reinterpret_cast <sockaddr_in *>(&saddr);
79- auto v6 = reinterpret_cast <sockaddr_in6 *>(&saddr);
82+ // Allocate enough data to fit any of the structures.
83+ std::array<char , max (sizeof (sockaddr), sizeof (sockaddr_in), sizeof (sockaddr_in6))> addr_data;
84+ auto saddr = reinterpret_cast <sockaddr *>(addr_data.data ());
85+ auto v4 = reinterpret_cast <sockaddr_in *>(saddr);
86+ auto v6 = reinterpret_cast <sockaddr_in6 *>(saddr);
8087 size_t addr_len;
8188
8289 if (addr.version == IpVersion::IP4) {
@@ -94,7 +101,7 @@ UniqueFd Acceptor::bind_address(IpAddress &addr, uint16_t port, bool ipv6_only)
94101
95102 const char *err_str;
96103
97- UniqueFd sd (socket (saddr. sa_family , SOCK_STREAM, 0 ));
104+ UniqueFd sd (socket (saddr-> sa_family , SOCK_STREAM, 0 ));
98105 if (!sd) {
99106 ipx_strerror (errno, err_str);
100107 throw std::runtime_error (" Failed to create socket: " + std::string (err_str));
@@ -128,7 +135,7 @@ UniqueFd Acceptor::bind_address(IpAddress &addr, uint16_t port, bool ipv6_only)
128135 std::array<char , INET6_ADDRSTRLEN> addr_str{};
129136 inet_ntop (static_cast <int >(addr.version ), &addr.v6 , addr_str.begin (), INET6_ADDRSTRLEN);
130137
131- if (bind (sd.get (), & saddr, addr_len) == -1 ) {
138+ if (bind (sd.get (), saddr, addr_len) == -1 ) {
132139 ipx_strerror (errno, err_str);
133140 throw std::runtime_error (
134141 " Failed to bind to socket (local IP: "
0 commit comments