Merge pull request #27270 from theanalyst/beast-fe-ipv6

rgw: normalize v6 endpoint behaviour for the beast frontend

Reviewed-by: Matt Benjamin <mbenjamin@redhat.com>
Reviewed-by: Casey Bodley <cbodley@redhat.com>
This commit is contained in:
Casey Bodley 2019-05-13 10:02:21 -04:00 committed by GitHub
commit 782be351c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 8 deletions

View File

@ -23,21 +23,21 @@ Options
``port`` and ``ssl_port``
:Description: Sets the listening port number. Can be specified multiple
:Description: Sets the ipv4 & ipv6 listening port number. Can be specified multiple
times as in ``port=80 port=8000``.
:Type: Integer
:Default: ``80``
``endpoint`` and ``ssl_endpoint``
:Description: Sets the listening address in the form ``address[:port]``,
where the address is an IPv4 address string in dotted decimal
form, or an IPv6 address in hexadecimal notation surrounded
by square brackets. The optional port defaults to 80 for
``endpoint`` and 443 for ``ssl_endpoint``. Can be specified
multiple times as in ``endpoint=[::1] endpoint=192.168.0.100:8000``.
:Description: Sets the listening address in the form ``address[:port]``, where
the address is an IPv4 address string in dotted decimal form, or
an IPv6 address in hexadecimal notation surrounded by square
brackets. Specifying a IPv6 endpoint would listen to v6 only. The
optional port defaults to 80 for ``endpoint`` and 443 for
``ssl_endpoint``. Can be specified multiple times as in
``endpoint=[::1] endpoint=192.168.0.100:8000``.
:Type: Integer
:Default: None

View File

@ -401,6 +401,9 @@ int AsioFrontend::init()
}
listeners.emplace_back(context);
listeners.back().endpoint.port(port);
listeners.emplace_back(context);
listeners.back().endpoint = tcp::endpoint(tcp::v6(), port);
}
auto endpoints = config.equal_range("endpoint");
@ -421,13 +424,31 @@ int AsioFrontend::init()
}
}
bool socket_bound = false;
// start listeners
for (auto& l : listeners) {
l.acceptor.open(l.endpoint.protocol(), ec);
if (ec) {
if (ec == boost::asio::error::address_family_not_supported) {
ldout(ctx(), 0) << "WARNING: cannot open socket for endpoint=" << l.endpoint
<< ", " << ec.message() << dendl;
continue;
}
lderr(ctx()) << "failed to open socket: " << ec.message() << dendl;
return -ec.value();
}
if (l.endpoint.protocol() == tcp::v6()) {
l.acceptor.set_option(boost::asio::ip::v6_only(true), ec);
if (ec) {
lderr(ctx()) << "failed to set v6_only socket option: "
<< ec.message() << dendl;
return -ec.value();
}
}
l.acceptor.set_option(tcp::acceptor::reuse_address(true));
l.acceptor.bind(l.endpoint, ec);
if (ec) {
@ -435,6 +456,7 @@ int AsioFrontend::init()
<< ": " << ec.message() << dendl;
return -ec.value();
}
l.acceptor.listen(boost::asio::socket_base::max_connections);
l.acceptor.async_accept(l.socket,
[this, &l] (boost::system::error_code ec) {
@ -442,7 +464,13 @@ int AsioFrontend::init()
});
ldout(ctx(), 4) << "frontend listening on " << l.endpoint << dendl;
socket_bound = true;
}
if (!socket_bound) {
lderr(ctx()) << "Unable to listen at any endpoints" << dendl;
return -EINVAL;
}
return drop_privileges(ctx());
}
@ -507,6 +535,10 @@ int AsioFrontend::init_ssl()
listeners.emplace_back(context);
listeners.back().endpoint.port(port);
listeners.back().use_ssl = true;
listeners.emplace_back(context);
listeners.back().endpoint = tcp::endpoint(tcp::v6(), port);
listeners.back().use_ssl = true;
}
auto endpoints = config.equal_range("ssl_endpoint");