]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: beast: bind both v4 and v6 ports when using a port argument
authorAbhishek Lekshmanan <abhishek@suse.com>
Fri, 29 Mar 2019 16:37:44 +0000 (17:37 +0100)
committerAbhishek Lekshmanan <alekshmanan@suse.com>
Thu, 9 May 2019 18:56:21 +0000 (20:56 +0200)
This commit adds binding to both v4 and v6 port when specifying a port argument,
endpoint *only* binds to v4 or v6 depending on the address specified. Failure to
bind when the protocol is not supported is not treated as an error and we warn
and continue then.

Fixes: http://tracker.ceph.com/issues/39038
Signed-off-by: Abhishek Lekshmanan <abhishek@suse.com>
src/rgw/rgw_asio_frontend.cc

index e4be074ec74f8342ccedda59b3c735738553991f..58a7446db3c15f9f0a473f134c40acf77da6c4a0 100644 (file)
@@ -397,6 +397,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");
@@ -417,13 +420,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) {
@@ -431,6 +452,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) {
@@ -438,7 +460,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());
 }
 
@@ -503,6 +531,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");