Branch data Line data Source code
1 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : #ifndef __UDP_SERVER_H
16 : : #define __UDP_SERVER_H 1
17 : :
18 : : #ifndef ASIO_HPP
19 : : #error "asio.hpp must be included before including this, see asiolink.h as to why"
20 : : #endif
21 : :
22 : : #include <asiolink/simple_callback.h>
23 : : #include <asiodns/dns_answer.h>
24 : : #include <asiodns/dns_lookup.h>
25 : : #include <asiodns/dns_server.h>
26 : :
27 : : #include <coroutine.h>
28 : :
29 : : namespace isc {
30 : : namespace asiodns {
31 : :
32 : : //
33 : : // Asynchronous UDP server coroutine
34 : : //
35 : : ///
36 : : /// \brief This class implements the coroutine to handle UDP
37 : : /// DNS query event. As such, it is both a \c DNSServer and
38 : : /// a \c coroutine
39 : : ///
40 : 1498 : class UDPServer : public virtual DNSServer, public virtual coroutine {
41 : : public:
42 : : /// \brief Constructor
43 : : /// \param io_service the asio::io_service to work with
44 : : /// \param fd the file descriptor of opened UDP socket
45 : : /// \param af address family, either AF_INET or AF_INET6
46 : : /// \param checkin the callbackprovider for non-DNS events
47 : : /// \param lookup the callbackprovider for DNS lookup events
48 : : /// \param answer the callbackprovider for DNS answer events
49 : : /// \throw isc::InvalidParameter if af is neither AF_INET nor AF_INET6
50 : : /// \throw isc::asiolink::IOError when a low-level error happens, like the
51 : : /// fd is not a valid descriptor.
52 : : UDPServer(asio::io_service& io_service, int fd, int af,
53 : : isc::asiolink::SimpleCallback* checkin = NULL,
54 : : DNSLookup* lookup = NULL, DNSAnswer* answer = NULL);
55 : :
56 : : /// \brief The function operator
57 : : void operator()(asio::error_code ec = asio::error_code(),
58 : : size_t length = 0);
59 : :
60 : : /// \brief Calls the lookup callback
61 : : void asyncLookup();
62 : :
63 : : /// \brief Stop the running server
64 : : /// \note once the server stopped, it can't restart
65 : : void stop();
66 : :
67 : : /// \brief Resume operation
68 : : ///
69 : : /// \param done Set this to true if the lookup action is done and
70 : : /// we have an answer
71 : : void resume(const bool done);
72 : :
73 : : /// \brief Clones the object
74 : : ///
75 : : /// \return a newly allocated copy of this object
76 : 0 : DNSServer* clone() {
77 : 0 : UDPServer* s = new UDPServer(*this);
78 [ # # ][ # # ]: 0 : return (s);
79 : : }
80 : :
81 : : private:
82 : : enum { MAX_LENGTH = 4096 };
83 : :
84 : : /**
85 : : * \brief Internal state and data.
86 : : *
87 : : * We use the pimple design pattern, but not because we need to hide
88 : : * internal data. This class and whole header is for private use anyway.
89 : : * It turned out that UDPServer is copied a lot, because it is a coroutine.
90 : : * This way the overhead of copying is lower, we copy only one shared
91 : : * pointer instead of about 10 of them.
92 : : */
93 : : struct Data;
94 : : boost::shared_ptr<Data> data_;
95 : : };
96 : :
97 : : } // namespace asiodns
98 : : } // namespace isc
99 : : #endif // __UDP_SERVER_H
|