Browse Source

Merge branch 'master' of ssh://bind10.isc.org/var/bind10/git/bind10

JINMEI Tatuya 14 years ago
parent
commit
910df2cc92

+ 9 - 2
ChangeLog

@@ -1,6 +1,12 @@
+  181.  [func]      feng
+	Add stop interface into dns server, so we can stop each running
+	server individually. With it, user can reconfigure her running server
+	with different ip address or port.
+	(Trac #388, git TBD)
+
   180.  [build]     jreed
-        Fix custom DESTDIR for make install.
-        (Trac $629, git 5ac67ede03892a5eacf42ce3ace1e4e376164c9f)
+  Fix custom DESTDIR for make install.
+  (Trac $629, git 5ac67ede03892a5eacf42ce3ace1e4e376164c9f)
 
 bind10-devel-20110224 released on February 24, 2011
 
@@ -51,6 +57,7 @@ bind10-devel-20110224 released on February 24, 2011
 	list and map item addressing, the correct display of actual values,
 	and internal help.
 	(Trac #384, git e5fb3bc1ed5f3c0aec6eb40a16c63f3d0fc6a7b2)
+>>>>>>> master
 
   171.  [func]      feng, jerry, jinmei, vorner
 	b10-auth, src/lib/datasrc: in memory data source now works as a

+ 2 - 2
src/bin/resolver/resolver.cc

@@ -626,7 +626,7 @@ Resolver::setListenAddresses(const vector<addr_t>& addresses) {
         setAddresses(dnss_, addresses);
         impl_->listen_ = addresses;
     }
-    catch (const exception& e) {
+    catch (exception& e) {
         /*
          * We couldn't set it. So return it back. If that fails as well,
          * we have a problem.
@@ -643,7 +643,7 @@ Resolver::setListenAddresses(const vector<addr_t>& addresses) {
             dlog(string("Rollback failed with: ") + e2.what(),true);
             abort();
         }
-        throw e; // Let it fly a little bit further
+        throw; // Let it fly a little bit further
     }
 }
 

+ 1 - 4
src/bin/resolver/tests/resolver_config_unittest.cc

@@ -174,7 +174,7 @@ TEST_F(ResolverConfig, listenAddresses) {
     EXPECT_TRUE(server.getListenAddresses().empty());
 }
 
-TEST_F(ResolverConfig, DISABLED_listenAddressConfig) {
+TEST_F(ResolverConfig, listenAddressConfig) {
     // Try putting there some address
     ElementPtr config(Element::fromJSON("{"
         "\"listen_on\": ["
@@ -192,9 +192,6 @@ TEST_F(ResolverConfig, DISABLED_listenAddressConfig) {
 
     // As this is example address, the machine should not have it on
     // any interface
-    // FIXME: This test aborts, because it tries to rollback and
-    //     it is impossible, since the sockets are not closed.
-    //     Once #388 is solved, enable this test.
     config = Element::fromJSON("{"
         "\"listen_on\": ["
         "   {"

+ 3 - 0
src/lib/asiolink/dns_server.h

@@ -75,6 +75,9 @@ public:
         (*self_)(ec, length);
     }
 
+    /// \brief Stop current running server
+    virtual void stop() { self_->stop();}
+
     /// \brief Resume processing of the server coroutine after an 
     /// asynchronous call (e.g., to the DNS Lookup provider) has completed.
     ///

+ 8 - 2
src/lib/asiolink/dns_service.cc

@@ -29,6 +29,11 @@
 #include <asiolink/tcp_server.h>
 #include <asiolink/udp_server.h>
 
+#include <log/dummylog.h>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/foreach.hpp>
+
 using isc::log::dlog;
 
 namespace asiolink {
@@ -184,8 +189,9 @@ DNSService::addServer(uint16_t port, const std::string& address) {
 
 void
 DNSService::clearServers() {
-    // FIXME: This does not work, it does not close the socket.
-    // How is it done?
+    BOOST_FOREACH(const DNSServiceImpl::DNSServerPtr& s, impl_->servers_) {
+        s->stop();
+    }
     impl_->servers_.clear();
 }
 

+ 17 - 1
src/lib/asiolink/tcp_server.cc

@@ -46,7 +46,7 @@ TCPServer::TCPServer(io_service& io_service,
                      const SimpleCallback* checkin,
                      const DNSLookup* lookup,
                      const DNSAnswer* answer) :
-    io_(io_service), done_(false),
+    io_(io_service), done_(false), stopped_by_hand_(false),
     checkin_callback_(checkin), lookup_callback_(lookup),
     answer_callback_(answer)
 {
@@ -68,6 +68,13 @@ TCPServer::operator()(error_code ec, size_t length) {
     /// Because the coroutine reeentry block is implemented as
     /// a switch statement, inline variable declarations are not
     /// permitted.  Certain variables used below can be declared here.
+
+    /// If user has stopped the server, we won't enter the
+    /// coroutine body, just return
+    if (stopped_by_hand_) {
+        return;
+    }
+
     boost::array<const_buffer,2> bufs;
     OutputBuffer lenbuf(TCP_MESSAGE_LENGTHSIZE);
 
@@ -188,6 +195,15 @@ TCPServer::asyncLookup() {
                         answer_message_, respbuf_, this);
 }
 
+void TCPServer::stop() {
+    //server should not be stopped twice
+    if (stopped_by_hand_)
+        return;
+
+    stopped_by_hand_ = true;
+    acceptor_->close();
+    socket_->close();
+}
 /// Post this coroutine on the ASIO service queue so that it will
 /// resume processing where it left off.  The 'done' parameter indicates
 /// whether there is an answer to return to the client.

+ 4 - 0
src/lib/asiolink/tcp_server.h

@@ -43,6 +43,7 @@ public:
     void operator()(asio::error_code ec = asio::error_code(),
                     size_t length = 0);
     void asyncLookup();
+    void stop();
     void resume(const bool done);
     bool hasAnswer() { return (done_); }
     int value() { return (get_value()); }
@@ -106,6 +107,9 @@ private:
     size_t bytes_;
     bool done_;
 
+    // whether user has stopped the server
+    bool stopped_by_hand_;
+
     // Callback functions provided by the caller
     const SimpleCallback* checkin_callback_;
     const DNSLookup* lookup_callback_;

+ 1 - 3
src/lib/asiolink/tests/recursive_query_unittest.cc

@@ -485,9 +485,7 @@ TEST_F(RecursiveQueryTest, v4AddServer) {
     EXPECT_THROW(sendTCP(AF_INET6), IOError);
 }
 
-TEST_F(RecursiveQueryTest, DISABLED_clearServers) {
-    // FIXME: Enable when clearServers actually close the sockets
-    //    See #388
+TEST_F(RecursiveQueryTest, clearServers) {
     setDNSService();
     dns_service_->clearServers();
 

+ 23 - 2
src/lib/asiolink/udp_server.cc

@@ -55,8 +55,9 @@ struct UDPServer::Data {
      */
     Data(io_service& io_service, const ip::address& addr, const uint16_t port,
         SimpleCallback* checkin, DNSLookup* lookup, DNSAnswer* answer) :
-        io_(io_service), done_(false), checkin_callback_(checkin),
-        lookup_callback_(lookup), answer_callback_(answer)
+        io_(io_service), done_(false), stopped_by_hand_(false),
+        checkin_callback_(checkin),lookup_callback_(lookup),
+        answer_callback_(answer)
     {
         // We must use different instantiations for v4 and v6;
         // otherwise ASIO will bind to both
@@ -78,6 +79,7 @@ struct UDPServer::Data {
      */
     Data(const Data& other) :
         io_(other.io_), socket_(other.socket_), done_(false),
+        stopped_by_hand_(false),
         checkin_callback_(other.checkin_callback_),
         lookup_callback_(other.lookup_callback_),
         answer_callback_(other.answer_callback_)
@@ -141,6 +143,9 @@ struct UDPServer::Data {
     size_t bytes_;
     bool done_;
 
+    //whether user explicitly stop the server
+    bool stopped_by_hand_;
+
     // Callback functions provided by the caller
     const SimpleCallback* checkin_callback_;
     const DNSLookup* lookup_callback_;
@@ -168,6 +173,12 @@ UDPServer::operator()(error_code ec, size_t length) {
     /// a switch statement, inline variable declarations are not
     /// permitted.  Certain variables used below can be declared here.
 
+    /// if user stopped the server, we won't enter the coroutine body
+    /// just return
+    if (data_->stopped_by_hand_) {
+        return;
+    }
+
     CORO_REENTER (this) {
         do {
             /*
@@ -277,6 +288,16 @@ UDPServer::asyncLookup() {
         data_->query_message_, data_->answer_message_, data_->respbuf_, this);
 }
 
+/// Stop the UDPServer
+void
+UDPServer::stop() {
+    //server should not be stopped twice
+    if (data_->stopped_by_hand_)
+        return;
+    data_->stopped_by_hand_ = true;
+    data_->socket_->close();
+}
+
 /// Post this coroutine on the ASIO service queue so that it will
 /// resume processing where it left off.  The 'done' parameter indicates
 /// whether there is an answer to return to the client.

+ 4 - 0
src/lib/asiolink/udp_server.h

@@ -58,6 +58,10 @@ public:
     /// \brief Calls the lookup callback
     void asyncLookup();
 
+    /// \brief Stop the running server
+    /// \note once the server stopped, it can't restart
+    void stop();
+
     /// \brief Resume operation
     ///
     /// \param done Set this to true if the lookup action is done and