LCOV - code coverage report
Current view: top level - asiodns - sync_udp_server.h (source / functions) Hit Total Coverage
Test: report.info Lines: 5 5 100.0 %
Date: 2012-05-15 Functions: 4 4 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 4 50.0 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2012  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 __SYNC_UDP_SERVER_H
      16                 :            : #define __SYNC_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 "dns_answer.h"
      23                 :            : #include "dns_lookup.h"
      24                 :            : #include "dns_server.h"
      25                 :            : 
      26                 :            : #include <dns/message.h>
      27                 :            : #include <asiolink/simple_callback.h>
      28                 :            : #include <util/buffer.h>
      29                 :            : #include <exceptions/exceptions.h>
      30                 :            : 
      31                 :            : #include <boost/noncopyable.hpp>
      32                 :            : 
      33                 :            : #include <stdint.h>
      34                 :            : 
      35                 :            : namespace isc {
      36                 :            : namespace asiodns {
      37                 :            : 
      38                 :            : /// \brief An UDP server that doesn't asynchronous lookup handlers.
      39                 :            : ///
      40                 :            : /// That means, the lookup handler must provide the answer right away.
      41                 :            : /// This allows for implementation with less overhead, compared with
      42                 :            : /// the UDPClass.
      43                 :         30 : class SyncUDPServer : public DNSServer, public boost::noncopyable {
      44                 :            : public:
      45                 :            :     /// \brief Constructor
      46                 :            :     /// \param io_service the asio::io_service to work with
      47                 :            :     /// \param fd the file descriptor of opened UDP socket
      48                 :            :     /// \param af address family, either AF_INET or AF_INET6
      49                 :            :     /// \param checkin the callbackprovider for non-DNS events
      50                 :            :     /// \param lookup the callbackprovider for DNS lookup events
      51                 :            :     /// \param answer the callbackprovider for DNS answer events
      52                 :            :     /// \throw isc::InvalidParameter if af is neither AF_INET nor AF_INET6
      53                 :            :     /// \throw isc::asiolink::IOError when a low-level error happens, like the
      54                 :            :     ///     fd is not a valid descriptor.
      55                 :            :     SyncUDPServer(asio::io_service& io_service, const int fd, const int af,
      56                 :            :                   isc::asiolink::SimpleCallback* checkin = NULL,
      57                 :            :                   DNSLookup* lookup = NULL, DNSAnswer* answer = NULL);
      58                 :            : 
      59                 :            :     /// \brief Start the SyncUDPServer.
      60                 :            :     ///
      61                 :            :     /// This is the function operator to keep interface with other server
      62                 :            :     /// classes. They need that because they're coroutines.
      63                 :            :     virtual void operator()(asio::error_code ec = asio::error_code(),
      64                 :            :                     size_t length = 0);
      65                 :            : 
      66                 :            :     /// \brief Calls the lookup callback
      67                 :          1 :     virtual void asyncLookup() {
      68         [ +  - ]:          2 :         isc_throw(Unexpected,
      69                 :            :                   "SyncUDPServer doesn't support asyncLookup by design, use "
      70                 :            :                   "UDPServer if you need it.");
      71                 :            :     }
      72                 :            : 
      73                 :            :     /// \brief Stop the running server
      74                 :            :     /// \note once the server stopped, it can't restart
      75                 :            :     virtual void stop();
      76                 :            : 
      77                 :            :     /// \brief Resume operation
      78                 :            :     ///
      79                 :            :     /// Note that unlike other servers, this one expects it to be called
      80                 :            :     /// directly from the lookup callback. If it isn't, the server will
      81                 :            :     /// throw an Unexpected exception (probably to the event loop, which
      82                 :            :     /// would usually lead to termination of the program, but that's OK,
      83                 :            :     /// as it would be serious programmer error).
      84                 :            :     ///
      85                 :            :     /// \param done Set this to true if the lookup action is done and
      86                 :            :     ///        we have an answer
      87                 :            :     virtual void resume(const bool done);
      88                 :            : 
      89                 :            :     /// \brief Check if we have an answer
      90                 :            :     ///
      91                 :            :     /// \return true if we have an answer
      92                 :            :     virtual bool hasAnswer();
      93                 :            : 
      94                 :            :     /// \brief Clones the object
      95                 :            :     ///
      96                 :            :     /// Since cloning is for the use of coroutines, the synchronous UDP server
      97                 :            :     /// does not need to be cloned. Therefore supporting it would be needless
      98                 :            :     /// work, and trying to clone it would be a programmer error anyway, this
      99                 :            :     /// throws Unexpected.
     100                 :            :     ///
     101                 :            :     /// \return a newly allocated copy of this object
     102                 :          1 :     virtual DNSServer* clone() {
     103         [ +  - ]:          2 :         isc_throw(Unexpected, "SyncUDPServer can't be cloned.");
     104                 :            :     }
     105                 :            : private:
     106                 :            :     // Internal state & buffers. We don't use the PIMPL idiom, as this class
     107                 :            :     // isn't usually used directly anyway.
     108                 :            : 
     109                 :            :     // Maximum size of incoming UDP packet
     110                 :            :     static const size_t MAX_LENGTH = 4096;
     111                 :            :     // Buffer for incoming data
     112                 :            :     uint8_t data_[MAX_LENGTH];
     113                 :            :     // The buffer to render the output to and send it.
     114                 :            :     // If it was OK to have just a buffer, not the wrapper class,
     115                 :            :     // we could reuse the data_
     116                 :            :     isc::util::OutputBufferPtr output_buffer_;
     117                 :            :     // Objects to hold the query message and the answer
     118                 :            :     isc::dns::MessagePtr query_, answer_;
     119                 :            :     // The socket used for the communication
     120                 :            :     std::auto_ptr<asio::ip::udp::socket> socket_;
     121                 :            :     // The event loop we use
     122                 :            :     asio::io_service& io_;
     123                 :            :     // Place the socket puts the sender of a packet when it is received
     124                 :            :     asio::ip::udp::endpoint sender_;
     125                 :            :     // Callbacks
     126                 :            :     const asiolink::SimpleCallback* checkin_callback_;
     127                 :            :     const DNSLookup* lookup_callback_;
     128                 :            :     const DNSAnswer* answer_callback_;
     129                 :            :     // Answers from the lookup callback (not sent directly, but signalled
     130                 :            :     // through resume()
     131                 :            :     bool resume_called_, done_;
     132                 :            :     // This turns true when the server stops. Allows for not sending the
     133                 :            :     // answer after we closed the socket.
     134                 :            :     bool stopped_;
     135                 :            : 
     136                 :            :     // Auxiliary functions
     137                 :            : 
     138                 :            :     // Schedule next read on the socket. Just a wrapper around
     139                 :            :     // socket_->async_read_from with the correct parameters.
     140                 :            :     void scheduleRead();
     141                 :            :     // Callback from the socket's read call (called when there's an error or
     142                 :            :     // when a new packet comes).
     143                 :            :     void handleRead(const asio::error_code& ec, const size_t length);
     144                 :            : };
     145                 :            : 
     146                 :            : } // namespace asiodns
     147                 :            : } // namespace isc
     148                 :            : #endif // __SYNC_UDP_SERVER_H

Generated by: LCOV version 1.9