Browse Source

[trac554] last few changes

Scott Mann 14 years ago
parent
commit
ad91697c60
2 changed files with 118 additions and 24 deletions
  1. 31 6
      src/lib/asiolink/internal/iofetch.h
  2. 87 18
      src/lib/asiolink/iofetch.cc

+ 31 - 6
src/lib/asiolink/internal/iofetch.h

@@ -28,14 +28,15 @@
 #include <asiolink/asiolink.h>
 #include <asiolink/internal/coroutine.h>
 
-// This file contains UDP-specific implementations of generic classes 
+// This file contains TCP/UDP-specific implementations of generic classes 
 // defined in asiolink.h.  It is *not* intended to be part of the public
 // API.
 
 namespace asiolink {
 //
-// Asynchronous UDP coroutine for upstream queries
+// Asynchronous UDP/TCP coroutine for upstream fetches
 //
+//class IOFetch : public coroutine, public UdpFetch, public TcpFetch {
 class IOFetch : public coroutine {
 public:
     // TODO Maybe this should be more generic than just for IOFetch?
@@ -66,11 +67,12 @@ public:
     ///        delete it if allocated on heap.
     ///@param timeout in ms.
     ///
-    explicit IOFetch(asio::io_service& io_service,
+    IOFetch(asio::io_service& io_service,
                       const isc::dns::Question& q,
                       const IOAddress& addr, uint16_t port,
                       isc::dns::OutputBufferPtr buffer,
-                      Callback* callback, int timeout = -1);
+                      Callback* callback, int timeout = -1, 
+                      int protocol = IPPROTO_UDP);
     void operator()(asio::error_code ec = asio::error_code(),
                     size_t length = 0);
     /// Terminate the query.
@@ -87,9 +89,32 @@ private:
     /// to many async_*() functions) and we want keep the same data. Some of
     /// the data is not copyable too.
     ///
-    struct IOFetchProtocol;
-    boost::shared_ptr<IOFetchProtocol> data_;
+    //struct IOFetchProtocol;
+    //boost::shared_ptr<IOFetchProtocol> data_;
+    //struct UdpData;
+    //struct TcpData;
+    boost::shared_ptr<UdpFetch> data_;
+    boost::shared_ptr<TcpFetch> tcp_data_;
 };
+class UdpFetch : public IOFetch {
+    public:
+        struct UdpData;
+        explicit UdpFetch(asio::io_service& io_service,
+                          const isc::dns::Question& q,
+                          const IOAddress& addr,
+                          uint16_t port,
+                          isc::dns::OutputBufferPtr buffer,
+                          IOFetch::Callback *callback,
+                          int timeout);
+};
+class TcpFetch : public IOFetch {
+    public:
+        struct TcpData;
+        explicit TcpFetch(io_service& io_service, const Question& q,
+                 const IOAddress& addr, uint16_t port,
+                 OutputBufferPtr buffer, Callback *callback, int timeout);
+};
+
 }
 
 

+ 87 - 18
src/lib/asiolink/iofetch.cc

@@ -50,16 +50,51 @@ using namespace isc::dns;
 
 namespace asiolink {
 
-// Private IOFetch data (see internal/iofetch.h for reasons)
-struct IOFetch::IOFetchProtocol {
+struct TcpFetch::UdpData {
     // UDP Socket we send query to and expect reply from there
     udp::socket socket;
     // Where was the query sent
     udp::endpoint remote;
+    // What we ask the server
+    Question question;
+    // We will store the answer here
+    OutputBufferPtr buffer;
+    OutputBufferPtr msgbuf;
+    // Temporary buffer for answer
+    boost::shared_array<char> data;
+    // This will be called when the data arrive or timeouts
+    Callback* callback;
+    //Callback* callback;
+    // Did we already stop operating (data arrived, we timed out, someone
+    // called stop). This can be so when we are cleaning up/there are
+    // still pointers to us.
+    bool stopped;
+    // Timer to measure timeouts.
+    deadline_timer timer;
+    // How many milliseconds are we willing to wait for answer?
+    int timeout;
+
+    UdpData(io_service& service,
+        const udp::socket::protocol_type& protocol,
+        const Question &q,
+        OutputBufferPtr b, Callback *c) :
+          socket(service, protocol),
+          question(q),
+          buffer(b),
+          msgbuf(new OutputBuffer(512)),
+          callback(c),
+          stopped(false),
+          timer(service)
+    { }
+
+
+};
+
+struct TcpFetch::TcpData {
     // TCP Socket
-    tcp::socket tsocket;
+    tcp::socket socket;
     // tcp endpoint
-    tcp::endpoint tremote;
+    tcp::endpoint remote;
     // What we ask the server
     Question question;
     // We will store the answer here
@@ -78,13 +113,11 @@ struct IOFetch::IOFetchProtocol {
     // How many milliseconds are we willing to wait for answer?
     int timeout;
 
-    IOFetchProtocol(io_service& service,
-        const udp::socket::protocol_type& protocol,
-        const tcp::socket::protocol_type& tprotocol,
+    TcpData(io_service& service,
+        const tcp::socket::protocol_type& protocol,
         const Question &q,
         OutputBufferPtr b, Callback *c) :
           socket(service, protocol),
-          tsocket(service, tprotocol),
           question(q),
           buffer(b),
           msgbuf(new OutputBuffer(512)),
@@ -96,22 +129,58 @@ struct IOFetch::IOFetchProtocol {
 
 };
 
+UdpFetch::UdpFetch(io_service& io_service, const Question& q,
+                 const IOAddress& addr, uint16_t port,
+                 OutputBufferPtr buffer, Callback *callback, int timeout) :
+    data_(new UdpData(io_service, 
+          addr.getFamily() == AF_INET ? udp::v4() : udp::v6(), 
+          q, buffer, callback))
+{
+    data_->remote = UDPEndpoint(addr, port).getASIOEndpoint();
+    data_->timeout = timeout;
+}
+TcpFetch::TcpFetch(io_service& io_service, const Question& q,
+                 const IOAddress& addr, uint16_t port,
+                 OutputBufferPtr buffer, Callback *callback, int timeout) :
+    tcp_data_(new TcpData(io_service, 
+          addr.getFamily() == AF_INET ? udp::v4() : udp::v6(), 
+          q, buffer, callback))
+{
+    tcp_data_->remote = TCPEndpoint(addr, port).getASIOEndpoint();
+    tcp_data_->timeout = timeout;
+}
+
+//
 /// The following functions implement the \c IOFetch class.
 ///
 /// The constructor
 IOFetch::IOFetch(io_service& io_service, const Question& q, 
                  const IOAddress& addr, uint16_t port,
-                 OutputBufferPtr buffer, Callback *callback, int timeout) :
-    data_(new IOFetchProtocol(io_service,
-        addr.getFamily() == AF_INET ? udp::v4() : udp::v6(), 
-        addr.getFamily() == AF_INET ? tcp::v4() : tcp::v6(), 
-        q, buffer,
-        callback))
-
+                 OutputBufferPtr buffer, Callback *callback, int timeout,
+                 int protocol)
 {
-    data_->tremote = TCPEndpoint(addr, port).getASIOEndpoint();
-    data_->remote = UDPEndpoint(addr, port).getASIOEndpoint();
-    data_->timeout = timeout;
+    if (protocol == IPPROTO_TCP)
+    {
+        TcpFetch(io_service, q, addr, port, buffer, callback, timeout);
+/*
+        tcp_data_ = new TcpData(io_service, 
+          addr.getFamily() == AF_INET ? udp::v4() : udp::v6(), 
+          q, buffer, callback);
+        tcp_data_->remote = TCPEndpoint(addr, port).getASIOEndpoint();
+        tcp_data_->timeout = timeout;
+*/
+    }
+    else
+    {
+        UdpFetch(io_service, q, addr, port, buffer, callback, timeout);
+/*
+        data_(new UdpData(io_service, 
+          addr.getFamily() == AF_INET ? udp::v4() : udp::v6(), 
+          q, buffer, callback));
+        data_->remote = UDPEndpoint(addr, port).getASIOEndpoint();
+        data_->timeout = timeout;
+*/
+    }
 }
 
 /// The function operator is implemented with the "stackless coroutine"