socket_request.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. #ifndef __SOCKET_REQUEST_H
  15. #define __SOCKET_REQUEST_H 1
  16. #include <exceptions/exceptions.h>
  17. #include <boost/noncopyable.hpp>
  18. #include <utility>
  19. #include <string>
  20. #include <stdint.h>
  21. namespace isc {
  22. namespace cc {
  23. class AbstractSession;
  24. };
  25. namespace server_common {
  26. /// \brief A singleton class for requesting sockets
  27. ///
  28. /// This class allows requesting sockets from the socket creator.
  29. ///
  30. /// It is considered to be a singleton - a class which is instantiated
  31. /// at most once in the whole application. This is because it makes no
  32. /// sense to have two of them.
  33. ///
  34. /// This is actually an abstract base class. There'll be one with
  35. /// hidden implementation and we expect the tests to create its own
  36. /// subclass when needed.
  37. ///
  38. /// \see socketRequestor function to access the object of this class.
  39. class SocketRequestor : boost::noncopyable {
  40. protected:
  41. /// \brief Protected constructor
  42. ///
  43. /// The constructor is protected so this class is not created by accident
  44. /// (which it can't anyway, as it has pure virtual methods, but just to
  45. /// be sure).
  46. SocketRequestor() {}
  47. public:
  48. /// \brief virtual destructor
  49. ///
  50. /// A virtual destructor, as we have virtual methods, to make sure it is
  51. /// destroyed by the destructor of the subclass. This shouldn't matter, as
  52. /// a singleton class wouldn't get destroyed, but just to be sure.
  53. virtual ~ SocketRequestor() {}
  54. /// \brief A representation of received socket
  55. ///
  56. /// The pair holds two parts. The OS-level file descriptor acting as the
  57. /// socket (you might want to use it directly with functions like recv,
  58. /// or fill it into an asio socket). The other part is the token
  59. /// representing the socket, which allows it to be given up again.
  60. typedef std::pair<int, std::string> SocketID;
  61. /// \brief The protocol of requested socket
  62. ///
  63. /// This describes which protocol the socket should have when created.
  64. enum Protocol {
  65. UDP,
  66. TCP
  67. };
  68. /// \brief The share mode of the requested socket
  69. ///
  70. /// The socket creator is able to "borrow" the same socket to multiple
  71. /// applications at once. However, it isn't always what is required. This
  72. /// describes the restrains we want to have on our socket regarding the
  73. /// sharing. Union of restriction of all requests on the given socket
  74. /// is taken (so you still don't have to get your socket even if you
  75. /// say SHARE_ANY, because someone else might already asked for the socket
  76. /// with DONT_SHARE).
  77. enum ShareMode {
  78. DONT_SHARE, //< Request an exclusive ownership of the socket.
  79. SHARE_SAME, //< It is possible to share the socket with anybody who
  80. //< provided the same share_name.
  81. SHARE_ANY //< Any sharing is allowed.
  82. };
  83. /// \brief Exception when we can't manipulate a socket
  84. ///
  85. /// This is thrown if the other side doesn't want to comply to our
  86. /// requests, like when we ask for a socket already held by someone
  87. /// else or ask for nonsense (releasing a socket we don't own).
  88. class SocketError : public Exception {
  89. public:
  90. SocketError(const char* file, size_t line, const char* what) :
  91. Exception(file, line, what)
  92. { }
  93. };
  94. /// \brief Exception when we can't return a requested socket, but we're
  95. /// sure we could return others
  96. ///
  97. /// This is thrown if the requested socket can't be granted, but it is only
  98. /// that one socket, not that the system would be broken or anything. This
  99. /// exception is a common base class for the concrete exceptions actually
  100. /// thrown.
  101. ///
  102. /// \see ShareError
  103. /// \see SocketAllocateError
  104. class NonFatalSocketError : public SocketError {
  105. public:
  106. NonFatalSocketError(const char* file, size_t line, const char* what) :
  107. SocketError(file, line, what)
  108. { }
  109. };
  110. /// \brief Exception when the socke is allocated by other bind10 module
  111. /// and it doesn't want to share it.
  112. ///
  113. /// This is thrown if a socket is requested and the socket is already
  114. /// allocated by bind10, but other bind10 module(s) is using it and
  115. /// the sharing parameters are incompatible (the socket can't be shared
  116. /// between the module and our module).
  117. class ShareError : public NonFatalSocketError {
  118. public:
  119. ShareError(const char* file, size_t line, const char* what) :
  120. NonFatalSocketError(file, line, what)
  121. { }
  122. };
  123. /// \brief Exception when the operation system doesn't allow us to create
  124. /// the requested socket.
  125. ///
  126. /// This happens when the socket() or bind() call fails in the socket
  127. /// creator. This can happen when the address/port pair is already taken
  128. /// by a different application, the socket creator doesn't have enough
  129. /// privileges, or for some kind of similar reason.
  130. class SocketAllocateError : public NonFatalSocketError {
  131. SocketAllocateError(const char* file, size_t line, const char* what) :
  132. NonFatalSocketError(file, line, what)
  133. { }
  134. };
  135. /// \brief Ask for a socket
  136. ///
  137. /// Asks the socket creator to give us a socket. The socket will be bound
  138. /// to the given address and port.
  139. ///
  140. /// \param protocol specifies the protocol of the socket. This must be
  141. /// either UDP or TCP.
  142. /// \param address to which the socket should be bound.
  143. /// \param port the port to which the socket should be bound (native endian,
  144. /// not network byte order).
  145. /// \param share_mode how the socket can be shared with other requests.
  146. /// This must be one of the defined values of ShareMode.
  147. /// \param share_name the name of sharing group, relevant for SHARE_SAME
  148. /// (specified by us or someone else).
  149. /// \return the socket, as a file descriptor and token representing it on
  150. /// the socket creator side.
  151. ///
  152. /// \throw InvalidParameter protocol or share_mode is invalid
  153. /// \throw CCSessionError when we have a problem talking over the CC
  154. /// session.
  155. /// \throw SocketError in case the other side doesn't want to give us
  156. /// the socket for some reason (common cases are when the socket
  157. /// can't be allocated or bound, or when the socket is claimed by
  158. /// some other application and the sharing parameters don't allow
  159. /// sharing it).
  160. virtual SocketID requestSocket(Protocol protocol,
  161. const std::string& address,
  162. uint16_t port, ShareMode share_mode,
  163. const std::string& share_name) = 0;
  164. /// \brief Tell the socket creator we no longer need the socket
  165. ///
  166. /// Releases the identified socket. This must be called *after*
  167. /// the file descriptor was closed on our side. This will allow
  168. /// the remote side to either give it to some other application
  169. /// or close it, depending on the situation.
  170. ///
  171. /// \param token the token representing the socket, as received
  172. /// in the second part of the requestSocket result.
  173. /// \throw CCSessionError when we have a problem talking over the CC
  174. /// session.
  175. /// \throw SocketError in case the other side doesn't like the
  176. /// release (like we're trying to release a socket that doesn't
  177. /// belong to us or exist at all).
  178. virtual void releaseSocket(const std::string& token) = 0;
  179. };
  180. /// \brief Access the requestor object.
  181. ///
  182. /// This returns the singleton object for the Requestor.
  183. ///
  184. /// \return the active socket requestor object.
  185. /// \throw InvalidOperation if the object was not yet initialized.
  186. /// \see SocketRequestor::init to initialize the object.
  187. SocketRequestor& socketRequestor();
  188. /// \brief Initialize the singleton object
  189. ///
  190. /// This creates the object that will be used to request sockets.
  191. /// It can be called only once per the life of application.
  192. ///
  193. /// \param session the CC session that'll be used to talk to the
  194. /// socket creator.
  195. /// \throw InvalidOperation when it is called more than once
  196. void initSocketRequestor(cc::AbstractSession& session);
  197. /// \brief Initialization for tests
  198. ///
  199. /// This is to support different subclasses in tests. It replaces
  200. /// the object used by socketRequestor() function by this one provided
  201. /// as parameter. The ownership is not taken, eg. it's up to the caller
  202. /// to delete it when necessary.
  203. ///
  204. /// This is not to be used in production applications. It is meant as
  205. /// an replacement of init.
  206. ///
  207. /// This never throws.
  208. ///
  209. /// \param requestor the object to be used. It can be NULL to reset to
  210. /// an "virgin" state (which acts as if initTest or init was never
  211. /// called before).
  212. void initTestSocketRequestor(SocketRequestor* requestor);
  213. /// \brief Destroy the singleton instance
  214. ///
  215. /// Calling this function is not strictly necessary; the socket
  216. /// requestor is a singleton anyway. However, for some tests it
  217. /// is useful to destroy and recreate it, as well as for programs
  218. /// that want to be completely clean on exit.
  219. /// After this function has been called, all operations except init
  220. /// will fail.
  221. void cleanupSocketRequestor();
  222. }
  223. }
  224. #endif // __SOCKET_REQUEST_H