Browse Source

Added a README file with asiolink overview

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac327@3127 e5f2f494-b856-4b98-b285-d166d9295462
Evan Hunt 14 years ago
parent
commit
e08892e97e
1 changed files with 100 additions and 0 deletions
  1. 100 0
      src/lib/asiolink/README

+ 100 - 0
src/lib/asiolink/README

@@ -0,0 +1,100 @@
+The asiolink library is intended to provide an abstraction layer between
+BIND10 modules and the socket I/O subsystem we are using (currently, the
+headers-only version of ASIO, release 1.43).  This has several benefits,
+including:
+
+  - Simple interface
+
+  - Back-end flexibility:  It would be easy to switch from using
+    ASIO to boost::asio, and even relatively straightforward to switch
+    to any other asynchronous I/O system.
+
+  - Cleaner compilation:  The ASIO headers include code which can
+    generate warnings in some compilers due to unused parameters and
+    such.  Including ASIO header files throughout the BIND 10 tree would
+    require us to relax the strictness of our error checking.  Including
+    them in only one place allows us to relax strictness here, while
+    leaving it in place elsewhere.
+
+Currently, the asiolink library only supports DNS servers (i.e., b10-auth
+and b10-recurse).  The plan is to make it more generic and allow it to
+support other modules as well.
+
+Some of the classes defined here--for example, IOSocket, IOEndpoint,
+and IOAddress--are to be used by BIND 10 modules as wrappers around
+ASIO-specific classes.
+
+Other classes implement the DNS protocol on behalf of BIND 10 modules.
+
+These DNS server and client routines are written using the "stackless
+coroutine" pattern invented by Chris Kohlhoff and described at
+http://blog.think-async.com/2010/03/potted-guide-to-stackless-coroutines.html.
+This is intended to simplify development a bit, since it allows the
+routines to be written in a straightfowrard step-step-step fashion rather
+than as a complex chain of separate handler functions.
+
+Coroutine objects (i.e., UDPServer, TCPServer and UDPQuery) are objects
+with reenterable operator() members.  When an instance of one of these
+classes is called as a function, it resumes at the position where it left
+off.  Thus, a UDPServer can issue an asynchronous I/O call and specify
+itself as the handler object; when the call completes, the UDPServer
+carries on at the same position.  As a result, the code can look as
+if it were using synchronous, not asynchronous, I/O, providing some of
+the benefit of threading but with minimal switching overhead.
+
+So, in simplified form, the behavior of a DNS Server is:
+
+  REENTER:
+    while true:
+      YIELD packet = read_packet
+      FORK
+      if not parent:
+        break
+
+    # This callback informs the caller that a packet has arrived, and
+    # gives it a chance to update configuration, etc
+    SimpleCallback(packet)
+    YIELD answer = DNSLookup(packet, this)
+    response = DNSAnswer(answer)
+    YIELD send(response)
+
+At each "YIELD" point, the coroutine initiates an asynchronous operation,
+then pauses and turns over control to some other task on the ASIO service
+queue.  When the operation completes, the coroutine resumes.
+
+DNSLookup, DNSAnswer and SimpleCallback define callback methods
+used by a DNS Server to communicate with the module that called it.
+They are abstract-only classes whose concrete implementations
+are supplied by the calling module.
+
+Note that the DNSLookup callback runs asynchronously.  A concrete
+implementation must be sure to call the server's "resume" method when
+it is finished.
+
+In an authoritative server, the DNSLookup implementation would examine
+the query, look up the answer, then call "resume".  In a recursive server,
+it would initiate a DNSQuery, which in turn would be responsible for
+calling the server's "resume" method.
+
+A DNSQuery object is intended to handle resolution of a query over
+the network when the local authoritative data sources or cache are not
+sufficient.  The plan is that it will make use of subsidiary DNSFetch
+calls to get data from particular authoritative servers, and when it has
+gotten a complete answer, it calls "resume".
+
+In current form, however, DNSQuery is much simpler; it forwards queries
+to a single upstream resolver and passes the answers back to the client.
+It is constructed with the address of the forward server.  Queries are
+initiated with the question to ask the forward server, a buffer into
+which to write the answer, and a pointer to the coroutine to be resumed
+when the answer has arrived.  In simplified form, the DNSQuery routine is:
+
+  REENTER:
+    render the question into a wire-format query packet
+    YIELD send(query)
+    YIELD response = read_packet
+    server->resume
+
+Currently, DNSQuery is only implemented for UDP queries.  In future work
+it will be necessary to write code to fall back to TCP when circumstances
+require it.