server: bind both wildcard for UDP
When possible, bind both ipv4 and ipv6 wildcard addresses for UDP. Even when only binding ipv6 address for TCP (Linux)
This commit is contained in:
+1
-26
@@ -483,9 +483,6 @@ void Config::updateDefs(defs_t& defs) const
|
||||
|
||||
void Config::expand()
|
||||
{
|
||||
if(tcp_port==0)
|
||||
tcp_port = 5075;
|
||||
|
||||
auto ifaces(parseAddresses(interfaces));
|
||||
auto bdest(parseAddresses(beaconDestinations));
|
||||
|
||||
@@ -500,29 +497,7 @@ void Config::expand()
|
||||
for(size_t i=0; i<ifaces.size(); i++) {
|
||||
auto& ep = ifaces[i];
|
||||
|
||||
if(evsocket::canIPv6 && ep.addr.isAny()) {
|
||||
// special handling for IP4/6 wildcard addresses
|
||||
|
||||
if(evsocket::ipstack==evsocket::Linsock && ep.addr.family()==AF_INET) {
|
||||
// Linux IP stack disallows binding both 0.0.0.0 and [::] for the same port.
|
||||
// so promote to IPv6 when possible
|
||||
ep.addr = SockAddr::any(AF_INET6, ep.addr.port());
|
||||
log_debug_printf(serversetup, "Promote 0.0.0.0 -> [::]%s", "\n");
|
||||
|
||||
} else if(evsocket::ipstack!=evsocket::Linsock) {
|
||||
/* Other IP stacks allow binding different sockets.
|
||||
* OSX has the added oddity of ordering dependence.
|
||||
* 0.0.0.0 and then :: is allowed, but not the reverse.
|
||||
*
|
||||
* So when possible, we always bind both in the allowed order.
|
||||
*/
|
||||
ep.addr = SockAddr::any(AF_INET, ep.addr.port());
|
||||
ifaces.emplace(ifaces.begin()+i+1u,
|
||||
SockAddr::any(AF_INET6, ep.addr.port()));
|
||||
i++; // continue after newly inserted EP
|
||||
}
|
||||
|
||||
} else if(!ep.addr.isMCast()) {
|
||||
if(!ep.addr.isMCast()) {
|
||||
// no-op
|
||||
|
||||
} else if(!ep.iface.empty()) {
|
||||
|
||||
+42
-1
@@ -396,12 +396,19 @@ Server::Pvt::Pvt(const Config &conf)
|
||||
|
||||
const auto cb(std::bind(&Pvt::onSearch, this, std::placeholders::_1));
|
||||
|
||||
bool bindAny = false;
|
||||
std::vector<SockAddr> tcpifaces; // may have port zero
|
||||
for(const auto& iface : effective.interfaces) {
|
||||
SockEndpoint addr(iface.c_str());
|
||||
if(!addr.addr.isMCast())
|
||||
|
||||
if(addr.addr.isAny()) {
|
||||
bindAny = true;
|
||||
|
||||
} else if(!addr.addr.isMCast()) {
|
||||
tcpifaces.push_back(addr.addr);
|
||||
|
||||
}
|
||||
|
||||
addr.addr.setPort(effective.udp_port);
|
||||
|
||||
listeners.push_back(manager.onSearch(addr, cb));
|
||||
@@ -409,12 +416,24 @@ Server::Pvt::Pvt(const Config &conf)
|
||||
// update to allow udp_port==0
|
||||
effective.udp_port = addr.addr.port();
|
||||
|
||||
|
||||
if(addr.addr.isAny()) {
|
||||
continue; // special case handling below
|
||||
}
|
||||
|
||||
if(addr.addr.family()==AF_INET && addr.addr.isAny()) {
|
||||
// if listening on 0.0.0.0, also listen on [::]
|
||||
auto any6(addr);
|
||||
any6.addr = SockAddr::any(AF_INET6);
|
||||
|
||||
listeners.push_back(manager.onSearch(any6, cb));
|
||||
|
||||
} else if(addr.addr.family()==AF_INET6 && addr.addr.isAny()) {
|
||||
// if listening on [::], also listen on 0.0.0.0
|
||||
auto any4(addr);
|
||||
any4.addr = SockAddr::any(AF_INET);
|
||||
|
||||
listeners.push_back(manager.onSearch(any4, cb));
|
||||
}
|
||||
|
||||
if(evsocket::ipstack!=evsocket::Winsock
|
||||
@@ -432,6 +451,28 @@ Server::Pvt::Pvt(const Config &conf)
|
||||
}
|
||||
}
|
||||
|
||||
if(bindAny) {
|
||||
if(evsocket::canIPv6) {
|
||||
if(evsocket::ipstack==evsocket::Linsock) {
|
||||
/* Linux IP stack disallows binding both 0.0.0.0 and [::] for the same port.
|
||||
* so we must always bind [::]
|
||||
*/
|
||||
tcpifaces.emplace_back(AF_INET6);
|
||||
} else {
|
||||
/* Other IP stacks allow binding different sockets.
|
||||
* OSX has the added oddity of ordering dependence.
|
||||
* 0.0.0.0 and then :: is allowed, but not the reverse.
|
||||
*
|
||||
* Always bind both in the OSX allowed order.
|
||||
*/
|
||||
tcpifaces.emplace_back(AF_INET);
|
||||
tcpifaces.emplace_back(AF_INET6);
|
||||
}
|
||||
} else {
|
||||
tcpifaces.emplace_back(AF_INET);
|
||||
}
|
||||
}
|
||||
|
||||
if(tcpifaces.empty()) {
|
||||
log_err_printf(serversetup, "Server Unreachable. Interface address list includes not TCP interfaces.%s", "\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user