Stephen Morris 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
..
doc f0f818b27b Addressed some review comments, including: il y a 14 ans
internal bbb0031f3a [trac554] Merge branch 'master' into trac554 il y a 14 ans
tests 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
Makefile.am 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
README bc3d1d70a2 [trac554] Changed UDPQuery to IOFetch everywhere il y a 14 ans
asiolink.h 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
dns_answer.h b9e1f48df9 [trac569] rename the original ioxxx files to io_xxx il y a 14 ans
dns_lookup.h b9e1f48df9 [trac569] rename the original ioxxx files to io_xxx il y a 14 ans
dns_server.h b9e1f48df9 [trac569] rename the original ioxxx files to io_xxx il y a 14 ans
dns_service.cc 5e35787731 [trac569] Move coroutine.h to ext/ il y a 14 ans
dns_service.h 8697c90c35 [trac569] split up asiolink.h into multiple files il y a 14 ans
interval_timer.cc 8697c90c35 [trac569] split up asiolink.h into multiple files il y a 14 ans
interval_timer.h 8697c90c35 [trac569] split up asiolink.h into multiple files il y a 14 ans
io_address.cc 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
io_address.h 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
io_asio_socket.h 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
io_completion_cb.h 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
io_endpoint.cc 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
io_endpoint.h 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
io_error.h e01aeb058b [trac554] First stage of adding protocol-dependent upstream fetch il y a 14 ans
io_fetch.cc 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
io_fetch.h 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
io_message.h 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
io_service.cc 8697c90c35 [trac569] split up asiolink.h into multiple files il y a 14 ans
io_service.h 8697c90c35 [trac569] split up asiolink.h into multiple files il y a 14 ans
io_socket.cc 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
io_socket.h 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
recursive_query.cc a151c4a620 [trac569] split up udpdns.[h|cc] and tcpdns.[h|cc] too il y a 14 ans
recursive_query.h 8697c90c35 [trac569] split up asiolink.h into multiple files il y a 14 ans
simple_callback.h 5e35787731 [trac569] Move coroutine.h to ext/ il y a 14 ans
tcp_endpoint.h b9e1f48df9 [trac569] rename the original ioxxx files to io_xxx il y a 14 ans
tcp_server.cc 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
tcp_server.h 5e35787731 [trac569] Move coroutine.h to ext/ il y a 14 ans
tcp_socket.h 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
udp_endpoint.h 7ddfd9eca1 [trac554] Now have UDPSocket and its unit test working il y a 14 ans
udp_query.cc 5e35787731 [trac569] Move coroutine.h to ext/ il y a 14 ans
udp_query.h 5e35787731 [trac569] Move coroutine.h to ext/ il y a 14 ans
udp_server.cc 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans
udp_server.h 5e35787731 [trac569] Move coroutine.h to ext/ il y a 14 ans
udp_socket.h 85b6fa72d6 [trac554] Added IOFetch il y a 14 ans

README

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-resolver). 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 IOFetch) 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.

The DNSLookup callback always runs asynchronously. Concrete
implementations 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". (See the diagram
in doc/auth_process.jpg.)

In a recursive server, the DNSLookup impelemtation would initiate a
DNSQuery, which in turn would be responsible for calling the server's
"resume" method. (See the diagram in doc/recursive_process.jpg.)

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.