summaryrefslogtreecommitdiff
path: root/src/SocketCore.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2016-01-09 14:06:09 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2016-01-09 14:06:09 +0900
commitd2d06395d985c08aacf497a6ecc37d757ef990e0 (patch)
tree17c545c8468802ab2cc5524216fa4fe1154c5786 /src/SocketCore.cc
parente92027b9f04f02d9887015fbec691446ae82e8ab (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.cc43
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)