diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2016-01-09 14:06:09 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2016-01-09 14:06:09 +0900 |
| commit | d2d06395d985c08aacf497a6ecc37d757ef990e0 (patch) | |
| tree | 17c545c8468802ab2cc5524216fa4fe1154c5786 /src/SocketCore.cc | |
| parent | e92027b9f04f02d9887015fbec691446ae82e8ab (diff) | |
Try all found address set to bind sockets with --multiple-interface
Fixes GH-523
Diffstat (limited to 'src/SocketCore.cc')
| -rw-r--r-- | src/SocketCore.cc | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/src/SocketCore.cc b/src/SocketCore.cc index 8bfedbeb..ae156d28 100644 --- a/src/SocketCore.cc +++ b/src/SocketCore.cc @@ -306,7 +306,7 @@ void SocketCore::bind(const char* addr, uint16_t port, int family, int flags) else { addrp = nullptr; } - if (!(flags & AI_PASSIVE) || bindAddrs_.empty()) { + if (addrp || !(flags & AI_PASSIVE) || bindAddrsList_.empty()) { sock_t fd = bindTo(addrp, port, family, sockType_, flags, error); if (fd == (sock_t)-1) { throw DL_ABORT_EX(fmt(EX_SOCKET_BIND, error.c_str())); @@ -315,25 +315,30 @@ void SocketCore::bind(const char* addr, uint16_t port, int family, int flags) return; } - for (const auto& a : bindAddrs_) { - char host[NI_MAXHOST]; - int s; - s = getnameinfo(&a.first.sa, a.second, host, NI_MAXHOST, nullptr, 0, - NI_NUMERICHOST); - if (s) { - error = gai_strerror(s); - continue; - } - if (addrp && strcmp(host, addrp) != 0) { - error = "Given address and resolved address do not match."; - continue; - } - sock_t fd = bindTo(host, port, family, sockType_, flags, error); - if (fd != (sock_t)-1) { - sockfd_ = fd; - break; + std::array<char, NI_MAXHOST> host; + for (const auto& bindAddrs : bindAddrsList_) { + for (const auto& a : bindAddrs) { + if (family != AF_UNSPEC && family != a.first.storage.ss_family) { + continue; + } + auto s = getnameinfo(&a.first.sa, a.second, host.data(), NI_MAXHOST, + nullptr, 0, NI_NUMERICHOST); + if (s) { + error = gai_strerror(s); + continue; + } + if (addrp && strcmp(host.data(), addrp) != 0) { + error = "Given address and resolved address do not match."; + continue; + } + auto fd = bindTo(host.data(), port, family, sockType_, flags, error); + if (fd != (sock_t)-1) { + sockfd_ = fd; + return; + } } } + if (sockfd_ == (sock_t)-1) { throw DL_ABORT_EX(fmt(EX_SOCKET_BIND, error.c_str())); } @@ -1287,6 +1292,8 @@ void SocketCore::bindAddress(const std::string& iface) A2_LOG_DEBUG(fmt("Sockets will bind to %s", host)); } } + bindAddrsList_.push_back(bindAddrs_); + bindAddrsListIt_ = std::begin(bindAddrsList_); } void SocketCore::bindAllAddress(const std::string& ifaces) |
