BIND 10 experiments/stephen-badpacket, updated. fd128eb60de1be08ce1f0a7a7c71f45945a871f1 [experiments/stephen-badpacket] Potentially Bad Packet Client

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Mar 17 19:24:25 UTC 2011


The branch, experiments/stephen-badpacket has been updated
       via  fd128eb60de1be08ce1f0a7a7c71f45945a871f1 (commit)
      from  012f9e78dc611c72ea213f9bd6743172e1a2ca20 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit fd128eb60de1be08ce1f0a7a7c71f45945a871f1
Author: Stephen Morris <stephen at isc.org>
Date:   Thu Mar 17 19:23:18 2011 +0000

    [experiments/stephen-badpacket] Potentially Bad Packet Client
    
    Creates a valid packet then sets various combinations of bits in
    the flags bytes (bytes 2 and 3) before sending it to the client.
    Prints out the combination of bits sent and the combination received.

-----------------------------------------------------------------------

Summary of changes:
 configure.ac                                    |    1 +
 src/lib/asiolink/Makefile.am                    |    2 +-
 src/lib/asiolink/badpacket/Makefile.am          |   23 +++
 src/lib/asiolink/badpacket/badpacket.cc         |  158 +++++++++++++++++++
 src/lib/asiolink/badpacket/header_flags_scan.cc |  191 +++++++++++++++++++++++
 src/lib/asiolink/badpacket/header_flags_scan.h  |  105 +++++++++++++
 src/lib/asiolink/io_fetch.cc                    |   38 ++++-
 src/lib/asiolink/io_fetch.h                     |   26 +++
 8 files changed, 535 insertions(+), 9 deletions(-)
 create mode 100644 src/lib/asiolink/badpacket/Makefile.am
 create mode 100644 src/lib/asiolink/badpacket/badpacket.cc
 create mode 100644 src/lib/asiolink/badpacket/header_flags_scan.cc
 create mode 100644 src/lib/asiolink/badpacket/header_flags_scan.h

-----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 7f2b3ea..bd53e95 100644
--- a/configure.ac
+++ b/configure.ac
@@ -642,6 +642,7 @@ AC_CONFIG_FILES([Makefile
                  src/lib/Makefile
                  src/lib/asiolink/Makefile
                  src/lib/asiolink/tests/Makefile
+                 src/lib/asiolink/badpacket/Makefile
                  src/lib/bench/Makefile
                  src/lib/bench/example/Makefile
                  src/lib/bench/tests/Makefile
diff --git a/src/lib/asiolink/Makefile.am b/src/lib/asiolink/Makefile.am
index 2fda728..fa38330 100644
--- a/src/lib/asiolink/Makefile.am
+++ b/src/lib/asiolink/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = . tests
+SUBDIRS = . tests badpacket
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += $(BOOST_INCLUDES)
diff --git a/src/lib/asiolink/badpacket/Makefile.am b/src/lib/asiolink/badpacket/Makefile.am
new file mode 100644
index 0000000..5d57700
--- /dev/null
+++ b/src/lib/asiolink/badpacket/Makefile.am
@@ -0,0 +1,23 @@
+SUBDIRS = .
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/log -I$(top_builddir)/src/lib/log
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+noinst_PROGRAMS  = badpacket
+badpacket_SOURCES  = badpacket.cc
+badpacket_SOURCES += header_flags_scan.cc header_flags_scan.h
+
+badpacket_LDADD  = $(top_builddir)/src/lib/asiolink/libasiolink.la
+badpacket_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
+badpacket_LDADD += $(top_builddir)/src/lib/log/liblog.la
+badpacket_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
+
diff --git a/src/lib/asiolink/badpacket/badpacket.cc b/src/lib/asiolink/badpacket/badpacket.cc
new file mode 100644
index 0000000..0bd0d2e
--- /dev/null
+++ b/src/lib/asiolink/badpacket/badpacket.cc
@@ -0,0 +1,158 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <unistd.h>
+
+#include <cstddef>
+#include <iostream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <boost/lexical_cast.hpp>
+
+#include <config.h>
+
+#include <asiolink/io_fetch.h>
+#include <dns/message.h>
+#include <log/strutil.h>
+
+#include "header_flags_scan.h"
+
+using namespace std;
+using namespace asiolink;
+using namespace isc::dns;
+using namespace isc::test;
+
+/// \brief Send Bad Packets
+///
+/// Sends a sequence of bad packets to the target nameserver and prints the
+/// packet settings and the response received.
+///
+/// Really, it should be "potentially bad packets".  The program treats the
+/// flags field in the header as an unsigned 16-bit number, and cycles through
+/// all combination of bits, sending a query for "www.example.com".  The result
+/// is then printed.
+///
+/// The principle raison d'etre for this is to check if the combination of bits
+/// will cause a crash.
+
+/// \brief Print usage information
+void
+Usage() {
+    cout << "Usage: badpacket [-a <address>] [-f<start>[-<end>]] [-p <port>]\n"
+            "                 [-h] [-v]\n"
+            "\n"
+            "Sends a sequence of packets to the specified nameserver and\n"
+            "prints the results.\n"
+            "\n"
+            "-a<address>      Address of nameserver.  Defaults to 127.0.0.1.\n"
+            "-f<start>[-<end>]\n"
+            "                 Do a flags scan.  This treats the packet header\n"
+            "                 flags as a 16-bit number and cycles through all\n"
+            "                 values in the range <start> to <end>. (If only\n"
+            "                 a single value is given, only that value is\n"
+            "                 tested.) Default to 0-65535.\n"
+            "-h               Print the help message and exits.\n"
+            "-p<port>         Port to which to send query.  Defaults to 53.\n"
+            "-t<timeout>      Timeout value in ms.  Default is 500\n"
+            "-v               Prints version information and exits\n";
+}
+
+/// \brief Print version information
+void
+Version() {
+    cout << "1.0-0\n";
+}
+
+/// \brief Parse -f flag
+///
+/// The "-f" flag should be of the form "-f<value>" or "-f<val1>-<val2>".
+/// This function checks that value and returns the start/end values (both the
+/// same if only one value were specified).  On an error it will output a
+/// message and terminate thge program.
+///
+/// \param ftext String passed to the parameter
+///
+/// \return pair of uint16_t holding the start and end values.
+pair<uint16_t, uint16_t>
+getRange(const char* ftext) {
+
+    // Split the string up into one or two tokens
+    vector<string> values = isc::strutil::tokens(string(ftext), "-");
+    if ((values.size() < 1) || (values.size() > 2)) {
+        cerr << "Error: format of flags scan parameter is 'v1' or 'v1-v2'\n";
+        exit(1);
+    }
+
+    // Convert to uint16.
+    uint16_t start = boost::lexical_cast<uint16_t>(values[0]);
+    uint16_t end = start;
+    if (values.size() == 2) {
+        end = boost::lexical_cast<uint16_t>(values[1]);
+    }
+
+    return make_pair(start, end);
+}
+
+
+/// \brief Main Program
+int main(int argc, char* argv[]) {
+    pair<uint16_t, uint16_t> range(0, 65535);   // Range of values to check
+    string  address = "127.0.0.1";              // Address of nameserver
+    uint16_t port = 53;                         // Port of nameserver
+    int timeout = 500;                          // Query timeout in ms
+
+    char    c;                          // Option being processed
+
+    while ((c = getopt(argc, argv, "a:f:hp:t:v")) != -1) {
+        switch (c) {
+            case 'a':
+                address = optarg;
+                break;
+
+            case 'f':
+                range = getRange(optarg);
+                break;
+
+            case 'h':
+                Usage();
+                exit(0);
+
+            case 'p':
+                port = boost::lexical_cast<uint16_t>(string(optarg));
+                break;
+
+            case 't':
+                timeout = boost::lexical_cast<int>(string(optarg));
+                break;
+
+            case 'v':
+                Version();
+                exit(0);
+
+            default:
+                cerr << "Error: unknown option " << c << "\n";
+                exit(1);
+        }
+    }
+
+    // Construct the scan object
+    HeaderFlagsScan scanner(address, port, timeout, range.first, range.second);
+
+    // Now perform the scan
+    scanner.scan("www.example.com");
+
+    return 0;
+}
diff --git a/src/lib/asiolink/badpacket/header_flags_scan.cc b/src/lib/asiolink/badpacket/header_flags_scan.cc
new file mode 100644
index 0000000..6102ff9
--- /dev/null
+++ b/src/lib/asiolink/badpacket/header_flags_scan.cc
@@ -0,0 +1,191 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include <boost/scoped_ptr.hpp>
+
+#include <asio.hpp>
+
+#include <asiolink/io_address.h>
+#include <asiolink/io_fetch.h>
+#include <dns/buffer.h>
+#include <dns/message.h>
+#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/question.h>
+#include <dns/rcode.h>
+#include <dns/rrclass.h>
+#include <dns/rrtype.h>
+#include <log/strutil.h>
+
+#include "header_flags_scan.h"
+
+using namespace std;
+using namespace asiolink;
+using namespace isc::dns;
+using namespace isc::strutil;
+
+namespace isc {
+namespace test {
+
+// Perform the scan from start to end on a single question.
+void
+HeaderFlagsScan::scan(const std::string& qname) {
+
+    // Create the message buffer to use
+    Message message(Message::RENDER);
+    message.setOpcode(Opcode::QUERY());
+    message.setRcode(Rcode::NOERROR());
+    message.addQuestion(Question(Name(qname), RRClass::IN(), RRType::A()));
+
+    OutputBufferPtr msgbuf(new OutputBuffer(512));
+    MessageRenderer renderer(*msgbuf);
+    message.toWire(renderer);
+
+    // Now loop through the settings sending the data
+    if (start_ < end_) {
+        for (uint16_t i = start_; i <= end_; ++i) {
+            scanOne(msgbuf, i);
+        }
+    } else {
+        for (uint16_t i = start_; i >= end_; --i) {
+            scanOne(msgbuf, i);
+        }
+    }
+}
+
+// Perform the scan on a single value
+void
+HeaderFlagsScan::scanOne(isc::dns::OutputBufferPtr& msgbuf, uint16_t value) {
+
+    // Set the flags field in the buffer and store the interpretation of it
+    msgbuf->writeUint16At(value, 2);
+    string fields = getFields(msgbuf);
+
+    // Do the I/O, waiting for a reply
+    OutputBufferPtr replybuf(new OutputBuffer(512));
+    performIO(msgbuf, replybuf);
+
+    string returned;
+    switch (result_) {
+    case IOFetch::SUCCESS:
+        {
+            // Parse the reply and get the fields
+            returned = getFields(replybuf);
+
+            // Put in a format suitable for returning
+            lowercase(returned);
+            returned = "SUCCESS: " + returned;
+        }
+        break;
+
+    case IOFetch::TIME_OUT:
+        returned = "TIMEOUT";
+        break;
+
+    case IOFetch::STOPPED:
+        returned = "STOPPED";
+        break;
+
+    default:
+        returned = "UNKNOWN - unknown fetch return code";
+    }
+        
+
+    // ... and output the result
+    cout << std::dec << setw(5) << value << " " << fields <<
+            "    " << returned << "\n";
+}
+
+// Get interpretation of the message fields.
+//
+// This takes the second and third bytes of the passed buffer and interprets
+// the values.  A summary string listing them is returned.
+std::string
+HeaderFlagsScan::getFields(isc::dns::OutputBufferPtr& msgbuf) {
+    struct header {
+        unsigned int rc : 4;
+        unsigned int cd : 1;
+        unsigned int ad : 1;
+        unsigned int rs : 1;    // Reserved
+        unsigned int ra : 1;
+        unsigned int rd : 1;
+        unsigned int tc : 1;
+        unsigned int aa : 1;
+        unsigned int op : 4;
+        unsigned int qr : 1;
+    };
+
+    union {
+        uint16_t        value;
+        struct header   fields;
+    } flags;
+
+    // Extract the flags field from the buffer
+    InputBuffer inbuf(msgbuf->getData(), msgbuf->getLength());
+    inbuf.setPosition(2);
+    flags.value = inbuf.readUint16();
+
+    std::ostringstream os;
+    os << std::hex << std::uppercase <<
+        "QR:" << flags.fields.qr << " " <<
+        "OP:" << flags.fields.op << " " <<
+        "AA:" << flags.fields.aa << " " <<
+        "TC:" << flags.fields.tc << " " <<
+        "RD:" << flags.fields.rd << " " <<
+        "RA:" << flags.fields.ra << " " <<
+        "RS:" << flags.fields.rs << " " <<
+        "AD:" << flags.fields.ad << " " <<
+        "CD:" << flags.fields.cd << " " <<
+        "RC:" << flags.fields.rc;
+    return (os.str());
+}
+
+// Perform the I/O
+void
+HeaderFlagsScan::performIO(OutputBufferPtr& sendbuf, OutputBufferPtr& recvbuf) {
+
+    // Set up an I/O service for the I/O.  This needs to be initialized before
+    // every call as the callback when the I/O completes stops it.
+    service_.reset(new IOService());
+
+    // The object that will do the I/O
+    IOFetch fetch(IOFetch::UDP, *service_, sendbuf, address_, port_, recvbuf,
+                  this, timeout_);
+
+    // Execute the I/O
+    (service_->get_io_service()).post(fetch); 
+    service_->run();
+}
+
+// I/O Callback
+void
+HeaderFlagsScan::operator()(IOFetch::Result result) {
+
+    // Record the result.  This is accessed when deciding what was returned
+    // (if a timeout, nothing was returned).
+    result_ = result;
+
+    // Stop the I/O service.  This will cause the call to run() to return.
+    service_->stop();
+}
+
+
+
+} // namespace test
+} // namespace isc
diff --git a/src/lib/asiolink/badpacket/header_flags_scan.h b/src/lib/asiolink/badpacket/header_flags_scan.h
new file mode 100644
index 0000000..a1fd2fb
--- /dev/null
+++ b/src/lib/asiolink/badpacket/header_flags_scan.h
@@ -0,0 +1,105 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __HEADER_FLAG_SCAN_H
+#define __HEADER_FLAG_SCAN_H
+
+#include <algorithm>
+#include <string>
+
+#include <config.h>
+
+#include <asiolink/io_address.h>
+#include <asiolink/io_fetch.h>
+#include <asiolink/io_service.h>
+#include <dns/buffer.h>
+#include <dns/message.h>
+
+namespace isc {
+namespace test {
+
+/// \brief Header Flags Scan
+///
+/// This class implements a header flag scan.  It treats the DNS packet header
+/// flags as a 16-bit value then cycles through values sending and receiving
+/// packets.
+
+class HeaderFlagsScan : public asiolink::IOFetch::Callback {
+public:
+
+    /// \brief Constructor
+    ///
+    /// \param address Address of target nameserver
+    /// \param port Port to use
+    /// \param timeout Query timeout (in ms)
+    /// \param start Start value for the scan
+    /// \param end End value for the scan
+    HeaderFlagsScan(std::string address = "127.0.0.1", uint16_t port = 53,
+                    int timeout = 500, uint16_t start = 0,
+                    uint16_t end = 65535) :
+        service_(), result_(), address_(address), port_(port),
+        timeout_(timeout), start_(start), end_(end)
+    {}
+
+    /// \brief Run Scan
+    ///
+    /// \param qname Name in the query being mangled.  The query will be for
+    ///        IN/A.
+    void scan(const std::string& qname);
+
+    /// \brief Perform I/O
+    ///
+    /// Performs a single query to the nameserver and reads the response.  It
+    /// outputs a summary of the result.
+    ///
+    /// \param sendbuf Buffer sent to the nameserver
+    /// \param recvbuf Buffer to hold reply from the nameserver
+    void performIO(isc::dns::OutputBufferPtr& sendbuf, isc::dns::OutputBufferPtr& recvbuf);
+    
+    /// \brief Callback
+    ///
+    /// When an I/O to the nameserver has completed, this method will be called
+    virtual void operator()(asiolink::IOFetch::Result result);
+
+private:
+    /// \brief Scan One Value
+    ///
+    /// \param msgbuf Message that will be sent to the remote nameserver.  The
+    ///        flags field (and QID) will be modified in the packet sent.
+    /// \param value Single value used in this scan.
+    void scanOne(isc::dns::OutputBufferPtr& msgbuf, uint16_t value);
+
+    /// \brief Get Fields
+    ///
+    /// \param msg Message for which the header is value
+    ///
+    /// \return A string that holds a textual interpretation of all the fields
+    ///         in the header.
+    std::string getFields(isc::dns::OutputBufferPtr& msgbuf);
+
+    // Member variables
+
+    boost::scoped_ptr<asiolink::IOService> service_;///< Service to run the scan
+    asiolink::IOFetch::Result   result_;            ///< Result of the I/O
+    asiolink::IOAddress         address_;           ///< Address of nameserver
+    uint16_t                    port_;              ///< Port on nameserver to use
+    int                         timeout_;           ///< Query timeout (in ms)
+    uint16_t                    start_;             ///< Start of scan value
+    uint16_t                    end_;               ///< End of scan value
+};
+
+} // namespace test
+} // namespace isc
+
+#endif // __HEADER_FLAG_SCAN_H
diff --git a/src/lib/asiolink/io_fetch.cc b/src/lib/asiolink/io_fetch.cc
index fdc1f2e..a00a0ef 100644
--- a/src/lib/asiolink/io_fetch.cc
+++ b/src/lib/asiolink/io_fetch.cc
@@ -86,6 +86,7 @@ struct IOFetchData {
     size_t                      offset;      ///< Offset to receive data
     bool                        stopped;     ///< Have we stopped running?
     int                         timeout;     ///< Timeout in ms
+    bool                        packet;      ///< true if packet was supplied
 
     // In case we need to log an error, the origin of the last asynchronous
     // I/O is recorded.  To save time and simplify the code, this is recorded
@@ -146,6 +147,7 @@ struct IOFetchData {
         offset(0),
         stopped(false),
         timeout(wait),
+        packet(false),
         origin(ASIO_UNKORIGIN),
         staging(),
         qid(QidGenerator::getInstance().generateQid())
@@ -175,6 +177,18 @@ IOFetch::IOFetch(Protocol protocol, IOService& service,
 {
 }
 
+IOFetch::IOFetch(Protocol protocol, IOService& service,
+    OutputBufferPtr& outpkt, const IOAddress& address, uint16_t port,
+    OutputBufferPtr& buff, Callback* cb, int wait)
+    :
+    data_(new IOFetchData(protocol, service,
+          isc::dns::Question(isc::dns::Name("dummy.example.org"), isc::dns::RRClass::IN(), isc::dns::RRType::A()),
+          address, port, buff, cb, wait))
+{
+    data_->msgbuf = outpkt;
+    data_->packet = true;
+}
+
 // Return protocol in use.
 
 IOFetch::Protocol
@@ -201,14 +215,22 @@ IOFetch::operator()(asio::error_code ec, size_t length) {
         /// This is done in a different scope to allow inline variable
         /// declarations.
         {
-            Message msg(Message::RENDER);
-            msg.setQid(data_->qid);
-            msg.setOpcode(Opcode::QUERY());
-            msg.setRcode(Rcode::NOERROR());
-            msg.setHeaderFlag(Message::HEADERFLAG_RD);
-            msg.addQuestion(data_->question);
-            MessageRenderer renderer(*data_->msgbuf);
-            msg.toWire(renderer);
+            if (data_->packet) {
+                // A packet was given, overwrite the QID (which is in the
+                // first two bytes of the packet).
+                data_->msgbuf->writeUint16At(data_->qid, 0);
+
+            } else {
+                // A question was given, construct the packet
+                Message msg(Message::RENDER);
+                msg.setQid(data_->qid);
+                msg.setOpcode(Opcode::QUERY());
+                msg.setRcode(Rcode::NOERROR());
+                msg.setHeaderFlag(Message::HEADERFLAG_RD);
+                msg.addQuestion(data_->question);
+                MessageRenderer renderer(*data_->msgbuf);
+                msg.toWire(renderer);
+            }
         }
 
         // If we timeout, we stop, which will can cancel outstanding I/Os and
diff --git a/src/lib/asiolink/io_fetch.h b/src/lib/asiolink/io_fetch.h
index 0723777..56cee87 100644
--- a/src/lib/asiolink/io_fetch.h
+++ b/src/lib/asiolink/io_fetch.h
@@ -137,6 +137,32 @@ public:
         uint16_t port, isc::dns::OutputBufferPtr& buff, Callback* cb,
         int wait = -1);
 
+    /// \brief Constructor.
+    ///
+    /// Creates the object that will handle the upstream fetch.
+    ///
+    /// TODO: Need to randomise the source port
+    ///
+    /// \param protocol Fetch protocol, either IOFetch::TCP or IOFetch::UDP
+    /// \param service I/O Service object to handle the asynchronous
+    ///     operations.
+    /// \param outpkt Packet to send to upstream server.  Note that the
+    ///     QID (first two bytes of the packet) may be altered in the sending.
+    /// \param buff Output buffer into which the response (in wire format)
+    ///     is written (if a response is received).
+    /// \param cb Callback object containing the callback to be called
+    ///     when we terminate.  The caller is responsible for managing this
+    ///     object and deleting it if necessary.
+    /// \param address IP address of upstream server
+    /// \param port Port to which to connect on the upstream server
+    /// (default = 53)
+    /// \param wait Timeout for the fetch (in ms).  The default value of
+    ///     -1 indicates no timeout.
+    IOFetch(Protocol protocol, IOService& service,
+        isc::dns::OutputBufferPtr& outpkt, const IOAddress& address,
+        uint16_t port, isc::dns::OutputBufferPtr& buff, Callback* cb,
+        int wait = -1);
+
     /// \brief Return Current Protocol
     ///
     /// \return Protocol associated with this IOFetch object.




More information about the bind10-changes mailing list