Browse Source

fixed a problem with asio port binding, if you specify v6() without further options, it binds to both IPv4 and IPv6 (at least in my version), so we need to specify a v6-only option for the UDPServer and TCPServer that listen on v6

git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1512 e5f2f494-b856-4b98-b285-d166d9295462
Jelte Jansen 15 years ago
parent
commit
924829fb3c
1 changed files with 21 additions and 5 deletions
  1. 21 5
      src/bin/auth/main.cc

+ 21 - 5
src/bin/auth/main.cc

@@ -200,10 +200,18 @@ class TCPServer {
 public:
     TCPServer(io_service& io_service, int af, short port) :
         io_service_(io_service),
-        acceptor_(io_service,
-                  tcp::endpoint(af == AF_INET6 ? tcp::v6() : tcp::v4(), port)),
+        acceptor_(io_service, af == AF_INET6 ? tcp::v6() : tcp::v4()),
         listening_(new TCPClient(io_service_))
     {
+        // Set v6-only (we use a different instantiation for v4,
+        // otherwise asio will bind to both v4 and v6
+        if (af == AF_INET6) {
+            boost::asio::ip::v6_only option(true);
+            acceptor_.set_option(option);
+            acceptor_.bind(tcp::endpoint(tcp::v6(), port));
+        } else {
+            acceptor_.bind(tcp::endpoint(tcp::v4(), port));
+        }
         // XXX: isn't the following exception free?  Need to check it.
         acceptor_.async_accept(listening_->getSocket(),
                                boost::bind(&TCPServer::handleAccept, this,
@@ -237,14 +245,22 @@ private:
 
 class UDPServer {
 public:
-    UDPServer(io_service& io_service, int af, short port) :
+    UDPServer(io_service& io_service, int af UNUSED_PARAM, short port UNUSED_PARAM) :
         io_service_(io_service),
-        socket_(io_service,
-                udp::endpoint(af == AF_INET6 ? udp::v6() : udp::v4(), port)),
+        socket_(io_service, af == AF_INET6 ? udp::v6() : udp::v4()),
         response_buffer_(0),
         response_renderer_(response_buffer_),
         dns_message_(Message::PARSE)
     {
+        // Set v6-only (we use a different instantiation for v4,
+        // otherwise asio will bind to both v4 and v6
+        if (af == AF_INET6) {
+            boost::asio::ip::v6_only option(true);
+            socket_.set_option(option);
+            socket_.bind(udp::endpoint(udp::v6(), port));
+        } else {
+            socket_.bind(udp::endpoint(udp::v4(), port));
+        }
         startReceive();
     }